Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 697)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 710)
@@ -535,5 +535,8 @@
 		@param splitCandidates returns sorted list of split candidates
 	*/
-	void SortSplitCandidates(const RayInfoContainer &rays, const int axis);
+	void SortSplitCandidates(const RayInfoContainer &rays, 
+							 const int axis, 
+							 float minBand, 
+							 float maxBand);
 
 	/** Computes best cost for axis aligned planes.
@@ -542,5 +545,5 @@
 								  const AxisAlignedBox3 &box,
 								  const int pvsSize,
-								  const int &axis,
+								  const int axis,
 								  float &position);
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 708)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 710)
@@ -560,5 +560,5 @@
 		mMergeQueue.pop();
 	
-		// both view cells equal
+		// both view cells equal because of previous merges
 		// NOTE: do I really still need this? probably cannot happen!!
 		if (mc.mLeftViewCell == mc.mRightViewCell)
@@ -579,11 +579,11 @@
 			totalRenderCost += renderCostIncr;
 			mDeviation += mc.GetDeviationIncr();
-			
-			
-			// merge the view cells of leaf1 and leaf2
+
+						
+			//-- merge the view cells of leaf1 and leaf2
 			int pvsDiff;
 			ViewCellInterior *mergedVc = 
 				MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff);
-
+			
 
 			// total render cost and deviation has changed
@@ -641,4 +641,10 @@
 		
 		ViewCellInterior *root = mViewCellsManager->MergeViewCells(activeViewCells);
+	
+		ViewCellContainer::const_iterator it, it_end = root->mChildren.end();
+
+		for (it = root->mChildren.begin(); it != it_end; ++ it)
+			(*it)->SetParent(root);
+	
 		root->SetMergeCost(totalRenderCost);
 		// $$JB keep this 0 temporarilly
@@ -647,8 +653,10 @@
 		mRoot = root;
 	}
-	else if ((int)activeViewCells.size() == 1)
+	// normal case
+	else if (!activeViewCells.empty())
 	{
 		Debug << "setting root of the merge history" << endl;
 		mRoot = activeViewCells[0];
+		Debug << "rootvc volume: " << mRoot->GetVolume() << endl;
 	}
 	
@@ -742,12 +750,16 @@
 
 		// all merged view cells have been found
-		if (i >= viewCells.size()) 
+		if (i >= (int)viewCells.size()) 
 			break;
 
-		// already merged view cell, put it to end of vector
+		// already merged this view cell, put it to end of vector
 		if (viewCells[i]->GetParent())
 			swap(viewCells[i], viewCells.back());
 		
-		viewCells[i ++]->Mail();
+		// mail view cell as it has not been merged
+		viewCells[i]->Mail();
+
+		// increase loop counter
+		++ i;
 	}
 
@@ -847,11 +859,18 @@
 	if (!vc) return NULL;
 
+	l->SetParent(vc);
+	r->SetParent(vc);
+
 	// set new size of view cell
 	if (mUseAreaForPvs)
+	{
 		vc->SetArea(l->GetArea() + l->GetArea());
+	}
 	else
 	{
 		vc->SetVolume(r->GetVolume() + l->GetVolume());
 	}
+
+	
 	// important so other merge candidates sharing this view cell
 	// are notified that the merge cost must be updated!!
@@ -957,6 +976,4 @@
 	return shuffledViewCells;
 }
-
-
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 697)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 710)
@@ -30,8 +30,17 @@
 	{};  
 
-	// copy constructor copying the polygon array
+	/** copy constructor copying the polygon array.
+		The polygons are deeply copied.
+	*/
 	BspNodeGeometry(const BspNodeGeometry &rhs);
-
-	//BspNodeGeometry(const PolygonContainer &polys);
+	/** This operator uses a deep copy to copy the polygons.
+	*/
+	BspNodeGeometry& operator=(const BspNodeGeometry& p);
+
+	/** Builds node geometry using this polygons. 
+		@NOTE The polygons are NOT duplicated, only
+		a shallow copy is used.
+	*/	
+    BspNodeGeometry(const PolygonContainer &polys);
 
 	~BspNodeGeometry();
@@ -67,5 +76,5 @@
 		-1 if geometry in back of plane
 	*/
-	int Side(const Plane3 &plane) const;
+	int Side(const Plane3 &plane, const float eps = 0.0f) const;
 
 	/** Splits the polygon and returns the part of the polygon inside of the node geometry.
@@ -97,4 +106,6 @@
 	const PolygonContainer &GetPolys();
 
+    /** Adds polygon and plane equation to this geometry.
+	*/
 	void Add(Polygon3 *p, const Plane3 &plane);
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 706)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 710)
@@ -348,5 +348,6 @@
 							 int maxPvsSize) const;
 
-  /** sets validy of all viewcells */
+	/** sets validy of all viewcells 
+	*/
   	virtual void SetValidity(
 							 int minPvsSize, 
@@ -355,8 +356,7 @@
 
 	/** set valid viewcells in the range of pvs. sorts the viewcells
-	  according to the pvs and then pickups those in the ranges */
-
-    
-	void SetValidityPercentage(const float minValid,	const float maxValid);
+	  according to the pvs and then pickups those in the ranges 
+	  */
+	void SetValidityPercentage(const float minValid, const float maxValid);
 
     int CountValidViewcells() const;
@@ -413,5 +413,5 @@
 	/** Returns true if this (logical) view cell is equal to a spatial node.
 	*/
-	virtual bool EqualToSpatialNode(ViewCell *viewCell) const { return false;}
+	virtual bool EqualToSpatialNode(ViewCell *viewCell) const;
 
 	/** Sets current view cells set to active, i.e., the sampling is done in this view cell set.
@@ -433,5 +433,6 @@
 		@returns number of view cells found
 	*/
-	virtual int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const {return 0;};
+	virtual int ComputeBoxIntersections(const AxisAlignedBox3 &box, 
+										ViewCellContainer &viewCells) const;
 
 	virtual void TestFilter(const ObjectContainer &objects) {};
@@ -511,5 +512,5 @@
 	ViewCellsTree *mViewCellsTree;
 
-	//bool mSampleEmptyViewCells;
+	bool mPruneEmptyViewCells;
 
 	/// maximum number of samples taken for construction of the view cells
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 708)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 710)
@@ -464,5 +464,5 @@
 
 	// first node is kd node, i.e. an axis aligned box
-	if (0)
+	if (1)
         tData.mIsKdNode = true;
 	else
@@ -731,5 +731,5 @@
 				++ mBspStats.polySplits;
 
-			tFrontData.mIsKdNode = tBackData.mIsKdNode = (tData.mIsKdNode && splitAxis < 3);
+			tFrontData.mIsKdNode = tBackData.mIsKdNode = (tData.mIsKdNode && (splitAxis < 3));
 
 			// how often was max cost ratio missed in this branch?
@@ -852,5 +852,5 @@
 			++ mBspStats.polySplits;
 
-		tFrontData.mIsKdNode = tBackData.mIsKdNode = (tData.mIsKdNode && splitAxis < 3);
+		tFrontData.mIsKdNode = tBackData.mIsKdNode = (tData.mIsKdNode && (splitAxis < 3));
 		
 		// how often was max cost ratio missed in this branch?
@@ -901,7 +901,7 @@
 		BspLeaf *leaf = dynamic_cast<BspLeaf *>(newNode);
 		BspViewCell *viewCell = new BspViewCell();
-		
-		leaf->SetViewCell(viewCell);
-	
+
+        leaf->SetViewCell(viewCell);
+		
 		//-- update pvs
 		int conSamp = 0;
@@ -1132,5 +1132,8 @@
 
 
-void VspBspTree::SortSplitCandidates(const RayInfoContainer &rays, const int axis)
+void VspBspTree::SortSplitCandidates(const RayInfoContainer &rays, 
+									 const int axis, 
+									 float minBand, 
+									 float maxBand)
 {
 	mSplitCandidates->clear();
@@ -1147,13 +1150,31 @@
 	mSplitCandidates->reserve(requestedSize);
 
+	float pos;
+
+	// float values => don't compare with exact values
+	if (0)
+	{
+		minBand += Limits::Small;
+		maxBand -= Limits::Small;
+	}
+
 	// insert all queries
 	for (RayInfoContainer::const_iterator ri = rays.begin(); ri < rays.end(); ++ ri)
 	{
 		const bool positive = (*ri).mRay->HasPosDir(axis);
-		mSplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMin : SortableEntry::ERayMax,
-												  (*ri).ExtrapOrigin(axis), (*ri).mRay));
-
-		mSplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMax : SortableEntry::ERayMin,
-												  (*ri).ExtrapTermination(axis), (*ri).mRay));
+				
+		pos = (*ri).ExtrapOrigin(axis);
+		// clamp to min / max band
+		if (0) ClipValue(pos, minBand, maxBand);
+		
+		mSplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMin : SortableEntry::ERayMax, 
+			pos, (*ri).mRay));
+
+		pos = (*ri).ExtrapTermination(axis);
+		// clamp to min / max band
+		if (0) ClipValue(pos, minBand, maxBand);
+
+		mSplitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMax : SortableEntry::ERayMin, 
+			pos, (*ri).mRay));
 	}
 
@@ -1165,8 +1186,15 @@
 										  const AxisAlignedBox3 &box,
 										  const int pvsSize,
-										  const int &axis,
+										  const int axis,
                                           float &position)
 {
-	SortSplitCandidates(rays, axis);
+	const float minBox = box.Min(axis);
+	const float maxBox = box.Max(axis);
+	const float sizeBox = maxBox - minBox;
+
+	const float minBand = minBox + 0.1f * sizeBox;
+	const float maxBand = minBox + 0.9f * sizeBox;
+
+	SortSplitCandidates(rays, axis, minBand, maxBand);
 
 	// go through the lists, count the number of objects left and right
@@ -1179,13 +1207,9 @@
 	int pvsFront = pvsr;
 
-	float minBox = box.Min(axis);
-	float maxBox = box.Max(axis);
-	float sizeBox = maxBox - minBox;
-
-	float minBand = minBox + 0.1f * (maxBox - minBox);
-	float maxBand = minBox + 0.9f * (maxBox - minBox);
-
 	float sum = (float)pvsSize * sizeBox;
 	float minSum = 1e20f;
+
+	// if no border can be found, take mid split
+	position = minBox + 0.5f * sizeBox;
 
 	Intersectable::NewMail();
@@ -1273,5 +1297,5 @@
 
 		// Note: sufficient to compare size of bounding boxes of front and back side?
-		if ((*ci).value > minBand && (*ci).value < maxBand)
+		if (((*ci).value >= minBand) && ((*ci).value <= maxBand))
 		{
 			sum = pvsl * ((*ci).value - minBox) + pvsr * (maxBox - (*ci).value);
@@ -1284,5 +1308,5 @@
 				minSum = sum;
 				position = (*ci).value;
-
+				
 				pvsBack = pvsl;
 				pvsFront = pvsr;
@@ -1290,7 +1314,8 @@
 		}
 	}
+	
+	//Debug << "pos: " << position << " sizebox: " << sizeBox << " pvs: " << pvsSize << endl;
 
 	// -- compute cost
-
 	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
 	const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize();
@@ -1324,5 +1349,5 @@
 										 float &pFront,
 										 float &pBack,
-										 const bool useKdSplit)
+										 const bool isKdNode)
 {
 	float nPosition[3];
@@ -1344,16 +1369,13 @@
 	// create bounding box of node geometry
 	AxisAlignedBox3 box;
-	box.Initialize();
-	
+		
 	//TODO: for kd split geometry already is box => only take minmax vertices
 	if (1)
 	{
-		PolygonContainer::const_iterator it, it_end = tData.mGeometry->GetPolys().end();
-
-		for(it = tData.mGeometry->GetPolys().begin(); it < it_end; ++ it)
-			box.Include(*(*it));
+		tData.mGeometry->GetBoundingBox(box);
 	}
 	else
 	{
+		box.Initialize();
 		RayInfoContainer::const_iterator ri, ri_end = tData.mRays->end();
 
@@ -1383,12 +1405,9 @@
 			if (!mUseCostHeuristics)
 			{
-				nFrontGeom[axis] = new BspNodeGeometry();
-				nBackGeom[axis] = new BspNodeGeometry();
-
 				nPosition[axis] = (box.Min()[axis] + box.Max()[axis]) * 0.5f;
 				Vector3 normal(0,0,0); normal[axis] = 1.0f;
 
 				// allows faster split because we have axis aligned kd tree boxes
-				if (0 && useKdSplit)
+				if (0 && isKdNode)
 				{
 					nCostRatio[axis] = EvalAxisAlignedSplitCost(tData,
@@ -1401,19 +1420,25 @@
 					Vector3 pos;
 					
+					// create back geometry from box
 					pos = box.Max(); pos[axis] = nPosition[axis];
 					AxisAlignedBox3 bBox(box.Min(), pos);
-					// TODO
-#if 0
-						bBox.ExtractPolys(nBackGeom[axis]->GetPolys());
-#endif					
+					PolygonContainer fPolys;
+					bBox.ExtractPolys(fPolys);
+
+					nBackGeom[axis] = new BspNodeGeometry(fPolys);
+	
+					// create front geometry from box
 					pos = box.Min(); pos[axis] = nPosition[axis];
 					AxisAlignedBox3 fBox(pos, box.Max());
-					// TODO
-#if 0
-						fBox.ExtractPolys(nFrontGeom[axis]->GetPolys());
-#endif
+
+					PolygonContainer bPolys;
+					fBox.ExtractPolys(bPolys);
+					nFrontGeom[axis] = new BspNodeGeometry(bPolys);
 				}
 				else
 				{
+					nFrontGeom[axis] = new BspNodeGeometry();
+					nBackGeom[axis] = new BspNodeGeometry();
+
 					nCostRatio[axis] = 
 						EvalSplitPlaneCost(Plane3(normal, nPosition[axis]), 
@@ -1978,5 +2003,5 @@
 
 	const int pvsSize = data.mPvs;
-
+//cout << "here433" << endl;
 	RayInfoContainer::const_iterator rit, rit_end = data.mRays->end();
 
@@ -2832,5 +2857,6 @@
 
 
-int VspBspTree::FindApproximateNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
+int VspBspTree::FindApproximateNeighbors(BspNode *n, 
+										 vector<BspLeaf *> &neighbors,
 										 const bool onlyUnmailed) const
 {
@@ -2900,5 +2926,5 @@
 				nodeStack.push(bspNodePair(interior->GetBack(), bGeom));
 				DEL_PTR(fGeom);
-			}
+				}
 			else
 			{
@@ -3442,8 +3468,11 @@
 		
 		vector<BspLeaf *> neighbors;
+		
+		// appoximate neighbor search has slightl relaxed constraints
 		if (1)
 			FindNeighbors(leaf, neighbors, true);
 		else
 			FindApproximateNeighbors(leaf, neighbors, true);
+
 		vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end();
 
@@ -3458,5 +3487,6 @@
 				// in the tree?
 				if (mEmptyViewCellsMergeAllowed ||
-					!leaf->GetViewCell()->GetPvs().Empty() || !(*nit)->GetViewCell()->GetPvs().Empty() ||
+					!leaf->GetViewCell()->GetPvs().Empty() || 
+					!(*nit)->GetViewCell()->GetPvs().Empty() ||
                     leaf->IsSibling(*nit))
 				{
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 704)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 710)
@@ -159,4 +159,5 @@
     mFront = f;
 }
+
 
 /****************************************************************/
@@ -588,12 +589,13 @@
 }
 
+
 int BspTree::AddMeshToPolygons(Mesh *mesh, 
 							   PolygonContainer &polys, 
 							   MeshInstance *parent)
 {
-	FaceContainer::const_iterator fi;
+	FaceContainer::const_iterator fi, fi_end = mesh->mFaces.end();
 	
 	// copy the face data to polygons
-	for (fi = mesh->mFaces.begin(); fi != mesh->mFaces.end(); ++ fi)
+	for (fi = mesh->mFaces.begin(); fi != fi_end; ++ fi)
 	{
 		Polygon3 *poly = new Polygon3((*fi), mesh);
@@ -2839,13 +2841,54 @@
 {
 	mPolys.reserve(rhs.mPolys.size());
-	
+	mPlanes.reserve(rhs.mPolys.size());
+
+
 	PolygonContainer::const_iterator it, it_end = rhs.mPolys.end();
 
 	int i = 0;
 
-	for (it = rhs.mPolys.begin(); it != it_end; ++ it)
+	for (it = rhs.mPolys.begin(); it != it_end; ++ it, ++i)
 	{
 		Polygon3 *poly = *it;
-		Add(new Polygon3(*poly), rhs.mPlanes[i ++]);
+		Add(new Polygon3(*poly), rhs.mPlanes[i]);
+	}
+}
+
+
+BspNodeGeometry& BspNodeGeometry::operator=(const BspNodeGeometry& g) 
+{
+    if (this == &g) 
+		return *this;
+ 
+	CLEAR_CONTAINER(mPolys);
+
+	mPolys.reserve(g.mPolys.size());
+	mPlanes.reserve(g.mPolys.size());
+
+	PolygonContainer::const_iterator it, it_end = g.mPolys.end();
+
+	int i = 0;
+
+	for (it = g.mPolys.begin(); it != it_end; ++ it, ++ i)
+	{
+		Polygon3 *poly = *it;
+		Add(new Polygon3(*poly), g.mPlanes[i]);
+	}
+
+	return *this;
+}
+
+
+BspNodeGeometry::BspNodeGeometry(const PolygonContainer &polys)
+{
+	mPolys = polys;
+	mPlanes.reserve(polys.size());
+	
+	PolygonContainer::const_iterator it, it_end = polys.end();
+
+	for (it = polys.begin(); it != it_end; ++ it)
+	{
+		Polygon3 *poly = *it;
+		mPlanes.push_back(poly->GetSupportingPlane());
 	}
 }
@@ -2922,5 +2965,5 @@
 
 
-int BspNodeGeometry::Side(const Plane3 &plane) const
+int BspNodeGeometry::Side(const Plane3 &plane, const float eps) const
 {
 	PolygonContainer::const_iterator it, it_end = mPolys.end();
@@ -2931,5 +2974,5 @@
 	for (it = mPolys.begin(); it != it_end; ++ it)
 	{
-        const int side = (*it)->Side(plane, 0.0f);
+        const int side = (*it)->Side(plane, eps);
 
 		if (side == -1)
@@ -3042,7 +3085,23 @@
 									const float epsilon) const
 {	
+#if 0
+	// trivial cases
+	const int cf = Side(splitPlane, epsilon);
+
+	if (cf == -1)
+	{
+		back = *this;
+		return false;
+	}
+	else if (cf == 1)
+	{
+		front = *this;
+		return false;
+	}
+#endif
+
 	// get cross section of new polygon
 	Polygon3 *planePoly = box.CrossSection(splitPlane);
-	//Vector3 ndummy = planePoly->GetSupportingPlane().mNormal;
+	
 	// split polygon with all other polygons
 	planePoly = SplitPolygon(planePoly, epsilon);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 708)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 710)
@@ -16,5 +16,5 @@
 #include "RssPreprocessor.h"
 
-#define SAMPLE_AFTER_SUBDIVISION 1
+#define SAMPLE_AFTER_SUBDIVISION 0
 #define TEST_EMPTY_VIEW_CELLS 0
 
@@ -62,7 +62,11 @@
 	environment->GetFloatValue("ViewCells.maxPvsRatio", mMaxPvsRatio);
 	
-	bool emptyViewCells = false;
-	environment->GetBoolValue("ViewCells.pruneEmptyViewCells", emptyViewCells);
-	mMinPvsSize = emptyViewCells ? 1 : 0;
+	environment->GetBoolValue("ViewCells.pruneEmptyViewCells", mPruneEmptyViewCells);
+
+	// HACK
+	if (0)
+		mMinPvsSize = mPruneEmptyViewCells ? 1 : 0;
+	else
+		mMinPvsSize = 0;
 
 	environment->GetBoolValue("ViewCells.processOnlyValidViewCells", mOnlyValidViewCells);
@@ -85,5 +89,5 @@
 	environment->GetIntValue("ViewCells.Filter.maxSize", mMaxFilterSize);
 	environment->GetFloatValue("ViewCells.Filter.width", mFilterWidth);
-//mSampleEmptyViewCells = true;
+
 	char buf[100];
 	environment->GetStringValue("ViewCells.samplingType", buf);
@@ -112,4 +116,5 @@
 
 
+
 	Debug << "***********View Cells options ****************" << endl;
 	Debug << "color code: " << mColorCode << endl;
@@ -119,5 +124,5 @@
 	Debug << "max pvs ratio: " << mMaxPvsRatio << endl;
 	
-	Debug << "prune empty view cells: " << emptyViewCells << endl;
+	Debug << "prune empty view cells: " << mPruneEmptyViewCells << endl;
 	
 	Debug << "process only valid view cells: " << mOnlyValidViewCells << endl;
@@ -137,5 +142,5 @@
 	Debug << "show visualization: " << mShowVisualization << endl;
 	Debug << "filter width: " << mFilterWidth << endl;
-
+	Debug << "sample after subdivision: " << SAMPLE_AFTER_SUBDIVISION << endl;
 	Debug << endl;
 }
@@ -427,5 +432,5 @@
 
 	// needed to fix empty view cells
-    SetValidity(0, 99999999999);
+    //SetValidity(0, 99999999999);
 
 	if (mEvaluateViewCells)
@@ -618,13 +623,24 @@
 {
 
-  if ((vc->GetPvs().GetSize() > maxPvsSize) ||
-	  (vc->GetPvs().GetSize() < minPvsSize))
-	{
-	  return false;
-	}
-
-  return true;
-}
-
+	if ((vc->GetPvs().GetSize() > maxPvsSize) ||
+		(vc->GetPvs().GetSize() < minPvsSize))
+	{
+		return false;
+	}
+
+	return true;
+}
+
+
+bool ViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const 
+{ 
+	return false;
+}
+
+int ViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box, 
+											  ViewCellContainer &viewCells) const
+{
+	return 0;
+};
 
 AxisAlignedBox3 ViewCellsManager::GetFilterBBox(const Vector3 &viewPoint, 
@@ -944,7 +960,6 @@
 	// generate parent view cell
 	ViewCellInterior *vc = new ViewCellInterior();//GenerateViewCell();
-	
+
 	vc->GetPvs() = left->GetPvs();
-
 	// merge pvs
 	vc->GetPvs().Merge(right->GetPvs());
@@ -961,7 +976,8 @@
 	}
 
-	vc->SetupChildLink(left);
-	vc->SetupChildLink(right);
-	
+	// set only links to child (not from child to parent, maybe not wished!!)
+	vc->mChildren.push_back(left);
+	vc->mChildren.push_back(right);
+
 	return vc;
 }
@@ -978,6 +994,6 @@
 		// merge pvs
 		vc->GetPvs().Merge((*it)->GetPvs());
-
-		vc->SetupChildLink(*it);
+		vc->mChildren.push_back(*it);
+		//vc->SetupChildLink(*it);
 	}
 
@@ -2902,4 +2918,6 @@
 												 const VssRayContainer &rays)
 {
+	mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size());
+
 	// if view cells were already constructed
 	if (ViewCellsConstructed())
@@ -2923,5 +2941,4 @@
 	Debug << "saved rays: " << (int)savedRays.size() << endl;
 
-	mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size());
 
 	//TODO: remove
@@ -2968,10 +2985,8 @@
 											const ObjectContainer &objects)
 {
-	//-- post processing of bsp view cells
     int vcSize = 0;
 	int pvsSize = 0;
 
 	//-- merge view cells
-	
 	cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl;
 	long startTime = GetTime();
@@ -2981,9 +2996,12 @@
 	{
 		// TODO: should be done BEFORE the ray casting
+		// compute tree by merging the nodes based on cost heuristics
 		mViewCellsTree->ConstructMergeTree(rays, objects);
 	}
 	else
 	{
-		mViewCellsTree->SetRoot(ConstructSpatialMergeTree(mVspBspTree->GetRoot()));
+		// compute tree by merging the nodes of the spatial hierarchy
+		ViewCell *root = ConstructSpatialMergeTree(mVspBspTree->GetRoot());
+		mViewCellsTree->SetRoot(root);
 	}
 
@@ -3162,9 +3180,22 @@
 	}
 
-
 	// check if new view cells turned invalid
-	Debug << "setting validity, min: " << mMinPvsSize << " max: " << mMaxPvsSize << endl;
-	cout << "setting validity, min: " << mMinPvsSize << " max: " << mMaxPvsSize << endl;
-	SetValidity(mMinPvsSize, mMaxPvsSize); 
+	int minPvs, maxPvs;
+
+	if (0)
+	{
+		minPvs = mMinPvsSize;
+		maxPvs = mMaxPvsSize;
+	}
+	else
+	{
+		minPvs = mPruneEmptyViewCells ? 1 : 0;
+		maxPvs = mMaxPvsSize;
+	}
+	Debug << "setting validity, min: " << minPvs << " max: " << maxPvs << endl;
+	cout << "setting validity, min: " << minPvs << " max: " << maxPvs << endl;
+	
+	SetValidity(minPvs, maxPvs); 
+
 	// update valid view space according to valid view cells
 	if (0)
@@ -3190,5 +3221,4 @@
 	MergeViewCells(postProcessRays, objects);
 	
-
 	// only for testing
 	TestSubdivision();
@@ -3749,11 +3779,12 @@
 			mVspBspTree->ConstructGeometry(leaf, geom);
 
-			const int cf = Polygon3::ClassifyPlane(geom.GetPolys(), *clipPlane, 0.00000001f);
-
-			if (cf == Polygon3::BACK_SIDE)
+			const float eps = 0.00000001f;
+			const int cf = geom.Side(*clipPlane, eps);
+
+			if (cf == -1)
 			{
 				exporter->ExportPolygons(geom.GetPolys());
 			}
-			else if (cf == Polygon3::SPLIT)
+			else if (cf == 0)
 			{
 				geom.SplitGeometry(front,
@@ -3761,5 +3792,5 @@
 								   *clipPlane,
 								   mViewSpaceBox, 
-								   0.00000001f);
+								   eps);
 	
 				//Debug << "geo size: " << geom.Size() << endl;
