Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1272)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1279)
@@ -17,4 +17,5 @@
 #include "ObjParser.h"
 #include "BvHierarchy.h"
+#include "HierarchyManager.h"
 
 #ifdef GTP_INTERNAL
@@ -125,9 +126,9 @@
 mVspBspTree(NULL),
 mVspTree(NULL),
-mOspTree(NULL),
-mBvHierarchy(NULL),
+mHierarchyManager(NULL),
 mViewCellsManager(NULL),
 mRenderSimulator(NULL),
-mPass(0)
+mPass(0),
+mRayCastMethod(0)
 {
 	Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
@@ -142,6 +143,7 @@
 	Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
 	Environment::GetSingleton()->GetBoolValue("Preprocessor.exportVisibility", mExportVisibility );
+//#if GTP_INTERNAL // choose other ray cast method
 	Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod", mRayCastMethod);
-
+//#endif
 	char buffer[256];
 	Environment::GetSingleton()->GetStringValue("Preprocessor.visibilityFile",  buffer);
@@ -177,6 +179,6 @@
   cout << "done.\n";
 
-  cout << "Deleting osp tree...\n";
-  DEL_PTR(mOspTree);
+  cout << "Deleting hierarchy manager...\n";
+  DEL_PTR(mHierarchyManager);
   cout << "done.\n";
 
@@ -479,10 +481,18 @@
 	{
 		mVspTree = new VspTree();
-		//mOspTree = new OspTree();
-		
+				
 		// HACK for testing if per kd evaluation works!!
-		mOspTree = new OspTree(*mKdTree);
-
-		mViewCellsManager = new VspOspViewCellsManager(vcTree, mVspTree, mOspTree);
+		const bool ishack = true;
+
+		if (ishack)
+		{
+			mHierarchyManager = new HierarchyManager(mVspTree, mKdTree);
+		}
+		else
+		{
+			mHierarchyManager = new HierarchyManager(mVspTree, HierarchyManager::KD_BASED_OBJ_SUBDIV);
+		}
+
+		mViewCellsManager = new VspOspViewCellsManager(vcTree, mHierarchyManager);
 	}
 	else if (strcmp(name, "sceneDependent") == 0)
@@ -500,5 +510,4 @@
 	}
 
-	//vcTree->SetViewCellsManager(mViewCellsManager);
 	return mViewCellsManager;
 }
@@ -767,4 +776,5 @@
 	//	return new ObjectsInteriorDistribution(*this);
 	default: // no valid strategy
+		Debug << "warning: no valid sampling strategy" << endl;
 		return NULL;
 	}
@@ -844,4 +854,5 @@
 		//Debug << "intel ray: " << *vssRay << endl;
 	}
+
 	//cout << "a";
 	return hits;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1259)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1279)
@@ -89,9 +89,14 @@
 	friend OspTree;
 	friend BvHierarchy;
+	friend ViewCellsParseHandlers;
 
 public:
-	/** Constructor taking an object space partition and a view space partition tree.
-	*/
-	HierarchyManager(VspTree &vspTree, OspTree &ospTree);
+	/** Constructor with the object space hierarchy type as argument.
+	*/
+	HierarchyManager(VspTree *vspTree, const int objectSpaceHierarchyType);
+	/** Hack: OspTree will copy the content from this kd tree.
+		Only view space hierarchy will be constructed.
+	*/
+	HierarchyManager(VspTree *vspTree, KdTree *kdTree);
 
 	/** Constructs the view space and object space subdivision from a given set of rays
@@ -130,4 +135,23 @@
 	}
 	
+	void SetViewCellsManager(ViewCellsManager *vcm);
+
+	void SetViewCellsTree(ViewCellsTree *vcTree);
+
+	void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
+
+	bool AddSampleToPvs(
+		Intersectable *obj, 
+		const Vector3 &hitPoint,
+		ViewCell *vc,
+		const float pdf, 
+		float &contribution) const;
+
+	void PrintObjectSpaceHierarchyStatistics(ofstream &stream) const;
+
+	VspTree *GetVspTree() { return mVspTree; }
+
+	void ExportObjectSpaceHierarchyForViz(const ObjectContainer &objects) const;
+
 protected:
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1272)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1279)
@@ -25,5 +25,5 @@
 class GlRendererBuffer;
 class VspTree;
-class OspTree;
+class HierarchyManager;
 class BvHierarchy;
 class Intersectable;
@@ -178,10 +178,7 @@
   // view space partition tree
   VspTree *mVspTree;
-  /// object space partition tree
-  OspTree *mOspTree;
+  HierarchyManager *mHierarchyManager;
   /// BSP tree representing the viewcells
   BspTree *mBspTree;
-
-  BvHierarchy *mBvHierarchy;
   
   /// list of all loaded occluders
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1272)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1279)
@@ -499,5 +499,4 @@
 	if ((int)(leaf->mObjects.size()) > mBvhStats.maxObjectRefs)
 		mBvhStats.maxObjectRefs = (int)leaf->mObjects.size();
-
 }
 
@@ -1594,4 +1593,49 @@
 }
 
-}
-
+
+void BvhStatistics::Print(ostream &app) const
+{
+	app << "=========== OspTree statistics ===============\n";
+
+	app << setprecision(4);
+
+	app << "#N_CTIME  ( Construction time [s] )\n" << Time() << " \n";
+
+	app << "#N_NODES ( Number of nodes )\n" << nodes << "\n";
+
+	app << "#N_INTERIORS ( Number of interior nodes )\n" << Interior() << "\n";
+
+	app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n";
+
+	app << "#AXIS_ALIGNED_SPLITS (number of axis aligned splits)\n" << splits << endl;
+
+	
+	app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n" 
+		<<	maxDepthNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINPVSLEAVES  ( Percentage of leaves with mininimal PVS )\n" 
+		<< minPvsNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_MAXCOSTNODES  ( Percentage of leaves with terminated because of max cost ratio )\n"
+		<< maxCostNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINPROBABILITYLEAVES  ( Percentage of leaves with mininum probability )\n"
+		<< minProbabilityNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl;
+
+	app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl;
+
+	app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl;
+
+	app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl;
+
+	app << "#N_MAXOBJECTREFS  ( Max number of object refs / leaf )\n" << maxObjectRefs << "\n";
+
+	//app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl;
+	
+	app << "========== END OF VspTree statistics ==========\n";
+}
+
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1264)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1279)
@@ -34,11 +34,82 @@
 
 
-HierarchyManager::HierarchyManager(VspTree &vspTree, OspTree &ospTree)
-//:mVspTree(vspTree), mOspTree(ospTree)
-{
+HierarchyManager::HierarchyManager(VspTree *vspTree, 
+								   const int objectSpaceSubdivisionType):
+mObjectSpaceSubdivisonType(objectSpaceSubdivisionType),
+mVspTree(vspTree), 
+mOspTree(NULL), 
+mBvHierarchy(NULL)
+{
+	switch(mObjectSpaceSubdivisonType)
+	{
+	case KD_BASED_OBJ_SUBDIV:
+		mOspTree = new OspTree();
+		mOspTree->mVspTree = mVspTree;
+		//mOspTree->mHierarchyManager = this;
+		Debug << "creating osp tree" << endl;
+		break;
+	case BV_BASED_OBJ_SUBDIV:
+        mBvHierarchy = new BvHierarchy();
+		mBvHierarchy->mVspTree = mVspTree;
+		//mBvHierarchy->mHierarchyManager = this;
+		Debug << "creating bv hierachy" << endl;
+		break;
+	default:
+		break;
+	}
+
+	if (mVspTree)
+		mVspTree->mHierarchyManager = this;
+
 	char subdivisionStatsLog[100];
 	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", 
 		subdivisionStatsLog);
 	mSubdivisionStats.open(subdivisionStatsLog);
+}
+
+
+HierarchyManager::HierarchyManager(VspTree *vspTree, KdTree *kdTree): 
+mObjectSpaceSubdivisonType(KD_BASED_OBJ_SUBDIV),
+mVspTree(vspTree), 
+mBvHierarchy(NULL)
+{
+	mOspTree = new OspTree(*kdTree);
+	mOspTree->mVspTree = mVspTree;
+
+	//mOspTree->mHierarchyManager = this;
+	Debug << "creating osp tree" << endl;
+
+	if (mVspTree)
+		mVspTree->mHierarchyManager = this;
+
+	char subdivisionStatsLog[100];
+	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", 
+		subdivisionStatsLog);
+	mSubdivisionStats.open(subdivisionStatsLog);
+}
+
+
+HierarchyManager::~HierarchyManager()
+{
+	DEL_PTR(mOspTree);
+	//DEL_PTR(mVspTree);
+	DEL_PTR(mBvHierarchy);
+}
+
+
+void HierarchyManager::SetViewCellsManager(ViewCellsManager *vcm)
+{
+	mVspTree->SetViewCellsManager(vcm);
+
+	if (mOspTree)
+		mOspTree->SetViewCellsManager(vcm);
+	if (mBvHierarchy)
+		mBvHierarchy->SetViewCellsManager(vcm);
+}
+
+
+void HierarchyManager::SetViewCellsTree(ViewCellsTree *vcTree)
+{
+	mVspTree->SetViewCellsTree(vcTree);
 }
 
@@ -211,8 +282,7 @@
 	mVspTree.mStoreObjectPvs = false;
 #endif
-
 	SubdivisionCandidate *vsc = 
 		mVspTree->PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
-
+	
 	// add to queue
 	mTQueue.Push(vsc);
@@ -409,3 +479,109 @@
 
 
-}
+void HierarchyManager::ExportObjectSpaceHierarchy(OUT_STREAM &stream)
+{
+	// the type of the view cells hierarchy
+	switch (mObjectSpaceSubdivisonType)
+	{
+	case KD_BASED_OBJ_SUBDIV:
+		stream << "<ObjectSpaceHierarchy type=\"osp\">" << endl;
+		mOspTree->Export(stream);
+		stream << endl << "</ObjectSpaceHierarchy>" << endl;
+		break;
+		
+	case BV_BASED_OBJ_SUBDIV:
+		stream << "<ObjectSpaceHierarchy type=\"bvh\">" << endl;
+		mBvHierarchy->Export(stream);
+		stream << endl << "</ObjectSpaceHierarchy>" << endl;
+		break;
+	}
+}
+
+
+bool HierarchyManager::AddSampleToPvs(Intersectable *obj, 
+									  const Vector3 &hitPoint,
+									  ViewCell *vc,
+									  const float pdf, 
+									  float &contribution) const
+{
+	if (!obj) return false;
+
+	switch (mObjectSpaceSubdivisonType)
+	{
+	case NO_OBJ_SUBDIV:
+		// potentially visible objects
+		return vc->AddPvsSample(obj, pdf, contribution);
+
+	case KD_BASED_OBJ_SUBDIV:
+		{
+			// potentially visible kd cells
+			KdLeaf *leaf = mOspTree->GetLeaf(hitPoint/*ray->mOriginNode*/);
+			return mOspTree->AddLeafToPvs(leaf, vc, pdf, contribution);
+		}
+	case BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+			return mBvHierarchy->AddLeafToPvs(leaf, vc, pdf, contribution);
+		}
+	default:
+		return false;
+	}
+}
+
+
+void HierarchyManager::PrintObjectSpaceHierarchyStatistics(ofstream &stream) const
+{
+	switch (mObjectSpaceSubdivisonType)
+	{
+	case KD_BASED_OBJ_SUBDIV:
+		{
+			stream << mOspTree->GetStatistics();
+			break;
+		}
+	case BV_BASED_OBJ_SUBDIV:
+		{
+			stream << mBvHierarchy->GetStatistics();
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+
+void HierarchyManager::ExportObjectSpaceHierarchyForViz(const ObjectContainer &objects) const
+{
+	if (mOspTree && mOspTree->GetRoot()) 
+	{	
+		//-- 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 0		
+			// export rays
+			exporter->ExportRays(visRays, RgbColor(0, 1, 0));
+#endif
+
+			exporter->SetWireframe();
+	
+			const int colorCode = 0;
+			const int maxPvs = 200;//mOspTree.GetStatistics().maxPvs;
+
+			exporter->ExportOspTree(*mOspTree, colorCode == 0 ? 0 : maxPvs);
+
+			delete exporter;
+
+			cout << "finished" << endl;
+		}
+	}
+}
+
+}
