Index: /GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 1283)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 1286)
@@ -70,5 +70,11 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				Optimization="0"
+				Optimization="3"
+				GlobalOptimizations="TRUE"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="TRUE"
+				FavorSizeOrSpeed="1"
+				OptimizeForProcessor="3"
+				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="..\include;..\..\..\..\..\..\NonGTP\Boost;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\MultiLevelRayTracing"
 				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
@@ -76,4 +82,5 @@
 				RuntimeTypeInfo="TRUE"
 				UsePrecompiledHeader="0"
+				BrowseInformation="1"
 				WarningLevel="3"
 				Detect64BitPortabilityProblems="TRUE"
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1283)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1286)
@@ -425,6 +425,4 @@
 		// default view space is the extent of the scene
 		mViewCellsManager->SetViewSpaceBox(mSceneGraph->GetBox());
-
-
 	}
 	
@@ -1231,4 +1229,5 @@
 }
 
+
 int Preprocessor::CastRay(
 						  const Vector3 &viewPoint,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 1283)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 1286)
@@ -61,7 +61,12 @@
 			<Tool
 				Name="VCCLCompilerTool"
-				Optimization="0"
-				InlineFunctionExpansion="0"
-				FavorSizeOrSpeed="0"
+				Optimization="3"
+				GlobalOptimizations="TRUE"
+				InlineFunctionExpansion="2"
+				EnableIntrinsicFunctions="TRUE"
+				FavorSizeOrSpeed="1"
+				OmitFramePointers="TRUE"
+				EnableFiberSafeOptimizations="TRUE"
+				OptimizeForProcessor="3"
 				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="..\include;..\src;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\..\..\..\..\NonGTP\Boost"
@@ -73,4 +78,5 @@
 				RuntimeTypeInfo="TRUE"
 				UsePrecompiledHeader="0"
+				BrowseInformation="1"
 				WarningLevel="2"
 				Detect64BitPortabilityProblems="TRUE"
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1283)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1286)
@@ -100,4 +100,6 @@
 	HierarchyManager(VspTree *vspTree, KdTree *kdTree);
 
+	~HierarchyManager();
+
 	/** Constructs the view space and object space subdivision from a given set of rays
 		and a set of objects.
@@ -153,5 +155,5 @@
 
 	void ExportObjectSpaceHierarchyForViz(const ObjectContainer &objects) const;
-    ~HierarchyManager();
+
 
 protected:
@@ -197,4 +199,16 @@
 	void CollectObjectSpaceDirtyList(SubdivisionCandidateContainer &dirtyList);
 		
+	void ExportOspTreeForViz(const ObjectContainer &objects) const;
+	void ExportBvhForViz(const ObjectContainer &objects) const;
+
+	void ConstructBvHierarchy(
+		const VssRayContainer &sampleRays,
+		const ObjectContainer &objects,
+		AxisAlignedBox3 *forcedViewSpace);
+
+	void ConstructOspTree(
+		const VssRayContainer &sampleRays,
+		const ObjectContainer &objects,
+		AxisAlignedBox3 *forcedViewSpace);
 
 protected:
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1279)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1286)
@@ -1454,4 +1454,14 @@
 
 
+void BvHierarchy::ExportObjects(BvhLeaf *leaf, OUT_STREAM &stream)
+{
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		stream << (*oit)->GetId() << " ";
+	}
+}
+
+
 void BvHierarchy::ExportNode(BvhNode *node, OUT_STREAM &stream)
 {
@@ -1460,12 +1470,13 @@
 		BvhLeaf *leaf = dynamic_cast<BvhLeaf *>(node);
 
-		stream << "<Leaf ";
-		stream << "objects=\"";
+		stream << "<Leaf"
+			   << " min=\"" << leaf->GetBoundingBox().Min()
+			   << " max=\"" << leaf->GetBoundingBox().Max() 
+			   << " objects=\"";
 		
-		//-- export objects in kd leaves
-		//if (mExportObjects) ExportObjects(leaf, stream);
+		//-- export objects
+		ExportObjects(leaf, stream);
 		
 		stream << "\" />" << endl;
-		//stream << " </Leaf>" << endl;
 	}
 	else
@@ -1473,5 +1484,8 @@
 		BvhInterior *interior = dynamic_cast<BvhInterior *>(node);
 	
-		stream << "<Interior box=\"" << interior->GetBoundingBox() << "\">" << endl;
+		stream << "<Interior"
+			   << " min=\"" << interior->GetBoundingBox().Min()
+			   << " max=\"" << interior->GetBoundingBox().Max()
+			   << "\">" << endl;
 
 		ExportNode(interior->GetBack(), stream);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1284)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1286)
@@ -362,5 +362,5 @@
 	startTime = GetTime();
 
-	// -- stats after contruction
+	// -- stats after construction
 	ResetViewCells();
   	Debug << "\nView cells after initial sampling:\n" << mCurrentViewCellsStats << endl;
@@ -480,9 +480,7 @@
 	}
 
-
-	//-- visualization
-
 	if (mShowVisualization)
 	{
+		//-- visualization
 		VssRayContainer visualizationSamples;
 
@@ -690,5 +688,5 @@
 
 	mVspBspTree->Export(stream);
-	stream << endl << "</ViewSpaceHierarchy>" << endl;
+	stream << "</ViewSpaceHierarchy>" << endl;
 
 	stream << "</VisibilitySolution>" << endl;
@@ -4800,6 +4798,4 @@
 	Debug << "saved rays: " << (int)savedRays.size() << endl;
 
-	long startTime;
-
 	//mHierarchyManager->Construct(constructionRays, objects, &mViewSpaceBox);
 	mHierarchyManager->Construct2(constructionRays, objects, &mViewSpaceBox);
@@ -4827,5 +4823,5 @@
 
 
-	startTime = GetTime();
+	const long startTime = GetTime();
 
 	cout << "Computing remaining ray contributions ... ";
@@ -5389,8 +5385,8 @@
 	stream << "<ViewSpaceHierarchy type=\"vsp\""
 		   << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\""
-		   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;
+		   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\">" << endl;
 
 	mHierarchyManager->GetVspTree()->Export(stream);
-	stream << endl << "</ViewSpaceHierarchy>" << endl;
+	stream << "</ViewSpaceHierarchy>" << endl;
 
 	
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1284)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1286)
@@ -304,4 +304,21 @@
 	else
 		mChildren.erase(it);
+}
+
+
+void ViewCellInterior::ReplaceChildLink(ViewCell *prev, ViewCell *cur)
+{
+	// erase leaf from old view cell
+	ViewCellContainer::iterator it = mChildren.begin();
+
+	for (; (*it) != prev; ++ it);
+	if (it == mChildren.end())
+	{
+		Debug << "error: child link not found" << endl;
+	}
+	else
+	{
+		(*it) = cur;
+	}
 }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1259)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1286)
@@ -640,4 +640,6 @@
 	void ExportNode(BvhNode *node, OUT_STREAM &stream);
 
+	void ExportObjects(BvhLeaf *leaf, OUT_STREAM &stream);
+
 	/** Returns estimated memory usage of tree.
 	*/
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1233)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1286)
@@ -331,6 +331,6 @@
 	ProcessMultipleRefs(front);
 
-  delete leaf;
-  return node;
+	delete leaf;
+	return node;
 }
 
@@ -852,6 +852,6 @@
 KdNode *
 KdTree::FindRandomNeighbor(KdNode *n,
-													 bool onlyUnmailed
-													 )
+						   bool onlyUnmailed
+						   )
 {
   stack<KdNode *> nodeStack;
@@ -1288,5 +1288,5 @@
 	IN_STREAM stream(filename.c_str(), IN_BIN_MODE);
 
-	//if (!stream.is_open()) return false;
+	if (!stream.is_open()) return false;
 
 	std::stable_sort(objects.begin(), objects.end(), ilt);
@@ -1299,5 +1299,4 @@
 	{
 		Intersectable *obj = *oit;
-
 		// compute bounding box of view space
 		mBox.Include(obj->GetBox());
@@ -1334,7 +1333,4 @@
 
 			++ mStat.splits[interior->mAxis];
-
-			//Debug << "plane: " << interior->mAxis << " " << interior->mPosition << endl;
-			//Debug << "box: " << tData.mBox << endl;
 
 			// compute new bounding box
@@ -1355,5 +1351,4 @@
 		}
 	}
-
 	Debug << mStat << endl;
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1284)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1286)
@@ -302,4 +302,6 @@
 	*/
 	void SetupChildLink(ViewCell *l);
+	void ReplaceChildLink(ViewCell *prev, ViewCell *cur);
+
 	void RemoveChildLink(ViewCell *l);
 	bool IsLeaf() const;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1278)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1286)
@@ -2759,7 +2759,7 @@
 
 	if (parent->GetFront() == node)
-      box.SetMin(parent->GetAxis(), parent->GetPosition());
+		box.SetMin(parent->GetAxis(), parent->GetPosition());
     else
-      box.SetMax(parent->GetAxis(), parent->GetPosition());
+		box.SetMax(parent->GetAxis(), parent->GetPosition());
 
 	return box;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1233)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1286)
@@ -576,6 +576,4 @@
   
 };
-  
-
 
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp	(revision 1281)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp	(revision 1286)
@@ -158,5 +158,5 @@
 	
 	SceneGraphNode *root = new SceneGraphNode;
-	cout<<"HERE2!\n";
+
 	int meshGrouping;
 	Environment::GetSingleton()->GetIntValue("ObjParser.meshGrouping", meshGrouping);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 1284)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 1286)
@@ -24,4 +24,5 @@
 class OspTree;
 class VspNode;
+class BvhNode;
 class BvHierarchy;
 class HierarchyManager;
@@ -83,8 +84,11 @@
 
   BspNode *mCurrentBspNode;
+  BvhNode *mCurrentBvhNode;
+  KdNode *mCurrentOspNode;
   VspNode *mCurrentVspNode;
+  //KdNode *mCurrentKdNode;
+
   ViewCell *mCurrentViewCell;
-  KdNode *mCurrentKdNode;
-  
+    
   BspNode *mBspRoot;
   VspNode *mVspRoot;
@@ -101,5 +105,9 @@
   int mCurrentState;
   
-  enum {PARSE_OPTIONS, PARSE_VIEWCELLS, PARSE_VIEWSPACE_HIERARCHY, PARSE_OBJECTSPACE_HIERARCHY};
+  enum {
+	  PARSE_OPTIONS, 
+	  PARSE_VIEWCELLS, 
+	  PARSE_VIEWSPACE_HIERARCHY, 
+	  PARSE_OBJECTSPACE_HIERARCHY};
 
   /// view space / object space hierarchy types
@@ -118,5 +126,5 @@
   void EndVspInterior();
 
-  void ParseViewCellPvs(ViewCell *viewCell, AttributeList&  attributes);
+  void StartViewCellPvs(ViewCell *viewCell, AttributeList&  attributes);
   void EndViewCells();
   void EndBoundingBoxes();
@@ -150,4 +158,13 @@
   void StartBvhElement(string element, AttributeList& attributes);
 
+  void EndViewSpaceHierarchyInterior();
+  void EndObjectSpaceHierarchyInterior();
+
+  void EndBvhInterior();
+  void EndOspInterior();
+
+  void EndObjectSpaceHierarchy();
+
+  void StartBvhLeafObjects(ObjectContainer &objects, const char *ptr);
 
   // -----------------------------------------------------------------------
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1284)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1286)
@@ -260,99 +260,4 @@
 
 
-void HierarchyManager::Construct2(const VssRayContainer &sampleRays,
-								  const ObjectContainer &objects,
-								  AxisAlignedBox3 *forcedViewSpace)
-{
-	// rays clipped in view space and in object space
-	RayInfoContainer *viewSpaceRays = new RayInfoContainer();
-	RayInfoContainer *objectSpaceRays = new RayInfoContainer();
-
-
-	/////////////////////////////////////////////////////////////
-	// view space space partition
-	/////////////////////////////////////////////////////////////
-
-#if 0
-	// makes no sense otherwise because only one kd cell available
-	// during view space partition
-	const bool savedCountMethod = mVspTree.mUseKdPvsForHeuristics;
-	const bool savedStoreMethod = mVspTree.mStoreObjectPvs;
-	
-	mVspTree.mUseKdPvsForHeuristics = false;
-	mVspTree.mStoreObjectPvs = false;
-#endif
-	SubdivisionCandidate *vsc = 
-		mVspTree->PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
-	
-	// add to queue
-	mTQueue.Push(vsc);
-
-	long startTime = GetTime();
-	cout << "starting vsp contruction ... " << endl;
-
-	mVspTree->mVspStats.Reset();
-	mVspTree->mVspStats.Start();
-
-	int i = 0;
-
-	// all objects can be seen from everywhere
-	mTotalCost = (float)dynamic_cast<VspTree::VspSubdivisionCandidate *>(vsc)->mParentData.mPvs;
-
-	const bool repairQueue = false;
-
-	// process view space candidates
-	RunConstruction(repairQueue);
-
-	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
-	mVspTree->mVspStats.Stop();
-
-
-	/////////////////////////////////////////////////////////////
-	// object space partition
-	/////////////////////////////////////////////////////////////
-
-
-	Debug << "\n$$$$$$$$$ osp tree construction $$$$$$$$$$\n" << endl;
-	cout << "starting osp contruction ... " << endl;
-
-	// start with one big kd cell - all objects can be seen from everywhere
-	// note: only true for view space = object space
-
-	// compute first candidate
-	SubdivisionCandidate *osc =
-		mOspTree->PrepareConstruction(sampleRays, objects, forcedViewSpace, *objectSpaceRays);
-
-	Debug << "reseting cost, new total cost: " << mTotalCost << endl;
-	mTotalCost = mOspTree->mTotalCost;
-
-    mTQueue.Push(osc);
-
-	mOspTree->mOspStats.Reset();
-	mOspTree->mOspStats.Start();
-
-	startTime = GetTime();
-	
-	// process object space candidates
-	RunConstruction(repairQueue);
-	
-	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-
-	mOspTree->mOspStats.Stop();
-
-	//////////////////////////
-	// matt: only for debugging purpose
-
-	const float rc = mOspTree->EvalRenderCost(sampleRays);
-
-	Debug << "My render cost evalulation: " << rc << endl;
-
-#if 0
-	// reset parameters
-	mVspTree->mUseKdPvsForHeuristics = savedCountMethod;
-	mVspTree->mStoreObjectPvs = savedStoreMethod;
-#endif
-}
-
-
 void HierarchyManager::Construct3(const VssRayContainer &sampleRays,
 								  const ObjectContainer &objects,
@@ -372,5 +277,5 @@
 	mTQueue.Push(sc);
 
-	cout << "starting vsp contruction ... " << endl;
+	cout << "starting vsp construction ... " << endl;
 
 	long startTime = GetTime();
@@ -552,36 +457,208 @@
 void HierarchyManager::ExportObjectSpaceHierarchyForViz(const ObjectContainer &objects) const
 {
-	if (mOspTree && mOspTree->GetRoot()) 
-	{	
-		//-- export final object partition
-		Exporter *exporter = Exporter::GetExporter("final_object_partition.wrl");
+	switch (mObjectSpaceSubdivisonType)
+	{
+	case KD_BASED_OBJ_SUBDIV:
+		{
+			ExportOspTreeForViz(objects);
+			break;
+		}
+	case BV_BASED_OBJ_SUBDIV:
+		{
+			ExportBvhForViz(objects);
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+
+void HierarchyManager::ExportBvhForViz(const ObjectContainer &objects) const
+{
+}
+
+
+void HierarchyManager::ExportOspTreeForViz(const ObjectContainer &objects) const
+{
+	//-- export final object partition
+	Exporter *exporter = Exporter::GetExporter("final_object_partition.wrl");
 		
-		if (exporter)
-		{
-			cout << "exporting object space partition ... ";
-
-			if (1)
-			{
-				exporter->ExportGeometry(objects);
-			}
+	if (exporter)
+	{
+		cout << "exporting object space partition ... ";
+
+		if (1) exporter->ExportGeometry(objects);
 			
 #if 0		
-			// export rays
-			exporter->ExportRays(visRays, RgbColor(0, 1, 0));
+		// export rays
+		exporter->ExportRays(visRays, RgbColor(0, 1, 0));
 #endif
-
-			exporter->SetWireframe();
-	
-			const int colorCode = 0;
-			const int maxPvs = 0;//mOspTree.GetStatistics().maxPvs;
-
-			exporter->ExportOspTree(*mOspTree, 0);
-
-			delete exporter;
-
-			cout << "finished" << endl;
-		}
-	}
-}
-
-}
+		exporter->SetWireframe();
+	
+		const int colorCode = 0;
+		const int maxPvs = 0;//mOspTree.GetStatistics().maxPvs;
+
+		exporter->ExportOspTree(*mOspTree, 0);
+		delete exporter;
+
+		cout << "finished" << endl;
+	}
+}
+
+
+void HierarchyManager::Construct2(const VssRayContainer &sampleRays,
+								  const ObjectContainer &objects,
+								  AxisAlignedBox3 *forcedViewSpace)
+{
+	// rays clipped in view space and in object space
+	RayInfoContainer *viewSpaceRays = new RayInfoContainer();
+	
+	/////////////////////////////////////////////////////////////
+	// view space space partition
+	/////////////////////////////////////////////////////////////
+
+	// use objects for evaluating vsp tree construction
+	const int savedobjectSpaceSubdivisionType = mObjectSpaceSubdivisonType;
+	mObjectSpaceSubdivisonType = NO_OBJ_SUBDIV;
+
+	SubdivisionCandidate *vsc = 
+		mVspTree->PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
+	
+	// add to queue
+	mTQueue.Push(vsc);
+
+	long startTime = GetTime();
+	cout << "starting vsp construction ... " << endl;
+
+	mVspTree->mVspStats.Reset();
+	mVspTree->mVspStats.Start();
+
+	int i = 0;
+
+	// all objects can be seen from everywhere
+	mTotalCost = (float)dynamic_cast<VspTree::VspSubdivisionCandidate *>(vsc)->mParentData.mPvs;
+
+	const bool repairQueue = false;
+
+	// process view space candidates
+	RunConstruction(repairQueue);
+
+	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
+	mVspTree->mVspStats.Stop();
+
+	// reset subdivision type
+	mObjectSpaceSubdivisonType = savedobjectSpaceSubdivisionType;
+
+
+	/////////////////////////////////////////////////////////////
+	// object space partition
+	/////////////////////////////////////////////////////////////
+	
+	
+	switch (mObjectSpaceSubdivisonType)
+	{
+	case KD_BASED_OBJ_SUBDIV:
+		{
+			ConstructOspTree(sampleRays, objects, forcedViewSpace);
+			break;
+		}
+	case BV_BASED_OBJ_SUBDIV:
+		{
+			ConstructBvHierarchy(sampleRays, objects, forcedViewSpace);
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+
+void HierarchyManager::ConstructBvHierarchy(const VssRayContainer &sampleRays,
+											const ObjectContainer &objects,
+											AxisAlignedBox3 *forcedViewSpace) 
+
+{
+	Debug << "\n$$$$$$$$$ bv hierarchy construction $$$$$$$$$$\n" << endl;
+	cout << "starting bv hierarchy construction ... " << endl;
+
+	// start with one big kd cell - all objects can be seen from everywhere
+	// note: only true for view space = object space
+
+	ObjectContainer obj = objects;
+
+	// compute first candidate
+	SubdivisionCandidate *sc =
+		mBvHierarchy->PrepareConstruction(sampleRays, obj, forcedViewSpace);
+
+	Debug << "reseting cost, new total cost: " << mTotalCost << endl;
+	mTotalCost = mOspTree->mTotalCost;
+
+    mTQueue.Push(sc);
+
+	mOspTree->mOspStats.Reset();
+	mOspTree->mOspStats.Start();
+
+	const long startTime = GetTime();
+	const bool repairQueue = false;
+
+	// process object space candidates
+	RunConstruction(repairQueue);
+	
+	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+
+	mOspTree->mOspStats.Stop();
+
+	//////////////////////////
+	// matt: only for debugging purpose
+
+	const float rc = mOspTree->EvalRenderCost(sampleRays);
+
+	Debug << "My render cost evalulation: " << rc << endl;
+}
+
+
+void HierarchyManager::ConstructOspTree(const VssRayContainer &sampleRays,
+										const ObjectContainer &objects,
+										AxisAlignedBox3 *forcedViewSpace) 
+
+{
+	RayInfoContainer *objectSpaceRays = new RayInfoContainer();
+
+	Debug << "\n$$$$$$$$$ osp tree construction $$$$$$$$$$\n" << endl;
+	cout << "starting osp tree construction ... " << endl;
+
+	// start with one big kd cell - all objects can be seen from everywhere
+	// note: only true for view space = object space
+
+	// compute first candidate
+	SubdivisionCandidate *osc =
+		mOspTree->PrepareConstruction(sampleRays, objects, forcedViewSpace, *objectSpaceRays);
+
+	Debug << "reseting cost, new total cost: " << mTotalCost << endl;
+	mTotalCost = mOspTree->mTotalCost;
+
+    mTQueue.Push(osc);
+
+	mOspTree->mOspStats.Reset();
+	mOspTree->mOspStats.Start();
+
+	const long startTime = GetTime();
+	const bool repairQueue = false;
+	
+	// process object space candidates
+	RunConstruction(repairQueue);
+	
+	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+
+	mOspTree->mOspStats.Stop();
+
+	//////////////////////////
+	// matt: only for debugging purpose
+
+	const float rc = mOspTree->EvalRenderCost(sampleRays);
+
+	Debug << "My render cost evalulation: " << rc << endl;
+}
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 1284)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 1286)
@@ -89,5 +89,6 @@
   , mCurrentBspNode(NULL)
   , mCurrentVspNode(NULL)
-  , mCurrentKdNode(NULL)
+  , mCurrentOspNode(NULL)
+  , mCurrentBvhNode(NULL)
   , mObjects(objects)
   , mBoundingBoxConverter(bconverter)
@@ -114,24 +115,85 @@
 
 	if (element == "BoundingBoxes")
+	{
 		EndBoundingBoxes();
+	}
 
 	if (element == "ViewCells")
+	{	
 		EndViewCells();
-
-	// inside the view cell description
-	if (mCurrentState == PARSE_VIEWCELLS)
-	{
-		if (element == "Interior")
-			EndViewCellInterior();
-	}
-	else
-	{
-		if (element == "Interior")
-			EndBspInterior();
+	}
+
+	if (element == "ObjectSpaceHierarchy")
+	{
+		EndObjectSpaceHierarchy();
 	}
 
 	// finished, create view cells manager
 	if (element == "VisibilitySolution")
+	{
 		CreateViewCellsManager();
+	}
+
+	if (element == "Interior")
+	{
+		switch (mCurrentState)
+		{
+		case PARSE_VIEWCELLS:
+			EndViewCellInterior();
+			break;
+		case PARSE_OBJECTSPACE_HIERARCHY:
+			EndObjectSpaceHierarchyInterior();
+			break;
+		case PARSE_VIEWSPACE_HIERARCHY:	
+			EndViewSpaceHierarchyInterior();
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+
+void ViewCellsParseHandlers::EndObjectSpaceHierarchy()
+{
+	if (mObjectSpaceHierarchyType == OSP)
+	{
+		mHierarchyManager->mOspTree->InsertObjects(
+			mHierarchyManager->mOspTree->mRoot, *mObjects);
+	}
+}
+
+
+void ViewCellsParseHandlers::EndViewSpaceHierarchyInterior()
+{
+	switch (mViewSpaceHierarchyType)
+	{
+	case BSP:
+		EndBspInterior();
+		break;
+	case VSP:
+		EndVspInterior();
+		break;	
+	default:
+		Debug << "not implemented view space hierarchy type " << mViewSpaceHierarchyType << endl;
+		break;
+	}
+}
+
+
+void ViewCellsParseHandlers::EndObjectSpaceHierarchyInterior()
+{
+	switch (mObjectSpaceHierarchyType)
+	{
+	case OSP:
+		EndOspInterior();
+		break;
+	case BVH:
+		EndBvhInterior();
+		break;	
+	default:
+		Debug << "not implemented object space hierarchy type " << mViewSpaceHierarchyType << endl;
+		break;
+	}
 }
 
@@ -143,4 +205,24 @@
 	{	cout << "]";
 		mCurrentBspNode = mCurrentBspNode->GetParent();
+	}
+}
+
+
+void ViewCellsParseHandlers::EndBvhInterior()
+{
+	// go one up in the tree
+	if (mCurrentBvhNode->GetParent())
+	{	cout << "]";
+		mCurrentBvhNode = mCurrentBvhNode->GetParent();
+	}
+}
+
+
+void ViewCellsParseHandlers::EndOspInterior()
+{
+	// go one up in the tree
+	if (mCurrentOspNode->mParent)
+	{	cout << "]";
+		mCurrentOspNode = mCurrentOspNode->mParent;
 	}
 }
@@ -243,5 +325,4 @@
 		StartVspInterior(attributes);
 	}
-
 	if (element == "Leaf") 
 	{
@@ -289,19 +370,16 @@
 															AttributeList& attributes)
 {
-	//if (!mViewCellsManager)return;
-
 	//-- use cell type according to the chosen method
-
 	switch (mViewSpaceHierarchyType)
 	{
-		case BSP:
-			StartBspElement(element, attributes);
-			break;
-		case VSP:
-			StartVspElement(element, attributes);
-			break;
-		default:
-			Debug << "not implemented" << endl;
-			break;
+	case BSP:
+		StartBspElement(element, attributes);
+		break;
+	case VSP:
+		StartVspElement(element, attributes);
+		break;
+	default:
+		Debug << "not implemented" << endl;
+		break;
 	}
 }
@@ -412,5 +490,5 @@
 
 
-void ViewCellsParseHandlers::ParseViewCellPvs(ViewCell *viewCell, 
+void ViewCellsParseHandlers::StartViewCellPvs(ViewCell *viewCell, 
 											  AttributeList&  attributes)
 {
@@ -433,8 +511,7 @@
 			while (1)
 			{
-				int index = strtol(ptr, &endptr, 10);
-
-				if (ptr == endptr)
-					break;
+				const int index = strtol(ptr, &endptr, 10);
+
+				if (ptr == endptr) break;
 
 				objIndices.push_back(index);
@@ -454,5 +531,7 @@
 
 				ObjectContainer::iterator oit =
-					lower_bound(mObjects->begin(), mObjects->end(), (Intersectable *)&dummyInst, ilt);	
+					lower_bound(mObjects->begin(), 
+								mObjects->end(), 
+								(Intersectable *)&dummyInst, ilt);	
 							
 				if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
@@ -551,8 +630,7 @@
 void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
 {
-	int len = attributes.getLength();
-
+	const int len = attributes.getLength();
 	Vector3 bmin, bmax;
-cout << "here3" << endl;
+
 	for (int i = 0; i < len; ++ i) 
 	{
@@ -567,10 +645,26 @@
 			{
 				cout << "\nobject space hierarchy: Osp" << endl;
+
 				mHierarchyManager = 
 					new HierarchyManager(mVspTree, HierarchyManager::KD_BASED_OBJ_SUBDIV);
+
+				mObjectSpaceHierarchyType = OSP;
+
+				//std::stable_sort(objects.begin(), objects.end(), ilt);
+				mHierarchyManager->mOspTree->mBoundingBox.Initialize();
+				ObjectContainer::const_iterator oit, oit_end = mObjects->end();
+				
+				//-- compute bounding box
+				for (oit = mObjects->begin(); oit != oit_end; ++ oit)
+				{
+					Intersectable *obj = *oit;
+					// compute bounding box of view space
+					mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
+				}
 			}
 			else if (strcmp(ptr, "bvh") == 0)
 			{
 				cout << "\nobject space hierarchy: Bvh" << endl;
+				mObjectSpaceHierarchyType = BVH;
 				mHierarchyManager = 
 					new HierarchyManager(mVspTree, HierarchyManager::BV_BASED_OBJ_SUBDIV);
@@ -579,5 +673,4 @@
 	}
 }
-
 
 
@@ -675,10 +768,7 @@
 	{
 		// add to invalid view space
-		if (mViewSpaceHierarchyType== ViewCellsManager::VSP_BSP)
-		{
-			leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
-			leaf->SetTreeValid(false);
-			mVspBspTree->PropagateUpValidity(leaf);
-		}
+		leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
+		leaf->SetTreeValid(false);
+		mVspBspTree->PropagateUpValidity(leaf);
 	}
 }
@@ -736,5 +826,5 @@
 	}
 
-	ParseViewCellPvs(viewCell, attributes);
+	StartViewCellPvs(viewCell, attributes);
 
 	// collect leaves
@@ -746,5 +836,5 @@
 {
 	ViewCellInterior* interior = new ViewCellInterior();
-	cout << "here7"<<endl;
+	
 	if (mCurrentViewCell) // replace NULL child of parent with current node
 	{
@@ -760,5 +850,5 @@
 	mCurrentViewCell = interior;
 
-	ParseViewCellPvs(interior, attributes);
+	StartViewCellPvs(interior, attributes);
 }
 
@@ -767,10 +857,10 @@
 {
 	ViewCellContainer::iterator it, it_end = mViewCells.end();
-	Debug << endl;
+	cout << "\n====================" << endl << endl;
 	for (it = mViewCells.begin(); it != it_end; ++ it)
 	{
-		Debug << (*it)->GetId() << " ";
-	}
-Debug << endl;
+		cout << (*it)->GetId() << " ";
+	}
+cout << endl;
 	if (mViewSpaceHierarchyType == BSP)
 	{
@@ -799,6 +889,5 @@
 			else
 			{
-                vc->GetParent()->SetupChildLink(bspVc);
-				vc->GetParent()->RemoveChildLink(vc);
+                vc->GetParent()->ReplaceChildLink(vc, bspVc);
 			}
 
@@ -806,5 +895,4 @@
 			(*vit) = bspVc;
 		}
-
 	}
 	else if (mViewSpaceHierarchyType == VSP) 
@@ -834,6 +922,5 @@
 			else
 			{
-                vc->GetParent()->SetupChildLink(vspVc);
-				vc->GetParent()->RemoveChildLink(vc);
+				vc->GetParent()->ReplaceChildLink(vc, vspVc);
 			}
 			
@@ -849,11 +936,11 @@
 		}
 	}
-	Debug << "************************" << endl;
+	cout << "************************" << endl;
 	it_end = mViewCells.end();
 	for (it = mViewCells.begin(); it != it_end; ++ it)
 	{
-		Debug << (*it)->GetId() << " ";
-	}
-	Debug << endl;
+		cout << (*it)->GetId() << " ";
+	}
+	cout << endl;
 	cout << "\nview space box: " << mViewSpaceBox << endl;
 }
@@ -862,9 +949,8 @@
 void ViewCellsParseHandlers::CreateViewCellsManager(/*const char *name*/)
 {
-	if (mViewSpaceHierarchyType == BSP) // 
+	if (mViewSpaceHierarchyType == BSP)
 	{
 		Debug << "creating view cells manager: VspBsp" << endl;
 
-		//mVspBspTree = new VspBspTree();
 		mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
 	}
@@ -950,7 +1036,7 @@
 		if (vit == mViewCells.end())
 			cout << "error: view cell " << viewCellId << " not found" << endl;
-
+	
 		VspViewCell *viewCell = dynamic_cast<VspViewCell *>(*vit);
-	
+		
 		if (viewCell->GetId() == viewCellId)
 		{
@@ -964,5 +1050,5 @@
 	}
 	else
-	{
+	{	
 		// add to invalid view space
 		leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
@@ -986,5 +1072,5 @@
 		if (attrName == "plane") 
 		{
-			sscanf(ptr, "%d %f", &plane.mAxis, &plane.mPosition);
+			sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
 		}
 	}
@@ -994,12 +1080,21 @@
 	if (mCurrentVspNode) // replace NULL child of parent with current node
 	{
-		VspInterior *current = dynamic_cast<VspInterior *>(mCurrentVspNode);
-
-		current->ReplaceChildLink(NULL, interior);
-		interior->SetParent(current);
+		VspInterior *parent = dynamic_cast<VspInterior *>(mCurrentVspNode);
+
+		parent->ReplaceChildLink(NULL, interior);
+		interior->SetParent(parent);
+		
+		AxisAlignedBox3 frontBox, backBox;
+
+		parent->GetBoundingBox().Split(parent->GetPlane().mAxis, parent->GetPlane().mPosition, frontBox, backBox);
+		if (parent->GetFront() == interior)
+			interior->SetBoundingBox(frontBox);
+		else
+			interior->SetBoundingBox(backBox);
 	}
 	else
 	{
 		mVspTree->mRoot = interior;
+		interior->SetBoundingBox(mVspTree->GetBoundingBox());
 	}
 
@@ -1021,6 +1116,5 @@
 		if (attrName == "plane") 
 		{
-			sscanf(ptr, "%d %f",
-				   &plane.mAxis, &plane.mPosition);
+			sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
 		}
 	}
@@ -1031,16 +1125,25 @@
 	interior->mPosition = plane.mPosition;
 
-	if (mCurrentKdNode) // replace NULL child of parent with current node
-	{
-		KdInterior *parent = dynamic_cast<KdInterior *>(mCurrentKdNode);
+	if (mCurrentOspNode) // replace NULL child of parent with current node
+	{
+		KdInterior *parent = dynamic_cast<KdInterior *>(mCurrentOspNode);
 		parent->ReplaceChildLink(NULL, interior);
 		interior->mParent = parent;
+
+		AxisAlignedBox3 frontBox, backBox;
+
+		parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
+		if (parent->mFront == interior)
+			interior->mBox = frontBox;
+		else
+			interior->mBox = backBox;
 	}
 	else
 	{
 		mHierarchyManager->mOspTree->mRoot = interior;
-	}
-
-	mCurrentKdNode = interior;
+		interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
+	}
+
+	mCurrentOspNode = interior;
 }
 
@@ -1049,9 +1152,9 @@
 {
 	KdLeaf * leaf = 
-		new KdLeaf(dynamic_cast<KdInterior *>(mCurrentKdNode), NULL);
-
-	if (mCurrentKdNode) // replace front or (if not NULL) back child
-	{
-		dynamic_cast<KdInterior *>(mCurrentKdNode)->ReplaceChildLink(NULL, leaf);
+		new KdLeaf(dynamic_cast<KdInterior *>(mCurrentOspNode), NULL);
+
+	if (mCurrentOspNode) // replace front or (if not NULL) back child
+	{
+		dynamic_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
 	}
 	else
@@ -1063,23 +1166,9 @@
 
 void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
-{/*
-	KdLeaf * leaf = 
-		new KdLeaf(dynamic_cast<KdInterior *>(mCurrentKdNode), NULL);
-
-	if (mCurrentKdNode) // replace front or (if not NULL) back child
-	{
-		dynamic_cast<KdInterior *>(mCurrentKdNode)->ReplaceChildLink(NULL, leaf);
-	}
-	else
-	{
-		mHierarchyManager->mBvHierarchy->mRoot = leaf;
-	}*/
-}
-
-
-void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
-{/*
-	AxisAlignedPlane plane;
-	int len = attributes.getLength();
+{
+	const int len = attributes.getLength();
+	Vector3 minBox, maxBox;
+
+	ObjectContainer objects;
 
 	for (int i = 0; i < len; ++ i) 
@@ -1089,30 +1178,115 @@
 		const char *ptr = attrValue.LocalForm();
 
-		if (attrName == "plane") 
-		{
-			sscanf(ptr, "%d %f",
-				   &plane.mAxis, &plane.mPosition);
-		}
-	}
-
-	KdInterior* interior = new KdInterior(NULL);
-	
-	interior->mAxis = plane.mAxis;
-	interior->mPosition = plane.mPosition;
-
-	if (mCurrentKdNode) // replace NULL child of parent with current node
-	{
-		KdInterior *parent = dynamic_cast<KdInterior *>(mCurrentKdNode);
+		if (attrName == "min") 
+		{
+			sscanf(ptr, "%f %f %f", &minBox);
+		}
+		if (attrName == "max") 
+		{
+			sscanf(ptr, "%f %f %f", &maxBox);
+		}
+		if (attrName == "objects")
+		{
+			StartBvhLeafObjects(objects, ptr);
+		}
+	}
+
+	BvhLeaf * leaf = 
+		new BvhLeaf(AxisAlignedBox3(minBox, maxBox), 
+					dynamic_cast<BvhInterior *>(mCurrentBvhNode), (int)objects.size());
+
+	leaf->mObjects = objects;
+
+	if (mCurrentBvhNode) // replace front or (if not NULL) back child
+	{
+		dynamic_cast<BvhInterior *>(mCurrentBvhNode)->ReplaceChildLink(NULL, leaf);
+	}
+	else
+	{
+		mHierarchyManager->mBvHierarchy->mRoot = leaf;
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects, 
+												 const char *ptr)
+{
+	vector<int> objIndices;
+
+	char *endptr;
+			
+	while (1)
+	{
+		const int index = strtol(ptr, &endptr, 10);
+
+		if (ptr == endptr) break;
+
+		objIndices.push_back(index);
+
+		ptr = endptr;
+	}
+
+	//TODO: find objects and add them to pvs
+	// TODO: get view cell with specified id
+	MeshInstance dummyInst(NULL);
+
+	vector<int>::const_iterator it, it_end = objIndices.end();
+
+	for (it = objIndices.begin(); it != it_end; ++ it)
+	{
+		const int objId = *it;	
+		dummyInst.SetId(objId);
+
+		ObjectContainer::iterator oit =
+			lower_bound(mObjects->begin(), mObjects->end(), (Intersectable *)&dummyInst, ilt);	
+							
+		if ((oit != mObjects->end()) && ((*oit)->GetId() == objId))
+		{
+			objects.push_back(*oit);	
+		}
+		else
+		{
+			cout << "error: object with id " << objId << " does not exist" << endl;
+		}
+	}
+}
+
+
+void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
+{
+	const int len = attributes.getLength();
+	Vector3 minBox, maxBox;
+
+	for (int i = 0; i < len; ++ i) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		StrX attrValue(attributes.getValue(i));
+		const char *ptr = attrValue.LocalForm();
+
+		if (attrName == "min") 
+		{
+			sscanf(ptr, "%f %f %f", &minBox);
+		}
+		if (attrName == "max") 
+		{
+			sscanf(ptr, "%f %f %f", &maxBox);
+		}
+	}
+
+	BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
+
+	if (mCurrentBvhNode) // replace NULL child of parent with current node
+	{
+		BvhInterior *parent = dynamic_cast<BvhInterior *>(mCurrentBvhNode);
 		parent->ReplaceChildLink(NULL, interior);
-		interior->mParent = parent;
+		interior->SetParent(parent);
 	}
 	else
 	{
-		mOspTree->mRoot = interior;
-	}
-
-	mCurrentKdNode = interior;*/
-}
-
+		mBvHierarchy->mRoot = interior;
+	}
+
+	mCurrentBvhNode = interior;
+}
 
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp	(revision 1264)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp	(revision 1286)
@@ -643,5 +643,4 @@
 
 	float sum = (float)totalVol * sizeBox;
-
 
 	Debug << "here82 render cost: " << renderCost / viewSpaceVol << endl;
@@ -2570,9 +2569,8 @@
 		stream << "objects=\"";
 		
-		//-- export objects in kd leaves
+		// export objects in kd leaves
 		//if (mExportObjects) ExportObjects(leaf, stream);
 		
 		stream << "\" />" << endl;
-		//stream << " </Leaf>" << endl;
 	}
 	else
@@ -2658,7 +2656,7 @@
 
 SubdivisionCandidate * OspTree::PrepareConstruction(const VssRayContainer &sampleRays,
-										   const ObjectContainer &objects,
-										   AxisAlignedBox3 *forcedObjectSpace,
-										   RayInfoContainer &rays)
+													const ObjectContainer &objects,
+													AxisAlignedBox3 *forcedObjectSpace,
+													RayInfoContainer &rays)
 {
 	// store pointer to this tree
