Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1184)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1186)
@@ -2737,5 +2737,5 @@
 
 		// get classification and receive new t
-		//-- test if start point behind or in front of plane
+		// test if start point behind or in front of plane
 		const int side = bRay.ComputeRayIntersection(plane.mAxis, plane.mPosition, t);
 			
@@ -2911,6 +2911,10 @@
 
 
-void VspTree::GetViewCells(const VssRay &ray, ViewCellContainer &viewCells)
-{
+void VspTree::GetViewCells(VssRay &ray, ViewCellContainer &viewCells)
+{
+	mViewCellsManager->ComputeSampleContribution(ray, false, true);
+	viewCells = ray.mViewCells;
+	ray.mViewCells.clear();
+	/*
 	static Ray hray;
 	hray.Init(ray);
@@ -2927,6 +2931,7 @@
 
 	// if no precomputation of view cells
-	CastLineSegment(origin, termination, viewCells);
-}
+	CastLineSegment(origin, termination, viewCells);*/
+}
+
 
 
@@ -3123,9 +3128,9 @@
 	backData.mRays = new RayInfoContainer();
 
-	SplitRays(splitPlane,
+/*	SplitRays(splitPlane,
 			  *tData.mRays,
 			  *frontData.mRays,
 			  *backData.mRays);
-
+*/
 
 	//-- classify objects
@@ -3150,6 +3155,6 @@
 
 	// TODO matt: compute pvs
-	frontData.mPvs = objectsFront;
-	backData.mPvs = objectsBack;
+	//frontData.mPvs = objectsFront;
+	//backData.mPvs = objectsBack;
 
 	//CheckViewCellsPvs(leaf, *tData.mRays);
@@ -3181,4 +3186,7 @@
 
 	SplitObjects(leaf, splitPlane, leaf->mObjects, front->mObjects, back->mObjects);
+	
+	FilterRays(front, *tData.mRays, *frontData.mRays);
+	FilterRays(back, *tData.mRays, *backData.mRays);
 
 
@@ -3273,6 +3281,8 @@
 	if (newNode->IsLeaf())
 	{
-		EvaluateLeafStats(tData);		
-const bool mStoreRays= true;
+		EvaluateLeafStats(tData);
+        
+		const bool mStoreRays= true;
+
 		//-- store additional info
 		if (mStoreRays)
@@ -3366,5 +3376,5 @@
 	++ mCreatedLeaves;
 
-	if (data.mPvs > mOspStats.maxPvs)
+	/*if (data.mPvs > mOspStats.maxPvs)
 	{
 		mOspStats.maxPvs = data.mPvs;
@@ -3376,5 +3386,5 @@
 	{
 		mOspStats.minDepth = data.mDepth;
-	}
+	}*/
 	
 	if (data.mDepth >= mTermMaxDepth)
@@ -3686,5 +3696,5 @@
 	ViewCellContainer viewCells;
 
-	mVspTree->GetViewCells(ray, viewCells);
+	mVspTree->GetViewCells(VssRay(ray), viewCells);
     	
 	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
@@ -3798,5 +3808,5 @@
 	ViewCellContainer viewCells;
 
-	mVspTree->GetViewCells(ray, viewCells);
+	mVspTree->GetViewCells(VssRay(ray), viewCells);
 
 	/// classify view cells and compute volume contri accordingly
@@ -4028,4 +4038,52 @@
 
 
+int OspTree::ClassifyRays(const RayInfoContainer &rays, 
+						  KdLeaf *leaf, 
+						  const AxisAlignedPlane &plane,
+						  RayInfoContainer &frontRays,
+						  RayInfoContainer &backRays) const
+{
+	RayInfoContainer::const_iterator rit, rit_end = rays.end();
+
+	for (rit = rays.begin(); rit < rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+
+		bool originGt = false;
+		bool terminationGt = false;
+		
+		Intersectable *obj = ray->mOriginObject;
+
+		if (obj)
+		{
+			originGt = ray->mOrigin[plane.mAxis] > plane.mPosition;
+		}
+
+		obj = ray->mTerminationObject;
+		
+		if (obj)
+		{
+			terminationGt = ray->mTermination[plane.mAxis] > plane.mPosition;
+		}
+
+		// either begin or end point on front side
+		const bool addToFront = originGt || terminationGt;
+
+		// add view cell volume to back volume
+		const bool addToBack = !originGt || !terminationGt;
+	
+		// classify ray with respect to the child nodes the view cells contribute
+		if (addToFront)
+			frontRays.push_back(*rit);
+		if (addToBack)
+			backRays.push_back(*rit);
+	}
+
+	return 0;
+}
+
+
+#if 1
+
 float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
 									  const OspTraversalData &tData,
@@ -4048,39 +4106,9 @@
 	const int totalPvs = (int)leaf->mObjects.size();
 	
-	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
-
-	// evaluate reverse pvs and view cell volume on left and right cell
-	// note: should I take all leaf objects or rather the objects hit by rays?
-	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
-	{
-		int pvsContri = 0;
-
-		Intersectable *obj = *oit;
-		const AxisAlignedBox3 box = obj->GetBox();
-
-		// test if box falls in left / right child node
-		if (box.Max(candidatePlane.mAxis) >= candidatePlane.mPosition)
-		{
-			++ pvsFront;
-			obj->Mail();		
-		}
-
-		if (box.Min(candidatePlane.mAxis) < candidatePlane.mPosition)
-		{
-			++ pvsBack;
-
-			if (obj->Mailed())
-				obj->Mail(2);
-			else 
-				obj->Mail(1);
-		}
-
-		//Debug << "here3 pt: " << obj << " mail: " << obj->mMailbox - Intersectable::sMailId << endl;
-	}
-
-	
+	RayInfoContainer frontRays, backRays;
+	ClassifyRays(*tData.mRays, leaf, candidatePlane, frontRays, backRays);
+
 	ViewCellContainer touchedViewCells;
-	RayInfoContainer touchedRays;
-
+	
 	// sum up volume seen from the objects of left and right children
 	// => the volume is the weight for the render cost equation
@@ -4088,5 +4116,4 @@
 
 	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
-	//map<Intersectable *, ViewCellContainer> objectsMap;
 
 	for (rit = tData.mRays->begin(); rit < rit_end; ++ rit)
@@ -4100,5 +4127,4 @@
 		if (originInside || terminationInside)
 		{
-			touchedRays.push_back(*rit);
 			// add volume to volumes of left and / or right children
 			// if one of the ray end points is inside
@@ -4124,9 +4150,4 @@
                 // classify / mail the view cell
 				MailViewCell(vc, classification);	
-
-				/*if (terminationInside)
-					objectsMap[ray->mTerminationObject].push_back(vc);
-				if (originInside)
-					objectsMap[ray->mOriginObject].push_back(vc);*/
 			}
 		}
@@ -4154,5 +4175,5 @@
 	ViewCellPvsData::NewMail();
 
-	for (rit = touchedRays.begin(); rit != touchedRays.end(); ++ rit)
+	for (rit = tData.mRays->begin(); rit != tData.mRays->end(); ++ rit)
 	{
 		VssRay *ray = (*rit).mRay;
@@ -4173,5 +4194,5 @@
 			// => the render cost was falsly reduced, add them again
 
-			if (EndPointInsideNode(leaf, *ray, true))
+			if (ray->mTerminationObject)
 			{	
 				Intersectable *obj = ray->mTerminationObject;
@@ -4179,9 +4200,5 @@
 				const bool renderCostWrong = 
 					ViewCellHasMultipleReferences(obj, viewCell, true);
-			//	if(!obj->Mailed()){
-			//	Debug << "pt: " << obj << endl;
-			//	Debug << "vc mail: " << viewCell->mMailbox - ViewCell::sMailId << " obj mail: " << obj->mMailbox << " "<< Intersectable::sMailId << " " <<obj->mMailbox - Intersectable::sMailId << endl;
-			//	obj->Mail();
-			//	}
+			
 				// if there is already an entry of this object in the view cell pvs 
 				if (renderCostWrong)
@@ -4189,11 +4206,15 @@
 					// view cell was counted only for front or back => correct tjos
 					if (viewCell->Mailed(1) && obj->Mailed())
+					{
 						additionalFrontRenderCost += viewCell->GetVolume();
+					}
 					else if (viewCell->Mailed() && obj->Mailed(1))
+					{
 						additionalBackRenderCost += viewCell->GetVolume();
+					}
 				}
 			}
 	
-			if (EndPointInsideNode(leaf, *ray, false))
+			if (ray->mOriginObject)
 			{
 				Intersectable *obj = ray->mOriginObject;
@@ -4205,7 +4226,11 @@
 				{
 					if (viewCell->Mailed(1) && obj->Mailed())
+					{
 						additionalFrontRenderCost += viewCell->GetVolume();
+					}
 					else if (viewCell->Mailed() && obj->Mailed(1))
+					{
 						additionalBackRenderCost += viewCell->GetVolume();
+					}
 				}
 			}
@@ -4256,4 +4281,200 @@
 }
 
+#else
+
+float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
+									  const OspTraversalData &tData,
+									  float &normalizedOldRenderCost) const
+{
+	float pvsFront = 0;
+	float pvsBack = 0;
+
+	// probability that view point lies in back / front node
+	float pOverall = 0;//data.mProbability; // todo matt§: value ok?
+	float pFront = 0;
+	float pBack = 0;
+	float pFrontAndBack = 0;
+
+	const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume();
+
+	Intersectable::NewMail(3);
+	
+	KdLeaf *leaf = tData.mNode;
+	const int totalPvs = (int)leaf->mObjects.size();
+	
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	// evaluate reverse pvs and view cell volume on left and right cell
+	// note: should I take all leaf objects or rather the objects hit by rays?
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		int pvsContri = 0;
+
+		Intersectable *obj = *oit;
+		const AxisAlignedBox3 box = obj->GetBox();
+
+		// test if box falls in left / right child node
+		if (box.Max(candidatePlane.mAxis) >= candidatePlane.mPosition)
+		{
+			++ pvsFront;
+			obj->Mail();		
+		}
+
+		if (box.Min(candidatePlane.mAxis) < candidatePlane.mPosition)
+		{
+			++ pvsBack;
+
+			if (obj->Mailed())
+				obj->Mail(2);
+			else 
+				obj->Mail(1);
+		}
+		//Debug << "here3 pt: " << obj << " mail: " << obj->mMailbox - Intersectable::sMailId << endl;
+	}
+
+	
+	ViewCellContainer touchedViewCells;
+
+	// sum up volume seen from the objects of left and right children
+	// => the volume is the weight for the render cost equation
+	ViewCell::NewMail(3);
+
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+	//map<Intersectable *, ViewCellContainer> objectsMap;
+
+	for (rit = tData.mRays->begin(); rit < rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+
+		// add volume to volumes of left and / or right children
+		// if one of the ray end points is inside
+		const int classification = ClassifyRay(ray, leaf, candidatePlane);
+
+		ViewCellContainer viewCells;
+		mVspTree->GetViewCells(*ray, viewCells);
+			
+		ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+
+		// traverse through view cells and classify them according
+		// to them being seen from to back / front / front and back node
+		for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+
+			// if not previously mailed
+			if (!vc->Mailed() && !vc->Mailed(1) && !vc->Mailed(2))
+			{
+				touchedViewCells.push_back(vc);
+			}
+
+			// classify / mail the view cell
+			MailViewCell(vc, classification);	
+
+			/*if (terminationInside)
+				objectsMap[ray->mTerminationObject].push_back(vc);
+			if (originInside)
+				objectsMap[ray->mOriginObject].push_back(vc);*/
+		}
+	}
+
+	// evaluate view cells volume contribution 
+	// with respect to the mail box classification
+	ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+
+	for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		AddViewCellVolumeContri(*vit, pFront, pBack, pFrontAndBack);
+	}
+
+	//////////////////////////////////////////////
+	//
+	// evaluate contribution of objects which are part of other kd nodes
+	// which are seen by the same view cell
+	// These contributions cannot be reduced by splitting, because
+	// the object would still be part of the pvs
+
+	float frontRc = 0;
+	float backRc = 0;
+	float rc = 0;
+
+	ViewCellPvsData::NewMail();
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	//Debug << "here53 " << touchedViewCells.size() << endl;
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = *oit;
+		ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+
+		for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+			/*ObjectPvsData *vdata = vc->GetPvs().Find(obj);
+
+			if (!vdata)
+			{
+				vc->GetPvs().AddSample(obj, 1);
+				newCost += vc->GetVolume();
+				//prop += vc->GetVolume();
+			}*/
+
+			ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+			if (!vdata || !vdata->Mailed())
+			{
+				newCost += vc->GetVolume();
+				if (!vdata)
+					vdata = obj->mViewCellPvs.AddSample2(vc, 1);
+				vdata->Mail();
+			}
+		}
+	}
+
+
+	}
+
+	/////////////////////////////
+
+
+	// these are non-overlapping sets
+	pOverall = pFront + pBack + pFrontAndBack;
+
+
+	//-- pvs rendering heuristics
+
+	const float oldRenderCost = pOverall * totalPvs;
+	
+	// sum up the terms: 
+	// the view cells seeing
+	// a) the left node are weighted by the #left node objects
+	// b) the right node are weighted by the #right node objects
+	// c) both nodes are weighted by the #parent node objects
+	const float newRenderCost = pvsFront * pFront + pvsBack * pBack + totalPvs * pFrontAndBack
+		+ additionalFrontRenderCost + additionalBackRenderCost;
+
+	// normalize volume with view space volume
+	const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol;
+
+	Debug << "\n(((( eval render cost decrease ))))" << endl
+		  << "back pvs: " << pvsBack << " front pvs " << pvsFront << " total pvs: " << totalPvs << endl 
+		  << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol 
+		  << " front and back p " << pFrontAndBack / viewSpaceVol << " p: " << tData.mProbability / viewSpaceVol << endl
+		  << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl
+		  << "render cost decrease: " << renderCostDecrease << endl
+		  << "additional front " << additionalFrontRenderCost / viewSpaceVol 
+		  << " additional back " << additionalBackRenderCost  / viewSpaceVol << endl;
+
+	if (oldRenderCost < newRenderCost * 0.99)
+		Debug <<"error!!"<<endl;
+
+	//if ((((pOverall - tData.mProbability) / viewSpaceVol) > 0.00001))
+	//	Debug << "ERROR!!"<<endl;
+
+	normalizedOldRenderCost = oldRenderCost / viewSpaceVol;
+
+		
+	return renderCostDecrease;
+}
+#endif
 
 void OspTree::ComputeBoundingBox(const ObjectContainer &objects,
@@ -4469,8 +4690,10 @@
 
 
-void OspTree::PreprocessRays(const VssRayContainer &sampleRays,
+void OspTree::PreprocessRays(KdLeaf *root,
+							 const VssRayContainer &sampleRays,
 							 RayInfoContainer &rays)
 {
 	VssRayContainer::const_iterator rit, rit_end = sampleRays.end();
+	RayInfoContainer clippedRays;
 
 	long startTime = GetTime();
@@ -4494,9 +4717,8 @@
 		{
 			float len = ray->Length();
-
-			if (!len)
+			if (!len) 
 				len = Limits::Small;
 
-			rays.push_back(RayInfo(ray, minT / len, maxT / len));
+			clippedRays.push_back(RayInfo(ray, minT / len, maxT / len));
 
 			// HACK: reset nodes for the case we have used object kd tree for
@@ -4506,4 +4728,6 @@
 		}
 	}
+
+	FilterRays(root, clippedRays, rays);
 
 	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
@@ -4560,4 +4784,28 @@
 }
 
+
+int OspTree::FilterRays(KdLeaf *leaf, 
+						const RayInfoContainer &rays,
+						RayInfoContainer &filteredRays)
+{
+	RayInfoContainer::const_iterator rit, rit_end = rays.end();
+
+	for (rit = rays.begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+
+		// test if intersection point with one of the objects is inside this node
+		const bool originInside = EndPointInsideNode(leaf, *ray, false);
+        const bool terminationInside = EndPointInsideNode(leaf, *ray, true);
+
+		if (originInside || terminationInside)
+		{
+			filteredRays.push_back(ray);
+		}
+	}
+
+	return 0;
+}
+					 
 
 int OspTree::SplitViewCells(const AxisAlignedPlane &candidatePlane,
@@ -4990,12 +5238,28 @@
 
 
-float OspTree::EvalRenderCost()
+float OspTree::EvalRenderCost(const VssRayContainer &myrays)
 {
 	float rc = 0;
-float prop = mVspTree->GetBoundingBox().GetVolume();	
+	float prop = mVspTree->GetBoundingBox().GetVolume();	
+
 	KdLeafContainer leaves;
 	CollectLeaves(leaves);
 
+	ViewCellContainer vcleaves;
+	mVspTree->CollectViewCells(vcleaves, false);
+	
+
+	ViewCellContainer::const_iterator vit, vit_end = vcleaves.end();
+
+	for (vit = vcleaves.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = *vit;
+		vc->GetPvs().Clear();
+	}
+
 	KdLeafContainer::const_iterator kit, kit_end = leaves.end();
+
+	ViewCellPvsData::NewMail();
+
 	for (kit = leaves.begin(); kit != kit_end; ++ kit)
 	{
@@ -5013,4 +5277,5 @@
 			
 			// test if intersection point with one of the objects is inside this node
+
 			const bool originInside = EndPointInsideNode(leaf, *ray, false);
 			const bool terminationInside = EndPointInsideNode(leaf, *ray, true);
@@ -5031,5 +5296,4 @@
 					{
 						vc->Mail();
-						vc->GetPvs().Clear();
 						touchedViewCells.push_back(vc);
 					}
@@ -5039,7 +5303,7 @@
 		}
 		
-		//ViewCellPvsData::NewMail();
 		ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
 
+		//Debug << "here53 " << touchedViewCells.size() << endl;
 		for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
 		{
@@ -5050,5 +5314,5 @@
 			{
 				ViewCell *vc = *vit;
-				ObjectPvsData *vdata = vc->GetPvs().Find(obj);
+				/*ObjectPvsData *vdata = vc->GetPvs().Find(obj);
 
 				if (!vdata)
@@ -5057,4 +5321,14 @@
 					newCost += vc->GetVolume();
 					//prop += vc->GetVolume();
+				}*/
+
+				ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+				if (!vdata || !vdata->Mailed())
+				{
+					newCost += vc->GetVolume();
+					if (!vdata)
+						vdata = obj->mViewCellPvs.AddSample2(vc, 1);
+					vdata->Mail();
 				}
 			}
@@ -5068,7 +5342,78 @@
 
 
-/********************************************************************/
-/*               class HierarchyManager implementation              */
-/********************************************************************/
+float OspTree::EvalLeafCost(const OspTraversalData &tData)
+{
+	KdLeaf *leaf = tData.mNode;
+
+	float rc = 0;
+	//float prop = mVspTree->GetBoundingBox().GetVolume();	
+	//float vol = 0;
+	//ViewCell::NewMail();
+	
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+	ViewCellContainer touchedViewCells;
+
+	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+			
+		// test if intersection point with one of the objects is inside this node
+
+		ViewCellContainer viewCells;
+		mVspTree->GetViewCells(*ray, viewCells);
+			
+		ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+
+		for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+
+			// if not previously mailed
+			if (!vc->Mailed())
+			{
+				vc->Mail();
+				touchedViewCells.push_back(vc);
+			}
+		}
+	}
+
+	// clear pvs of involved view cells
+	ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+
+	for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = *vit;
+		vc->GetPvs().Clear();
+	}
+	
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	//Debug << "here53 " << touchedViewCells.size() << endl;
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = *oit;
+
+		for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+			ObjectPvsData *vdata = vc->GetPvs().Find(obj);
+
+			if (!vdata)
+			{
+				vc->GetPvs().AddSample(obj, 1);
+				rc += vc->GetVolume();
+				//prop += vc->GetVolume();
+			}
+		}
+	}
+	
+	return rc;
+}
+
+
+
+/*******************************************************************/
+/*              class HierarchyManager implementation              */
+/*******************************************************************/
 
 
@@ -5178,7 +5523,4 @@
 	mGlobalCostMisses = 0;
 
-	// get clipped rays
-	mOspTree.PreprocessRays(sampleRays, rays);
-
 	// create new root
 	KdLeaf *kdleaf = new KdLeaf(NULL, 0);
@@ -5186,6 +5528,10 @@
 	mOspTree.mRoot = kdleaf;
 	
+	// get clipped rays
+	mOspTree.PreprocessRays(kdleaf, sampleRays, rays);
+
+
 	// probabilty is voume of all "seen" view cells
-#if 1
+#if 0
 	const float prop = mOspTree.EvalViewCellsVolume(kdleaf, rays);
 #else
@@ -5436,27 +5782,8 @@
 	mOspTree.mOspStats.Stop();
 
-	float rc = mOspTree.EvalRenderCost();
+	float rc = mOspTree.EvalRenderCost(sampleRays);
 
 	Debug << "My render cost evalulation: " << rc << endl;
 
-	
-
-
-ViewCellContainer leaves;
-
-mVspTree.CollectViewCells(leaves, false);
-float rc2 = 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();
-		rc2 += (float)pvs * vol;
-
-	}
-	
-	Debug << "here225 " << rc2 / mVspTree.GetBoundingBox().GetVolume()<<endl;
 #if 0
 	// reset parameters
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1184)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1186)
@@ -778,5 +778,5 @@
 		or by recomputation.
 	*/
-	void GetViewCells(const VssRay &ray, ViewCellContainer &viewCells);
+	void GetViewCells(VssRay &ray, ViewCellContainer &viewCells);
 
 
@@ -1124,5 +1124,4 @@
 
 
-
 	//-- split heuristics based parameters
 	
@@ -1192,5 +1191,5 @@
 		AxisAlignedBox3 mBoundingBox;
 		/// pvs size
-		int mPvs;
+		float mRenderCost;
 		/// how often this branch has missed the max-cost ratio
 		int mMaxCostMisses;
@@ -1205,5 +1204,5 @@
 		mRays(NULL),
 		mDepth(0),
-		mPvs(0),
+		mRenderCost(0),
 		mProbability(0.0),
 		mMaxCostMisses(0), 
@@ -1215,5 +1214,5 @@
 						 const int depth,
                          RayInfoContainer *rays,
-						 const int pvs,
+						 const float rc,
 						 const float p,
 						 const AxisAlignedBox3 &box):
@@ -1221,5 +1220,5 @@
 		mDepth(depth),
 		mRays(rays),
-		mPvs(pvs),
+		mRenderCost(rc),
 		mProbability(p),
 		mBoundingBox(box),
@@ -1235,5 +1234,5 @@
 		mDepth(depth),
 		mRays(rays),
-		mPvs(0),
+		mRenderCost(0),
 		mProbability(0),
 		mMaxCostMisses(0),
@@ -1422,5 +1421,6 @@
 	void SetViewCellsTree(ViewCellsTree *vt) { mViewCellsTree = vt; }
 
-	float EvalRenderCost();
+	float EvalRenderCost(const VssRayContainer &myrays);
+	float EvalLeafCost(const OspTraversalData &tData);
 
 protected:
@@ -1585,4 +1585,6 @@
 		RayInfoContainer &backRays) const;
 
+	int FilterRays(KdLeaf *leaf, const RayInfoContainer &rays, RayInfoContainer &filteredRays);
+
 	int SplitViewCells(
 		const AxisAlignedPlane &candidatePlane,
@@ -1679,5 +1681,7 @@
 	/** Rays will be clipped to the bounding box.
 	*/
-	void PreprocessRays(const VssRayContainer &sampleRays,
+	void PreprocessRays(
+		KdLeaf *root, 
+		const VssRayContainer &sampleRays,
 		RayInfoContainer &rays);
 
@@ -1729,4 +1733,11 @@
 		float &contribution,
 		bool onlyMailed) const;
+
+	int ClassifyRays(
+		const RayInfoContainer &rays, 
+		KdLeaf *leaf, 
+		const AxisAlignedPlane &plane,
+		RayInfoContainer &frontRays,
+		RayInfoContainer &backRays) const;
 
 protected:
