Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1168)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1189)
@@ -499,5 +499,5 @@
 		  mBspStats.Leaves() * sizeof(BspLeaf) + 
 		  mCreatedViewCells * sizeof(BspViewCell) +
-		  mBspStats.pvs * sizeof(ObjectPvsData) +
+		  mBspStats.pvs * sizeof(PvsData) +
 		  mBspStats.Interior() * sizeof(BspInterior) +
 		  mBspStats.accumRays * sizeof(RayInfo)) / (1024.0f * 1024.0f);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1186)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1189)
@@ -22,4 +22,5 @@
 namespace GtpVisibilityPreprocessor {
 
+
 #define USE_FIXEDPOINT_T 0
 
@@ -32,4 +33,6 @@
 // variable for debugging volume contribution for heuristics
 static float debugVol;
+
+int VspNode::sMailId = 1;
 
 // pvs penalty can be different from pvs size
@@ -40,7 +43,11 @@
 	// clamp to minmax values
 	if (pvs < lower)
+	{
 		return (float)lower;
+	}
 	else if (pvs > upper)
+	{
 		return (float)upper;
+	}
 
 	return (float)pvs;
@@ -48,5 +55,26 @@
 
 
-int VspNode::sMailId = 1;
+static bool ViewCellHasMultipleReferences(Intersectable *obj, 
+										  ViewCell *vc, 
+										  bool checkOnlyMailed)
+{
+	MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+	if (vdata)
+	{
+		//Debug << "sumpdf: " << vdata->mSumPdf << endl;
+		// more than one view cell sees this object inside different kd cells
+		if (!checkOnlyMailed || !vdata->Mailed())
+		{
+			if (checkOnlyMailed)
+				vdata->Mail();
+
+			if (vdata->mSumPdf > 1.5f) 
+				return true;
+		}
+	}
+
+	return false;
+}
 
 
@@ -548,5 +576,5 @@
 		  mVspStats.Leaves() * sizeof(VspLeaf) + 
 		  mCreatedViewCells * sizeof(VspViewCell) +
-		  mVspStats.pvs * sizeof(ObjectPvsData) +
+		  mVspStats.pvs * sizeof(PvsData) +
 		  mVspStats.Interior() * sizeof(VspInterior) +
 		  mVspStats.accumRays * sizeof(RayInfo)) / (1024.0f * 1024.0f);
@@ -3203,5 +3231,5 @@
 	// This is important during the subdivision
 
-//ViewCellPvsData::NewMail();
+//MailablePvsData::NewMail();
 	UpdateViewCellsPvs(front, *frontData.mRays);
 	UpdateViewCellsPvs(back, *backData.mRays);
@@ -3409,7 +3437,5 @@
 	Debug << "BSP stats: "
 		  << "Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), "
-		 // << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), "
-	  	  << "Prob: " << data.mProbability << " (min: " << mTermMinProbability << "), "
-		  << "#pvs: " << data.mPvs << ")\n";
+	  	  << "Prob: " << data.mProbability << " (min: " << mTermMinProbability << ")\n";
 #endif
 }
@@ -3450,13 +3476,12 @@
 	SortSplitCandidates(tData, axis, minBand, maxBand);
 
-	int numViewCells;
-
-	float totalVol = PrepareHeuristics(tData, numViewCells);
+	float totalVol = 0;//PrepareHeuristics(tData);
 	float voll = 0;
 	float volr = totalVol;
 
-	int vcl = 0;
-	int vcr = numViewCells;
-  
+	ViewCellContainer touchedViewCells;
+	const float totalRenderCost = PrepareHeuristics(tData, touchedViewCells);
+	float renderCost = totalRenderCost;
+
 	/// this is kind of a reverse pvs
 	const int totalPvs = (int)tData.mNode->mObjects.size();
@@ -3483,17 +3508,16 @@
 	int pvsFront = pvsr;
 	
-	float minSum = 1e20f;
+	float minRenderCost = 1e20f;
 
 	debugVol = 0;
 	const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume();
 
+
 	/////////////////////////////
 	// the sweep heuristics
 
-
 	Intersectable::NewMail();
 	ViewCell::NewMail();
-	
-	
+		
 	//-- traverse through events and find best split plane
 	
@@ -3506,6 +3530,6 @@
 		EvalHeuristicsContribution(tData.mNode, 
 								   *ci, 
-								   voll, volr, 
-								   pvsl, pvsr
+								   renderCost,
+								   touchedViewCells
 								  );
 
@@ -3514,9 +3538,4 @@
 		if (((*ci).mPos >= minBand) && ((*ci).mPos <= maxBand))
 		{
-			// voll = view cells that see only left node (i.e., left pvs)
-			// volr = view cells that see only right node (i.e., right pvs)
-			// rest = view cells that see both nodes (i.e., total pvs)
-            sum = voll * pvsl + volr * pvsr + (totalVol - voll - volr) * totalPvs;
-
 			float currentPos;
 			
@@ -3527,25 +3546,9 @@
 				currentPos = (*ci).mPos;			
 
-			/*if ((totalVol - voll - volr - debugVol) / viewSpaceVol > 0.0001)
-				Debug << "front and back volume: " << (totalVol - voll - volr) / viewSpaceVol << " error: " << (totalVol - voll - volr - debugVol) / viewSpaceVol << endl;
-				Debug << "pos: " << currentPos 
-				 << "\t (pvsl: " << pvsl << ", pvsr: " << pvsr << ")"
-				 << "\t (voll: " << voll << ", volr: " << volr << ")"
-				 << "\t (vcl: " << vcl << ", vcr: " << vcr << ", nvc: " << numViewCells << ")"
-				 << "\t sum: " << sum << endl;
-				 */
-
-			if (sum < minSum)
+			if (renderCost < minRenderCost)
 			{
 				splitPlaneFound = true;
-
-				minSum = sum;
-
-				pvsBack = pvsl;
-				pvsFront = pvsr;
-				
-				volBack = voll;
-				volFront = volr;
-
+				Debug << "pos: " << position << endl;
+				minRenderCost = renderCost;
 				position = currentPos;
 			}
@@ -3553,31 +3556,12 @@
 	}
 	
-	//-- compute cost
-	const float frontAndBackVol = totalVol - volFront - volBack;
-
-	const float oldRenderCost = (float)totalPvs * totalVol + Limits::Small;
-	const float newRenderCost = (float)pvsFront * volFront + 
-								(float)pvsBack * volBack +
-								(float)totalPvs * frontAndBackVol;
-
-
 	if (splitPlaneFound)
 	{
-		ratio = newRenderCost / oldRenderCost;
-	}
-
-	//Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" 
-	//	  << position << " t=" << (position - minBox) / (maxBox - minBox)
-	//      << "\t pb=(" << volBack << ")\t pf=(" << volFront << ")" << endl;
-
-/*	Debug << "\n§§§§ eval local cost §§§§" << endl
-		  << "back pvs: " << pvsBack << " front pvs: " << pvsFront << " total pvs: " << totalPvs << endl 
-		  << "back p: " << volBack / viewSpaceVol << " front p " << volFront / viewSpaceVol << " p: " << totalVol / viewSpaceVol << endl
-		  << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl
-		  << "render cost decrease: " << oldRenderCost / viewSpaceVol - newRenderCost / viewSpaceVol << endl;
-*/
-	if (oldRenderCost < newRenderCost)
-		Debug << "\nwarning!!:\n" << "old rc: " << oldRenderCost * viewSpaceVol << " new rc: " << newRenderCost * viewSpaceVol << endl;
-	
+		ratio = totalRenderCost / minRenderCost;
+	}
+
+	Debug << "\n§§§§ eval local cost §§§§" << endl
+		  << "old rc: " << totalRenderCost / viewSpaceVol << " new rc: " << minRenderCost / viewSpaceVol << endl
+		  << "render cost decrease: " << (totalRenderCost - minRenderCost) / viewSpaceVol  << endl;
 
 	return ratio;
@@ -3689,11 +3673,10 @@
 
 
-float OspTree::PrepareHeuristics(const VssRay &ray, int &numViewCells)
-{
-	float vol = 0;
-	numViewCells = 0;
-
+void OspTree::PrepareHeuristics(const VssRay &ray, 
+								ViewCellContainer &touchedViewCells)
+{
+
+	// collect view cells and set mail + counter
 	ViewCellContainer viewCells;
-
 	mVspTree->GetViewCells(VssRay(ray), viewCells);
     	
@@ -3706,9 +3689,7 @@
 		if (!vc->Mailed())
 		{
-			//Debug << "single vol: "<< vc->GetVolume() << endl;
-			vc->Mail();
+			vc->Mail(); // set as belonging to front leaf
 			vc->mCounter = 0;
-			vol += vc->GetVolume();
-			++ numViewCells;
+			touchedViewCells.push_back(vc);
 		}
 		
@@ -3716,16 +3697,15 @@
 		++ vc->mCounter;
 	}
-
-	return vol;
-}
-
-
-float OspTree::PrepareHeuristics(const OspTraversalData &tData, int &numViewCells)
+}
+
+
+float OspTree::PrepareHeuristics(const OspTraversalData &tData,
+								 ViewCellContainer &touchedViewCells)
 {	
-	float vol = 0;
-
-	Intersectable::NewMail();
-	ViewCell::NewMail();
-	numViewCells = 0;
+	float renderCost = 0;
+
+	Intersectable::NewMail(3);
+	ViewCell::NewMail(3);
+	MailablePvsData::NewMail();
 
 	KdLeaf *leaf = tData.mNode;
@@ -3736,73 +3716,86 @@
 	{
 		VssRay *ray = (*rit).mRay;
-
-		int newViewCells;
-
-		// if hitpoint with one of the objects is inside this node, we
-		// evaluate the volume of the view cells seen by this ray
-		if (EndPointInsideNode(leaf, *ray, true))
-		{
-            vol += PrepareHeuristics(*ray, newViewCells);
-			numViewCells += newViewCells;
-		}
-
-		// count double if both hit points are within the kd node
-		if (EndPointInsideNode(leaf, *ray, false))
-		{
-			vol += PrepareHeuristics(*ray, newViewCells);
-			numViewCells += newViewCells;
-		}
-	}
-
-	
-	return vol;
-}
-
-
-void OspTree::EvalHeuristicsContribution(KdLeaf *leaf,
-										 const SortableEntry &ci,
-										 float &volLeft,
-										 float &volRight,
-										 int &pvsLeft,
-										 int &pvsRight
-										 )
-{
-	Intersectable *obj = ci.mObject;
-	VssRay *ray = ci.mRay;
-
-	// switch between different types of events
-	switch (ci.mType) 
-	{
-		// add reverse pvs to left side of split plane
-		case SortableEntry::BOX_MIN:
-			++ pvsLeft;
-			break;
-			
-		case SortableEntry::BOX_MAX:
-			-- pvsRight;
-			break;
-
-		// compute volume contribution from view cells
-		case SortableEntry::BOX_INTERSECT:
-				// process ray if the hit point with termination / origin object 
-				// is inside this kd leaf
-				if (EndPointInsideNode(leaf, *ray, true) ||
-					EndPointInsideNode(leaf, *ray, false))
-				{
-					EvalVolumeContribution(*ray, volLeft, volRight);
-				}
-			break;
-		default:
-			cout << "should not come here" << endl;
-			break;
-	}
-
-	//cout << "vol left: " << volLeft << " vol right " << volRight << endl;
-}
-
-
-void OspTree::EvalVolumeContribution(const VssRay &ray, 
-									 float &volLeft, 
-									 float &volRight)
+     	PrepareHeuristics(*ray, touchedViewCells);
+	}
+
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = *oit;
+		obj->Mail(); // set as belonging to front leaf
+		
+		ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+
+		for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+			MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+			if (!vdata) // should never happen
+				continue;
+
+			if (!vdata->Mailed())
+			{
+				vdata->Mail();
+				renderCost += vc->GetVolume();
+			}
+		}
+	}
+
+	Debug << "here32 " << touchedViewCells.size() << endl;
+	return renderCost;
+}
+
+
+void OspTree::AddObjectContribution(KdLeaf *leaf,
+						  Intersectable *obj,
+						  ViewCellContainer &touchedViewCells,
+						  float &renderCost)
+{
+	obj->Mail(2); // set as belonging to both leafs
+
+	ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+	
+	for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = *vit;
+
+		// if obj not previously associated with this view cell => increase render cost
+		if (vc->Mailed(1) && 
+			!ViewCellHasMultipleReferences(obj, vc, false))
+		{
+			renderCost += vc->GetVolume();
+		}
+	}
+}
+
+
+void OspTree::SubtractObjectContribution(KdLeaf *leaf,
+								Intersectable * obj,
+								ViewCellContainer &touchedViewCells,
+								float &renderCost)
+{
+    obj->Mail(1); // set as belonging to back leaf
+	ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+	
+	for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = *vit;
+
+		// if obj was previously associated with this view cell but is not now 
+		// => decrease render cost
+		if (vc->Mailed() && 
+			!ViewCellHasMultipleReferences(obj, vc, false))
+		{
+			renderCost -= vc->GetVolume();
+		}
+	}
+}
+
+
+void OspTree::EvalRayContribution(KdLeaf *leaf,
+								  const VssRay &ray, 
+								  float &renderCost)
 {
 	ViewCellContainer viewCells;
@@ -3819,36 +3812,93 @@
 	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
 	{
-		// view cells can also be seen from left child node
-		ViewCell *viewCell = *vit;
-
-		const float vol = viewCell->GetVolume();
-
-		if (!viewCell->Mailed())
-		{
-			viewCell->Mail();
-
-			// we now see view cell from both nodes 
-			// => remove ref to right child node
-			volRight -= vol;
-
-			debugVol += vol;
-		}
-
-		// last reference into the right node
-		if (-- viewCell->mCounter == 0)
-		{
-#if 0
-			// view cell was previousy seen from right node only
-			// => remove from right node (matt: need this?)
-			if (!viewCell->Mailed())
-				volRight -= vol;
-			else
-#endif
-			// view cell was previously seen from both nodes  =>
-			// contributes only to left node now
-			volLeft += vol;
-			debugVol -= vol;
-		}
-	}
+		EvalViewCellContribution(leaf, *vit, renderCost);
+	}
+}
+
+
+void OspTree::EvalViewCellContribution(KdLeaf *leaf, 
+									   ViewCell *viewCell,
+									   float &renderCost)
+{
+	// view cells can also be seen from left child node
+	const float vol = viewCell->GetVolume();
+
+	if (viewCell->Mailed())
+	{
+		viewCell->NewMail(2); // view cell can be seen from both nodes
+
+        // we now see view cell from both nodes => add contri
+		ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+		for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+		{
+			Intersectable *obj = *oit;
+
+			// was render cost already added?
+			if (!ViewCellHasMultipleReferences(obj, viewCell, false) ||
+				obj->Mailed(1))
+			{
+				renderCost += viewCell->GetVolume();
+			}
+		}
+	}
+
+	if (-- viewCell->mCounter == 0)
+	{
+		ViewCell::NewMail(1); // view cell can be seen from back node only
+
+		//MailablePvsData::NewMail();
+		ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+		for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+		{
+			Intersectable *obj = *oit;
+
+			// can render cost be be reduced?
+			if (!ViewCellHasMultipleReferences(obj, viewCell, false) ||
+				obj->Mailed())
+			{
+				renderCost -= viewCell->GetVolume();
+			}
+		}
+	}
+}
+
+
+void OspTree::EvalHeuristicsContribution(KdLeaf *leaf,
+										 const SortableEntry &ci,
+										 float &renderCost,
+										 ViewCellContainer &touchedViewCells)
+{
+	Intersectable *obj = ci.mObject;
+	VssRay *ray = ci.mRay;
+
+	// switch between different types of events
+	switch (ci.mType) 
+	{
+		case SortableEntry::BOX_MIN:
+			cout << "<";
+			AddObjectContribution(leaf, ci.mObject, touchedViewCells, renderCost);	
+			break;
+			
+		case SortableEntry::BOX_MAX:
+			cout << ">";
+			SubtractObjectContribution(leaf, ci.mObject, touchedViewCells, renderCost);
+			break;
+
+		// compute volume contribution from view cells
+		case SortableEntry::BOX_INTERSECT:
+			cout << "i";
+			// process ray if the hit point with termination / origin object 
+			// is inside this kd leaf
+			EvalRayContribution(leaf, *ray, renderCost);
+			break;
+
+		default:
+			cout << "should not come here" << endl;
+			break;
+	}
+
+	//cout << "vol left: " << volLeft << " vol right " << volRight << endl;
 }
 
@@ -3956,5 +4006,6 @@
 	else
 	{
-		 return ray.mOriginObject && (GetLeaf(ray.mOrigin, ray.mOriginNode) == leaf);
+		return false; // no origin object!
+		return ray.mOriginObject && (GetLeaf(ray.mOrigin, ray.mOriginNode) == leaf);
 	}
 }
@@ -3970,5 +4021,4 @@
 						);
 }
-
 
 
@@ -3992,15 +4042,17 @@
     const bool terminationInside = EndPointInsideNode(leaf, *ray, true);
 
-	const bool originGt = 
-		ray->mOrigin[plane.mAxis] > plane.mPosition;
-		
-	const bool terminationGt = 
-		ray->mTermination[plane.mAxis] > plane.mPosition;
+	const bool originGt = (ray->mOrigin[plane.mAxis] >= plane.mPosition);
+	const bool originLt = (ray->mOrigin[plane.mAxis] <= plane.mPosition);
+
+	const bool terminationGt = (ray->mTermination[plane.mAxis] >= plane.mPosition);
+	const bool terminationLt = (ray->mTermination[plane.mAxis] <= plane.mPosition);
 
 	// add view cell volume to front volume
-	const bool addToFront = ((originInside && originGt) || (terminationInside && terminationGt));
+	const bool addToFront = 
+		((originInside && originGt) || (terminationInside && terminationGt));
 
 	// add view cell volume to back volume
-	const bool addToBack = ((originInside && !originGt) || (terminationInside && !terminationGt));
+	const bool addToBack = 
+		((originInside && originLt/*!originGt*/) || (terminationInside && terminationLt/*terminationGt*/));
 
 	// classify ray with respect to the child nodes the view cells contribute
@@ -4016,26 +4068,4 @@
 
 
-static bool ViewCellHasMultipleReferences(Intersectable *obj, 
-										  ViewCell *vc, 
-										  bool checkOnlyMailed)
-{
-	ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
-
-	if (vdata)
-	{
-		//Debug << "sumpdf: " << vdata->mSumPdf << endl;
-		// more than one view cell sees this object inside different kd cells
-		if (!checkOnlyMailed || !vdata->Mailed())
-		{
-			vdata->Mail();//return true;
-			if (vdata->mSumPdf > 1.5f) 
-				return true;
-		}
-	}
-
-	return false;
-}
-
-
 int OspTree::ClassifyRays(const RayInfoContainer &rays, 
 						  KdLeaf *leaf, 
@@ -4055,7 +4085,7 @@
 		Intersectable *obj = ray->mOriginObject;
 
-		if (obj)
-		{
-			originGt = ray->mOrigin[plane.mAxis] > plane.mPosition;
+		if (0 && obj)
+		{
+			originGt = ray->mOrigin[plane.mAxis] >= plane.mPosition;
 		}
 
@@ -4064,5 +4094,5 @@
 		if (obj)
 		{
-			terminationGt = ray->mTermination[plane.mAxis] > plane.mPosition;
+			terminationGt = ray->mTermination[plane.mAxis] >= plane.mPosition;
 		}
 
@@ -4084,5 +4114,5 @@
 
 
-#if 1
+#if 0
 
 float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
@@ -4121,34 +4151,27 @@
 		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)
-		{
-			// 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);
+		// 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);	
-			}
+		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);	
 		}
 	}
@@ -4173,5 +4196,5 @@
 	float additionalBackRenderCost = 0;
 	
-	ViewCellPvsData::NewMail();
+	MailablePvsData::NewMail();
 
 	for (rit = tData.mRays->begin(); rit != tData.mRays->end(); ++ rit)
@@ -4296,9 +4319,8 @@
 	float pFrontAndBack = 0;
 
+	Intersectable::NewMail(3);
+	KdLeaf *leaf = tData.mNode;
+
 	const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume();
-
-	Intersectable::NewMail(3);
-	
-	KdLeaf *leaf = tData.mNode;
 	const int totalPvs = (int)leaf->mObjects.size();
 	
@@ -4330,5 +4352,4 @@
 				obj->Mail(1);
 		}
-		//Debug << "here3 pt: " << obj << " mail: " << obj->mMailbox - Intersectable::sMailId << endl;
 	}
 
@@ -4369,10 +4390,5 @@
 
 			// classify / mail the view cell
-			MailViewCell(vc, classification);	
-
-			/*if (terminationInside)
-				objectsMap[ray->mTerminationObject].push_back(vc);
-			if (originInside)
-				objectsMap[ray->mOriginObject].push_back(vc);*/
+			MailViewCell(vc, classification);
 		}
 	}
@@ -4394,12 +4410,10 @@
 	// the object would still be part of the pvs
 
-	float frontRc = 0;
-	float backRc = 0;
+	float newRc = 0;
 	float rc = 0;
 
-	ViewCellPvsData::NewMail();
-	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
-
-	//Debug << "here53 " << touchedViewCells.size() << endl;
+	MailablePvsData::NewMail();
+	//ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
 	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
 	{
@@ -4410,27 +4424,31 @@
 		{
 			ViewCell *vc = *vit;
-			/*ObjectPvsData *vdata = vc->GetPvs().Find(obj);
+			
+			MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
 
 			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);
+				Debug << "here86 error!!"<<endl;
+				continue;
+			}
+
+			if (!vdata->Mailed())
+			{
 				vdata->Mail();
-			}
-		}
-	}
-
-
-	}
+				rc += vc->GetVolume();
+
+				if ((vdata->mSumPdf > 1.5) || 
+					vc->Mailed(2) || 
+					obj->Mailed(2) ||
+					(obj->Mailed() && vc->Mailed()) ||
+					(obj->Mailed(1) && vc->Mailed(1))
+					)
+				{
+					newRc += vc->GetVolume();
+				}
+			}
+		}
+	}
+
 
 	/////////////////////////////
@@ -4443,5 +4461,5 @@
 	//-- pvs rendering heuristics
 
-	const float oldRenderCost = pOverall * totalPvs;
+	const float oldRenderCost = rc;//pOverall * totalPvs;
 	
 	// sum up the terms: 
@@ -4450,6 +4468,6 @@
 	// 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;
+	const float newRenderCost = newRc//pvsFront * pFront + pvsBack * pBack + totalPvs * pFrontAndBack
+;//		+ additionalFrontRenderCost + additionalBackRenderCost;
 
 	// normalize volume with view space volume
@@ -4461,7 +4479,7 @@
 		  << " 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;
+		  << "render cost decrease: " << renderCostDecrease << endl;
+		  //<< "additional front " << additionalFrontRenderCost / viewSpaceVol 
+		  //<< " additional back " << additionalBackRenderCost  / viewSpaceVol << endl;
 
 	if (oldRenderCost < newRenderCost * 0.99)
@@ -4477,4 +4495,5 @@
 }
 #endif
+
 
 void OspTree::ComputeBoundingBox(const ObjectContainer &objects,
@@ -4724,5 +4743,5 @@
 			// HACK: reset nodes for the case we have used object kd tree for
 			// tree building.
-			ray->mOrigin = NULL;
+			ray->mOriginNode = NULL;
 			ray->mTerminationNode = NULL;
 		}
@@ -4809,77 +4828,4 @@
 					 
 
-int OspTree::SplitViewCells(const AxisAlignedPlane &candidatePlane,
-							const RayInfoContainer &rays,
-							KdLeaf *leaf,							
-							ViewCellContainer &frontViewCells,
-							ViewCellContainer &backViewCells,
-							ViewCellContainer &frontAndBackViewCells) const 
-{
-	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
-	ViewCell::NewMail(3);
-
-	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)
-		{
-			touchedRays.push_back(*rit);
-			// 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(*vit, classification);	
-			}
-		}
-	}
-	
-	// the important view cells
-	ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
-
-	for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
-	{
-		ViewCell *vc = *vit;
-
-		if (vc->Mailed())
-			frontViewCells.push_back(vc);
-		else if (vc->Mailed(1))
-			backViewCells.push_back(vc);
-		else if (vc->Mailed(2))
-			frontAndBackViewCells.push_back(vc);
-	}
-
-	return 0;
-}
-
-
 int OspTree::CheckViewCellsPvs(KdLeaf *leaf, 
 							   const RayInfoContainer &rays) const
@@ -4895,9 +4841,5 @@
 		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 (terminationInside)
+		if (ray->mTerminationObject)
 		{
 			Intersectable *obj = ray->mTerminationObject;
@@ -4910,5 +4852,5 @@
 		}
 
-		if (originInside)
+		if (ray->mOriginObject)
 		{
 			Intersectable *obj = ray->mOriginObject;
@@ -4938,6 +4880,4 @@
 
 
-
-
 KdIntersectable *OspTree::GetOrCreateKdIntersectable(KdNode *node)
 {
@@ -4952,6 +4892,5 @@
 
 	// not in map => create new entry
-	KdIntersectable *kdObj= new KdIntersectable(node);
-
+	KdIntersectable *kdObj = new KdIntersectable(node);
 	mKdIntersectables[node] = kdObj;
 
@@ -5014,5 +4953,5 @@
 	if (cf >= 0) // front volume
 	{
-		 // already in back volume => in both volumes
+		// already in back volume => in both volumes
 		if (vc->Mailed(1))
 		{
@@ -5072,12 +5011,6 @@
 		VssRay *ray = (*rit).mRay;
 
-		// process ray if the hit point with termination / origin object 
-		// is inside this kd leaf
-		if (!((EndPointInsideNode(leaf, *ray, true)) ||
-			  (EndPointInsideNode(leaf, *ray, false))))
-			continue;
-		
 		ViewCellContainer viewCells;
-		mVspTree->CastLineSegment(ray->mOrigin, ray->mTermination, viewCells);
+		mVspTree->GetViewCells(*ray, viewCells);
 
 		ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
@@ -5106,5 +5039,5 @@
 	contribution = 0; // todo
 
-	ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
+	MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
 
 	if (!vdata)
@@ -5120,4 +5053,35 @@
 
 	return true;
+}
+
+
+void OspTree::CollectTouchedViewCells(const RayInfoContainer &rays, 
+									  ViewCellContainer &touchedViewCells) const
+{
+	ViewCell::NewMail();
+	
+	RayInfoContainer::const_iterator rit, rit_end = rays.end();
+
+	for (rit = rays.begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+
+		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 (!vc->Mailed())
+			{
+				vc->Mail();
+				touchedViewCells.push_back(vc);
+			}
+		}
+	}
 }
 
@@ -5127,8 +5091,7 @@
 
 {
-	RayInfoContainer::const_iterator rit, rit_end = rays.end();
-
-	//ViewCell::NewMail(); Intersectable::NewMail();
-	ViewCellPvsData::NewMail();
+	MailablePvsData::NewMail();
+	
+	/*RayInfoContainer::const_iterator rit, rit_end = rays.end();
 
 	for (rit = rays.begin(); rit < rit_end; ++ rit)
@@ -5136,37 +5099,48 @@
 		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)
-		{
-			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;
-
-				Intersectable *obj = ray->mTerminationObject;
-			
-				if (obj)
-				{
-					float contri;
-					AddViewCellToObjectPvs(obj, vc, contri, true);
-				}
-
-				obj = ray->mOriginObject;
-			
-				if (obj)
-				{
-					float contri;
-					AddViewCellToObjectPvs(obj, vc, contri, true);
-				}
-			}
+		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;
+
+			Intersectable *obj = ray->mTerminationObject;
+			if (obj)
+			{
+				float contri;
+				AddViewCellToObjectPvs(obj, vc, contri, true);
+			}
+
+			obj = ray->mOriginObject;
+			if (obj)
+			{
+				float contri;
+				AddViewCellToObjectPvs(obj, vc, contri, true);
+			}
+		}
+	}*/
+	
+	ViewCellContainer touchedViewCells;
+	CollectTouchedViewCells(rays, touchedViewCells);
+
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	for (oit = leaf->mObjects.begin(); oit < oit_end; ++ oit)
+	{
+		Intersectable *obj = *oit;
+		ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+
+		// traverse through view cells and classify them according
+		// to them being seen from to back / front / front and back node
+		for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+			float contri;
+			AddViewCellToObjectPvs(obj, vc, contri, true);
 		}
 	}
@@ -5181,8 +5155,7 @@
 
 {
-	RayInfoContainer::const_iterator rit, rit_end = rays.end();
-	//ViewCell::NewMail(); Intersectable::NewMail();
-	ViewCellPvsData::NewMail();
-
+	MailablePvsData::NewMail();
+
+	/*RayInfoContainer::const_iterator rit, rit_end = rays.end();
 	for (rit = rays.begin(); rit < rit_end; ++ rit)
 	{
@@ -5190,44 +5163,65 @@
 
 		// 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)
-		{
-			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;
-
-				Intersectable *obj = ray->mTerminationObject;
-				if (obj)
+		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;
+			Intersectable *obj = ray->mTerminationObject;
+
+			if (obj)
+			{
+				MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+				if (vdata && !vdata->Mailed())
 				{
-					ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
-
-					if (vdata && !vdata->Mailed())
-					{
-						vdata->Mail();
-						obj->mViewCellPvs.RemoveSample(vc, 1);
-					}
-					
+					vdata->Mail();
+					obj->mViewCellPvs.RemoveSample(vc, 1);
 				}
-
-				obj = ray->mOriginObject;
-				if (obj)
+			}
+
+			obj = ray->mOriginObject;
+
+			if (obj)
+			{
+				MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+				if (vdata && !vdata->Mailed())
 				{
-					ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
-
-					if (vdata && !vdata->Mailed())
-					{
-						vdata->Mail();
-						obj->mViewCellPvs.RemoveSample(vc, 1);
-					}
+					vdata->Mail();
+					obj->mViewCellPvs.RemoveSample(vc, 1);
 				}
+			}
+		}
+	}*/
+
+	ViewCellContainer touchedViewCells;
+	CollectTouchedViewCells(rays, touchedViewCells);
+
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = *oit;
+
+		// traverse through view cells and classify them according
+		// to them being seen from to back / front / front and back node
+        ViewCellContainer::const_iterator vit, vit_end = touchedViewCells.end();
+
+		for (vit = touchedViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			ViewCell *vc = *vit;
+			
+			MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
+
+			if (vdata && !vdata->Mailed())
+			{
+				vdata->Mail();
+				obj->mViewCellPvs.RemoveSample(vc, 1);
 			}
 		}
@@ -5260,5 +5254,5 @@
 	KdLeafContainer::const_iterator kit, kit_end = leaves.end();
 
-	ViewCellPvsData::NewMail();
+	MailablePvsData::NewMail();
 
 	for (kit = leaves.begin(); kit != kit_end; ++ kit)
@@ -5277,5 +5271,4 @@
 			
 			// 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);
@@ -5305,5 +5298,4 @@
 		ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
 
-		//Debug << "here53 " << touchedViewCells.size() << endl;
 		for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
 		{
@@ -5314,5 +5306,5 @@
 			{
 				ViewCell *vc = *vit;
-				/*ObjectPvsData *vdata = vc->GetPvs().Find(obj);
+				PvsData *vdata = vc->GetPvs().Find(obj);
 
 				if (!vdata)
@@ -5320,8 +5312,7 @@
 					vc->GetPvs().AddSample(obj, 1);
 					newCost += vc->GetVolume();
-					//prop += vc->GetVolume();
-				}*/
-
-				ViewCellPvsData *vdata = obj->mViewCellPvs.Find(vc);
+				}
+
+/*				MailablePvsData *vdata = obj->mViewCellPvs.Find(vc);
 
 				if (!vdata || !vdata->Mailed())
@@ -5331,5 +5322,5 @@
 						vdata = obj->mViewCellPvs.AddSample2(vc, 1);
 					vdata->Mail();
-				}
+				}*/
 			}
 		}
@@ -5397,5 +5388,5 @@
 		{
 			ViewCell *vc = *vit;
-			ObjectPvsData *vdata = vc->GetPvs().Find(obj);
+			PvsData *vdata = vc->GetPvs().Find(obj);
 
 			if (!vdata)
@@ -5426,5 +5417,6 @@
 
 	char subdivisionStatsLog[100];
-	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", subdivisionStatsLog);
+	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", 
+		subdivisionStatsLog);
 	mSubdivisionStats.open(subdivisionStatsLog);
 }
@@ -5533,5 +5525,5 @@
 
 	// probabilty is voume of all "seen" view cells
-#if 0
+#if 1
 	const float prop = mOspTree.EvalViewCellsVolume(kdleaf, rays);
 #else
@@ -5545,5 +5537,5 @@
 									0,
 									&rays,
-									(int)objects.size(),
+									0,//(int)objects.size(),
 									prop,
 									mOspTree.mBoundingBox);
@@ -5553,4 +5545,6 @@
 	OspTree::OspSplitCandidate *oSplitCandidate = 
 		new OspTree::OspSplitCandidate(oData);
+
+	mOspTree.UpdateViewCellsPvs(kdleaf, rays);
 
 	mOspTree.EvalSplitCandidate(*oSplitCandidate);
@@ -5755,4 +5749,5 @@
 	/////////////////////////////////////////////////////////////
 
+
 	Debug << "\n$$$$$$$$$ osp tree construction $$$$$$$$$$\n" << endl;
 	cout << "starting osp contruction ... " << endl;
@@ -5784,5 +5779,5 @@
 	float rc = mOspTree.EvalRenderCost(sampleRays);
 
-	Debug << "My render cost evalulation: " << rc << endl;
+	Debug << "here47 My render cost evalulation: " << rc << endl;
 
 #if 0
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1159)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1189)
@@ -147,5 +147,5 @@
 		for (int tries = 0; tries < 10; tries++) {
 			int index = (int)RandomValue(0, (Real)(pvsSize - 1));
-			KdPvsData data;
+			PvsData data;
 			KdNode *node;
 			object->mKdPvs.GetData(index, node, data);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1184)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1189)
@@ -2340,15 +2340,14 @@
   Intersectable::NewMail();
   
-  std::map<Intersectable *,
-	PvsData<Intersectable *>,
-	LtSample<Intersectable *> >::const_iterator oi;
+ ObjectPvsMap::const_iterator oi;
   
-  for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) {
-	Intersectable *object = (*oi).first;
-	object->Mail();
+  for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++ oi) 
+  {
+	  Intersectable *object = (*oi).first;
+      object->Mail();
   }
 
   ObjectPvs nPvs;
-  int nPvsSize=0;
+  int nPvsSize = 0;
   // now go through the pvs again
   for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) {
@@ -3418,5 +3417,5 @@
 			ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
 			// -- output PVS of view cell
-			for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
+			for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
 			{
 				Intersectable *intersect = (*it).first;
@@ -5385,13 +5384,12 @@
 		{	
 			//-- export pvs
+			
+			Intersectable::NewMail();
+			KdLeaf::NewMail();
+
+			vector<KdLeaf *> kdLeaves;
+
 			ObjectPvsMap::const_iterator oit, oit_end = pvs.mEntries.end();
 
-			Intersectable::NewMail();
-
-			vector<KdLeaf *> kdLeaves;
-
-			KdLeaf::NewMail();
-
-			// export pvs entries
 			for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit)
 			{	
@@ -5803,5 +5801,5 @@
 	}
 	
-	Debug << "here295 " << rc / mVspTree->GetBoundingBox().GetVolume();
+	Debug << "\nhere295 " << rc / mVspTree->GetBoundingBox().GetVolume() << endl;
 
 	mViewCellsTree->ExportStats(fileName);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1179)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1189)
@@ -92,5 +92,5 @@
 	it_end = pvs2.mEntries.end();
 
-	// look if they are in second pvs
+	// look if the entries are also in second pvs
 	for (it = pvs2.mEntries.begin(); it != it_end; ++ it)
 	{
@@ -1626,5 +1626,5 @@
 	}
 
-	interior->GetPvs().mEntries.clear();
+	interior->GetPvs().Clear();
 	
 	
@@ -1656,5 +1656,7 @@
 		{
 			if (!(*cit)->GetPvs().RemoveSample((*oit).first, Limits::Infinity))
+			{
 				Debug << "should not come here!" << endl;
+			}
 		}
 	}
@@ -1985,5 +1987,5 @@
 {
 	const float entrySize = 
-		sizeof(PvsData<Intersectable *>) + sizeof(Intersectable *);
+		sizeof(PvsData) + sizeof(Intersectable *);
 
 	return (float)GetStoredPvsEntriesNum(vc) * entrySize;
@@ -2286,5 +2288,5 @@
 		tstack.pop();
 
-		vc->GetPvs().mEntries.clear();
+		vc->GetPvs().Clear();
 		
 		if (!vc->IsLeaf())
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1184)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1189)
@@ -4,4 +4,5 @@
 #include <map>
 #include <vector>
+#include "common.h"
 
 namespace GtpVisibilityPreprocessor {
@@ -15,5 +16,6 @@
 
 template<typename T>
-struct LtSample {
+struct LtSample 
+{
     bool operator()(const T a, const T b) const
     {
@@ -25,7 +27,24 @@
 	the object was seen from the view cell.
 */
-
-template<typename T> 
-struct PvsData {
+class PvsData {
+public:
+  // sum of probability density of visible sample rays
+  float mSumPdf;
+
+  PvsData() {}
+  PvsData(const float sumPdf):
+	mSumPdf(sumPdf) {}
+
+  // $$JB in order to return meaningfull values
+  // it assumes that the sum pdf has been normalized somehow!!!
+  float GetVisibility() 
+  { 
+	  return mSumPdf; 
+  }
+};
+
+
+class MailablePvsData 
+{
 ////////////////////////////
 //  Mailing stuff
@@ -56,7 +75,8 @@
   // sum of probability density of visible sample rays
   float mSumPdf;
-
-  PvsData<T>() {}
-  PvsData<T>(const float sumPdf):
+  int mCounter;
+
+  MailablePvsData() {}
+  MailablePvsData(const float sumPdf):
 	mSumPdf(sumPdf) {}
 
@@ -69,11 +89,9 @@
 };
 
-template<typename T> int PvsData<T>::sMailId = 1;
-template<typename T> int PvsData<T>::sReservedMailboxes = 1;
 
 /** Template class representing the Potentially Visible Set (PVS) 
 	mainly from a view cell, but also e.g., from objects.
 */
-template<typename T>
+template<typename T, typename S>
 class Pvs
 {
@@ -81,6 +99,6 @@
   Pvs(): /*mSamples(0), */mEntries() {}
   
-  //int mSamples;
-  
+  //virtual ~Pvs();
+    
   /** Compresses PVS lossless or lossy.
   */
@@ -96,15 +114,15 @@
   /** Merges pvs of a into this pvs.
    */
-  void Merge(const Pvs<T> &a);
+  void Merge(const Pvs<T, S> &a);
   
   /** Difference of pvs to pvs b.
 	  @returns number of different entries.
   */
-  int Diff(const Pvs<T> &b);
+  int Diff(const Pvs<T, S> &b);
   
   /** Finds sample in PVS.
 	  @returns sample if found, NULL otherwise.
   */
-  PvsData<T> *Find(T sample);
+  S *Find(T sample);
 
   bool GetSampleContribution(T sample, const float pdf, float &contribution);
@@ -124,10 +142,10 @@
 	  @returns PvsData
   */
-  PvsData<T> *AddSample2(T sample, const float pdf);
+  S *AddSample2(T sample, const float pdf);
 
   /** Adds one pvs to another one.
 	  @returns new pvs size
   */
-  int AddPvs(const Pvs<T> &pvs);
+  int AddPvs(const Pvs<T, S> &pvs);
 
   /** Subtracts one pvs from another one.
@@ -135,9 +153,9 @@
 	  @returns new pvs size
   */
-  int SubtractPvs(const Pvs<T> &pvs);
+  int SubtractPvs(const Pvs<T, S> &pvs);
   /** Returns PVS data, i.e., how often it was seen from the view cell, 
 	  and the object itsef.
   */
-  void GetData(const int index, T &entry, PvsData<T> &data);
+  void GetData(const int index, T &entry, S &data);
 
   /** Collects the PVS entries and returns them in the vector.
@@ -151,5 +169,5 @@
 
   /** Compute continuous PVS difference */
-  void ComputeContinuousPvsDifference(Pvs<T> &pvs,
+  void ComputeContinuousPvsDifference(Pvs<T, S> &pvs,
 									  float &pvsReduction,
 									  float &pvsEnlargement);
@@ -161,5 +179,5 @@
 
   /** Compute continuous PVS difference */
-  float GetPvsHomogenity(Pvs<T> &pvs) {
+  float GetPvsHomogenity(Pvs<T, S> &pvs) {
 	float 
 	  pvsReduction,
@@ -176,5 +194,5 @@
 					  
   /// Map of PVS entries
-  std::map<T, PvsData<T>, LtSample<T> > mEntries;
+  std::map<T, S, LtSample<T> > mEntries;
 };
 
@@ -186,7 +204,7 @@
 
 */
-template <typename T>
+template <typename T, typename S>
 void
-Pvs<T>::ComputeContinuousPvsDifference(Pvs<T> &b,
+Pvs<T, S>::ComputeContinuousPvsDifference(Pvs<T, S> &b,
 									   float &pvsReduction,
 									   float &pvsEnlargement)
@@ -195,15 +213,17 @@
 	pvsEnlargement = 0.0f;
   // Uses sum of log differences, which corresponds to entropy
-  std::map<T, PvsData<T>, LtSample<T> >::iterator it;
-  
-  for (it = b.mEntries.begin(); 
-	  it != b.mEntries.end(); ++ it) {
+  std::map<T, S, LtSample<T> >::iterator it;
+  
+  for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it) 
+  {
 	float bSumPdf = (*it).second.mSumPdf;
 	float aSumPdf = 0.0f;
-	PvsData<T> *data = Find((*it).first);		
-	if (data) {
-	  aSumPdf = data->mSumPdf;
-	  // mark this entry as processed to avoid double counting
-	  data->mSumPdf = -aSumPdf;
+	S *data = Find((*it).first);		
+	
+	if (data) 
+	{
+		aSumPdf = data->mSumPdf;
+		// mark this entry as processed to avoid double counting
+		data->mSumPdf = -aSumPdf;
 	}
 
@@ -230,5 +250,5 @@
 	  (*it).second.mSumPdf = -aSumPdf;
 	} else {
-	  PvsData<T> *data = b.Find((*it).first);
+	  S *data = b.Find((*it).first);
 	  if (data) {
 		bSumPdf = data->mSumPdf;
@@ -251,14 +271,14 @@
 }
 
-template <typename T>
-int Pvs<T>::Diff(const Pvs<T> &b)
+template <typename T, typename S>
+int Pvs<T, S>::Diff(const Pvs<T, S> &b)
 {
 	int dif = 0;
 
-	std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
+	std::map<T, S, LtSample<T> >::const_iterator it;
 
 	for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
 	{
-		PvsData<T> *data = Find((*it).first);		
+		S data = Find((*it).first);		
 		if (!data) ++ dif;
 	}
@@ -267,21 +287,16 @@
 }
 
-template <typename T>
-void Pvs<T>::Merge(const Pvs<T> &a)
-{
-	std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
+template <typename T, typename S> void Pvs<T, S>::Merge(const Pvs<T, S> &a)
+{
+	std::map<T, S, LtSample<T> >::const_iterator it;
 
 	for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
 	{
-		PvsData<T> *data = Find((*it).first);
-		
-		if (data)
-			data->mSumPdf += (*it).second.mSumPdf;
-		else
-			mEntries.insert(*it);
-	}
-}
-
-template <typename T> void Pvs<T>::Clear()
+		AddSample((*it).first, (*it).second.mSumPdf);
+	}
+}
+
+
+template <typename T, typename S> void Pvs<T, S>::Clear()
 {
 	mEntries.clear();
@@ -289,73 +304,84 @@
 
 
-template <typename T>
-PvsData<T> *Pvs<T>::Find(T sample)
-{
-  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.find(sample);
-  if (i != mEntries.end()) {
-    return &(*i).second;
-  } else
-    return NULL;
-}
-
-template <typename T>
-void Pvs<T>::GetData(const int index,
+template <typename T, typename S> 
+S *Pvs<T, S>::Find(T sample)
+{
+  std::map<T, S, LtSample<T> >::iterator i = mEntries.find(sample);
+
+  if (i != mEntries.end()) 
+  {
+	  return &(*i).second;
+  } 
+  else
+  {
+	  return NULL;
+  }
+}
+
+template <typename T, typename S>
+void Pvs<T, S>::GetData(const int index,
 					 T &entry,
-					 PvsData<T> &data)
-{
-  std::map<T, PvsData<T>, LtSample<T> >::iterator i = mEntries.begin();
+					 S &data)
+{
+  std::map<T, S, LtSample<T> >::iterator i = mEntries.begin();
   for (int k = 0; k != index && i != mEntries.end(); i++, k++);
 
   entry = (*i).first;
   data = (*i).second;
-}
-
-template <typename T>
+  
+}
+
+template <typename T, typename S>
 float
-Pvs<T>::AddSample(T sample, const float pdf)
-{
-  PvsData<T> *data = Find(sample);
-  
-  if (data)  {
-	data->mSumPdf += pdf;
-	return data->mSumPdf;
-  }
-  else {
-	mEntries[sample] = PvsData<T>(pdf);
-	return pdf;
-  }
-}
-
-template <typename T>
-PvsData<T> *
-Pvs<T>::AddSample2(T sample, const float pdf)
-{
-  PvsData<T> *data = Find(sample);
-  
-  if (data)  {
-	data->mSumPdf += pdf;
-  }
-  else {
-	mEntries[sample] = PvsData<T>(pdf);
-	data = Find(sample);
-  }
-  return data;
-}
-
-template <typename T>
-bool
-Pvs<T>::AddSample(T sample,
+Pvs<T, S>::AddSample(T sample, const float pdf)
+{
+	S *data = Find(sample);
+  
+	if (data)  
+	{
+		data->mSumPdf += pdf;
+		return data->mSumPdf;
+	}
+	else 
+	{
+		mEntries[sample] = S(pdf);
+		return pdf;
+	}
+}
+
+
+template <typename T, typename S>
+S * Pvs<T, S>::AddSample2(T sample, const float pdf)
+{
+	S *data = Find(sample);
+  
+	if (data)  
+	{
+		data->mSumPdf += pdf;
+	}
+	else 
+	{
+		mEntries[sample] = S(pdf);
+		data = Find(sample);
+	}
+
+	return data;
+}
+
+template <typename T, typename S> 
+bool Pvs<T, S>::AddSample(T sample,
 				  const float pdf,
 				  float &contribution)
 {
-  PvsData<T> *data = Find(sample);
-  
-  if (data)  {
+  S *data = Find(sample);
+  
+  if (data)  
+  {
 	data->mSumPdf += pdf;
-	contribution = pdf/data->mSumPdf;
+	contribution = pdf / data->mSumPdf;
 	return false;
   }
   else {
-	mEntries[sample] = PvsData<T>(pdf);
+	mEntries[sample] = S(pdf);
 	contribution = 1.0f;
 	return true;
@@ -363,14 +389,14 @@
 }
 
-template <typename T>
+template <typename T, typename S>
 bool
-Pvs<T>::GetSampleContribution(T sample,
+Pvs<T, S>::GetSampleContribution(T sample,
 							  const float pdf,
 							  float &contribution) 
 {
-  PvsData<T> *data = Find(sample);
+  S *data = Find(sample);
   
   if (data)  {
-	contribution = pdf/(data->mSumPdf + pdf);
+	contribution = pdf / (data->mSumPdf + pdf);
 	return false;
   }
@@ -381,9 +407,9 @@
 }
 
-template <typename T>
-bool Pvs<T>::RemoveSample(T sample,
+template <typename T, typename S>
+bool Pvs<T, S>::RemoveSample(T sample,
 						  const float pdf)
 {
-  std::map<T, PvsData<T>, LtSample<T> >::
+  std::map<T, S, LtSample<T> >::
 	iterator it = mEntries.find(sample);
   
@@ -391,31 +417,36 @@
 	return false;
   
-  PvsData<T> *data = &(*it).second;
+  S *data = &(*it).second;
   
   data->mSumPdf -= pdf;
+
   if (data->mSumPdf <= 0.0f)
-	mEntries.erase(it);
-  
+  {
+	  mEntries.erase(it);
+  }
+
   return true;
 }
 
-template <typename T>
-int Pvs<T>::AddPvs(const Pvs<T> &pvs)
-{
-  std::map<T, PvsData<T>, LtSample<T> >::
+template <typename T, typename S>
+int Pvs<T, S>::AddPvs(const Pvs<T, S> &pvs)
+{
+  std::map<T, S, LtSample<T> >::
 	const_iterator it, it_end = pvs.mEntries.end();
   
   float contri;
   // output PVS of view cell
-  for (it = pvs.mEntries.begin(); it != it_end; ++ it) 
-	AddSample((*it).first, (*it).second.mSumPdf, contri);
+  for (it = pvs.mEntries.begin(); it != it_end; ++ it)
+  {	
+	  AddSample((*it).first, (*it).second.mSumPdf, contri);
+  }
   
   return GetSize();
 }
  
-template <typename T>
-int Pvs<T>::SubtractPvs(const Pvs<T> &pvs)
-{
-  std::map<T, PvsData<T>, LtSample<T> >::
+template <typename T, typename S>
+int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
+{
+  std::map<T, S, LtSample<T> >::
 	const_iterator it, it_end = pvs.mEntries.end();
   
@@ -427,8 +458,8 @@
 }
 
-template <typename T>
-void Pvs<T>::CollectEntries(std::vector<T> &entries)
-{
-	std::map<T, PvsData<T>, LtSample<T> >::
+template <typename T, typename S>
+void Pvs<T, S>::CollectEntries(std::vector<T> &entries)
+{
+	std::map<T, S, LtSample<T> >::
 		const_iterator it, it_end = mEntries.end();
 
@@ -438,8 +469,8 @@
 }
 
-template <typename T>
-void Pvs<T>::NormalizeMaximum()
-{
-  std::map<T, PvsData<T>, LtSample<T> >::
+template <typename T, typename S>
+void Pvs<T, S>::NormalizeMaximum()
+{
+  std::map<T, S, LtSample<T> >::
 	const_iterator it, it_end = mEntries.end();
 
@@ -453,5 +484,5 @@
   }
 
-  maxSum = 1.0f/maxSum;
+  maxSum = 1.0f / maxSum;
 
   for (it = mEntries.begin(); it != it_end; ++ it) {
@@ -464,5 +495,5 @@
 /** Class instantiating the Pvs template for kd tree nodes.
 */
-class KdPvs: public Pvs<KdNode *>
+class KdPvs: public Pvs<KdNode *, PvsData>
 {
 public:
@@ -471,5 +502,5 @@
 
 
-class ObjectPvs: public Pvs<Intersectable *>
+class ObjectPvs: public Pvs<Intersectable *, PvsData>
 {
 public:
@@ -483,13 +514,10 @@
 //-- typedefs
 
-typedef std::map<KdNode *, PvsData<KdNode *>, LtSample<KdNode *> > KdPvsMap;
-typedef std::map<Intersectable *, PvsData<Intersectable *>, LtSample<Intersectable *> > ObjectPvsMap;
-typedef std::map<ViewCell *, PvsData<ViewCell *>, LtSample<ViewCell *> > ViewCellPvsMap;
-
-typedef PvsData<Intersectable *> ObjectPvsData;
-typedef PvsData<KdNode *> KdPvsData;
-
-typedef Pvs<ViewCell *> ViewCellPvs;
-typedef PvsData<ViewCell *> ViewCellPvsData;
+typedef std::map<KdNode *, PvsData, LtSample<KdNode *> > KdPvsMap;
+typedef std::map<Intersectable *, PvsData, LtSample<Intersectable *> > ObjectPvsMap;
+typedef std::map<ViewCell *, MailablePvsData, LtSample<ViewCell *> > ViewCellPvsMap;
+
+
+typedef Pvs<ViewCell *, MailablePvsData> ViewCellPvs;
 
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1186)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1189)
@@ -1587,12 +1587,4 @@
 	int FilterRays(KdLeaf *leaf, const RayInfoContainer &rays, RayInfoContainer &filteredRays);
 
-	int SplitViewCells(
-		const AxisAlignedPlane &candidatePlane,
-		const RayInfoContainer &rays,
-		KdLeaf *leaf,
-		ViewCellContainer &frontViewCells,
-		ViewCellContainer &backViewCells,
-		ViewCellContainer &frontAndBackViewCells) const;
-
 	/** Adds the object to the pvs of the front and back leaf with a given classification.
 
@@ -1641,8 +1633,10 @@
 	/** Evaluate the contributions of view cell volume of the left and the right view cell.
 	*/
-	void EvalVolumeContribution(const VssRay &ray, 
-									float &volLeft, 
-									float &volRight);
-
+	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
@@ -1652,17 +1646,15 @@
 	void EvalHeuristicsContribution(KdLeaf *leaf,
 		const SortableEntry &ci,
-		float &volLeft,
-		float &volRight,
-		int &pvsLeft,
-		int &pvsRight);
+		float &renderCost,
+		ViewCellContainer &touchedViewCells);
 
 	/** Prepares objects for the cost heuristics.
 		@returns pvs size of the node
 	*/
-	float PrepareHeuristics(const OspTraversalData &tData, int &numViewCells);
+	float PrepareHeuristics(const OspTraversalData &tData, ViewCellContainer &touchedViewCells);
 
 	/** Prepares heuristics for a particular ray.
 	*/
-	float PrepareHeuristics(const VssRay &ray, int &numViewCells);
+	void PrepareHeuristics(const VssRay &ray, ViewCellContainer &touchedViewCells);
 
 	/** Prepares construction for vsp and osp trees.
@@ -1726,5 +1718,5 @@
 
 	int UpdateViewCellsPvs(KdLeaf *leaf, const RayInfoContainer &rays) const;
-int OspTree::CheckViewCellsPvs(KdLeaf *leaf, 
+int CheckViewCellsPvs(KdLeaf *leaf, 
 							   const RayInfoContainer &rays) const;
 	bool AddViewCellToObjectPvs(
@@ -1741,4 +1733,16 @@
 		RayInfoContainer &backRays) const;
 
+	void CollectTouchedViewCells(
+		const RayInfoContainer &rays, 
+		ViewCellContainer &touchedViewCells) const;
+
+	void AddObjectContribution(KdLeaf *leaf,
+						  Intersectable * obj,
+						  ViewCellContainer &touchedViewCells,
+						  float &renderCost);
+	void SubtractObjectContribution(KdLeaf *leaf,
+						  Intersectable * obj,
+						  ViewCellContainer &touchedViewCells,
+						  float &renderCost);
 protected:
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1145)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1189)
@@ -648,5 +648,5 @@
 	case 3: {
 	  float newCost = info.raysBack*info.pvsBack  + info.raysFront*info.pvsFront;
-	  float oldCost = leaf->rays.size()*pvsSize;
+	  float oldCost = (float)leaf->rays.size()*pvsSize;
 	  info.costRatio = newCost/oldCost;
 	}
@@ -675,5 +675,5 @@
 	case 3: {
 	  float newCost = abs(info.raysBack  - info.raysFront);
-	  float oldCost = leaf->rays.size();
+	  float oldCost = (float)leaf->rays.size();
 	  info.costRatio = newCost/oldCost;
 	  break;
@@ -1762,5 +1762,5 @@
 	  RssTreeLeaf *leaf = (RssTreeLeaf *)node;
 	  float c = leaf->GetImportance();
-	  int num = (c*ratioPerLeaf + 0.5);
+	  int num = int(c*ratioPerLeaf + 0.5f);
 	  //			cout<<num<<" ";
 
@@ -2323,8 +2323,8 @@
 	   RssTreeLeaf::RayInfo::GreaterWeightedPvsContribution);
 
-  int desired = ratio*leaf->rays.size();
-  int removed = leaf->rays.size() - desired;
-  
-  for (i=desired; i < leaf->rays.size(); i++) {
+  int desired = int(ratio*leaf->rays.size());
+  int removed = (int)leaf->rays.size() - desired;
+  
+  for (i=desired; i < (int)leaf->rays.size(); i++) {
 	// delete the ray
 	leaf->rays[i].mRay->Unref();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.cpp	(revision 1184)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.cpp	(revision 1189)
@@ -9,4 +9,7 @@
 
 namespace GtpVisibilityPreprocessor {
+
+int MailablePvsData::sMailId = 1;
+int MailablePvsData::sReservedMailboxes = 1;
 
 
