Index: /GTP/trunk/Lib/Vis/Preprocessing/scripts/preprocess_visibility.env
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/scripts/preprocess_visibility.env	(revision 2075)
+++ /GTP/trunk/Lib/Vis/Preprocessing/scripts/preprocess_visibility.env	(revision 2210)
@@ -24,5 +24,5 @@
 	useGlDebugger false
 # 0 = INTERNAL 		1 = MLRT
-	rayCastMethod 0
+	rayCastMethod 1
 	
 	type combined
@@ -128,5 +128,5 @@
 	importRandomViewCells false
 
-	useKdPvs true
+	useKdPvs false
 	useKdPvsAfterFiltering true
 	# samples used for view cell construction
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp	(revision 2172)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp	(revision 2210)
@@ -92,5 +92,5 @@
 		Intersectable *newObject = vssRays[i]->mTerminationObject;
 
-		Intersectable *oldObject =mRays[vssRays[i]->mGeneratorId].mRay->mTerminationObject;
+		Intersectable *oldObject = mRays[vssRays[i]->mGeneratorId].mRay->mTerminationObject;
 		
 		if (oldObject == newObject)
@@ -600,5 +600,5 @@
   //rr[0] = RandomValue(0,1);
   // use binary search to find index with this cdf
-  int l=0, r=mRays.size()-1;
+  int l=0, r=(int)mRays.size()-1;
   while(l<r) {
 	int i = (l+r)/2;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 2199)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 2210)
@@ -551,8 +551,14 @@
 		float mCorrectedBackPvs;
 
+		float mFrontPvs;
+		float mBackPvs;
+
 		float mCorrectedFrontRenderCost;
 		float mCorrectedBackRenderCost;
-		float mCorrectedFrontVolume;
-		float mCorrectedBackVolume;
+		//float mCorrectedFrontVolume;
+		//float mCorrectedBackVolume;
+
+		float mFrontRenderCost;
+		float mBackRenderCost;
 	};
 
@@ -1092,4 +1098,6 @@
 
 	HierarchyManager *mHierarchyManager;
+	BvHierarchy *mBvHierarchy;
+
 	//OspTree *mOspTree;
 	//bool mUseKdPvsForHeuristics;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 2206)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 2210)
@@ -237,6 +237,5 @@
 mRoot(NULL),
 mTimeStamp(1),
-mIsInitialSubdivision(false),
-mCachedObjects(NULL)
+mIsInitialSubdivision(false)
 {
 	ReadEnvironment();
@@ -394,8 +393,10 @@
 	mNodeTimer.Entry();
 
+/*
 #if STORE_VIEWCELLS_WITH_BVH
-	AssociateViewCellsWithObjects(sc.mFrontObjects);
-	AssociateViewCellsWithObjects(sc.mBackObjects);
+	AssociateViewCellsWithObjects(sc.mSampledFrontObjects);
+	AssociateViewCellsWithObjects(sc.mSampledBackObjects);
 #endif	
+*/
 	const BvhTraversalData &tData = sc.mParentData;
 	BvhLeaf *leaf = tData.mNode;
@@ -451,4 +452,10 @@
 	backData.mNode = back;
 
+	backData.mSampledObjects = new ObjectContainer();
+	frontData.mSampledObjects = new ObjectContainer();
+
+	*backData.mSampledObjects = sc.mSampledBackObjects;
+	*frontData.mSampledObjects = sc.mSampledFrontObjects;
+
 	back->mObjects = sc.mBackObjects;
 	front->mObjects = sc.mFrontObjects;
@@ -456,6 +463,6 @@
 	// if the number of rays is too low, no assumptions can be made
 	// (=> switch to surface area heuristics?)
-	frontData.mNumRays = CountRays(sc.mFrontObjects);
-	backData.mNumRays = CountRays(sc.mBackObjects);
+	frontData.mNumRays = CountRays(sc.mSampledFrontObjects);
+	backData.mNumRays = CountRays(sc.mSampledBackObjects);
 
 	AssociateObjectsWithLeaf(back);
@@ -465,6 +472,6 @@
 	//-- compute pvs correction to cope with undersampling
 
-	frontData.mPvs = (float)CountViewCells(front->mObjects);
-	backData.mPvs = (float)CountViewCells(back->mObjects);
+	frontData.mPvs = (float)sc.mNumFrontViewCells;//(float)CountViewCells(sc.mSampledFrontObjects);
+	backData.mPvs = (float)sc.mNumBackViewCells;//(float)CountViewCells(sc.mSampledBackObjects);
 
 	frontData.mCorrectedPvs = sc.mCorrectedFrontPvs;
@@ -474,6 +481,6 @@
 	// compute probability of this node being visible, 
 	// i.e., volume of the view cells that can see this node
-	frontData.mVolume = EvalViewCellsVolume(sc.mFrontObjects) / GetViewSpaceVolume();
-	backData.mVolume = EvalViewCellsVolume(sc.mBackObjects) / GetViewSpaceVolume();
+	frontData.mVolume = sc.mVolumeFrontViewCells;//EvalViewCellsVolume(sc.mSampledFrontObjects) / GetViewSpaceVolume();
+	backData.mVolume = sc.mVolumeBackViewCells;//EvalViewCellsVolume(sc.mSampledBackObjects) / GetViewSpaceVolume();
 
 	frontData.mCorrectedVolume = sc.mCorrectedFrontVolume;
@@ -493,10 +500,10 @@
 		AssignSortedObjects(sc, frontData, backData);
 	}
-
+/*
 #if STORE_VIEWCELLS_WITH_BVH
-	ReleaseViewCells(sc.mFrontObjects);
-	ReleaseViewCells(sc.mBackObjects);
+	ReleaseViewCells(sc.mSampledFrontObjects);
+	ReleaseViewCells(sc.mSampledBackObjects);
 #endif
-
+*/
 	mNodeTimer.Exit();
 
@@ -637,9 +644,14 @@
 #if STORE_VIEWCELLS_WITH_BVH
 	// fill view cells cache
-	AssociateViewCellsWithObjects(*splitCandidate.mParentData.mSortedObjects[3]);
+	AssociateViewCellsWithObjects(*splitCandidate.mParentData.mSampledObjects);
 #endif
 
 	if (computeSplitPlane)
 	{
+		splitCandidate.mFrontObjects.clear();
+		splitCandidate.mBackObjects.clear();
+		splitCandidate.mSampledFrontObjects.clear();
+		splitCandidate.mSampledBackObjects.clear();
+
 		const bool sufficientSamples = 
 			splitCandidate.mParentData.mNumRays > mMinRaysForVisibility;
@@ -663,5 +675,9 @@
 		splitCandidate.SetMaxCostMisses(maxCostRatioViolated ? 
 										previousMisses + 1 : previousMisses);
-	}
+
+		StoreSampledObjects(splitCandidate.mSampledFrontObjects, splitCandidate.mFrontObjects);
+		StoreSampledObjects(splitCandidate.mSampledBackObjects, splitCandidate.mBackObjects);
+	}
+
 	mPlaneTimer.Exit();
 
@@ -672,5 +688,5 @@
 
 	// avg contribution of a ray to a pvs
-	const float pvs = (float)CountViewCells(leaf->mObjects);
+	const float pvs = (float)CountViewCells(*tData.mSampledObjects);
 	const float avgRayContri = AvgRayContribution((int)pvs, tData.mNumRays);
 
@@ -679,5 +695,5 @@
 	const float viewSpaceVol = GetViewSpaceVolume();
 
-	const float oldVolume = EvalViewCellsVolume(leaf->mObjects) / viewSpaceVol;
+	const float oldVolume = EvalViewCellsVolume(*tData.mSampledObjects) / viewSpaceVol;
 	const float oldRatio = (tData.mVolume) > 0 ? oldVolume / tData.mVolume : 1;
 	const float parentVol = tData.mCorrectedVolume * oldRatio;
@@ -685,12 +701,15 @@
 	// this leaf is a pvs entry in all the view cells
 	// that see one of the objects.
-	const float frontVol = EvalViewCellsVolume(splitCandidate.mFrontObjects) / viewSpaceVol;
-	const float backVol = EvalViewCellsVolume(splitCandidate.mBackObjects) / viewSpaceVol;
+	splitCandidate.mVolumeFrontViewCells = EvalViewCellsVolume(splitCandidate.mSampledFrontObjects) / viewSpaceVol;
+	splitCandidate.mVolumeBackViewCells = EvalViewCellsVolume(splitCandidate.mSampledBackObjects) / viewSpaceVol;
+
+	splitCandidate.mNumFrontViewCells = CountViewCells(splitCandidate.mSampledFrontObjects);
+	splitCandidate.mNumBackViewCells = CountViewCells(splitCandidate.mSampledBackObjects);
 
 	splitCandidate.mCorrectedFrontVolume = 
-		mHierarchyManager->EvalCorrectedPvs(frontVol, parentVol, avgRayContri);
+		mHierarchyManager->EvalCorrectedPvs(splitCandidate.mVolumeFrontViewCells, parentVol, avgRayContri);
 	
 	splitCandidate.mCorrectedBackVolume = 
-		mHierarchyManager->EvalCorrectedPvs(backVol, parentVol, avgRayContri);
+		mHierarchyManager->EvalCorrectedPvs(splitCandidate.mVolumeBackViewCells, parentVol, avgRayContri);
 	
 	const float relfrontCost = splitCandidate.mCorrectedFrontVolume * 
@@ -707,5 +726,10 @@
 
 	// increase in pvs entries
-	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, avgRayContri);
+	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, 
+												  avgRayContri, 
+												  (int)pvs, 
+												  splitCandidate.mNumFrontViewCells, 
+												  splitCandidate.mNumBackViewCells);
+
 	splitCandidate.SetPvsEntriesIncr(pvsEntriesIncr);
 
@@ -715,6 +739,6 @@
 		 << " avg ray contri: " << avgRayContri << " ratio: " << oldRatio 
 		 << " parent: " << parentVol << " old vol: " << oldVolume 
-		 << " frontvol: " << frontVol << " corr. " << splitCandidate.mCorrectedFrontVolume 
-		 << " backvol: " << backVol << " corr. " << splitCandidate.mCorrectedBackVolume << endl;
+		 << " frontvol: " << splitCandidate.mVolumeFrontViewCells << " corr. " << splitCandidate.mCorrectedFrontVolume 
+		 << " backvol: " << splitCandidate.mVolumeBackViewCells << " corr. " << splitCandidate.mCorrectedBackVolume << endl;
 	}
 
@@ -733,5 +757,5 @@
 
 #if STORE_VIEWCELLS_WITH_BVH
-	ReleaseViewCells(*splitCandidate.mParentData.mSortedObjects[3]);
+	ReleaseViewCells(*splitCandidate.mParentData.mSampledObjects);
 #endif
 
@@ -741,13 +765,16 @@
 
 int BvHierarchy::EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate, 
-									const float avgRayContri) //const
-{
-	const float oldPvsSize = (float)CountViewCells(splitCandidate.mParentData.mNode->mObjects);
+									const float avgRayContri,
+									const int numParentViewCells,
+									const int numFrontViewCells,
+									const int numBackViewCells) //const
+{
+	const float oldPvsSize = (float)numParentViewCells;//CountViewCells(*splitCandidate.mParentData.mSampledObjects);
 	const float oldPvsRatio = (splitCandidate.mParentData.mPvs > 0) ? oldPvsSize / splitCandidate.mParentData.mPvs : 1;
 
 	const float parentPvs = splitCandidate.mParentData.mCorrectedPvs * oldPvsRatio;
 
-	const int frontViewCells = CountViewCells(splitCandidate.mFrontObjects);
-	const int backViewCells = CountViewCells(splitCandidate.mBackObjects);
+	const int frontViewCells = numFrontViewCells;//CountViewCells(splitCandidate.mSampledFrontObjects);
+	const int backViewCells = numBackViewCells;//CountViewCells(splitCandidate.mSampledBackObjects);
 	
 	splitCandidate.mCorrectedFrontPvs = 
@@ -976,5 +1003,5 @@
 	const float cost = (tData.mNode->GetBoundingBox().Size().DrivingAxis() == axis) ? -1.0f : 0.0f;
 #else
-	const float oldRenderCost = EvalRenderCost(tData.mNode->mObjects);
+	const float oldRenderCost = EvalAbsCost(tData.mLeaf->mObjects) / EvalProbability(tData.mSampledObjects);
 	const float newRenderCost = EvalRenderCost(objectsFront) + EvalRenderCost(objectsBack);
 
@@ -1196,5 +1223,5 @@
 		Intersectable *obj = (*cit).mObject;
 
-		const float renderCost = mViewCellsManager->EvalRenderCost(obj);
+		const float renderCost = ViewCellsManager::EvalRenderCost(obj);
 		
 		objectsLeft += renderCost;
@@ -1329,5 +1356,5 @@
 	float volRight = totalVol;
 	
-#if USE_BETTER_RENDERCOST_EST
+#if 1//USE_BETTER_RENDERCOST_EST
 	const float nTotalObjects = EvalAbsCost(tData.mNode->mObjects);
 	float nObjectsLeft = 0;
@@ -1386,17 +1413,13 @@
 		nObjectsLeft += rc;
 		nObjectsRight -= rc;
-		
-		// split is only valid if #objects on left and right is not zero
-		const bool noValidSplit = ((nObjectsLeft <= Limits::Small) || 
-								   (nObjectsRight <= Limits::Small));
+	
 #else
 		++ nObjectsLeft;
 		-- nObjectsRight;
-
+#endif
+	
 		// split is only valid if #objects on left and right is not zero
-		const bool noValidSplit = !nObjectsLeft || !nObjectsRight;
-
-#endif
-		
+		const bool noValidSplit = (nObjectsRight <= Limits::Small);
+
 		// the heuristics
 	    const float sum = noValidSplit ? 
@@ -1531,5 +1554,5 @@
 
 	
-	CollectViewCells(tData.mNode->mObjects, 
+	CollectViewCells(*tData.mSampledObjects, 
 					 viewCells, 
 					 setCounter, 
@@ -1851,4 +1874,5 @@
 	///////////////
 	//-- render cost heuristics
+	const float objRenderCost = EvalAbsCost(objects);
 
 	const float viewSpaceVol = mViewCellsManager->GetViewSpaceBox().GetVolume();
@@ -1856,7 +1880,15 @@
 	// probability that view point lies in a view cell which sees this node
 	const float p = EvalViewCellsVolume(objects) / viewSpaceVol;
-    const float objRenderCost = EvalAbsCost(objects);
 	
 	return objRenderCost * p;
+}
+
+
+float BvHierarchy::EvalProbability(const ObjectContainer &objects)// const
+{	
+	const float viewSpaceVol = mViewCellsManager->GetViewSpaceBox().GetVolume();
+	
+	// probability that view point lies in a view cell which sees this node
+	return EvalViewCellsVolume(objects) / viewSpaceVol;
 }
 
@@ -1941,4 +1973,27 @@
 
 
+int BvHierarchy::CollectViewCells(const ObjectContainer &objects, 
+								  ViewCellContainer &viewCells,
+								  const bool setCounter,
+								  const bool onlyUnmailedRays)// const
+{
+	ViewCell::NewMail();
+
+	ObjectContainer::const_iterator oit, oit_end = objects.end();
+
+	// use mailing to avoid dublicates
+	const bool useMailBoxing = true;
+
+	int numRays = 0;
+	// loop through all object and collect view cell pvs of this node
+	for (oit = objects.begin(); oit != oit_end; ++ oit)
+	{
+		// use mailing to avoid duplicates
+		numRays += CollectViewCells(*oit, viewCells, useMailBoxing, setCounter, onlyUnmailedRays);
+	}
+
+	return numRays;
+}
+
 
 #if STORE_VIEWCELLS_WITH_BVH
@@ -1953,27 +2008,19 @@
 		(*oit)->DelViewCells();
 	}
-
-	DEL_PTR(mCachedObjects);
-}
-
-
-void BvHierarchy::AssociateViewCellsWithObjects(const ObjectContainer &objects)// const
+}
+
+
+void BvHierarchy::AssociateViewCellsWithObjects(const ObjectContainer &objects) const
 {
 	ObjectContainer::const_iterator oit, oit_end = objects.end();
 
 	const bool useMailBoxing = true;
-
-	mCachedObjects = new ObjectContainer();
+	VssRay::NewMail();
 	
 	for (oit = objects.begin(); oit != oit_end; ++ oit)
 	{
-		if (!(*oit)->GetOrCreateRays()->empty())
-		{
 			ViewCell::NewMail();
 			// use mailing to avoid duplicates
 			AssociateViewCellsWithObject(*oit, useMailBoxing);
-			
-			mCachedObjects->push_back(*oit);
-		}
 	}
 }
@@ -1982,8 +2029,9 @@
 int BvHierarchy::AssociateViewCellsWithObject(Intersectable *obj, const bool useMailBoxing) const
 {
+	int nRays = 0;
+
 	if (!obj->GetOrCreateViewCells()->empty())
 	{
-		cerr << "AssociateViewCellsWithObject: view cells cache error" << endl;
-		exit(0);
+		cerr << "AssociateViewCellsWithObject: view cells cache not working" << endl;
 	}
 
@@ -2001,7 +2049,15 @@
 		//		continue;
 		mHierarchyManager->mVspTree->GetViewCells(*ray, *objViewCells);
-	}
-
-	return (int)vssRays->size();
+		
+		if (!useMailBoxing || !ray->Mailed())
+		{
+			if (useMailBoxing)
+				ray->Mail();
+
+			++ nRays;
+		}
+	}
+
+	return nRays;
 }
 
@@ -2014,5 +2070,5 @@
 	if (obj->GetOrCreateViewCells()->empty())
 	{
-		cerr << "h";//CountViewCells: view cells empty, view cells cache not working" << endl;
+		//cerr << "h";//CountViewCells: view cells empty, view cells cache not working" << endl;
 		return CountViewCellsFromRays(obj);
 	}
@@ -2177,118 +2233,5 @@
 }
 
-
-int BvHierarchy::CollectViewCells(const ObjectContainer &objects, 
-								  ViewCellContainer &viewCells,
-								  const bool setCounter,
-								  const bool onlyUnmailedRays)// const
-{
-	ViewCell::NewMail();
-
-	// use mailing to avoid dublicates
-	const bool useMailBoxing = true;
-
-	int numRays = 0;
-
-	if (mCachedObjects)
-	{
-		ObjectContainer::const_iterator oit, oit_end = mCachedObjects->end();
-
-		// loop through all object and collect view cell pvs of this node
-		for (oit = mCachedObjects->begin(); oit != oit_end; ++ oit)
-		{
-			// use mailing to avoid duplicates
-			numRays += CollectViewCells(*oit, viewCells, useMailBoxing, setCounter, onlyUnmailedRays);
-		}
-	}
-	else
-	{
-		ObjectContainer::const_iterator oit, oit_end = objects.end();
-
-		// loop through all object and collect view cell pvs of this node
-		for (oit = objects.begin(); oit != oit_end; ++ oit)
-		{
-			// use mailing to avoid duplicates
-			numRays += CollectViewCellsFromRays(*oit, viewCells, useMailBoxing, setCounter, onlyUnmailedRays);
-		}
-	}
-
-	return numRays;
-}
-
-
-int BvHierarchy::CountViewCells(const ObjectContainer &objects)// const
-{
-	int nViewCells = 0;
-
-	ViewCell::NewMail();
-	
-	if (mCachedObjects)
-	{
-		ObjectContainer::const_iterator oit, oit_end = mCachedObjects->end();
-
-		// loop through all object and collect view cell pvs of this node
-		for (oit = mCachedObjects->begin(); oit != oit_end; ++ oit)
-		{
-			// use mailing to avoid duplicates
-			nViewCells += CountViewCells(*oit);
-		}
-	}
-	else
-	{
-		ObjectContainer::const_iterator oit, oit_end = objects.end();
-
-		// loop through all object and collect view cell pvs of this node
-		for (oit = objects.begin(); oit != oit_end; ++ oit)
-		{
-			nViewCells += CountViewCellsFromRays(*oit);
-		}
-	}
-
-	return nViewCells;
-}
-
-
 #else
-
-int BvHierarchy::CollectViewCells(const ObjectContainer &objects, 
-								  ViewCellContainer &viewCells,
-								  const bool setCounter,
-								  const bool onlyUnmailedRays)// const
-{
-	ViewCell::NewMail();
-
-	ObjectContainer::const_iterator oit, oit_end = objects.end();
-
-	// use mailing to avoid dublicates
-	const bool useMailBoxing = true;
-
-	int numRays = 0;
-	// loop through all object and collect view cell pvs of this node
-	for (oit = objects.begin(); oit != oit_end; ++ oit)
-	{
-		// use mailing to avoid duplicates
-		numRays += CollectViewCells(*oit, viewCells, useMailBoxing, setCounter, onlyUnmailedRays);
-	}
-
-	return numRays;
-}
-
-
-int BvHierarchy::CountViewCells(const ObjectContainer &objects)// const
-{
-	int nViewCells = 0;
-
-	ViewCell::NewMail();
-	ObjectContainer::const_iterator oit, oit_end = objects.end();
-
-	// loop through all object and collect view cell pvs of this node
-	for (oit = objects.begin(); oit != oit_end; ++ oit)
-	{
-		nViewCells += CountViewCells(*oit);
-	}
-
-	return nViewCells;
-}
-
 
 int BvHierarchy::CountViewCells(Intersectable *obj) //const
@@ -2377,4 +2320,20 @@
 
 
+int BvHierarchy::CountViewCells(const ObjectContainer &objects)// const
+{
+	int nViewCells = 0;
+
+	ViewCell::NewMail();
+	ObjectContainer::const_iterator oit, oit_end = objects.end();
+
+	// loop through all object and collect view cell pvs of this node
+	for (oit = objects.begin(); oit != oit_end; ++ oit)
+	{
+		nViewCells += CountViewCells(*oit);
+	}
+
+	return nViewCells;
+}
+
 
 void BvHierarchy::CollectDirtyCandidates(BvhSubdivisionCandidate *sc, 
@@ -2387,5 +2346,5 @@
 	ViewCellContainer viewCells;
 	//ViewCell::NewMail();
-	int numRays = CollectViewCells(node->mObjects, viewCells, false, false);
+	int numRays = CollectViewCells(*tData.mSampledObjects, viewCells, false, false);
 
 	if (0) cout << "collected " << (int)viewCells.size() << " dirty candidates" << endl;
@@ -2435,15 +2394,16 @@
 }
 
-
+#if 0
 BvhLeaf *BvHierarchy::GetLeaf(Intersectable *object, BvhNode *node) const
 {
-	// rather use the simple version
+	// hack: we use the simpler but faster version
 	if (!object) 
 		return NULL;
+
 	return object->mBvhLeaf;
 	
 	///////////////////////////////////////
 	// start from root of tree
-	
+	/*
 	if (node == NULL)
 		node = mRoot;
@@ -2489,6 +2449,7 @@
   
 	return leaf;
-}
-
+	*/
+}
+#endif
 
 bool BvHierarchy::Export(OUT_STREAM &stream)
@@ -2586,17 +2547,18 @@
 
 
-/*
-Mesh *BvHierarchy::MergeLeafToMesh()
-{
-	vector<BvhLeaf *> leaves;
-	CollectLeaves(leaves);
-
-	vector<BvhLeaf *>::const_iterator lit, lit_end = leaves.end();
-
-	for (lit = leaves.begin(); lit != lit_end; ++ lit)
-	{
-		Mesh *mesh = MergeLeafToMesh(*lit);
-	}
-}*/
+void BvHierarchy::StoreSampledObjects(ObjectContainer &sampledObjects, const ObjectContainer &objects)
+{
+	ObjectContainer::const_iterator oit, oit_end = objects.end();
+
+	for (oit = objects.begin(); oit != objects.end(); ++ oit)
+	{
+		Intersectable *obj = *oit;
+
+		if (!obj->GetOrCreateRays()->empty())
+	{
+			sampledObjects.push_back(obj);
+		}
+	}
+	}
 
 
@@ -2624,10 +2586,13 @@
 	//cout << "using " << nRays << " of " << (int)sampleRays.size() << " rays" << endl;
 	
+	ObjectContainer *sampledObjects = new ObjectContainer();
+	StoreSampledObjects(*sampledObjects, objects);
+
 #if STORE_VIEWCELLS_WITH_BVH
-	AssociateViewCellsWithObjects(objects);
+	AssociateViewCellsWithObjects(*sampledObjects);
 #endif
 
 	// probability that volume is "seen" from the view cells
-	const float prop = EvalViewCellsVolume(objects) / GetViewSpaceVolume();
+	const float prop = EvalViewCellsVolume(*sampledObjects) / GetViewSpaceVolume();
 
 	// create bvh traversal data
@@ -2640,9 +2605,11 @@
 	}
 	
+	oData.mSampledObjects = sampledObjects;
+	
 	///////////////////
 	//-- add first candidate for object space partition	
 
 	mTotalCost = EvalRenderCost(objects);
-	mPvsEntries = CountViewCells(objects);
+	mPvsEntries = CountViewCells(*sampledObjects);
 
 	oData.mCorrectedPvs = oData.mPvs = (float)mPvsEntries;
@@ -2655,5 +2622,5 @@
 
 #if STORE_VIEWCELLS_WITH_BVH
-	ReleaseViewCells(objects);
+	ReleaseViewCells(*sampledObjects);
 #endif
 
@@ -2727,5 +2694,5 @@
 	}
 
-	// last sorted list: by size
+	// next sorted list: by size (for initial criteria)
 	tData.mSortedObjects[3] = new ObjectContainer();
 	tData.mSortedObjects[3]->reserve((int)objects.size());
@@ -2734,5 +2701,4 @@
 	
 	stable_sort(tData.mSortedObjects[3]->begin(), tData.mSortedObjects[3]->end(), smallerSize);
-	//sort(tData.mSortedObjects[3]->begin(), tData.mSortedObjects[3]->end(), smallerSize);
 }
 
@@ -2796,6 +2762,9 @@
 	mRoot = bvhleaf;
 	
+	ObjectContainer *sampledObjects = new ObjectContainer();
+	StoreSampledObjects(*sampledObjects, objects);
+
 #if STORE_VIEWCELLS_WITH_BVH
-	AssociateViewCellsWithObjects(objects);
+	AssociateViewCellsWithObjects(*sampledObjects);
 #endif
 
@@ -2803,7 +2772,7 @@
 	// probability that volume is "seen" from the view cells
 	const float viewSpaceVol = mViewCellsManager->GetViewSpaceBox().GetVolume();
-	const float prop = EvalViewCellsVolume(objects);
-
-	const int nRays = CountRays(objects);
+	const float prop = EvalViewCellsVolume(*sampledObjects);
+
+	const int nRays = CountRays(*sampledObjects);
 	BvhLeaf *bvhLeaf = static_cast<BvhLeaf *>(mRoot);
 
@@ -2811,9 +2780,11 @@
 	BvhTraversalData oData(bvhLeaf, 0, prop, nRays);
 
+	oData.mSampledObjects = sampledObjects;
+
 	if (mUseGlobalSorting)
 		AssignInitialSortedObjectList(oData, objects);
 	
 #if STORE_VIEWCELLS_WITH_BVH
-	ReleaseViewCells(objects);
+	ReleaseViewCells(*sampledObjects);
 #endif
 	///////////////////
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 2205)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 2210)
@@ -238,5 +238,5 @@
 { 
 	const bool result = mPvs.AddSample(sample, pdf);
-	// have to recompute pvs size
+	// we have to recompute pvs size
 	mPvsSizeValid = false;
 
@@ -515,4 +515,5 @@
 	/////////////
 	//-- fill merge queue
+
 	vector<MergeCandidate> candidates;
 
@@ -527,5 +528,5 @@
 	}
 
-	Debug << "************************* merge ***********************************" << endl;  
+	Debug << "********************** merge ******************************" << endl;  
 	Debug << "deviation: " << mDeviation << endl;
 	Debug << "avg render cost: " << mAvgRenderCost << endl;
@@ -648,7 +649,8 @@
 			totalRenderCost += renderCostIncr;
 			mDeviation += mc.GetDeviationIncr();
-
-						
+			
+			///////////
 			//-- merge the view cells of leaf1 and leaf2
+
 			float pvsDiff;
 			ViewCellInterior *mergedVc = 
@@ -834,5 +836,5 @@
 		if (!obj->Mailed())
 		{
-			renderCost += mViewCellsManager->EvalRenderCost(obj);
+			renderCost += ViewCellsManager::EvalRenderCost(obj);
 		}
 	}
@@ -1028,6 +1030,6 @@
 		// set scalars
 		mViewCellsManager->UpdateScalarPvsSize(right, 
-			right->GetPvs().EvalPvsCost(), 
-			right->GetPvs().GetSize());
+											   right->GetPvs().EvalPvsCost(), 
+											   right->GetPvs().GetSize());
 
 		right->mPvsSizeValid = true;
@@ -1804,6 +1806,4 @@
 		return vc->GetPvs().GetSize();
 	}
-	
-	// interior node
 
 	// interior nodes: pvs is either stored as a scalar or
@@ -1987,6 +1987,6 @@
 	Intersectable::NewMail();
 
-	////////////////////////////////////////////////
-	// for interiors, pvs can be stored using different methods
+	/////////////////////////
+	//-- different storage methods for interiors
 	
 	switch (mViewCellsStorage)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 2206)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 2210)
@@ -407,5 +407,6 @@
 		mPvs(0),
 		mCorrectedVolume(0),
-		mVolume(v)
+		mVolume(v),
+		mSampledObjects(NULL)
 		{
 			for (int i = 0; i < 4; ++ i)
@@ -420,4 +421,6 @@
 			for (int i = 0; i < 4; ++ i)
 				DEL_PTR(mSortedObjects[i]);
+
+			DEL_PTR(mSampledObjects);
 		}
 
@@ -441,6 +444,9 @@
 		float mCorrectedPvs;
 
-		/// the sorted objects for the three dimensions
+		/** the sorted objects for the three dimensions + one for the original
+			order + one for the objects which have been sampled at least once
+		*/
 		ObjectContainer *mSortedObjects[4];		
+		ObjectContainer *mSampledObjects;	
     };
 
@@ -511,4 +517,9 @@
 		ObjectContainer mBackObjects;
 			
+		/// the sampled objects on the front of the potential split
+		ObjectContainer mSampledFrontObjects;
+		/// the sampled objects on the back of the potential split
+		ObjectContainer mSampledBackObjects;
+
 		float mCorrectedFrontPvs;
 		float mCorrectedBackPvs;
@@ -516,4 +527,13 @@
 		float mCorrectedFrontVolume;
 		float mCorrectedBackVolume;
+
+		//int mNumFrontRays;
+		//int mNumBackRays;
+		
+		int mNumFrontViewCells;
+		int mNumBackViewCells;
+
+		float mVolumeFrontViewCells;
+		float mVolumeBackViewCells;
 	};
 
@@ -620,5 +640,12 @@
 	/** Returns leaf the point pt lies in, starting from root.
 	*/
-	BvhLeaf *GetLeaf(Intersectable *obj, BvhNode *root = NULL) const;
+	inline BvhLeaf *GetLeaf(Intersectable *object, BvhNode *root = NULL) const
+	{
+		// hack: we use the simpler but faster version
+		if (!object) 
+			return NULL;
+
+		return object->mBvhLeaf;
+	}
 
 	/** Sets a pointer to the view cells tree.
@@ -638,4 +665,6 @@
 	void SetActive(BvhNode *node) const;
 
+
+	void StoreSampledObjects(ObjectContainer &sampledObjects, const ObjectContainer &objects);
 
 	///////////////////////////
@@ -711,4 +740,6 @@
 	float EvalRenderCost(const ObjectContainer &objects);// const;
 
+	float EvalProbability(const ObjectContainer &objects);
+
 	/** Evaluates tree stats in the BSP tree leafs.
 	*/
@@ -860,5 +891,5 @@
 	int AssociateViewCellsWithObject(Intersectable *obj, const bool useMailBoxing) const;
 
-	void AssociateViewCellsWithObjects(const ObjectContainer &objects);// const;
+	void AssociateViewCellsWithObjects(const ObjectContainer &objects) const;
 
 	void ReleaseViewCells(const ObjectContainer &objects);
@@ -876,5 +907,8 @@
 	*/
 	int EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate, 
-						   const float avgRayContri);// const;
+						   const float avgRayContri,
+						   const int numParentViewCells,
+						   const int numFrontViewCells,
+						   const int numBackViewCells);// const;
 
 	/** Rays will be clipped to the bounding box.
@@ -975,6 +1009,4 @@
 	HierarchyManager *mHierarchyManager;
 
-
-	ObjectContainer *mCachedObjects;
 
 	////////////////////
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2206)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2210)
@@ -881,4 +881,7 @@
 											splitCandidate.GetAvgRayContribution());
 	
+	splitCandidate.mFrontPvs = fPvsSize;
+	splitCandidate.mBackPvs = bPvsSize;
+
 	if (0)
 	cout << "vsp pvs"
@@ -902,5 +905,5 @@
 
 	const VspTraversalData &tData = sc.mParentData;
-	const AxisAlignedPlane splitPlane = sc.mSplitPlane;
+	const AxisAlignedPlane &splitPlane = sc.mSplitPlane;
 
 	///////////////
@@ -917,6 +920,6 @@
 
 	//-- compute pvs
-	frontData.mPvs = (float)EvalPvsEntriesSize(*frontData.mRays);
-	backData.mPvs = (float)EvalPvsEntriesSize(*backData.mRays);
+	frontData.mPvs = sc.mFrontPvs;//(float)EvalPvsEntriesSize(*frontData.mRays);
+	backData.mPvs = sc.mBackPvs;//(float)EvalPvsEntriesSize(*backData.mRays);
 	
 	//-- compute pvs correction for coping with undersampling
@@ -934,6 +937,6 @@
 
 	//-- compute render cost
-	frontData.mRenderCost = (float)EvalPvsCost(*frontData.mRays);
-	backData.mRenderCost = (float)EvalPvsCost(*backData.mRays);
+	frontData.mRenderCost = sc.mFrontRenderCost;//(float)EvalPvsCost(*frontData.mRays);
+	backData.mRenderCost = sc.mBackRenderCost;//(float)EvalPvsCost(*backData.mRays);
 	
 	frontData.mCorrectedRenderCost = sc.mCorrectedFrontRenderCost;
@@ -1275,4 +1278,5 @@
 	const float maxBand = minBox + mMaxBand * sizeBox;
 
+	// sort by the current dimension
 	SortSubdivisionCandidates(usedRays, axis, minBand, maxBand);
 
@@ -1589,4 +1593,7 @@
 	sc.mCorrectedBackRenderCost = mHierarchyManager->EvalCorrectedPvs(pvsBack, penaltyOld, avgRayContri);
 
+	sc.mFrontRenderCost = pvsFront;
+	sc.mBackRenderCost = pvsBack;
+
 	const float oldRenderCost = pOverall * penaltyOld;
 	const float newRenderCost = sc.mCorrectedFrontRenderCost * pFront + 
@@ -1727,5 +1734,5 @@
 
 	const float renderCost = countEntries ? 1 : 
-		mHierarchyManager->mBvHierarchy->EvalAbsCost(leaf->mObjects);
+		mBvHierarchy->EvalAbsCost(leaf->mObjects);
 	
 	// leaf in no pvs => new
@@ -2286,5 +2293,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(obj);
 
 			if (!bvhleaf->Mailed())
@@ -2901,4 +2908,6 @@
 	VspSubdivisionCandidate::sVspTree = this;
 	
+	mBvHierarchy = mHierarchyManager->mBvHierarchy;
+
 	// initialise termination criteria
 	mTermMinProbability *= mBoundingBox.GetVolume();
@@ -2969,5 +2978,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 
 			if (!leaf->Mailed())
@@ -3049,5 +3058,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 
 			if (-- leaf->mCounter == 0)
@@ -3098,5 +3107,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 
 			if (!leaf->Mailed())
@@ -3151,5 +3160,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 			if (!leaf->Mailed())
 			{
@@ -3198,5 +3207,5 @@
 		case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 			UpdateContributionsToPvs(leaf, cf, frontPvs, backPvs, totalPvs, false);
 			break;
@@ -3227,5 +3236,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 			UpdateContributionsToPvs(leaf, cf, pvsFront, pvsBack, totalPvs, true);
 			break;
@@ -3269,5 +3278,5 @@
 	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
 		{
-			BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+			BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(obj);
 
 			if (!bvhleaf->Mailed())
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 2206)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 2210)
@@ -2524,4 +2524,5 @@
 	// delete old "base" view cells: only pvss in the leaves are allowed
 	ViewCellContainer::const_iterator oit, oit_end = mOldViewCells.end();
+
 	for (oit = mOldViewCells.begin(); oit != oit_end; ++ oit)
 	{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 2205)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 2210)
@@ -438,5 +438,10 @@
 
 
-  // has to called before first usage
+/******************************************************************/
+/*           class MixtureDistribution implementation             */
+/******************************************************************/
+
+
+// has to be called before first usage
 void
 MixtureDistribution::Init()
@@ -683,4 +688,5 @@
 }
 
+
 bool HwGlobalLinesDistribution::GenerateSample(SimpleRay &ray) 
 {
