Index: GTP/trunk/Lib/Vis/Preprocessing/src/SubdivisionCandidate.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SubdivisionCandidate.h	(revision 1239)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SubdivisionCandidate.h	(revision 1259)
@@ -56,5 +56,5 @@
 typedef FlexibleHeap<SubdivisionCandidate *> SplitQueue;
 
-
+typedef vector<SubdivisionCandidate *> SubdivisionCandidateContainer;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1201)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1259)
@@ -36,6 +36,7 @@
 class VspNode;
 class HierarchyManager;
+class BvHierarchy;
+
 struct AxisAlignedPlane;
-
 struct BspRay;
 
@@ -490,4 +491,11 @@
 	bool GetStoreKdPVs() const;
 
+	virtual bool AddSampleToPvs(
+		Intersectable *obj, 
+		const Vector3 &hitPoint,
+		ViewCell *vc,
+		const float pdf, 
+		float &contribution) const;
+
 protected:
 
@@ -672,5 +680,5 @@
 	bool mExportPvs;
 
-	bool mStoreKdPvs;
+	bool mStoreObjectPvs;
 
 	VssRayContainer storedRays;
@@ -1016,4 +1024,10 @@
 		BoundingBoxConverter *bconverter);
 
+	bool AddSampleToPvs(
+		Intersectable *obj, 
+		const Vector3 &hitPoint,
+		ViewCell *vc,
+		const float pdf, 
+        float &contribution) const;
 
 protected:
@@ -1050,7 +1064,9 @@
 
 	/////////////////////////////////////////
-	/// the view space partition tree.
+
+	/// the view space / object partition hierarchies
 	VspTree *mVspTree;
 	OspTree *mOspTree;
+	BvHierarchy *mBvHierarchy;
 
 	HierarchyManager *mHierarchyManager;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1239)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1259)
@@ -39,5 +39,5 @@
 class VspTree;
 class KdTreeStatistics;
-
+class BvHierarchy;
 
 
@@ -86,4 +86,8 @@
 class HierarchyManager
 {
+	friend VspTree;
+	friend OspTree;
+	friend BvHierarchy;
+
 public:
 	/** Constructor taking an object space partition and a view space partition tree.
@@ -112,8 +116,18 @@
 					AxisAlignedBox3 *forcedViewSpace);
 
-public:
-	VspTree &mVspTree;
-	OspTree &mOspTree;
-
+	enum 
+	{
+		NO_OBJ_SUBDIV,
+		KD_BASED_OBJ_SUBDIV,
+		BV_BASED_OBJ_SUBDIV
+	};
+
+	/** The type of object space subdivison
+	*/
+	inline int GetObjectSpaceSubdivisonType() const
+	{
+		return mObjectSpaceSubdivisonType;
+	}
+	
 protected:
 
@@ -143,10 +157,27 @@
 	void EvalSubdivisionStats(const SubdivisionCandidate &tData);
 
-	void AddSubdivisionStats(const int splits,
+	void AddSubdivisionStats(
+		const int splits,
 		const float renderCostDecr,
 		const float totalRenderCost);
 
+	void CollectObjectSpaceDirtyList();
+	void CollectViewSpaceDirtyList();
+
+	bool AddSampleToPvs(Intersectable *obj, 
+						const float pdf,
+						float &contribution) const;
+
+	void CollectViewSpaceDirtyList(SubdivisionCandidateContainer &dirtyList);
+	void CollectObjectSpaceDirtyList(SubdivisionCandidateContainer &dirtyList);
+		
 
 protected:
+
+	int mObjectSpaceSubdivisonType;
+
+	VspTree *mVspTree;
+	OspTree *mOspTree;
+	BvHierarchy *mBvHierarchy;
 
 	AxisAlignedBox3 mBoundingBox;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h	(revision 1259)
@@ -397,4 +397,12 @@
 	void InsertObjects(KdNode *node, const ObjectContainer &objects);
 
+	/** Add the leaf to the pvs of the view cell.
+	*/
+	bool AddLeafToPvs(
+		KdLeaf *leaf, 
+		ViewCell *vc, 
+		const float pdf, 
+		float &contribution);
+
 protected:
 
@@ -596,10 +604,14 @@
 	/** Evaluate the contributions of view cell volume of the left and the right view cell.
 	*/
-	void EvalRayContribution(KdLeaf *leaf,
-									 const VssRay &ray, 
-									 float &renderCost);
-void EvalViewCellContribution(KdLeaf *leaf, 
-									   ViewCell *viewCell,
-									   float &renderCost);
+	void EvalRayContribution(
+		KdLeaf *leaf,
+		const VssRay &ray, 
+		float &renderCost);
+	
+	void EvalViewCellContribution(
+		KdLeaf *leaf, 
+		ViewCell *viewCell,
+		float &renderCost);
+
 	/** Evaluates the influence on the pvs of the event.
 		@param ve the visibility event
@@ -718,6 +730,6 @@
 		RayInfoContainer &rays);
 
+
 protected:
-
 	
 	/// pointer to the hierarchy of view cells
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 1259)
@@ -31,5 +31,5 @@
 class KdInterior;
 class KdLeaf;
-class OspTree;
+class HierarchyManager;
 class KdIntersectable;
 class KdTree;
@@ -759,5 +759,5 @@
 							 float maxBand);
 
-	/** Evaluate pvs size associated with the rays.
+	/** Evaluate pvs size as induced by the samples.
 	*/
 	int EvalPvsSize(const RayInfoContainer &rays) const;
@@ -778,15 +778,24 @@
 								  float &position);
 
-	/** Evaluates the influence on the pvs of the visibility event ve.
+	/** Evaluates the contribution to left and right pvs at a visibility event ve.
 		@param ve the visibility event
 		@param pvsLeft updates the left pvs
 		@param rightPvs updates the right pvs
 	*/
-	void EvalPvsIncr(const SortableEntry &ve,
-					  int &pvsLeft,
-					  int &pvsRight) const;
-
-	void RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const;
-	void AddContriToPvs(KdLeaf *leaf, int &pvs) const;
+	void EvalHeuristicsContribution(
+		const SortableEntry &ve, 
+		int &pvsLeft, 
+		int &pvsRight) const;
+
+	/** Evaluates contribution of the ray to the left and right pvs.
+	*/
+	int EvalMinEventContribution(
+		const VssRay &ray, const bool isTermination) const;
+
+	int EvalMaxEventContribution(
+		const VssRay &ray, const bool isTermination) const;
+
+	int EvalMinEventContribution(KdLeaf *leaf) const;
+	int EvalMaxEventContribution(KdLeaf *leaf) const;
 
 	/** Prepares objects for the heuristics.
@@ -794,5 +803,5 @@
 	*/
 	int PrepareHeuristics(const RayInfoContainer &rays);
-
+	int PrepareHeuristics(const VssRay &ray, const bool isTermination);
 	int PrepareHeuristics(KdLeaf *leaf);
 
@@ -859,9 +868,4 @@
 						 int &contributingSamples);
 
-	bool AddKdLeafToPvs(KdLeaf *leaf, 
-						ViewCell *vc, 
-						const float pvs, 
-						float &contribution);
-
 	/** Propagates valid flag up the tree.
 	*/
@@ -898,19 +902,22 @@
 	void EvalSubdivisionStats(const SubdivisionCandidate &tData);
 
-	SubdivisionCandidate *PrepareConstruction(const VssRayContainer &sampleRays,
-							   AxisAlignedBox3 *forcedViewSpace,
-							   RayInfoContainer &rays);
+	SubdivisionCandidate *PrepareConstruction(
+		const VssRayContainer &sampleRays,
+		AxisAlignedBox3 *forcedViewSpace,
+		RayInfoContainer &rays);
+
+	/** Add pvs contribution of this ray.
+	*/
+	int EvalPvsContribution(const VssRay &ray, const bool isTermination) const;
 
 protected:
-
 
 	/// pointer to the hierarchy of view cells
 	ViewCellsTree *mViewCellsTree;
 
-	OspTree *mOspTree;
-
-	bool mUseKdPvsForHeuristics;
-	bool mStoreKdPvs;
-
+	HierarchyManager *mHierarchyManager;
+	//OspTree *mOspTree;
+	//bool mUseKdPvsForHeuristics;
+	
 	ViewCellsManager *mViewCellsManager;
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1259)
@@ -1590,4 +1590,15 @@
 
 
-
-}
+bool BvHierarchy::AddLeafToPvs(BvhLeaf *leaf, 
+							   ViewCell *vc, 
+							   const float pdf, 
+							   float &contribution)
+{
+	// add kd intersecable to pvs
+	BvhIntersectable *bvhObj = GetOrCreateBvhIntersectable(leaf);
+	
+	return vc->AddPvsSample(bvhObj, pdf, contribution);
+}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1259)
@@ -21,5 +21,5 @@
 #include "VspTree.h"
 #include "OspTree.h"
-
+#include "BvHierarchy.h"
 
 // should not count origin object for sampling because it disturbs heuristics
@@ -58,6 +58,5 @@
 mMaxPvsRatio(1.0),
 mViewCellPvsIsUpdated(false),
-mPreprocessor(NULL),
-mStoreKdPvs(false)
+mPreprocessor(NULL)
 {
 	mViewSpaceBox.Initialize();
@@ -107,7 +106,4 @@
 	Environment::GetSingleton()->GetBoolValue("ViewCells.exportPvs", mExportPvs);
 	
-	Environment::GetSingleton()->GetBoolValue("ViewCells.storeKdPvs", mStoreKdPvs);
-
-
 	char buf[100];
 	Environment::GetSingleton()->GetStringValue("ViewCells.samplingType", buf);
@@ -223,6 +219,4 @@
 	Debug << "export pvs for view cells: " << mExportPvs << endl;
 	
-	Debug << "store kd pvs: " << mStoreKdPvs << endl;
-
 	Debug << endl;
 }
@@ -877,4 +871,17 @@
 {
 	return mExportPvs;
+}
+
+
+bool ViewCellsManager::AddSampleToPvs(Intersectable *obj, 
+									  const Vector3 &hitPoint,
+									  ViewCell *vc,
+									  const float pdf, 
+									  float &contribution) const
+{
+	if (!obj) return false;
+
+	// potentially visible objects
+	return vc->AddPvsSample(obj, pdf, contribution);
 }
 
@@ -2456,16 +2463,4 @@
 
 
-void ViewCellsManager::SetStoreKdPvs(const bool storeKdPvs)
-{
-	mStoreKdPvs = storeKdPvs;
-}
-
-
-bool ViewCellsManager::GetStoreKdPVs() const
-{
-	return mStoreKdPvs;
-}
-
-
 void ViewCellsManager::UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs)
 {
@@ -5681,55 +5676,65 @@
 	}
 
-	// if addrays is true, sampled entities are stored in the pvs
-	if (addRays)
-	{
-		for (it = viewcells.begin(); it != viewcells.end(); ++ it) 
+	if (!addRays)
+		return ray.mRelativePvsContribution;
+
+	// sampled objects are stored in the pvs
+	for (it = viewcells.begin(); it != viewcells.end(); ++ it) 
+	{
+		ViewCell *viewCell = *it;
+
+		if (!viewCell->GetValid())
+			break;
+
+		AddSampleToPvs(
+			ray.mTerminationObject, 
+			ray.mTermination, 
+			viewCell, 
+			ray.mPdf, 
+			ray.mRelativePvsContribution);
+
+#if SAMPLE_ORIGIN_OBJECTS
+
+		AddSampleToPvs(
+			ray.mOriginObject, 
+			ray.mOrigin, 
+			viewCell, 
+			ray.mPdf, 
+			ray.mRelativePvsContribution);
+#endif			
+	}
+
+	return ray.mRelativePvsContribution;
+}
+
+
+bool VspOspViewCellsManager::AddSampleToPvs(Intersectable *obj, 
+											const Vector3 &hitPoint,
+											ViewCell *vc,
+											const float pdf, 
+											float &contribution) const
+{
+	if (!obj) return false;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+    {
+	case HierarchyManager::NO_OBJ_SUBDIV:
+			// potentially visible objects
+			return vc->AddPvsSample(obj, pdf, contribution);
+
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
 		{
-			ViewCell *viewcell = *it;
-            
-			if (viewcell->GetValid())
-			{
-				// if ray not outside of view space
-
-				// add kd cell
-				if (ray.mTerminationObject)
-				{
-					if (!mStoreKdPvs)
-					{
-						viewcell->AddPvsSample(ray.mTerminationObject, 
-							ray.mPdf, ray.mRelativePvsContribution);
-					}
-					else
-					{
-						// get current leaf the point is located in
-						KdLeaf *leaf = mOspTree->GetLeaf(ray.mTermination);
-						KdIntersectable *entry = mOspTree->GetOrCreateKdIntersectable(leaf);
-
-						viewcell->AddPvsSample(entry, ray.mPdf, ray.mRelativePvsContribution);
-					}
-				}
-				
-#if SAMPLE_ORIGIN_OBJECTS
-				 if (ray.mOriginObject)
-				 {
-					 if (!mStoreKdPvs)
-					 {
-						 viewcell->AddPvsSample(ray.mOriginObject, ray.mPdf, ray.mPvsContribution);
-					 }
-					 else
-					 {
-						 /// get current leaf the point
-						KdLeaf *leaf = mOspTree->GetLeaf(ray.mOrigin);
-						KdIntersectable *entry = mOspTree->GetOrCreateKdIntersectable(leaf);
-
-						viewcell->AddPvsSample(entry, ray.mPdf, ray.mRelativePvsContribution);
-					 }
-				 }
-#endif
-			}
-		}
-	}
-
-	return ray.mRelativePvsContribution;
+			// potentially visible kd cells
+			KdLeaf *leaf = mOspTree->GetLeaf(hitPoint/*ray->mOriginNode*/);
+			return mOspTree->AddLeafToPvs(leaf, vc, pdf, contribution);
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+			return mBvHierarchy->AddLeafToPvs(leaf, vc, pdf, contribution);
+		}
+	default:
+		return false;
+	}
 }
 
@@ -5811,28 +5816,26 @@
 	UpdatePvsForEvaluation(mViewCellsTree->GetRoot(), pvs);
 
-
-//-- test render cost
-
-sprintf(s, "-%09d-eval.log", castSamples);
-string fileName = string(statsPrefix) + string(s);
-
-ViewCellContainer leaves;
-
-mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
-float rc = 0;
-ViewCellContainer::const_iterator vit, vit_end = leaves.end();
-for (vit = leaves.begin(); vit != vit_end; ++ vit)
-{
-	ViewCell *vc = *vit;
+	///////////////////////////////////////
+	//-- temporary matt: test render cost
+
+	sprintf(s, "-%09d-eval.log", castSamples);
+	string fileName = string(statsPrefix) + string(s);
+
+	ViewCellContainer leaves;
+
+	mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
+	float rc = 0;
+	ViewCellContainer::const_iterator vit, vit_end = leaves.end();
+	for (vit = leaves.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = *vit;
 		int pvs = vc->GetPvs().CountObjectsInPvs();
-	float vol = vc->GetVolume();
-	rc += pvs * vol;
-
-	}
-	
+		float vol = vc->GetVolume();
+		rc += pvs * vol;
+
+	}
+
 	Debug << "\nhere295 " << rc / mVspTree->GetBoundingBox().GetVolume() << endl;
-
 	mViewCellsTree->ExportStats(fileName);
-	
 	cout << "finished" << endl;
 
@@ -5840,11 +5843,5 @@
 }
 #endif
-//////////////////////////////////
-/*ViewCellsManager *ViewCellsManagerFactory::Create(const string mName)
-{
-	//TODO
-	return NULL;// new VspBspViewCellsManager();
-}*/
-
-
-}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1259)
@@ -259,4 +259,6 @@
 	ObjectContainer mObjects;
 
+	/// universal counter
+	int mCounter;
 protected:
 
@@ -498,6 +500,7 @@
 		@returns number of view cells found
 	*/
-	int ComputeBoxIntersections(const AxisAlignedBox3 &box, 
-								ViewCellContainer &viewCells) const;
+	int ComputeBoxIntersections(
+		const AxisAlignedBox3 &box, 
+		ViewCellContainer &viewCells) const;
 
 
@@ -510,4 +513,11 @@
 	void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
 
+	/** Add the bvh leaf to the pvs of the view cell.
+	*/
+	bool AddLeafToPvs(
+		BvhLeaf *leaf, 
+		ViewCell *vc, 
+		const float pdf, 
+		float &contribution);
 
 protected:
@@ -560,5 +570,4 @@
 		}
 	};
-
  
 	/** faster evaluation of split plane cost for kd axis aligned cells.
@@ -748,4 +757,5 @@
 
 	float EvalViewCellsVolume(BvhLeaf *leaf) const;
+
 
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.h	(revision 1233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.h	(revision 1259)
@@ -266,4 +266,8 @@
   };
 
+  void GetSampleData(const bool isTerminaton, 
+				  Vector3 &pt, 
+				  Intersectable **obj,
+				  KdNode **node) const;
 
   typedef vector<RayInfo> RayInfoContainer;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1259)
@@ -18,5 +18,8 @@
 #include "KdTree.h"
 #include "KdIntersectable.h"
+#include "HierarchyManager.h"
+#include "BvHierarchy.h"
 #include "OspTree.h"
+
 
 namespace GtpVisibilityPreprocessor {
@@ -358,5 +361,5 @@
 mStoreRays(false),
 mTimeStamp(1),
-mOspTree(NULL)
+mHierarchyManager(NULL)
 {
 	bool randomize = false;
@@ -397,5 +400,5 @@
 	Environment::GetSingleton()->GetBoolValue("VspTree.simulateOctree", mCirculatingAxis);
 	
-	Environment::GetSingleton()->GetBoolValue("VspTree.useKdPvsForHeuristics", mUseKdPvsForHeuristics);
+	//Environment::GetSingleton()->GetBoolValue("VspTree.useKdPvsForHeuristics", mUseKdPvsForHeuristics);
 
 	char subdivisionStatsLog[100];
@@ -433,9 +436,4 @@
 	Debug << "maxband: " << mMaxBand << endl;
 
-	if (!mUseKdPvsForHeuristics)
-		Debug << "pvs heuristics: per object" << endl;
-	else
-		Debug << "pvs heuristics: per kd node" << endl;
-
 	mLocalSubdivisionCandidates = new vector<SortableEntry>;
 
@@ -911,43 +909,4 @@
 
 
-bool VspTree::AddKdLeafToPvs(KdLeaf *leaf, 
-							 ViewCell *vc, 
-							 const float pdf, 
-							 float &contribution)
-{
-	bool contri = false;
-
-#if 1 // add kd intersecable to pvs
-	KdIntersectable *kdObj = mOspTree->GetOrCreateKdIntersectable(leaf);
-	
-	if (vc->AddPvsSample(kdObj, pdf, contribution))
-	{
-		return true;
-	}
-
-#else // add all objects of kd node
-
-	contribution = 0;
-
-	ObjectContainer::const_iterator it, it_end = leaf->mObjects.end();
-
-	for (it = leaf->mObjects.begin(); it != it_end; ++ it)
-	{
-		Intersectable *object = *it;						
-
-		float newcontri;
-						
-		if (vc->AddPvsSample(object, pdf, newcontri))
-		{
-			contri = true;
-		}
-
-		//pdf += newPdf;
-		newContri += contribution;
-	}
-#endif
-
-	return contri;
-}
 
 
@@ -977,15 +936,11 @@
 		if (obj) 
 		{
-			if (!mStoreKdPvs)
-			{
-				// potentially visible objects
-				madeContrib = vc->AddPvsSample(obj, ray->mPdf, contribution);
-			}
-			else
-			{
-				// potentially visible kd cells
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);	
-				madeContrib = AddKdLeafToPvs(leaf, vc, ray->mPdf, contribution);
-			}	
+			madeContrib = 
+				mViewCellsManager->AddSampleToPvs(
+					obj, 
+					ray->mTermination, 
+					vc, 
+					ray->mPdf, 
+					contribution);
 
 			sc += contribution;
@@ -996,15 +951,11 @@
 		if (obj) 
 		{
-			if (!mStoreKdPvs)
-			{
-				// potentially visible objects
-				madeContrib = vc->AddPvsSample(obj, ray->mPdf, contribution);
-			}
-			else
-			{
-				// potentially visible kd cells
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);	
-				madeContrib = AddKdLeafToPvs(leaf, vc, ray->mPdf, contribution);
-			}	
+			madeContrib = 
+				mViewCellsManager->AddSampleToPvs(
+					obj,
+					ray->mOrigin, 
+					vc, 
+					ray->mPdf, 
+					contribution);
 
 			sc += contribution;
@@ -1092,4 +1043,65 @@
 
 
+int VspTree::PrepareHeuristics(const VssRay &ray, const bool isTermination)
+{
+	int pvsSize = 0;
+	
+	Intersectable *obj;
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj)
+		return 0;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+				obj->mCounter = 1;
+
+				++ pvsSize;
+			}
+			else
+			{
+				++ obj->mCounter;
+			}
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+			pvsSize += PrepareHeuristics(leaf);	
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj, NULL);
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				leaf->mCounter = 1;
+
+				++ pvsSize;
+			}
+			else
+			{
+				++ leaf->mCounter;
+			}
+			break;
+		}
+	default:
+		break;
+	}
+
+	return pvsSize;
+}
+
+
 int VspTree::PrepareHeuristics(KdLeaf *leaf)
 {	
@@ -1144,57 +1156,11 @@
 	RayInfoContainer::const_iterator ri, ri_end = rays.end();
 
-	//-- set all kd nodes / objects as belonging to the front pvs
-
+    // set all kd nodes / objects as belonging to the front pvs
 	for (ri = rays.begin(); ri != ri_end; ++ ri)
 	{
 		VssRay *ray = (*ri).mRay;
-		Intersectable *oObject = ray->mOriginObject;
-
-		if (oObject)
-		{
-			if (!mUseKdPvsForHeuristics)
-			{
-				if (!oObject->Mailed())
-				{
-					oObject->Mail();
-					oObject->mCounter = 1;
-
-					++ pvsSize;
-				}
-				else
-				{
-					++ oObject->mCounter;
-				}
-			}
-			else
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-				pvsSize += PrepareHeuristics(leaf);	
-			}	
-		}
-
-		Intersectable *tObject = (*ri).mRay->mTerminationObject;
-
-		if (tObject)
-		{
-			if (!mUseKdPvsForHeuristics)
-			{
-				if (!tObject->Mailed())
-				{
-					tObject->Mail();
-					tObject->mCounter = 1;
-					++ pvsSize;
-				}
-				else
-				{
-					++ tObject->mCounter;
-				}
-			}
-			else
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-				pvsSize += PrepareHeuristics(leaf);	
-			}	
-		}
+		
+		pvsSize += PrepareHeuristics(*ray, true);
+		pvsSize += PrepareHeuristics(*ray, false);
 	}
 
@@ -1203,6 +1169,8 @@
 
 
-void VspTree::RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const
-{
+int VspTree::EvalMaxEventContribution(KdLeaf *leaf) const
+{
+	int pvs = 0;
+
 	// leaf falls out of right pvs
 	if (-- leaf->mCounter == 0)
@@ -1211,5 +1179,6 @@
 	}
 
-	//-- handle objects which are in several kd leaves separately 
+	//-- separately handle objects which are in several kd leaves
+
 	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
 
@@ -1220,21 +1189,23 @@
 		if (-- object->mCounter == 0)
 		{
-			-- pvs;
-		}
-	}
-}
-
-
-void VspTree::AddContriToPvs(KdLeaf *leaf, int &pvs) const
+			++ pvs;
+		}
+	}
+
+	return pvs;
+}
+
+
+int VspTree::EvalMinEventContribution(KdLeaf *leaf) const
 {
 	if (leaf->Mailed())
-		return;
+		return 0;
 	
 	leaf->Mail();
 
 	// add objects without those which are part of several kd leaves
-	pvs += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
-
-	//-- handle objects of several kd leaves separately
+	int pvs = ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
+
+	// separately handle objects which are part of several kd leaves 
 	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
 
@@ -1249,82 +1220,121 @@
 			++ pvs;
 		}
-	}					
-}
-
-
-void VspTree::EvalPvsIncr(const SortableEntry &ci,
-						  int &pvsLeft,
-						  int &pvsRight) const
+	}	
+
+	return pvs;
+}
+
+
+int VspTree::EvalMinEventContribution(const VssRay &ray, 
+									  const bool isTermination) const
+{
+	Intersectable *obj;
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj) return 0;
+
+	int pvs = 0;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+				++ pvs;
+			}
+
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+			// add contributions of the kd nodes
+			pvs += EvalMinEventContribution(leaf);
+					
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				++ pvs;
+			}
+			break;
+		}
+	default:
+		break;
+	}
+	return pvs;
+}
+
+
+int VspTree::EvalMaxEventContribution(const VssRay &ray, 
+									  const bool isTermination) const
+{
+	Intersectable *obj;
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj) return 0;
+
+	int pvs = 0;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (-- obj->mCounter == 0)
+				++ pvs;
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+
+			// add contributions of the kd nodes
+			pvs += EvalMaxEventContribution(leaf);
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+
+			if (-- leaf->mCounter == 0)
+				++ pvs;
+			break;
+		}
+	default:
+		break;
+	}
+
+	return pvs;
+}
+
+
+void VspTree::EvalHeuristicsContribution(const SortableEntry &ci,
+										 int &pvsLeft,
+										 int &pvsRight) const
 {
 	VssRay *ray = ci.ray;
 
-	Intersectable *oObject = ray->mOriginObject;
-	Intersectable *tObject = ray->mTerminationObject;
-
-	if (oObject)
-	{	
-		if (!mUseKdPvsForHeuristics)
-		{
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				if (!oObject->Mailed())
-				{
-					oObject->Mail();
-					++ pvsLeft;
-				}
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				if (-- oObject->mCounter == 0)
-					-- pvsRight;
-			}
-		}
-		else // per kd node
-		{
-			KdLeaf *node = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-
-			// add contributions of the kd nodes
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				AddContriToPvs(node, pvsLeft);
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				RemoveContriFromPvs(node, pvsRight);
-			}
-		}
-	}
-	
-	if (tObject)
-	{	
-		if (!mUseKdPvsForHeuristics)
-		{
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				if (!tObject->Mailed())
-				{
-					tObject->Mail();
-					++ pvsLeft;
-				}
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				if (-- tObject->mCounter == 0)
-					-- pvsRight;
-			}
-		}
-		else // per kd node
-		{
-			KdLeaf *node = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				AddContriToPvs(node, pvsLeft);
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				RemoveContriFromPvs(node, pvsRight);
-			}
-		}
+	if (ci.type == SortableEntry::ERayMin)
+	{
+		pvsLeft += EvalMinEventContribution(*ray, true);
+		pvsLeft += EvalMinEventContribution(*ray, false);
+	}
+	else
+	{
+		pvsRight -= EvalMaxEventContribution(*ray, true);
+		pvsRight -= EvalMaxEventContribution(*ray, false);
 	}
 }
@@ -1336,4 +1346,5 @@
 									   float &position)
 {
+	// get subset of rays
 	RayInfoContainer usedRays;
 
@@ -1395,5 +1406,5 @@
 	for (ci = mLocalSubdivisionCandidates->begin(); ci != ci_end; ++ ci)
 	{
-		EvalPvsIncr(*ci, pvsl, pvsr);
+		EvalHeuristicsContribution(*ci, pvsl, pvsr);
 
 		// Note: sufficient to compare size of bounding boxes of front and back side?
@@ -1580,5 +1591,5 @@
 			rayInf.ComputeRayIntersection(candidatePlane.mAxis, 
 										  candidatePlane.mPosition, t);
-
+/*
 		if (!mUseKdPvsForHeuristics)
 		{
@@ -1591,5 +1602,5 @@
 			if (ray->mTerminationObject)
 			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+				KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
 				UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs);
 			}
@@ -1597,8 +1608,9 @@
 			if (ray->mOriginObject)
 			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+				KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
 				UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs);
 			}
 		}
+*/
 	}
 
@@ -2243,91 +2255,89 @@
 
 
-int VspTree::EvalPvsSize(const RayInfoContainer &rays) const
-{
-	int pvsSize = 0;
-	Intersectable::NewMail();
-
-	RayInfoContainer::const_iterator rit, rit_end = rays.end();
-
-	if (!mUseKdPvsForHeuristics)
-	{
-		for (rit = rays.begin(); rit != rays.end(); ++ rit)
-		{
-			VssRay *ray = (*rit).mRay;
-
-			if (ray->mOriginObject)
-			{
-				if (!ray->mOriginObject->Mailed())
+int VspTree::EvalPvsContribution(const VssRay &ray, const bool isTermination) const
+{	
+	Intersectable *obj; 
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj) return 0;
+
+	int pvs = 0;
+
+	switch(mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+				++ pvs;
+			}
+
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
+				
+				ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
+				for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
 				{
-					ray->mOriginObject->Mail();
-					++ pvsSize;
-				}
-			}
-			if (ray->mTerminationObject)
-			{
-				if (!ray->mTerminationObject->Mailed())
-				{
-					ray->mTerminationObject->Mail();
-					++ pvsSize;
-				}
-			}
-		}
-	}
-	else // compute pvs from kd nodes
-	{
-		KdNode::NewMail();
-
-		for (rit = rays.begin(); rit != rays.end(); ++ rit)
-		{
-			VssRay *ray = (*rit).mRay;
-
-			if (ray->mTerminationObject)
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-
-				if (!leaf->Mailed())
-				{
-					leaf->Mail();
-					pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
-				
-					ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
-					for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
+					Intersectable *obj = *oit;
+
+					if (!obj->Mailed())
 					{
-						Intersectable *obj = *oit;
-
-						if (!obj->Mailed())
-						{
-							obj->Mail();
-							++ pvsSize;
-						}
+						obj->Mail();
+						++ pvs;
 					}
 				}
 			}
 
-			if (ray->mOriginObject)
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-
-				if (!leaf->Mailed())
-				{
-					leaf->Mail();
-					pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
-				
-					ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
-					for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
-					{
-						Intersectable *obj = *oit;
-
-						if (!obj->Mailed())
-						{
-							obj->Mail();
-							++ pvsSize;
-						}
-					}
-				}
-			}
-		}
-	}
-
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+
+			if (!bvhleaf->Mailed())
+			{
+				bvhleaf->Mail();
+				pvs += (int)bvhleaf->mObjects.size();
+			}
+
+			break;
+		}
+	default:
+		break;
+	}
+
+	return pvs;
+}
+
+
+int VspTree::EvalPvsSize(const RayInfoContainer &rays) const
+{
+	int pvsSize = 0;
+	
+	Intersectable::NewMail();
+	KdNode::NewMail();
+	BvhNode::NewMail();
+
+	RayInfoContainer::const_iterator rit, rit_end = rays.end();
+
+	for (rit = rays.begin(); rit != rays.end(); ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+		pvsSize += EvalPvsContribution(*ray, true);
+		pvsSize += EvalPvsContribution(*ray, false);
+	}
+	
 	return pvsSize;
 }
@@ -2806,38 +2816,4 @@
 
 
-void VspTree::CollectDirtyCandidates(VspSubdivisionCandidate *sc, 
-									 vector<SubdivisionCandidate *> &dirtyList)
-{
-	VspTraversalData &tData = sc->mParentData;
-	VspLeaf *node = tData.mNode;
-	
-	KdLeaf::NewMail();
-
-	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
-
-	// add all kd nodes seen by the rays
-	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
-	{
-		VssRay *ray = (*rit).mRay;
-	
-		KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-	
-		if (!leaf->Mailed())
-		{
-			leaf->Mail();
-			dirtyList.push_back(leaf->mSubdivisionCandidate);
-		}
-		
-		leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-	
-		if (!leaf->Mailed())
-		{
-			leaf->Mail();
-			dirtyList.push_back(leaf->mSubdivisionCandidate);
-		}
-	}
-}
-
-
 void VspTree::PreprocessRays(const VssRayContainer &sampleRays,
 							 RayInfoContainer &rays)
@@ -2965,4 +2941,36 @@
 
 
-
-}
+void VspTree::CollectDirtyCandidates(VspSubdivisionCandidate *sc, 
+									 vector<SubdivisionCandidate *> &dirtyList)
+{
+	VspTraversalData &tData = sc->mParentData;
+	VspLeaf *node = tData.mNode;
+	
+	KdLeaf::NewMail();
+
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+
+	// add all kd nodes seen by the rays
+	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+	
+		KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+	
+		if (!leaf->Mailed())
+		{
+			leaf->Mail();
+			dirtyList.push_back(leaf->mSubdivisionCandidate);
+		}
+		
+		leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+	
+		if (!leaf->Mailed())
+		{
+			leaf->Mail();
+			dirtyList.push_back(leaf->mSubdivisionCandidate);
+		}
+	}
+}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1221)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1259)
@@ -282,4 +282,11 @@
     return SqrMagnitude(diff);
   }
+
+  void GetSampleData(
+	  const bool isTerminaton, 
+	  Vector3 &pt, 
+	  Intersectable **obj,
+	  KdNode **node) const;
+
   friend ostream& operator<< (ostream &s, const VssRay &vssRay);
     
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1259)
@@ -264,3 +264,24 @@
 }
 
-}
+
+void VssRay::GetSampleData(const bool isTermination, 
+						   Vector3 &pt, 
+						   Intersectable **obj,
+						   KdNode **node) const
+{
+	if (isTermination)
+	{
+		pt = mTermination;
+		*obj = mTerminationObject;
+		*node = mTerminationNode;
+	}
+	else
+	{
+		pt = mOrigin;
+		*obj = mOriginObject;
+		*node = mOriginNode;
+	}
+}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1237)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1259)
@@ -20,4 +20,5 @@
 #include "VspTree.h"
 #include "OspTree.h"
+#include "BvHierarchy.h"
 
 
@@ -33,11 +34,7 @@
 
 
-HierarchyManager::HierarchyManager(VspTree &vspTree, OspTree &ospTree):
-mVspTree(vspTree), mOspTree(ospTree)
-{
-	// cross references
-	mVspTree.mOspTree = &ospTree;
-	mOspTree.mVspTree = &vspTree;
-
+HierarchyManager::HierarchyManager(VspTree &vspTree, OspTree &ospTree)
+//:mVspTree(vspTree), mOspTree(ospTree)
+{
 	char subdivisionStatsLog[100];
 	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", 
@@ -63,9 +60,9 @@
 {
 	SubdivisionCandidate *vsc = 
-		mVspTree.PrepareConstruction(sampleRays, forcedViewSpace, viewSpaceRays);
+		mVspTree->PrepareConstruction(sampleRays, forcedViewSpace, viewSpaceRays);
 	mTQueue.Push(vsc);
 
 	SubdivisionCandidate *osc = 
-		mOspTree.PrepareConstruction(sampleRays, objects, forcedViewSpace, objectSpaceRays);
+		mOspTree->PrepareConstruction(sampleRays, objects, forcedViewSpace, objectSpaceRays);
 
 	mTQueue.Push(osc);
@@ -78,7 +75,7 @@
 
 	//mTotalCost -= costDecr;
-	// mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs;
-
-	AddSubdivisionStats(mOspTree.mOspStats.Leaves() + mVspTree.mVspStats.Leaves(),
+	//mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs;
+
+	AddSubdivisionStats(mOspTree->mOspStats.Leaves() + mVspTree->mVspStats.Leaves(),
 						costDecr,
 						mTotalCost
@@ -116,6 +113,6 @@
 	PrepareConstruction(sampleRays, objects, forcedViewSpace, *viewSpaceRays, *objectSpaceRays);
 
-	mVspTree.mVspStats.Reset();
-	mVspTree.mVspStats.Start();
+	mVspTree->mVspStats.Reset();
+	mVspTree->mVspStats.Start();
 
 	cout << "Constructing view space / object space tree ... \n";
@@ -126,5 +123,5 @@
 	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
 
-	mVspTree.mVspStats.Stop();
+	mVspTree->mVspStats.Stop();
 }
 
@@ -139,9 +136,9 @@
 	if (vspSplit)
 	{
-		VspNode *n = mVspTree.Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
+		VspNode *n = mVspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
 	}
 	else
 	{
-		KdNode *n = mOspTree.Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
+		KdNode *n = mOspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
 	}
 	
@@ -209,12 +206,12 @@
 	// during view space partition
 	const bool savedCountMethod = mVspTree.mUseKdPvsForHeuristics;
-	const bool savedStoreMethod = mVspTree.mStoreKdPvs;
+	const bool savedStoreMethod = mVspTree.mStoreObjectPvs;
 	
 	mVspTree.mUseKdPvsForHeuristics = false;
-	mVspTree.mStoreKdPvs = false;
+	mVspTree.mStoreObjectPvs = false;
 #endif
 
 	SubdivisionCandidate *vsc = 
-		mVspTree.PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
+		mVspTree->PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
 
 	// add to queue
@@ -224,6 +221,6 @@
 	cout << "starting vsp contruction ... " << endl;
 
-	mVspTree.mVspStats.Reset();
-	mVspTree.mVspStats.Start();
+	mVspTree->mVspStats.Reset();
+	mVspTree->mVspStats.Start();
 
 	int i = 0;
@@ -238,6 +235,5 @@
 
 	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
-	mVspTree.mVspStats.Stop();
-	
+	mVspTree->mVspStats.Stop();
 
 
@@ -255,13 +251,13 @@
 	// compute first candidate
 	SubdivisionCandidate *osc =
-		mOspTree.PrepareConstruction(sampleRays, objects, forcedViewSpace, *objectSpaceRays);
+		mOspTree->PrepareConstruction(sampleRays, objects, forcedViewSpace, *objectSpaceRays);
 
 	Debug << "reseting cost, new total cost: " << mTotalCost << endl;
-	mTotalCost = mOspTree.mTotalCost;
+	mTotalCost = mOspTree->mTotalCost;
 
     mTQueue.Push(osc);
 
-	mOspTree.mOspStats.Reset();
-	mOspTree.mOspStats.Start();
+	mOspTree->mOspStats.Reset();
+	mOspTree->mOspStats.Start();
 
 	startTime = GetTime();
@@ -272,7 +268,7 @@
 	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
 
-	mOspTree.mOspStats.Stop();
-
-	float rc = mOspTree.EvalRenderCost(sampleRays);
+	mOspTree->mOspStats.Stop();
+
+	float rc = mOspTree->EvalRenderCost(sampleRays);
 
 	Debug << "here47 My render cost evalulation: " << rc << endl;
@@ -280,6 +276,6 @@
 #if 0
 	// reset parameters
-	mVspTree.mUseKdPvsForHeuristics = savedCountMethod;
-	mVspTree.mStoreKdPvs = savedStoreMethod;
+	mVspTree->mUseKdPvsForHeuristics = savedCountMethod;
+	mVspTree->mStoreObjectPvs = savedStoreMethod;
 #endif
 }
@@ -290,14 +286,14 @@
 								  AxisAlignedBox3 *forcedViewSpace)
 {
-	// only view space partition
+	// construct only view space partition
 	// object kd tree is taken for osp
 
-	mVspTree.mVspStats.Reset();
-	mVspTree.mVspStats.Start();
+	mVspTree->mVspStats.Reset();
+	mVspTree->mVspStats.Start();
 
 	RayInfoContainer *viewSpaceRays = new RayInfoContainer();
 	
 	SubdivisionCandidate *sc = 
-		mVspTree.PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
+		mVspTree->PrepareConstruction(sampleRays, forcedViewSpace, *viewSpaceRays);
 
 	mTQueue.Push(sc);
@@ -310,5 +306,5 @@
 
 	cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl;
-	mVspTree.mVspStats.Stop();
+	mVspTree->mVspStats.Stop();
 }
 
@@ -320,20 +316,49 @@
 
 
-void HierarchyManager::CollectDirtyCandidates(vector<SubdivisionCandidate *> &dirtyList)
+void HierarchyManager::CollectObjectSpaceDirtyList(SubdivisionCandidateContainer &dirtyList)
+{
+	switch (mObjectSpaceSubdivisonType)
+	{
+	case KD_BASED_OBJ_SUBDIV:
+		{
+			OspTree::OspSubdivisionCandidate *sc = 
+				dynamic_cast<OspTree::OspSubdivisionCandidate *>(mCurrentCandidate);
+
+			mOspTree->CollectDirtyCandidates(sc, dirtyList);
+			break;
+		}
+	case BV_BASED_OBJ_SUBDIV:
+		{
+			BvHierarchy::BvhSubdivisionCandidate *sc = 
+				dynamic_cast<BvHierarchy::BvhSubdivisionCandidate *>(mCurrentCandidate);
+
+			mBvHierarchy->CollectDirtyCandidates(sc, dirtyList);
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+
+void HierarchyManager::CollectViewSpaceDirtyList(SubdivisionCandidateContainer &dirtyList)
+{
+	VspTree::VspSubdivisionCandidate *sc = 
+		dynamic_cast<VspTree::VspSubdivisionCandidate *>(mCurrentCandidate);
+
+	mVspTree->CollectDirtyCandidates(sc, dirtyList);
+}
+
+
+void HierarchyManager::CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList)
 {	
 	// we have either a object space or view space split
 	if (mCurrentCandidate->Type() == SubdivisionCandidate::VIEW_SPACE)
 	{
-		VspTree::VspSubdivisionCandidate *sc = 
-			dynamic_cast<VspTree::VspSubdivisionCandidate *>(mCurrentCandidate);
-
-		mVspTree.CollectDirtyCandidates(sc, dirtyList);
+		CollectViewSpaceDirtyList(dirtyList);
 	}
 	else // object space split
-	{			
-		OspTree::OspSubdivisionCandidate *sc = 
-			dynamic_cast<OspTree::OspSubdivisionCandidate *>(mCurrentCandidate);
-
-		mOspTree.CollectDirtyCandidates(sc, dirtyList);
+	{	
+		CollectObjectSpaceDirtyList(dirtyList);
 	}
 }
@@ -380,3 +405,4 @@
 }
 
-}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp	(revision 1259)
@@ -2712,3 +2712,15 @@
 
 
-}
+bool OspTree::AddLeafToPvs(KdLeaf *leaf, 
+						   ViewCell *vc, 
+						   const float pdf, 
+						   float &contribution)
+{
+	// add kd intersecable to pvs
+	KdIntersectable *kdObj = GetOrCreateKdIntersectable(leaf);
+	
+	return vc->AddPvsSample(kdObj, pdf, contribution);
+}
+
+
+}
