Index: GTP/trunk/Lib/Vis/Preprocessing/scripts/TestPreprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/scripts/TestPreprocessor.vcproj	(revision 1076)
+++ GTP/trunk/Lib/Vis/Preprocessing/scripts/TestPreprocessor.vcproj	(revision 1077)
@@ -86,5 +86,5 @@
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="..\support\xercesc\lib\;..\support\zlib\lib\;..\support\devil\lib;&quot;$(QTDIR)\lib&quot;;..\include;..\src\GL;&quot;$(CG_LIB_PATH)&quot;;&quot;$(GTPDIR)\NonGTP\Xerces&quot;;&quot;$(GTPDIR)\NonGTP\Xerces\xercesc\lib&quot;;&quot;$(GTPDIR)\NonGTP\zlib\lib&quot;;&quot;$(GTPDIR)\NonGTP\Devil\lib&quot;;..\lib\release;..\..\Preprocessing\lib\release"
-				GenerateDebugInformation="TRUE"
+				GenerateDebugInformation="FALSE"
 				SubSystem="1"
 				OptimizeReferences="2"
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1074)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1077)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1076)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1077)
@@ -18,5 +18,8 @@
 #include "Beam.h"
 
+
+
 namespace GtpVisibilityPreprocessor {
+
 
 #define USE_FIXEDPOINT_T 0
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1076)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1077)
@@ -40,5 +40,5 @@
 	if (pvs < lower)
 		return (float)lower;
-	if (pvs > upper)
+	else if (pvs > upper)
 		return (float)upper;
 
@@ -778,6 +778,6 @@
 			++ contributingSamples;
 		
-		// warning: rays get never deleted!
-		if (1) leaf->mVssRays.push_back(new VssRay(*ray));
+		// store rays for visualization
+		if (0) leaf->mVssRays.push_back(new VssRay(*ray));
 	}
 }
@@ -992,177 +992,4 @@
 
 
-float VspTree::EvalLocalCostHeuristics(const RayInfoContainer &rays,
-									   const AxisAlignedBox3 &box,
-									   int pvsSize,
-									   const int axis,
-									   float &position)
-{
-	const float minBox = box.Min(axis);
-	const float maxBox = box.Max(axis);
-
-	const float sizeBox = maxBox - minBox;
-
-	const float minBand = minBox + mMinBand * sizeBox;
-	const float maxBand = minBox + mMaxBand * sizeBox;
-
-	SortSplitCandidates(rays, axis, minBand, maxBand);
-
-	// go through the lists, count the number of objects left and right
-	// and evaluate the following cost funcion:
-	// C = ct_div_ci  + (ql*rl + qr*rr)/queries
-
-	int pvsl = 0;
-	int pvsr = pvsSize;
-
-	int pvsBack = pvsl;
-	int pvsFront = pvsr;
-
-	float sum = (float)pvsSize * sizeBox;
-	float minSum = 1e20f;
-
-	
-	// if no good split can be found, take mid split
-	position = minBox + 0.5f * sizeBox;
-	
-	// the relative cost ratio
-	float ratio = 99999999.0f;
-	bool splitPlaneFound = false;
-
-	Intersectable::NewMail();
-
-   	RayInfoContainer::const_iterator ri, ri_end = rays.end();
-
-	//-- set all object as belonging to the front pvs
-
-	for(ri = rays.begin(); ri != ri_end; ++ ri)
-	{
-		Intersectable *oObject = (*ri).mRay->mOriginObject;
-		Intersectable *tObject = (*ri).mRay->mTerminationObject;
-
-		if (oObject)
-		{
-			if (!oObject->Mailed())
-			{
-				oObject->Mail();
-				oObject->mCounter = 1;
-			}
-			else
-			{
-				++ oObject->mCounter;
-			}
-		}
-		if (tObject)
-		{
-			if (!tObject->Mailed())
-			{
-				tObject->Mail();
-				tObject->mCounter = 1;
-			}
-			else
-			{
-				++ tObject->mCounter;
-			}
-		}
-	}
-
-	Intersectable::NewMail();
-
-	vector<SortableEntry>::const_iterator ci, ci_end = mSplitCandidates->end();
-
-	for (ci = mSplitCandidates->begin(); ci != ci_end; ++ ci)
-	{
-		VssRay *ray;
-		ray = (*ci).ray;
-		
-		Intersectable *oObject = ray->mOriginObject;
-		Intersectable *tObject = ray->mTerminationObject;
-		
-
-		switch ((*ci).type)
-		{
-			case SortableEntry::ERayMin:
-				{
-					if (oObject && !oObject->Mailed())
-					{
-						oObject->Mail();
-						++ pvsl;
-					}
-					if (tObject && !tObject->Mailed())
-					{
-						tObject->Mail();
-						++ pvsl;
-					}
-					break;
-				}
-			case SortableEntry::ERayMax:
-				{
-					if (oObject)
-					{
-						if (-- oObject->mCounter == 0)
-							-- pvsr;
-					}
-
-					if (tObject)
-					{
-						if (-- tObject->mCounter == 0)
-							-- pvsr;
-					}
-
-					break;
-				}
-		}
-		
-		
-		// Note: sufficient to compare size of bounding boxes of front and back side?
-		if (((*ci).value >= minBand) && ((*ci).value <= maxBand))
-		{
-			sum = pvsl * ((*ci).value - minBox) + pvsr * (maxBox - (*ci).value);
-
-			//Debug  << "pos=" << (*ci).value << "\t pvs=(" <<  pvsl << "," << pvsr << ")" << endl;
-			//Debug << "cost= " << sum << endl;
-
-			if (sum < minSum)
-			{
-				splitPlaneFound = true;
-
-				minSum = sum;
-				position = (*ci).value;
-				
-				pvsBack = pvsl;
-				pvsFront = pvsr;
-			}
-		}
-	}
-	
-	
-	// -- compute cost
-
-	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
-	const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize();
-
-	const float pOverall = sizeBox;
-	const float pBack = position - minBox;
-	const float pFront = maxBox - position;
-
-	
-	const float penaltyOld = EvalPvsPenalty(pvsSize, lowerPvsLimit, upperPvsLimit);
-    const float penaltyFront = EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit);
-	const float penaltyBack = EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit);
-	
-	const float oldRenderCost = penaltyOld * pOverall + Limits::Small;
-	const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack;
-
-	if (splitPlaneFound)
-	{
-		ratio = newRenderCost / oldRenderCost;
-	}
-	//if (axis != 1)
-	//Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox)
-	 //    <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl;
-
-	return ratio;
-}
-
-
 void VspTree::RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const
 {
@@ -1194,5 +1021,5 @@
 		leaf->Mail();
 
-		// add objects without objects which are part of several kd leaves
+		// add objects without those which are part of several kd leaves
 		pvs += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
 
@@ -1286,5 +1113,5 @@
 		{
 			set<KdLeaf *>::const_iterator kit, kit_end = tObject->mKdLeaves.end();
-
+			
 			for (kit = tObject->mKdLeaves.begin(); kit != kit_end; ++ kit)
 			{
@@ -1305,5 +1132,4 @@
 
 
-/*
 float VspTree::EvalLocalCostHeuristics(const RayInfoContainer &rays,
 									   const AxisAlignedBox3 &box,
@@ -1322,5 +1148,5 @@
 	SortSplitCandidates(rays, axis, minBand, maxBand);
 
-	// prepare the heuristics sweep 
+	// prepare the sweep
 	// (note: returns pvs size, so there would be no need 
 	// to give pvs size as argument)
@@ -1410,5 +1236,5 @@
 
 	return ratio;
-}*/
+}
 
 
@@ -3016,4 +2842,320 @@
 
 
+/*
+float OspTree::EvalLocalCostHeuristics(const RayInfoContainer &rays,
+									   const AxisAlignedBox3 &box,
+									   int pvsSize,
+									   const int axis,
+									   float &position)
+{
+	const float minBox = box.Min(axis);
+	const float maxBox = box.Max(axis);
+
+	const float sizeBox = maxBox - minBox;
+
+	const float minBand = minBox + mMinBand * sizeBox;
+	const float maxBand = minBox + mMaxBand * sizeBox;
+
+	SortSplitCandidates(rays, axis, minBand, maxBand);
+
+	// prepare the sweep 
+	// (note: returns pvs size, so there would be no need 
+	// to give pvs size as argument)
+	pvsSize = PrepareHeuristics(rays);
+
+	Debug << "here45 pvs: " << pvsSize << endl;
+
+	// go through the lists, count the number of objects left and right
+	// and evaluate the following cost funcion:
+	// C = ct_div_ci  + (ql*rl + qr*rr)/queries
+
+	int pvsl = 0;
+	int pvsr = pvsSize;
+
+	int pvsBack = pvsl;
+	int pvsFront = pvsr;
+
+	float sum = (float)pvsSize * sizeBox;
+	float minSum = 1e20f;
+
+	
+	// if no good split can be found, take mid split
+	position = minBox + 0.5f * sizeBox;
+	
+	// the relative cost ratio
+	float ratio = 99999999.0f;
+	bool splitPlaneFound = false;
+
+	Intersectable::NewMail();
+	KdLeaf::NewMail();
+
+
+	vector<SortableEntry>::const_iterator ci, ci_end = mSplitCandidates->end();
+
+	//-- traverse through visibility events
+	for (ci = mSplitCandidates->begin(); ci != ci_end; ++ ci)
+	{
+		EvalPvsIncr(*ci, pvsl, pvsr);
+
+		// Note: sufficient to compare size of bounding boxes of front and back side?
+		if (((*ci).value >= minBand) && ((*ci).value <= maxBand))
+		{
+			sum = pvsl * ((*ci).value - minBox) + pvsr * (maxBox - (*ci).value);
+
+			//Debug  << "pos=" << (*ci).value << "\t pvs=(" <<  pvsl << "," << pvsr << ")" << "\t cost= " << sum << endl;
+
+			if (sum < minSum)
+			{
+				splitPlaneFound = true;
+
+				minSum = sum;
+				position = (*ci).value;
+				
+				pvsBack = pvsl;
+				pvsFront = pvsr;
+			}
+		}
+	}
+	
+	
+	// -- compute cost
+
+	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
+	const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize();
+
+	const float pOverall = sizeBox;
+	const float pBack = position - minBox;
+	const float pFront = maxBox - position;
+
+	const float penaltyOld = EvalPvsPenalty(pvsSize, lowerPvsLimit, upperPvsLimit);
+    const float penaltyFront = EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit);
+	const float penaltyBack = EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit);
+	
+	const float oldRenderCost = penaltyOld * pOverall + Limits::Small;
+	const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack;
+
+	if (splitPlaneFound)
+	{
+		ratio = newRenderCost / oldRenderCost;
+	}
+	
+	//if (axis != 1)
+	Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox)
+	      <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl;
+
+	return ratio;
+}
+*/
+
+float OspTree::EvalLocalCostHeuristics(BspLeaf *node,
+									   const AxisAlignedBox3 &box,
+									   const int axis,
+									   float &position,
+									   int &objectsBack,
+									   int &objectsFront)
+{
+	
+	/*SortSplitCandidates(node, axis);
+  
+	// go through the lists, count the number of objects left and right
+	// and evaluate the following cost funcion:
+	// C = ct_div_ci  + (ol + or)/queries
+
+	float totalIntersections = 0.0f;
+	
+	vector<SortableEntry>::const_iterator ci, ci_end = splitCandidates.end();
+
+	for(ci = splitCandidates->begin(); ci != ci_end; ++ ci)
+	{
+		 if ((*ci).type == SortableEntry::BOX_MIN) 
+		 {
+			 totalIntersections += (*ci).intersectable->IntersectionComplexity();
+		 }
+	}
+	
+	float intersectionsLeft = 0;
+	float intersectionsRight = totalIntersections;
+
+	
+	int objectsLeft = 0, objectsRight = (int)node->mObjects.size();
+  
+	float minBox = box.Min(axis);
+	float maxBox = box.Max(axis);
+	
+	float boxArea = box.SurfaceArea();
+  
+	float minBand = minBox + mSplitBorder*(maxBox - minBox);
+	float maxBand = minBox + (1.0f - mSplitBorder)*(maxBox - minBox);
+
+    float minSum = 1e20f;
+  
+	for(ci = splitCandidates->begin(); ci != ci_end; ++ ci)
+	{
+		EvalPvsIncr(ci, pvsl, pvsr);
+
+		if ((*ci).value > minBand && (*ci).value < maxBand) 
+		{
+			AxisAlignedBox3 lbox = box;
+			AxisAlignedBox3 rbox = box;
+			
+			lbox.SetMax(axis, (*ci).value);
+			rbox.SetMin(axis, (*ci).value);
+
+			float sum;
+			
+			if (mSahUseFaces)
+				sum = intersectionsLeft*lbox.SurfaceArea() + intersectionsRight*rbox.SurfaceArea();
+			else
+				sum = objectsLeft*lbox.SurfaceArea() + objectsRight*rbox.SurfaceArea();
+      
+			//      cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl;
+			//      cout<<"cost= "<<sum<<endl;
+      
+			if (sum < minSum) 
+			{
+				minSum = sum;
+				position = (*ci).value;
+
+				objectsBack = objectsLeft;
+				objectsFront = objectsRight;
+			}
+		}
+	}
+  
+	float oldCost = mSahUseFaces ? totalIntersections : node->mObjects.size();
+	float newCost = mCt_div_ci + minSum/boxArea;
+	float ratio = newCost/oldCost;
+  
+#if 0
+	cout<<"===================="<<endl;
+	cout<<"costRatio="<<ratio<<" pos="<<position<<" t="<<(position - minBox)/(maxBox - minBox)
+		<<"\t o=("<<objectsBack<<","<<objectsFront<<")"<<endl;
+#endif
+	
+	return ratio;
+	*/
+	return 0;
+}
+
+
+void OspTree::SortSplitCandidates(const RayInfoContainer &rays,
+								  const int axis, 
+								  float minBand, 
+								  float maxBand)
+{
+	// TODO
+}
+
+
+
+int OspTree::PrepareHeuristics(Intersectable *object)
+{
+	ViewCellPvsMap::const_iterator vit, vit_end = object->mViewCellPvs.mEntries.end();
+	
+	int pvsSize = 0;
+
+	for (vit = object->mViewCellPvs.mEntries.begin(); vit != vit_end; ++ vit)
+	{
+        ViewCell *vc = (*vit).first;
+
+		if (!vc->Mailed())
+		{
+			vc->Mail();
+			vc->mCounter = 1;
+			++ pvsSize;
+		}
+		else
+		{
+			++ vc->mCounter;
+		}
+	}
+
+	return pvsSize;
+}
+
+
+int OspTree::PrepareHeuristics(const RayInfoContainer &rays)
+{	
+	Intersectable::NewMail();
+	KdNode::NewMail();
+
+	int pvsSize = 0;
+
+	RayInfoContainer::const_iterator ri, ri_end = rays.end();
+
+	//-- set all kd nodes as belonging to the front pvs
+
+	for (ri = rays.begin(); ri != ri_end; ++ ri)
+	{
+		Intersectable *oObject = (*ri).mRay->mOriginObject;
+
+		if (oObject)
+		{
+			pvsSize += PrepareHeuristics(oObject);		
+		}
+
+		Intersectable *tObject = (*ri).mRay->mTerminationObject;
+
+		if (tObject)
+		{
+			pvsSize += PrepareHeuristics(tObject);	
+		}
+	}
+
+	return pvsSize;
+}
+
+
+void OspTree::EvalPvsIncr(const SortableEntry &ci,
+						  int &pvsLeft,
+						  int &pvsRight) const
+{
+	Intersectable *obj = ci.mObject;
+
+	switch (ci.type) 
+	{
+		case SortableEntry::BOX_MIN:
+			AddContriToPvs(obj, pvsLeft);
+			break;
+			
+		case SortableEntry::BOX_MAX:
+			RemoveContriFromPvs(obj, pvsRight);
+			break;
+	}
+}
+
+
+void OspTree::RemoveContriFromPvs(Intersectable *object, int &pvs) const
+{
+	ViewCellPvsMap::const_iterator vit, vit_end = object->mViewCellPvs.mEntries.end();
+	
+	for (vit = object->mViewCellPvs.mEntries.begin(); vit != vit_end; ++ vit)
+	{
+        ViewCell *vc = (*vit).first;
+
+		if (-- vc->mCounter == 0)
+		{
+			-- pvs;
+		}
+	}
+}
+
+
+void OspTree::AddContriToPvs(Intersectable *object, int &pvs) const
+{
+	ViewCellPvsMap::const_iterator vit, vit_end = object->mViewCellPvs.mEntries.end();
+
+	for (vit = object->mViewCellPvs.mEntries.begin(); vit != vit_end; ++ vit)
+	{
+        ViewCell *vc = (*vit).first;
+
+		if (!vc->Mailed())
+		{
+			vc->Mail();		
+			++ pvs;
+		}
+	}
+}
+
 
 /*********************************************************************/
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1074)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1077)
@@ -386,6 +386,6 @@
 {
 	int numSamples = 0;
+
 	SimpleRayContainer simpleRays;
-	
 	VssRayContainer initialSamples;
 
@@ -426,5 +426,5 @@
 
 
-	if (1) // export initial view cells
+	if (0) // export initial view cells
 	{
 		const char filename[] = "view_cells.wrl";
@@ -524,5 +524,5 @@
 
 	//-- post processing (e.g.,merging) of the view cells
-	PostProcess(preprocessor->mObjects, postProcessSamples);
+	if (1) PostProcess(preprocessor->mObjects, postProcessSamples);
 
 	cout << "time needed for post processing (merge) step: "
@@ -3075,5 +3075,5 @@
 										  const ObjectContainer &objects)
 {
-#if STILL_HAS_TODO
+#if TODO
 	cout << "exporting view cells to xml ... ";
 	std::ofstream stream;
@@ -3673,7 +3673,8 @@
 	cout << "construction finished" << endl;
 
-	// real meshes are contructed at this stage
+	
 	if (0)
 	{
+		//-- real meshes are contructed at this stage
 		cout << "finalizing view cells ... ";
 		FinalizeViewCells(true);
@@ -3769,5 +3770,5 @@
 	}
 
-	if (1) // export merged view cells using pvs coding
+	if (0) // export merged view cells using pvs coding
 	{
 		mColorCode = 1;
@@ -4158,6 +4159,7 @@
 	GetRaySets(sampleRays, mVisualizationSamples, visRays);
 
-	//-- export view cells
-	if (1) 
+	//-- export final view cell partition
+
+	if (0) 
 	{	
 		// hack pvs
@@ -5227,5 +5229,6 @@
 	GetRaySets(sampleRays, mVisualizationSamples, visRays);
 
-	//-- export view cells
+	//-- export final view cells
+
 	if (1) 
 	{	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1001)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1077)
@@ -11,5 +11,6 @@
 class Ray;
 class Intersectable;
-class ViewCellKdNode;
+class ViewCell;
+
 
 template<typename T>
@@ -415,11 +416,16 @@
 };
 
+
+//-- 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<Intersectable *> ObjectPvs;
-
+typedef Pvs<ViewCell *> ViewCellPvs;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1074)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1077)
@@ -882,11 +882,4 @@
 							 float maxBand);
 
-	/** Prepares objects for SAH.
-		@returns pvs size of the ray container
-	*/
-	int PrepareHeuristics(const RayInfoContainer &rays);
-
-	int PrepareHeuristics(Intersectable *object);
-
 	/** Computes pvs increase with respect to the previous pvs for SAH.
 	*/
@@ -916,4 +909,11 @@
 	void RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const;
 	void AddContriToPvs(KdLeaf *leaf, int &pvs) const;
+
+	/** Prepares objects for SAH.
+		@returns pvs size of the ray container
+	*/
+	int PrepareHeuristics(const RayInfoContainer &rays);
+
+	int PrepareHeuristics(Intersectable *object);
 
 	/** Subdivides the rays into front and back rays according to the split plane.
@@ -1333,28 +1333,29 @@
 	// For sorting objects
 	// --------------------------------------------------------------
-	struct SortableEntry
+	struct  SortableEntry
 	{
-		enum EType 
+		enum
 		{
-			ERayMin,
-			ERayMax
+			BOX_MIN,
+			BOX_MAX
 		};
 
 		int type;
 		float value;
-		VssRay *ray;
-  
+		Intersectable *mObject;
+
 		SortableEntry() {}
-		SortableEntry(const int t, const float v, VssRay *r):type(t),
-					  value(v), ray(r) 
+
+		SortableEntry(const int t, const float v, Intersectable *obj):
+		type(t), value(v), mObject(obj) 
+		{}
+
+		bool operator<(const SortableEntry &b) const 
 		{
-		}
-		
-		friend bool operator<(const SortableEntry &a, const SortableEntry &b) 
-		{
-			return a.value < b.value;
+			return value < b.value;
 		}
 	};
 
+ 
 	/** faster evaluation of split plane cost for kd axis aligned cells.
 	*/
@@ -1449,9 +1450,16 @@
 	/** Computes best cost for axis aligned planes.
 	*/
-	float EvalLocalCostHeuristics(const RayInfoContainer &rays,
+/*	float EvalLocalCostHeuristics(const RayInfoContainer &rays,
 								  const AxisAlignedBox3 &box,
 								  const int pvsSize,
 								  const int axis,
 								  float &position);
+*/
+	float EvalLocalCostHeuristics(BspLeaf *node,
+		const AxisAlignedBox3 &box,
+		const int axis,
+		float &position,
+		int &objectsBack,
+		int &objectsFront);
 
 	/** Subdivides the rays into front and back rays according to the split plane.
@@ -1523,4 +1531,22 @@
 	float GetMemUsage() const;
 
+	/** Evaluates the influence on the pvs of the visibility event ve.
+		@param ve the visibility event
+		@param pvsLeft updates the left pvs
+		@param rightPvs updates the right pvs
+	*/
+	void EvalPvsIncr(const SortableEntry &ve,
+					  int &pvsLeft,
+					  int &pvsRight) const;
+
+	void RemoveContriFromPvs(Intersectable *object, int &pvs) const;
+	void AddContriToPvs(Intersectable *object, int &pvs) const;
+
+	/** Prepares objects for SAH.
+		@returns pvs size of the ray container
+	*/
+	int PrepareHeuristics(const RayInfoContainer &rays);
+
+	int PrepareHeuristics(Intersectable *object);
 
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1074)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1077)
@@ -28,4 +28,6 @@
   KdPvs mKdPvs;
   
+  ViewCellPvs mViewCellPvs;
+
   /// kd leaves that this intersectable belongs to
   set<KdLeaf *> mKdLeaves;
