Index: /GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj	(revision 1099)
+++ /GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj	(revision 1106)
@@ -544,263 +544,4 @@
 			</File>
 		</Filter>
-		<Filter
-			Name="mixkit"
-			Filter="">
-			<File
-				RelativePath="..\src\mixkit\getopt.c">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\getopt.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\getopt1.c">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\mixio.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\mixmops.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\mixmops.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\mixmsg.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\mixmsg.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\mixvops.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxArcball.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxArcball.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxAsp.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxAsp.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxBlock.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxBlock2.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxBlock3.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxBlockModel.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxBlockModel.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxCamera.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxCamera.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxCmdParser.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxCmdParser.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxDynBlock.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxEdgeFilter.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxEdgeFilter.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGeom3D.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGeom3D.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGeoPrims.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGL.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGLDebug.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGLPane.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGLPane.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGLUtils.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxGLUtils.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxHeap.cxx">
-				<FileConfiguration
-					Name="Debug|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)/$(InputName)1.obj"/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32">
-					<Tool
-						Name="VCCLCompilerTool"
-						ObjectFile="$(IntDir)/$(InputName)1.obj"/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxHeap.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxLineModel.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxManipulator.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat2.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat2.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat3-jacobi.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat3.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat3.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat4-jacobi.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat4.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMat4.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMath.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMatrix.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxMatrix.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxPropSlim.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxPropSlim.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQMetric.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQMetric.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQMetric2.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQMetric2.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQMetric3.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQMetric3.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQSlim.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQSlim.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxQVis3.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxRaster-tiff.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxRaster.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxRaster.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxSMF.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxSMF.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStack.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdModel.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdModel.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdPane.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdPane.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdRender.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdSlim.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxStdSlim.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxTimer.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxTimer.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxTriProject.cxx">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxVec2.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxVec3.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxVec4.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\MxVector.h">
-			</File>
-			<File
-				RelativePath="..\src\mixkit\stdmix.h">
-			</File>
-		</Filter>
 		<File
 			RelativePath=".\VTune\Preprocessor.vpj">
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1077)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1106)
@@ -11,4 +11,5 @@
 #include "VssTree.h"
 #include "VspBspTree.h"
+#include "VspOspTree.h"
 #include "RssTree.h"
 #include "Beam.h"
@@ -595,77 +596,4 @@
 }
 
-#if 0
-bool VrmlExporter::ExportVspOspTree(const VspOspTree &tree, 
-								   const int maxPvs)
-{
-	stack<VspKdNode *> tStack;
-
-	tStack.push(tree.GetRoot());
-
-	//Mesh *mesh = new Mesh;
-  
-	if (maxPvs)
-		mUseForcedMaterial = true;
-
-	while (!tStack.empty()) 
-	{
-		VspKdNode *node = tStack.top();
-    
-		tStack.pop();
-
-		if (node->IsLeaf())
-		{
-			AxisAlignedBox3 box = tree.GetBBox(node);
-
-			Mesh *mesh = new Mesh;
-
-			// add 6 vertices of the box
-			int index = (int)mesh->mVertices.size();
-
-			for (int i=0; i < 8; ++ i) 
-			{
-				Vector3 v;
-				box.GetVertex(i, v);
-				mesh->mVertices.push_back(v);
-			}
-
-			mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
-			mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
-			mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
-
-			mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
-			mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
-			mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
-
-			if (maxPvs)
-			{
-				VspKdLeaf *leaf = dynamic_cast<VspKdLeaf *>(node);
-
-				mForcedMaterial.mDiffuseColor.b = 1.0f;
-				
-				leaf->UpdatePvsSize();
-			
-				const float importance = (float)leaf->GetPvsSize() / (float)maxPvs;
-				mForcedMaterial.mDiffuseColor.r = importance;
-				mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
-			}
-
-			ExportMesh(mesh);
-			DEL_PTR(mesh);
-		}
-		else  
-		{
-			VspKdInterior *interior = dynamic_cast<VspKdInterior *>(node);
-			tStack.push(interior->GetFront());
-			tStack.push(interior->GetBack());
-		}
-	}
-  
-	//ExportMesh(mesh);
-	//DEL_PTR(mesh);
-
-	return true;
-}
-#endif
 
 bool VrmlExporter::ExportKdTree(const KdTree &tree)
@@ -685,11 +613,11 @@
 	 {
 		 KdNode *node = tStack.top();
-		 
+
 		 tStack.pop();
-		 
+
 		 AxisAlignedBox3 box = tree.GetBox(node);
 		 // add 6 vertices of the box
 		 int index = (int)mesh->mVertices.size();
-		 
+
 		 for (int i=0; i < 8; i++) 
 		 {
@@ -703,21 +631,38 @@
 		 mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
 
-		mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
-		mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
-		mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
-
-		if (!node->IsLeaf()) 
-		{
-			KdInterior *interior = (KdInterior *)node;
-			tStack.push(interior->mFront);
-			tStack.push(interior->mBack);
-		}
-  }
-  
-  ExportMesh(mesh);
-
-  delete mesh;
-  return true;
-}
+		 mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
+		 mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
+		 mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
+
+		 if (!node->IsLeaf()) 
+		 {
+			 KdInterior *interior = (KdInterior *)node;
+			 tStack.push(interior->mFront);
+			 tStack.push(interior->mBack);
+		 }
+	 }
+
+	 ExportMesh(mesh);
+
+	 delete mesh;
+	 return true;
+}
+
+
+bool VrmlExporter::ExportOspTree(const OspTree &ospTree)
+{
+	vector<KdLeaf *> leaves;
+	ospTree.CollectLeaves(leaves);
+
+	vector<KdLeaf *>::const_iterator it, it_end = leaves.end();
+
+	for (it = leaves.begin(); it != it_end; ++ it)
+	{
+		ExportBox(ospTree.GetBBox(*it));
+	}
+
+	return true;
+}
+
 
 bool VrmlExporter::ExportVssTree(const VssTree &tree)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1077)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1106)
@@ -1554,8 +1554,7 @@
 		if (!useSpecialAxis || (axis == sAxis))
 		{
-			//-- place split plane using heuristics
-
 			if (mUseCostHeuristics)
 			{
+				//-- place split plane using heuristics
 				nCostRatio[axis] =
 					BestCostRatioHeuristics(*tData.mRays,
@@ -1565,6 +1564,7 @@
 											nPosition[axis]);			
 			}
-			else //-- split plane position is spatial median
-			{
+			else 
+			{
+				//-- split plane position is spatial median
 
 				nPosition[axis] = (box.Min()[axis] + box.Max()[axis]) * 0.5f;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1074)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1106)
@@ -2206,4 +2206,92 @@
 					"1");
 
+	
+/***************************************************************************/
+/*               Object space partition tree related options               */
+/***************************************************************************/
+
+	RegisterOption("OspTree.Construction.randomize",
+		optBool,
+		"osp_construction_randomize=",
+		"false");
+
+	RegisterOption("OspTree.Termination.maxDepth",
+					optInt,
+					"osp_term_max_depth=",
+					"30");
+	
+	RegisterOption("OspTree.Termination.maxLeaves",
+					optInt,
+					"osp_term_max_leaves=",
+					"1000");
+	
+	RegisterOption("OspTree.Termination.minObjects",
+					optInt,
+					"osp_term_min_objects=",
+					"1");
+
+	RegisterOption("OspTree.Termination.minProbability",
+					optFloat,
+					"osp_term_min_objects=",
+					"0.0001");
+
+	RegisterOption("OspTree.Termination.missTolerance",
+					optInt,
+					"osp_term_miss_tolerance=",
+					"4");
+
+	RegisterOption("OspTree.Termination.maxCostRatio",
+					optFloat,
+					"osp_term_max_cost_ratio=",
+					"0.99");
+
+	RegisterOption("OspTree.Termination.minGlobalCostRatio",
+					optFloat,
+					"osp_term_min_global_cost_ratio=",
+					"0.00001");
+
+	RegisterOption("OspTree.Termination.globalCostMissTolerance",
+					optInt,
+					"osp_term_global_cost_miss_tolerance=",
+					"4");
+
+	RegisterOption("OspTree.Termination.ct_div_ci",
+					optFloat,
+					"osp_term_ct_div_ci=",
+					"0");
+	
+	RegisterOption("OspTree.Construction.epsilon",
+					optFloat,
+					"osp_construction_epsilon=",
+					"0.00001");
+	
+	// if only the driving axis is used for axis aligned split
+	RegisterOption("OspTree.splitUseOnlyDrivingAxis", 
+					optBool, 
+					"osp_split_only_driving_axis=", 
+					"false");
+
+	RegisterOption("OspTree.maxStaticMemory", 
+		optFloat, 
+		"osp_max_static_mem=", 
+		"8.0");
+
+	RegisterOption("OspTree.useCostHeuristics",
+		optBool,
+		"osp_use_cost_heuristics=",
+		"false");
+
+
+	RegisterOption("OspTree.subdivisionStats",
+					optString,
+					"osp_subdivision_stats=",
+					"ospSubdivisionStats.log");
+
+	RegisterOption("OspTree.Construction.splitBorder",
+					optFloat,
+					"osp_construction_split_border=",
+					"0.01");
+
+
 
 	//////////////////////////////////////////////////////////////////////////////////
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1006)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1106)
@@ -27,4 +27,6 @@
 class Mesh;
 class Beam;
+class OspTree;
+
 
 class Exporter
@@ -66,4 +68,7 @@
   virtual bool
   ExportBspTree(const BspTree &tree) = 0;
+
+  virtual bool
+  ExportOspTree(const OspTree &tree) = 0;
 
 //    virtual bool
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 1027)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 1106)
@@ -1094,11 +1094,8 @@
 	mStat.nodes += 2;
 	
-	BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
-
-	
+	BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);	
 	
 	// select subdivision plane
-	BspInterior *interior = 
-		new BspInterior(SelectPlane(leaf, tData)); 
+	BspInterior *interior = new BspInterior(SelectPlane(leaf, tData)); 
 	
 	
@@ -1107,9 +1104,6 @@
 #endif
 	
-
 	// subdivide rays into front and back rays
 	SplitRays(interior->mPlane, *tData.mRays, *frontData.mRays, *backData.mRays);
-	
-	
 
 	// subdivide polygons with plane
@@ -1119,5 +1113,4 @@
 									  *backData.mPolygons, 
 									  coincident);
-
 	
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h	(revision 1006)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h	(revision 1106)
@@ -59,8 +59,8 @@
 				 const Vector3 direction
 				 );
-#if VSP_OPS
+
   bool
-  ExportVspOspTree(const VspOspTree &tree, const int maxPvs);
-#endif
+  ExportOspTree(const OspTree &tree);
+
   bool ExportBspTree(const BspTree &tree);
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 1020)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 1106)
@@ -9,5 +9,5 @@
 #include "Polygon3.h"
 #include "VssRay.h"
-//#include "VspOspTree.h"
+#include "VspOspTree.h"
 #include "VssTree.h"
 #include "VspBspTree.h"
@@ -538,76 +538,4 @@
 }
 
-#if 0
-bool X3dExporter::ExportVspOspTree(const VspOspTree &tree, const int maxPvs)
-{
-	stack<VspKdNode *> tStack;
-
-	tStack.push(tree.GetRoot());
-
-	//Mesh *mesh = new Mesh;
-  
-	if (maxPvs > 0)
-		mUseForcedMaterial = true;
-
-	while (!tStack.empty()) 
-	{
-		VspKdNode *node = tStack.top();
-    
-		tStack.pop();
-
-		if (node->IsLeaf())
-		{
-			AxisAlignedBox3 box = tree.GetBBox(node);
-
-			Mesh *mesh = new Mesh;
-
-			// add 6 vertices of the box
-			int index = (int)mesh->mVertices.size();
-
-			for (int i=0; i < 8; ++ i) 
-			{
-				Vector3 v;
-				box.GetVertex(i, v);
-				mesh->mVertices.push_back(v);
-			}
-
-			mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
-			mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
-			mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
-
-			mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
-			mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
-			mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
-
-			if (maxPvs > 0)
-			{
-				VspKdLeaf *leaf = dynamic_cast<VspKdLeaf *>(node);
-
-				mForcedMaterial.mDiffuseColor.b = 1.0f;
-				
-				leaf->UpdatePvsSize();
-			
-				const float importance = (float)leaf->GetPvsSize() / (float)maxPvs;
-				mForcedMaterial.mDiffuseColor.r = importance;
-				mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
-			}
-
-			ExportMesh(mesh);
-			DEL_PTR(mesh);
-		}
-		else  
-		{
-			VspKdInterior *interior = dynamic_cast<VspKdInterior *>(node);
-			tStack.push(interior->GetFront());
-			tStack.push(interior->GetBack());
-		}
-	}
-  
-	//ExportMesh(mesh);
-	//DEL_PTR(mesh);
-
-	return true;
-}
-#endif
 
 bool X3dExporter::ExportKdTree(const KdTree &tree)
@@ -1309,3 +1237,20 @@
 }
 
-}
+
+bool X3dExporter::ExportOspTree(const OspTree &ospTree)
+{
+	vector<KdLeaf *> leaves;
+	ospTree.CollectLeaves(leaves);
+
+	vector<KdLeaf *>::const_iterator it, it_end = leaves.end();
+
+	for (it = leaves.begin(); it != it_end; ++ it)
+	{
+		ExportBox(ospTree.GetBBox(*it));
+	}
+
+	return true;
+}
+
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1101)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1106)
@@ -22,11 +22,7 @@
 
 #define USE_FIXEDPOINT_T 0
-
+#define COUNT_OBJECTS 1
 
 //-- static members
-
-int VspTree::sFrontId = 0;
-int VspTree::sBackId = 0;
-int VspTree::sFrontAndBackId = 0;
 
 VspTree *VspTree::VspSplitCandidate::sVspTree = NULL;
@@ -379,4 +375,5 @@
 
 	Debug << "******* VSP options ******** " << endl;
+
     Debug << "max depth: " << mTermMaxDepth << endl;
 	Debug << "min PVS: " << mTermMinPvs << endl;
@@ -399,6 +396,9 @@
 	Debug << "minband: " << mMinBand << endl;
 	Debug << "maxband: " << mMaxBand << endl;
-	Debug << "pvs count method: " << mPvsCountMethod << endl;
-
+
+	if (mPvsCountMethod == 0)
+		Debug << "pvs count method: per object" << endl;
+	else
+		Debug << "pvs count method: per kd node" << endl;
 
 	mSplitCandidates = new vector<SortableEntry>;
@@ -504,14 +504,12 @@
 bool VspTree::LocalTerminationCriteriaMet(const VspTraversalData &data) const
 {
-	return
-#if TODO
-		(((int)data.mRays->size() <= mTermMinRays) ||
-		 (data.mPvs <= mTermMinPvs)   ||
-		 (data.mProbability <= mTermMinProbability) ||
-		 (data.GetAvgRayContribution() > mTermMaxRayContribution) ||
-		 (data.mDepth >= mTermMaxDepth));
-#else
-		false;
-#endif
+	return(
+		((int)data.mRays->size() <= mTermMinRays) ||
+		(data.mPvs <= mTermMinPvs)   ||
+		(data.mProbability <= mTermMinProbability) ||
+		(data.GetAvgRayContribution() > mTermMaxRayContribution) ||
+		(data.mDepth >= mTermMaxDepth)
+		);
+		
 }
 
@@ -519,12 +517,9 @@
 bool VspTree::GlobalTerminationCriteriaMet(const VspTraversalData &data) const
 {
-	return
-#if TODO
-		(mOutOfMemory || 
+	return (
+//		mOutOfMemory || 
 		(mVspStats.Leaves() >= mMaxViewCells) || 
-		(mGlobalCostMisses >= mTermGlobalCostMissTolerance));
-#else
-		(mVspStats.Leaves() >= mMaxViewCells) ;		
-#endif
+        (mGlobalCostMisses >= mTermGlobalCostMissTolerance) 
+		);		
 }
 
@@ -729,6 +724,11 @@
 	// and setup child links
 	interior->SetupChildLinks(new VspLeaf(interior), new VspLeaf(interior));
+	
 	// add bounding box
 	interior->SetBoundingBox(tData.mBoundingBox);
+
+	// set front and back leaf
+	frontData.mNode = interior->GetFront();
+	backData.mNode = interior->GetBack();
 
 	interior->mTimeStamp = mTimeStamp ++;
@@ -915,5 +915,4 @@
 			node->mCounter = 1;
 
-			//Debug << "here5 "<<(int)node->mObjects.size() <<" "<< node->mMultipleObjects.size()<< " " <<(int)node->mObjects.size() - node->mMultipleObjects.size()<<endl;
 			// add objects without the objects which are in several kd leaves
 			pvsSize += (int)(node->mObjects.size() - node->mMultipleObjects.size());
@@ -933,5 +932,4 @@
 			if (!object->Mailed())
 			{
-				//Debug << "here233: " << object->mKdLeaves.size() << endl;
 				object->Mail();
 				object->mCounter = 1;
@@ -1322,13 +1320,12 @@
 		sAxis = box.Size().DrivingAxis();
 	}
-	//sAxis = 2;
+	
 	for (int axis = 0; axis < 3; ++ axis)
 	{
 		if (!useSpecialAxis || (axis == sAxis))
 		{
-			//-- place split plane using heuristics
-
 			if (mUseCostHeuristics)
 			{
+				//-- place split plane using heuristics
 				nCostRatio[axis] =
 					EvalLocalCostHeuristics(*tData.mRays,
@@ -1338,6 +1335,8 @@
 											nPosition[axis]);			
 			}
-			else //-- split plane position is spatial median
-			{
+			else
+			{
+				//-- split plane position is spatial median
+
 				nPosition[axis] = (box.Min()[axis] + box.Max()[axis]) * 0.5f;
 
@@ -2545,5 +2544,5 @@
 mTimeStamp(1)
 {
-#if TODO
+
 	bool randomize = false;
 	Environment::GetSingleton()->GetBoolValue("VspTree.Construction.randomize", randomize);
@@ -2552,45 +2551,38 @@
 
 	//-- termination criteria for autopartition
-	Environment::GetSingleton()->GetIntValue("VspTree.Termination.maxDepth", mTermMaxDepth);
-	Environment::GetSingleton()->GetIntValue("VspTree.Termination.minPvs", mTermMinPvs);
-	Environment::GetSingleton()->GetIntValue("VspTree.Termination.minRays", mTermMinRays);
-	Environment::GetSingleton()->GetFloatValue("VspTree.Termination.minProbability", mTermMinProbability);
-	Environment::GetSingleton()->GetFloatValue("VspTree.Termination.maxRayContribution", mTermMaxRayContribution);
-	
-	Environment::GetSingleton()->GetIntValue("VspTree.Termination.missTolerance", mTermMissTolerance);
-	Environment::GetSingleton()->GetIntValue("VspTree.Termination.maxViewCells", mMaxViewCells);
-
+	Environment::GetSingleton()->GetIntValue("OspTree.Termination.maxDepth", mTermMaxDepth);
+	Environment::GetSingleton()->GetIntValue("OspTree.Termination.maxLeaves", mTermMaxLeaves);
+	Environment::GetSingleton()->GetIntValue("OspTree.Termination.minObjects", mTermMinObjects);
+	Environment::GetSingleton()->GetFloatValue("OspTree.Termination.minProbability", mTermMinProbability);
+	
+	Environment::GetSingleton()->GetIntValue("OspTree.Termination.missTolerance", mTermMissTolerance);
+	
 	//-- max cost ratio for early tree termination
-	Environment::GetSingleton()->GetFloatValue("VspTree.Termination.maxCostRatio", mTermMaxCostRatio);
-
-	Environment::GetSingleton()->GetFloatValue("VspTree.Termination.minGlobalCostRatio", mTermMinGlobalCostRatio);
-	Environment::GetSingleton()->GetIntValue("VspTree.Termination.globalCostMissTolerance", mTermGlobalCostMissTolerance);
-
-	// HACK//mTermMinPolygons = 25;
+	Environment::GetSingleton()->GetFloatValue("OspTree.Termination.maxCostRatio", mTermMaxCostRatio);
+
+	Environment::GetSingleton()->GetFloatValue("OspTree.Termination.minGlobalCostRatio", mTermMinGlobalCostRatio);
+	Environment::GetSingleton()->GetIntValue("OspTree.Termination.globalCostMissTolerance", mTermGlobalCostMissTolerance);
+
 
 	//-- factors for bsp tree split plane heuristics
-	Environment::GetSingleton()->GetFloatValue("VspTree.Termination.ct_div_ci", mCtDivCi);
+	Environment::GetSingleton()->GetFloatValue("OspTree.Termination.ct_div_ci", mCtDivCi);
 
 	//-- partition criteria
-	Environment::GetSingleton()->GetFloatValue("VspTree.Construction.epsilon", mEpsilon);
+	Environment::GetSingleton()->GetFloatValue("OspTree.Construction.epsilon", mEpsilon);
 
 	// if only the driving axis is used for axis aligned split
-	Environment::GetSingleton()->GetBoolValue("VspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis);
-	
-	//Environment::GetSingleton()->GetFloatValue("VspTree.maxTotalMemory", mMaxTotalMemory);
-	Environment::GetSingleton()->GetFloatValue("VspTree.maxStaticMemory", mMaxMemory);
-
-	Environment::GetSingleton()->GetBoolValue("VspTree.useCostHeuristics", mUseCostHeuristics);
-	Environment::GetSingleton()->GetBoolValue("VspTree.simulateOctree", mCirculatingAxis);
+	Environment::GetSingleton()->GetBoolValue("OspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis);
+	
+	Environment::GetSingleton()->GetFloatValue("OspTree.maxStaticMemory", mMaxMemory);
+
+	Environment::GetSingleton()->GetBoolValue("OspTree.useCostHeuristics", mUseCostHeuristics);
 
 
 	char subdivisionStatsLog[100];
-	Environment::GetSingleton()->GetStringValue("VspTree.subdivisionStats", subdivisionStatsLog);
+	Environment::GetSingleton()->GetStringValue("OspTree.subdivisionStats", subdivisionStatsLog);
 	mSubdivisionStats.open(subdivisionStatsLog);
 
-	Environment::GetSingleton()->GetFloatValue("VspTree.Construction.minBand", mMinBand);
-	Environment::GetSingleton()->GetFloatValue("VspTree.Construction.maxBand", mMaxBand);
-	
-	mSplitBorder = 0.1f;
+	Environment::GetSingleton()->GetFloatValue("OspTree.Construction.splitBorder", mSplitBorder);
+	//mSplitBorder = 0.1f;
 
 
@@ -2598,12 +2590,12 @@
 
 	Debug << "******* OSP options ******** " << endl;
+
     Debug << "max depth: " << mTermMaxDepth << endl;
-	Debug << "min PVS: " << mTermMinPvs << endl;
 	Debug << "min probabiliy: " << mTermMinProbability << endl;
-	Debug << "min rays: " << mTermMinRays << endl;
-	Debug << "max ray contri: " << mTermMaxRayContribution << endl;
+	Debug << "min objects: " << mTermMinObjects << endl;
 	Debug << "max cost ratio: " << mTermMaxCostRatio << endl;
 	Debug << "miss tolerance: " << mTermMissTolerance << endl;
-	Debug << "max view cells: " << mMaxViewCells << endl;
+	Debug << "max leaves: " << mTermMaxLeaves << endl;
+
 	Debug << "randomize: " << randomize << endl;
 
@@ -2615,13 +2607,10 @@
 	Debug << "subdivision stats log: " << subdivisionStatsLog << endl;
 	
-	Debug << "circulating axis: " << mCirculatingAxis << endl;
-	Debug << "minband: " << mMinBand << endl;
-	Debug << "maxband: " << mMaxBand << endl;
-	
+	Debug << "split borders: " << mSplitBorder << endl;
+
 
 	mSplitCandidates = new vector<SortableEntry>;
 
 	Debug << endl;
-#endif
 }
 
@@ -2630,6 +2619,6 @@
 void OspTree::SplitObjects(const AxisAlignedPlane & splitPlane,
 						   const ObjectContainer &objects,
-						   ObjectContainer &back,
-						   ObjectContainer &front)
+						   ObjectContainer &front,
+						   ObjectContainer &back)
 {
 	ObjectContainer::const_iterator oit, oit_end = objects.end();
@@ -2645,22 +2634,20 @@
 		if (box.Min(splitPlane.mAxis) < splitPlane.mPosition)
 			back.push_back(*oit);
-#if TODO    
-		mStat.objectRefs -= (int)objects.size();
-		mStat.objectRefs += objectsBack + objectsFront;
-#endif
-	}
-}
-
-
-KdInterior *OspTree::SubdivideNode(KdLeaf *leaf,
+	}
+
+	mOspStats.objectRefs -= (int)objects.size();
+	mOspStats.objectRefs += (int)back.size() + (int)front.size();
+}
+
+
+KdInterior *OspTree::SubdivideNode(
+								   KdLeaf *leaf,
 								   const AxisAlignedPlane &splitPlane,
 								   const AxisAlignedBox3 &box,
-								   AxisAlignedBox3 &backBBox,
-								   AxisAlignedBox3 &frontBBox)
-{
-#if TODO
-    mSpatialStat.nodes += 2;
-	mSpatialStat.splits[axis];
-#endif
+								   OspTraversalData &frontData,
+								   OspTraversalData &backData
+								   )
+{
+    mOspStats.nodes += 2;
 
 	// add the new nodes to the tree
@@ -2674,6 +2661,6 @@
 	node->mBox = box;
 
-    backBBox = box;
-	frontBBox = box;
+	backData.mBoundingBox = box;
+	frontData.mBoundingBox = box;
   
 	// first count ray sides
@@ -2681,6 +2668,6 @@
 	int objectsFront = 0;
   
-	backBBox.SetMax(axis, position);
-	frontBBox.SetMin(axis, position);
+	backData.mBoundingBox.SetMax(axis, position);
+	frontData.mBoundingBox.SetMin(axis, position);
 
 	ObjectContainer::const_iterator mi, mi_end = leaf->mObjects.end();
@@ -2701,16 +2688,31 @@
 	KdLeaf *front = new KdLeaf(node, objectsFront);
 
+	/////////////
+	//-- create front and back leaf
+
+	KdInterior *parent = leaf->mParent;
+
 	// replace a link from node's parent
-	if (leaf->mParent)
-		leaf->mParent->ReplaceChildLink(leaf, node);
+	if (parent)
+	{
+		parent->ReplaceChildLink(leaf, node);
+		node->mParent = parent;
+	}
+	else // new root
+	{
+		mRoot = node;
+	}
 
 	// and setup child links
 	node->SetupChildLinks(back, front);
 
-	SplitObjects(splitPlane, leaf->mObjects, back->mObjects, front->mObjects);
+	SplitObjects(splitPlane, leaf->mObjects, front->mObjects, back->mObjects);
 
 	ProcessLeafObjects(back, leaf);
     ProcessLeafObjects(front, leaf);
   
+	backData.mNode = back;
+	frontData.mNode = front;
+
 	//delete leaf;
 	return node;
@@ -2721,14 +2723,15 @@
 						   OspSplitCandidate &splitCandidate,
 						   const bool globalCriteriaMet)
-{
+{Debug << "here11" << endl;
 	OspTraversalData &tData = splitCandidate.mParentData;
-
+Debug << "here993" << endl;
 	KdNode *newNode = tData.mNode;
 
+Debug << "here996" << endl;
 	if (!LocalTerminationCriteriaMet(tData) && !globalCriteriaMet)
 	{	
 		OspTraversalData tFrontData;
 		OspTraversalData tBackData;
-
+Debug << "here3" << endl;
 		//-- continue subdivision
 		
@@ -2739,6 +2742,6 @@
 								splitPlane, 
 								tData.mBoundingBox, 
-								tFrontData.mBoundingBox, 
-								tBackData.mBoundingBox);
+								tFrontData, 
+								tBackData);
 	
 		const int maxCostMisses = splitCandidate.mMaxCostMisses;
@@ -2752,4 +2755,6 @@
 		OspSplitCandidate *backCandidate = new OspSplitCandidate(tBackData);
 
+		Debug << "here 54 " << tFrontData.mNode << " " <<  tBackData.mNode << endl;
+
 		EvalSplitCandidate(*frontCandidate);
 		EvalSplitCandidate(*backCandidate);
@@ -2766,11 +2771,10 @@
 	if (newNode->IsLeaf())
 	{
-		//KdLeaf *leaf = dynamic_cast<KdLeaf *>(newNode);
 		EvaluateLeafStats(tData);		
 	}
-
+	Debug << "here888 "<< endl;
 	//-- cleanup
 	tData.Clear();
-	
+	Debug << "here876"<< endl;
 	return newNode;
 }
@@ -2782,14 +2786,14 @@
 	float backProb;
 	
-	KdLeaf *leaf = dynamic_cast<KdLeaf *>(splitCandidate.mParentData.mNode);
-
 	// compute locally best split plane
 	const bool success = 
 		SelectSplitPlane(splitCandidate.mParentData, splitCandidate.mSplitPlane, frontProb, backProb);
 
-	//TODO
+	const float priority = EvalRenderCostDecrease(splitCandidate.mSplitPlane, splitCandidate.mParentData);
 	// compute global decrease in render cost
-	splitCandidate.SetPriority(EvalRenderCostDecrease(splitCandidate.mSplitPlane, splitCandidate.mParentData));
-	splitCandidate.mMaxCostMisses = success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1;
+	splitCandidate.SetPriority(priority);
+
+	splitCandidate.mMaxCostMisses = 
+		success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1;
 }
 
@@ -2798,10 +2802,9 @@
 {
 	// matt: TODO
-	return true;
-    /*		(((int)data.mRays->size() <= mTermMinRays) ||
-		 (data.mPvs <= mTermMinPvs)   ||
-		 (data.mProbability <= mTermMinProbability) ||
-		 (data.GetAvgRayContribution() > mTermMaxRayContribution) ||
-		 (data.mDepth >= mTermMaxDepth));*/
+	return ( 
+		//(data.mNode->mObjects.size() < mTermMinObjects) ||
+		//(data.mProbability <= mTermMinProbability) ||
+		(data.mDepth >= mTermMaxDepth)
+		 );
 }
 
@@ -2810,8 +2813,10 @@
 {
 	// matt: TODO
-	return true;
-		/*(mOutOfMemory || 
-		(mVspStats.Leaves() >= mMaxViewCells) || 
-		(mGlobalCostMisses >= mTermGlobalCostMissTolerance));*/
+	Debug << "here888 " << mTermMaxLeaves << " " << mOspStats.Leaves() << endl;
+	return (
+		(mOspStats.Leaves() >= mTermMaxLeaves)
+		//mOutOfMemory || 
+		//(mGlobalCostMisses >= mTermGlobalCostMissTolerance)
+		);
 }
 
@@ -2819,56 +2824,42 @@
 void OspTree::EvaluateLeafStats(const OspTraversalData &data)
 {
-#if TODO
 	// the node became a leaf -> evaluate stats for leafs
-	VspLeaf *leaf = dynamic_cast<VspLeaf *>(data.mNode);
-
-	if (data.mPvs > mVspStats.maxPvs)
-	{
-		mVspStats.maxPvs = data.mPvs;
-	}
-
-	mVspStats.pvs += data.mPvs;
-
-	if (data.mDepth < mVspStats.minDepth)
-	{
-		mVspStats.minDepth = data.mDepth;
+	KdLeaf *leaf = data.mNode;
+
+	if (data.mPvs > mOspStats.maxPvs)
+	{
+		mOspStats.maxPvs = data.mPvs;
+	}
+
+	mOspStats.pvs += data.mPvs;
+
+	if (data.mDepth < mOspStats.minDepth)
+	{
+		mOspStats.minDepth = data.mDepth;
 	}
 	
 	if (data.mDepth >= mTermMaxDepth)
 	{
-        ++ mVspStats.maxDepthNodes;
+        ++ mOspStats.maxDepthNodes;
 		//Debug << "new max depth: " << mVspStats.maxDepthNodes << endl;
 	}
 
-	// accumulate rays to compute rays /  leaf
-	mVspStats.accumRays += (int)data.mRays->size();
-
-	if (data.mPvs < mTermMinPvs)
-		++ mVspStats.minPvsNodes;
-
-	if ((int)data.mRays->size() < mTermMinRays)
-		++ mVspStats.minRaysNodes;
-
-	if (data.GetAvgRayContribution() > mTermMaxRayContribution)
-		++ mVspStats.maxRayContribNodes;
+//	if (data.mPvs < mTermMinPvs)
+//		++ mOspStats.minPvsNodes;
 
 	if (data.mProbability <= mTermMinProbability)
-		++ mVspStats.minProbabilityNodes;
+		++ mOspStats.minProbabilityNodes;
 	
 	// accumulate depth to compute average depth
-	mVspStats.accumDepth += data.mDepth;
-
-	++ mCreatedViewCells;
+	mOspStats.accumDepth += data.mDepth;
+
+	++ mCreatedLeaves;
 
 #ifdef _DEBUG
 	Debug << "BSP stats: "
 		  << "Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), "
-		  << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), "
-	  	  << "Area: " << data.mProbability << " (min: " << mTermMinProbability << "), "
-		  << "#rays: " << (int)data.mRays->size() << " (max: " << mTermMinRays << "), "
-		  << "#pvs: " << leaf->GetViewCell()->GetPvs().GetSize() << "), "
-		  << "#avg ray contrib (pvs): " << (float)data.mPvs / (float)data.mRays->size() << endl;
-#endif
-
+		 // << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), "
+	  	  << "Prob: " << data.mProbability << " (min: " << mTermMinProbability << "), "
+		  << "#pvs: " << data.mPvs << ")\n";
 #endif
 }
@@ -2879,6 +2870,6 @@
 									   const int axis,
 									   float &position,
-									   int &objectsBack,
-									   int &objectsFront)
+									   int &objectsFront,
+									   int &objectsBack)
 {
 	
@@ -2889,5 +2880,5 @@
 	// C = ct_div_ci  + (ol + or)/queries
 	
-	int pvsSize = PrepareHeuristics(node->mObjects);;
+	int pvsSize = PrepareHeuristics(node->mObjects);
 	int pvsl = 0, pvsr = pvsSize;
   
@@ -3009,4 +3000,7 @@
 int OspTree::PrepareHeuristics(Intersectable *object)
 {
+#if COUNT_OBJECTS
+	return 1;
+#else
 	ViewCellPvsMap::const_iterator vit, vit_end = object->mViewCellPvs.mEntries.end();
 	
@@ -3030,4 +3024,5 @@
 
 	return pvsSize;
+#endif
 }
 
@@ -3073,6 +3068,21 @@
 
 
+void OspTree::SetViewCellsManager(ViewCellsManager *vcm)
+{
+	mViewCellsManager = vcm;
+}
+
+
+AxisAlignedBox3 OspTree::GetBoundingBox() const
+{
+	return mBoundingBox;
+}
+
+
 void OspTree::RemoveContriFromPvs(Intersectable *object, int &pvs) const
 {
+#if COUNT_OBJECTS
+	-- pvs;
+#else
 	ViewCellPvsMap::const_iterator vit, vit_end = object->mViewCellPvs.mEntries.end();
 	
@@ -3086,4 +3096,5 @@
 		}
 	}
+#endif
 }
 
@@ -3093,4 +3104,7 @@
 	ViewCellPvsMap::const_iterator vit, vit_end = object->mViewCellPvs.mEntries.end();
 
+#if COUNT_OBJECTS
+	++ pvs;
+#else
 	for (vit = object->mViewCellPvs.mEntries.begin(); vit != vit_end; ++ vit)
 	{
@@ -3103,4 +3117,5 @@
 		}
 	}
+#endif
 }
 
@@ -3127,23 +3142,26 @@
 	}
 
-/*
-	//sAxis = 2;
+	// -- evaluate split cost for all three axis
 	for (int axis = 0; axis < 3; ++ axis)
 	{
 		if (!mOnlyDrivingAxis || (axis == sAxis))
 		{
-			//-- place split plane using heuristics
-
-			if (mUseCostHeuristics)
-			{
+			if (1 || mUseCostHeuristics)
+			{
+				//-- place split plane using heuristics
+				int objectsFront, objectsBack;
+
 				nCostRatio[axis] =
-					EvalLocalCostHeuristics(*tData.mRays,
-											box,
-											tData.mPvs,
-											axis,
-											nPosition[axis]);			
-			}
-			else //-- split plane position is spatial median
-			{
+					EvalLocalCostHeuristics(tData.mNode,
+									   tData.mBoundingBox,
+									   axis,
+									   nPosition[axis],
+									   objectsFront,
+									   objectsBack);			
+			}
+			/*	else 
+			{
+				//-- split plane position is spatial median
+
 				nPosition[axis] = (box.Min()[axis] + box.Max()[axis]) * 0.5f;
 
@@ -3154,5 +3172,5 @@
 													  nProbFront[axis], 
 													  nProbBack[axis]);
-			}
+			}*/
 						
 			if (bestAxis == -1)
@@ -3167,7 +3185,6 @@
 	}
 
-*/
 	//-- assign values
-	
+
 	plane.mAxis = bestAxis;
 	// split plane position
@@ -3184,5 +3201,6 @@
 float OspTree::EvalViewCellPvsIncr(Intersectable *object) const
 {
-	return 0;
+	// TODO		
+	return 1;
 }
 
@@ -3206,7 +3224,8 @@
 
 	Intersectable::NewMail();
+	KdLeaf::NewMail();
 	ViewCell::NewMail();
 
-	KdLeaf *leaf = dynamic_cast<KdLeaf *>(data.mNode);
+	KdLeaf *leaf = data.mNode;
 	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
 
@@ -3252,4 +3271,5 @@
 
 	const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume();
+
 	return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost;
 }
@@ -3315,8 +3335,54 @@
 
 
-
-/*********************************************************************/
-/*                class HierarchyManager implementation              */
-/*********************************************************************/
+void OspTree::CollectLeaves(vector<KdLeaf *> &leaves) const
+{
+	stack<KdNode *> nodeStack;
+	nodeStack.push(mRoot);
+
+	while (!nodeStack.empty()) 
+	{
+		KdNode *node = nodeStack.top();
+		nodeStack.pop();
+		if (node->IsLeaf()) 
+		{
+			KdLeaf *leaf = (KdLeaf *)node;
+			leaves.push_back(leaf);
+		}
+		else 
+		{
+			KdInterior *interior = (KdInterior *)node;
+			nodeStack.push(interior->mBack);
+			nodeStack.push(interior->mFront);
+		}
+	}
+}
+
+
+AxisAlignedBox3 OspTree::GetBBox(KdNode *node) const
+{
+	if (!node->mParent)
+		return mBoundingBox;
+
+	if (!node->IsLeaf())
+	{
+		return (dynamic_cast<KdInterior *>(node))->mBox;		
+	}
+
+	KdInterior *parent = dynamic_cast<KdInterior *>(node->mParent);
+
+	AxisAlignedBox3 box(parent->mBox);
+
+	if (parent->mFront == node)
+		box.SetMin(parent->mAxis, parent->mPosition);
+    else
+		box.SetMax(parent->mAxis, parent->mPosition);
+
+	return box;
+}
+
+
+/********************************************************************/
+/*               class HierarchyManager implementation              */
+/********************************************************************/
 
 
@@ -3330,6 +3396,9 @@
 SplitCandidate *HierarchyManager::NextSplitCandidate()
 {
-	SplitCandidate *splitCandidate = static_cast<SplitCandidate *>(mTQueue.Top());
-	//Debug << "priority: " << splitCandidate->GetPriority() << endl;
+	SplitCandidate *splitCandidate = mTQueue.Top();
+
+	Debug << "next candidate: " << splitCandidate->Type()
+		<< ", priority: " << splitCandidate->GetPriority() << endl;
+
 	mTQueue.Pop();
 
@@ -3415,7 +3484,6 @@
 
 	// first osp traversal data
-	OspTree::OspTraversalData oData(mOspTree.mRoot,
+	OspTree::OspTraversalData oData(leaf,
 									0,
-									&rays,
 									pvsSize,
 									prop,
@@ -3455,6 +3523,6 @@
 
 void HierarchyManager::Construct2(const VssRayContainer &sampleRays,
-								 const ObjectContainer &objects,
-								 AxisAlignedBox3 *forcedViewSpace)
+								  const ObjectContainer &objects,
+								  AxisAlignedBox3 *forcedViewSpace)
 {
 	RayInfoContainer *rays = new RayInfoContainer();
@@ -3493,5 +3561,4 @@
 
 	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-
 
 	const int pvsSize = mVspTree.ComputePvsSize(*rays);
@@ -3549,8 +3616,7 @@
 
 	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
-
 	mVspTree.mVspStats.Stop();
-
-
+	
+	Debug << "object space" << endl;
 
 	//-- object space partition
@@ -3566,7 +3632,6 @@
 
 	//-- first osp traversal data
-	OspTree::OspTraversalData oData(mOspTree.mRoot,
+	OspTree::OspTraversalData oData(leaf,
 									0,
-									rays,
 									pvsSize,
 									prop,
@@ -3580,5 +3645,5 @@
     mOspTree.EvalSplitCandidate(*oSplitCandidate);
 
-	mTQueue.Push(splitCandidate);
+	mTQueue.Push(oSplitCandidate);
 
 	i = 0;
@@ -3590,5 +3655,5 @@
 			GlobalTerminationCriteriaMet(splitCandidate);
 
-		cout << "view cells: " << i ++ << endl;
+		cout << "kd nodes: " << i ++ << endl;
 
 		// cost ratio of cost decrease / totalCost
@@ -3609,5 +3674,5 @@
 		DEL_PTR(splitCandidate);
 	}
-
+	
 	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h	(revision 1006)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h	(revision 1106)
@@ -24,6 +24,6 @@
 class VspBspTree;
 class BspNode;
-//class VspKdViewCell;
 class Beam;
+class OspTree;
 
 class VrmlExporter : public Exporter
@@ -46,4 +46,7 @@
   bool
   ExportKdTree(const KdTree &tree);
+
+  bool
+  ExportOspTree(const OspTree &tree);
 
   bool
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1077)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1106)
@@ -4810,5 +4810,8 @@
 	mHierarchyManager = new HierarchyManager(*vspTree, *ospTree);
 	Environment::GetSingleton()->GetIntValue("VspTree.Construction.samples", mInitialSamples);
+
 	mVspTree->SetViewCellsManager(this);
+	mOspTree->SetViewCellsManager(this);
+
 	mVspTree->mViewCellsTree = mViewCellsTree;
 }
@@ -4881,5 +4884,5 @@
 	long startTime;
 
-	mHierarchyManager->Construct(constructionRays, objects, &mViewSpaceBox);
+	mHierarchyManager->Construct2(constructionRays, objects, &mViewSpaceBox);
 
 	
@@ -5229,8 +5232,8 @@
 	GetRaySets(sampleRays, mVisualizationSamples, visRays);
 
-	//-- export final view cells
-
 	if (1) 
 	{	
+		//-- export final view cells
+
 		// hack pvs
 		const int savedColorCode = mColorCode;
@@ -5266,6 +5269,5 @@
 			// HACK: export without clip plane
 			const bool b = mUseClipPlaneForViz;
-			if (0)
-				mUseClipPlaneForViz = false;
+			if (0) mUseClipPlaneForViz = false;
 
 			ExportViewCellsForViz(exporter);
@@ -5278,4 +5280,33 @@
 
 		mColorCode = savedColorCode;
+	}
+
+	if (1) 
+	{	
+		//-- export final object partition
+		Exporter *exporter = Exporter::GetExporter("final_object_partition.wrl");
+		
+		if (exporter)
+		{
+			cout << "exporting object space partition ... ";
+
+			if (mExportGeometry)
+			{
+				exporter->ExportGeometry(objects);
+			}
+
+			// export rays
+			if (0 && mExportRays)
+			{
+				exporter->ExportRays(visRays, RgbColor(0, 1, 0));
+			}
+
+			exporter->SetWireframe();
+			exporter->ExportOspTree(*mOspTree);
+
+			delete exporter;
+
+			cout << "finished" << endl;
+		}
 	}
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1101)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1106)
@@ -181,6 +181,4 @@
 	int splits[3];
 	
-	// totals number of rays
-	int rays;
 	// maximal reached depth
 	int maxDepth;
@@ -194,14 +192,11 @@
 	// max depth nodes
 	int minPvsNodes;
-	// nodes with minimum PVS
-	int minRaysNodes;
-	// max ray contribution nodes
-	int maxRayContribNodes;
 	// minimum area nodes
 	int minProbabilityNodes;
 	/// nodes termination because of max cost ratio;
 	int maxCostNodes;
-	// max number of rays per node
+	// max number of objects per node
 	int maxObjectRefs;
+	int objectRefs;
 	/// samples contributing to pvs
 	int contributingSamples;
@@ -214,5 +209,7 @@
 	/// accumulated number of rays refs
 	int accumRays;
+	/// potentially visible objects from this leaf
 	int pvs;
+
 	// accumulated depth (used to compute average)
 	int accumDepth;
@@ -230,5 +227,5 @@
 	// TODO: computation wrong
 	double AvgDepth() const { return accumDepth / (double)Leaves();}; 
-	double AvgRays() const { return accumRays / (double)Leaves();}; 
+	
 
 	void Reset() 
@@ -244,6 +241,5 @@
 		maxDepthNodes = 0;
 		minPvsNodes = 0;
-		minRaysNodes = 0;
-		maxRayContribNodes = 0;
+	
 		minProbabilityNodes = 0;
 		maxCostNodes = 0;
@@ -254,6 +250,7 @@
 		maxPvs = 0;
 		invalidLeaves = 0;
-		accumRays = 0;
+		objectRefs = 0;
 	}
+
 
 	void Print(ostream &app) const;
@@ -558,5 +555,5 @@
 	public:
 		static VspTree* sVspTree;
-		/// parent data
+		/// parent node traversal data
 		VspTraversalData mParentData;
 		
@@ -619,5 +616,5 @@
 	/** Returns box which bounds the whole tree.
 	*/
-	AxisAlignedBox3 GetBoundingBox()const;
+	AxisAlignedBox3 GetBoundingBox() const;
 
 	/** Returns root of the view space partitioning tree.
@@ -1060,14 +1057,4 @@
 	/// number of currenly generated view cells
 	int mCreatedViewCells;
-
-private:
-
-	/// Generates unique ids for PVS criterium
-	static void GenerateUniqueIdsForPvs();
-
-	//-- unique ids for PVS criterium
-	static int sFrontId; 
-	static int sBackId;
-	static int sFrontAndBackId;
 };
 
@@ -1088,9 +1075,9 @@
 	public:
 		/// the current node
-		KdNode *mNode;
+		KdLeaf *mNode;
 		/// current depth
 		int mDepth;
 		/// rays piercing this node
-		RayInfoContainer *mRays;
+		//RayInfoContainer *mRays;
 		/// the probability that this node contains view point
 		float mProbability;
@@ -1106,17 +1093,8 @@
 		float mPriority;
 
-		
-		/** Returns average ray contribution.
-		*/
-		float GetAvgRayContribution() const
-		{
-			return (float)mPvs / ((float)mRays->size() + Limits::Small);
-		}
-
 
 		OspTraversalData():
 		mNode(NULL),
 		mDepth(0),
-		mRays(NULL),
 		mPvs(0),
 		mProbability(0.0),
@@ -1126,7 +1104,6 @@
 		{}
 		
-		OspTraversalData(KdNode *node, 
+		OspTraversalData(KdLeaf *node, 
 						 const int depth, 
-						 RayInfoContainer *rays,
 						 const int pvs,
 						 const float p,
@@ -1134,5 +1111,4 @@
 		mNode(node), 
 		mDepth(depth), 
-		mRays(rays),
 		mPvs(pvs),
 		mProbability(p),
@@ -1144,9 +1120,7 @@
 
 		OspTraversalData(const int depth, 
-						 RayInfoContainer *rays,
 						 const AxisAlignedBox3 &box): 
 		mNode(NULL), 
 		mDepth(depth), 
-		mRays(rays),
 		mPvs(0),
 		mProbability(0),
@@ -1167,5 +1141,4 @@
 		void Clear()
 		{
-			DEL_PTR(mRays);
 		}
 
@@ -1189,5 +1162,5 @@
 		{};
 
-		int Type() const { return VIEW_SPACE; }
+		int Type() const { return OBJECT_SPACE; }
 	
 		void EvalPriority()
@@ -1231,16 +1204,16 @@
 	/** Returns bounding box of the specified node.
 	*/
-	AxisAlignedBox3 GetBoundingBox(KdNode *node) const;
-
-	/** Returns list of BSP leaves with pvs smaller than
+	AxisAlignedBox3 GetBBox(KdNode *node) const;
+
+	/** Returns list of leaves with pvs smaller than
 		a certain threshold.
 		@param onlyUnmailed if only the unmailed leaves should be considered
 		@param maxPvs the maximal pvs of a leaf to be added (-1 means unlimited)
 	*/
-	void CollectLeaves(vector<VspLeaf *> &leaves, 
-					   const bool onlyUnmailed = false,
-					   const int maxPvs = -1) const;
-
-	/** Returns box which bounds the whole tree.
+	
+	void CollectLeaves(vector<KdLeaf *> &leaves) const;
+
+
+	/** Returns bounding box of the whole tree (= bbox of root node)
 	*/
 	AxisAlignedBox3 GetBoundingBox()const;
@@ -1406,14 +1379,14 @@
 		@returns the root of the subdivision
 	*/
+	KdInterior *SubdivideNode(KdLeaf *leaf,
+		const AxisAlignedPlane &splitPlane,
+		const AxisAlignedBox3 &box,
+		OspTraversalData &frontData,
+		OspTraversalData &backData);
+
 	void SplitObjects(const AxisAlignedPlane & splitPlane,
 					  const ObjectContainer &objects,
-					  ObjectContainer &back,
-					  ObjectContainer &front);
-
-	KdInterior *SubdivideNode(KdLeaf *leaf,
-							  const AxisAlignedPlane &splitPlane,
-							  const AxisAlignedBox3 &box,
-							  AxisAlignedBox3 &backBBox,
-							  AxisAlignedBox3 &frontBBox);
+					  ObjectContainer &front,
+					  ObjectContainer &back);
 
 	void ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const;
@@ -1439,6 +1412,6 @@
 		const int axis,
 		float &position,
-		int &objectsBack,
-		int &objectsFront);
+		int &objectsFront,
+		int &objectsBack);
 
 	/** Subdivides the rays into front and back rays according to the split plane.
@@ -1553,12 +1526,10 @@
 	//-- local termination
 
-	/// minimal number of rays before subdivision termination
-	int mTermMinRays;
 	/// maximal possible depth
 	int mTermMaxDepth;
 	/// mininum probability
 	float mTermMinProbability;
-	/// mininum PVS
-	int mTermMinPvs;
+	/// minimal number of objects
+	int mTermMinObjects;
 	/// maximal contribution per ray
 	float mTermMaxRayContribution;
@@ -1569,4 +1540,5 @@
 
 
+
 	//-- global criteria
 	float mTermMinGlobalCostRatio;
@@ -1575,5 +1547,5 @@
 
 	/// maximal number of view cells
-	int mMaxViewCells;
+	int mTermMaxLeaves;
 	/// maximal tree memory
 	float mMaxMemory;
@@ -1590,14 +1562,5 @@
 	/// if only driving axis should be used for split
 	bool mOnlyDrivingAxis;
-	/// if random split axis should be used
-	bool mUseRandomAxis;
-	/// if vsp bsp tree should simulate octree
-	bool mCirculatingAxis;
-	/// minimal relative position where the split axis can be placed
-	float mMinBand;
-	/// maximal relative position where the split axis can be placed
-	float mMaxBand;
-
-
+	
 	/// current time stamp (used for keeping split history)
 	int mTimeStamp;
@@ -1616,18 +1579,8 @@
 	int mTotalPvsSize;
 	/// number of currenly generated view cells
-	int mCreatedViewCells;
-
+	int mCreatedLeaves;
+
+	/// represents min and max band for sweep
 	float mSplitBorder;
-
-
-private:
-
-	/// Generates unique ids for PVS criterium
-	static void GenerateUniqueIdsForPvs();
-
-	//-- unique ids for PVS criterium
-	static int sFrontId; 
-	static int sBackId;
-	static int sFrontAndBackId;
 };
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/FlexibleHeap.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/FlexibleHeap.h	(revision 1099)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/FlexibleHeap.h	(revision 1106)
@@ -193,5 +193,5 @@
 		return NULL;
 
-	Swap(0, mBuffer.size() - 1);
+	Swap(0, (int)mBuffer.size() - 1);
 
 	T dead = mBuffer.back();
