Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 710)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 719)
@@ -1566,4 +1566,8 @@
 	if (!mIsCompressed)
 		return vc->GetPvs().GetSize();
+
+
+	////////////////////////777
+	//-- compressed pvs
 
 	int pvsSize = 0;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 713)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 719)
@@ -267,4 +267,8 @@
 	virtual void PrintPvsStatistics(ostream &s);
 
+	/** Updates pvs of the view cell hierarchy if necessary.
+	*/
+	void UpdatePvs();
+
 	/** Returns probability that view point lies in one view cell.
 	*/
@@ -529,4 +533,5 @@
 	bool mPruneEmptyViewCells;
 
+	bool mViewCellPvsIsUpdated;
 	/// maximum number of samples taken for construction of the view cells
 	int mConstructionSamples;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 711)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 719)
@@ -2641,13 +2641,15 @@
 	vector<Plane3> candidatePlanes;
 
+	vector<Plane3>::const_iterator pit, pit_end = halfSpaces.end();
+
 	// bounded planes are added to the polygons
-	for (int i = 0; i < (int)halfSpaces.size(); ++ i)
-	{
-		Polygon3 *p = GetBoundingBox().CrossSection(halfSpaces[i]);
+	for (pit = halfSpaces.begin(); pit != pit_end; ++ pit)
+	{
+		Polygon3 *p = GetBoundingBox().CrossSection(*pit);
 
 		if (p->Valid(mEpsilon))
 		{
 			candidatePolys.push_back(p);
-			candidatePlanes.push_back(halfSpaces[i]);
+			candidatePlanes.push_back(*pit);
 		}
 	}
@@ -3137,5 +3139,5 @@
 {
 	int hits = 0;
-	stack<BspRayTraversalData> tQueue;
+	stack<BspRayTraversalData> tStack;
 
 	float mint = 0.0f, maxt = 1.0f;
@@ -3195,5 +3197,5 @@
 
 			// push data for far child
-			tQueue.push(BspRayTraversalData(farChild, extp));
+			tStack.push(BspRayTraversalData(farChild, extp));
 
 			// find intersection of ray segment with plane
@@ -3219,15 +3221,15 @@
 
 			//-- fetch the next far child from the stack
-			if (tQueue.empty())
+			if (tStack.empty())
 				break;
 
 			entp = extp;
 			
-			BspRayTraversalData &s = tQueue.top();
+			const BspRayTraversalData &s = tStack.top();
 
 			node = s.mNode;
 			extp = s.mExitPoint;
 
-			tQueue.pop();
+			tStack.pop();
 		}
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 711)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 719)
@@ -44,7 +44,7 @@
 
 
-/****************************************************************/
-/*                  class BspNode implementation                */
-/****************************************************************/
+/******************************************************************/
+/*                  class BspNode implementation                  */
+/******************************************************************/
 
 
@@ -2086,5 +2086,5 @@
 	stack<BspRayTraversalData> tStack;
 
-	float mint = 0.0f, maxt = 1.0f;
+		float mint = 0.0f, maxt = 1.0f;
 
 	Intersectable::NewMail();
@@ -2097,4 +2097,5 @@
 	BspNode *farChild = NULL;
 
+
 	const float thresh = 1 ? 1e-6f : 0.0f;
 
@@ -2104,5 +2105,5 @@
 		{
 			BspInterior *in = dynamic_cast<BspInterior *>(node);
-		
+
 			Plane3 splitPlane = in->GetPlane();
 			
@@ -2113,32 +2114,31 @@
 			{
 				node = in->GetBack();
-		
-				if(extSide <= 0) // plane does not split ray => no far child
+				
+				// plane does not split ray => no far child
+				if (extSide <= 0) 
 					continue;
-		
+  
 				farChild = in->GetFront(); // plane splits ray
-		
 			} 
-			else if (entSide > 0) 
+			else if (entSide > 0)
 			{
 				node = in->GetFront();
-			
+
 				if (extSide >= 0) // plane does not split ray => no far child
 					continue;
-			
-				farChild = in->GetBack(); // plane splits ray			
+
+				farChild = in->GetBack(); // plane splits ray
 			}
-			else // ray and plane are coincident
-			{
-				// NOTE: what to do if ray is coincident with plane?
+			else // one of the ray end points is on the plane
+			{	// NOTE: what to do if ray is coincident with plane?
 				if (extSide < 0)
 					node = in->GetBack();
 				else //if (extSide > 0)
 					node = in->GetFront();
-				//else break;
+				//else break; // coincident => count no intersections
 
 				continue; // no far child
 			}
-		
+
 			// push data for far child
 			tStack.push(BspRayTraversalData(farChild, extp, maxt));
@@ -2177,4 +2177,5 @@
 		}
 	}
+
 	return hits;
 }
@@ -2319,5 +2320,5 @@
 		// split plane of node itself
 		n = n->GetParent();
-		
+
 		if (n)
 		{
@@ -2361,13 +2362,15 @@
 	vector<Plane3> candidatePlanes;
 
+	vector<Plane3>::const_iterator pit, pit_end = halfSpaces.end();
+
 	// bounded planes are added to the polygons
-	for (int i = 0; i < (int)halfSpaces.size(); ++ i)
-	{
-		Polygon3 *p = GetBoundingBox().CrossSection(halfSpaces[i]);
+	for (pit = halfSpaces.begin(); pit != pit_end; ++ pit)
+	{
+		Polygon3 *p = GetBoundingBox().CrossSection(*pit);
 
 		if (p->Valid(mEpsilon))
 		{
 			candidatePolys.push_back(p);
-			candidatePlanes.push_back(halfSpaces[i]);
+			candidatePlanes.push_back(*pit);
 		}
 	}
@@ -2415,10 +2418,11 @@
 					DEL_PTR(candidatePolys[i]);
 
-					if (frontPoly->Valid(mEpsilon))
-						candidatePolys[i] = frontPoly;
+					if (backPoly->Valid(mEpsilon))
+						candidatePolys[i] = backPoly;
 					else
-						DEL_PTR(frontPoly);
-
-					DEL_PTR(backPoly);
+						DEL_PTR(backPoly);
+
+					// outside, don't need this
+					DEL_PTR(frontPoly);
 					break;
 				// polygon outside of halfspace
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 718)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 719)
@@ -47,5 +47,6 @@
 mMaxPvsSize(9999999),
 mMinPvsSize(0), // one means only empty view cells are invalid
-mMaxPvsRatio(1.0)
+mMaxPvsRatio(1.0),
+mViewCellPvsIsUpdated(false)
 {
 	mViewSpaceBox.Initialize();
@@ -558,5 +559,7 @@
 	// find empty view cells bug
 	if (TEST_EMPTY_VIEW_CELLS)
+	{
 		TestEmptyViewCells(preprocessor->mObjects);
+	}
 }
 
@@ -1131,24 +1134,52 @@
 
 
+void ViewCellsManager::UpdatePvs()
+{
+	if (mViewCellPvsIsUpdated)
+		return;
+
+	mViewCellPvsIsUpdated = true;
+
+	ViewCellContainer leaves;
+	mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
+
+	ViewCellContainer::const_iterator it, it_end = leaves.end();
+
+	for (it = leaves.begin(); it != it_end; ++ it)
+	{
+		mViewCellsTree->PropagatePvs(*it);
+	}
+}
+
+
 void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
 {
-  ViewCellContainer::const_iterator it = mViewCells.begin();
-  stat.viewcells = 0;
-  stat.minPvs = 100000000;
-  stat.maxPvs = 0;
-  stat.avgPvs = 0.0f;
-
-  for (; it != mViewCells.end(); ++it) {
-	ViewCell *viewcell = *it;
-	int pvsSize = viewcell->GetPvs().GetSize();
-	if ( pvsSize < stat.minPvs)
-	  stat.minPvs = pvsSize;
-	if (pvsSize > stat.maxPvs)
-	  stat.maxPvs = pvsSize;
-	stat.avgPvs += pvsSize;
-	stat.viewcells++;
-  }
-  if (stat.viewcells)
-	stat.avgPvs/=stat.viewcells;
+	// update pvs of view cells tree if necessary
+	UpdatePvs();
+
+	ViewCellContainer::const_iterator it = mViewCells.begin();
+
+	stat.viewcells = 0;
+	stat.minPvs = 100000000;
+	stat.maxPvs = 0;
+	stat.avgPvs = 0.0f;
+
+	for (; it != mViewCells.end(); ++ it) 
+	{
+		ViewCell *viewcell = *it;
+		
+		const int pvsSize = mViewCellsTree->GetPvsSize(viewcell);
+		
+		if (pvsSize < stat.minPvs)
+			stat.minPvs = pvsSize;
+		if (pvsSize > stat.maxPvs)
+			stat.maxPvs = pvsSize;
+		stat.avgPvs += pvsSize;
+		
+		++ stat.viewcells;
+	}
+
+	if (stat.viewcells)
+		stat.avgPvs/=stat.viewcells;
 }
 
@@ -1571,4 +1602,12 @@
 		ComputeSampleContributions(savedRays, true, false);
 
+	// real meshes are contructed at this stage
+	if (0)
+	{
+		cout << "finalizing view cells ... ";
+		FinalizeViewCells(true);
+		cout << "finished" << endl;	
+	}
+
 	return sampleContributions;
 }
@@ -1732,6 +1771,7 @@
 	mColorCode = savedColorCode;
 
-	FinalizeViewCells(true);
-	
+	// compute final meshes and volume / area
+	if (1) FinalizeViewCells(true);
+
 	// write view cells to disc
 	if (mExportViewCells)
@@ -2113,6 +2153,6 @@
 		mBspTree->ConstructGeometry(leaf, geom);
 
-		float lVol = geom.GetVolume();
-		float lArea = geom.GetArea();
+		const float lVol = geom.GetVolume();
+		const float lArea = geom.GetArea();
 
 		//(*it)->SetVolume(vol);
@@ -3062,4 +3102,12 @@
 	cout << "construction finished" << endl;
 
+	// real meshes are contructed at this stage
+	if (0)
+	{
+		cout << "finalizing view cells ... ";
+		FinalizeViewCells(true);
+		cout << "finished" << endl;
+	}
+
 	return sampleContributions;
 }
@@ -3296,9 +3344,6 @@
 	// should maybe be done here to allow merge working with area or volume
 	// and to correct the rendering statistics
-	if (0)
-	{
-		FinalizeViewCells(false);
-	}
-
+	if (0) FinalizeViewCells(false);
+	
 	
 	//-- merge the individual view cells
@@ -3312,5 +3357,5 @@
 		RefineViewCells(postProcessRays, objects);
 
-
+	
 	//-- render simulation after merge + refine
 	
@@ -3347,6 +3392,7 @@
 	ResetViewCells();
 
-	// real meshes are only contructed only at this stage
-	FinalizeViewCells(true);
+	// compute final meshes and volume / area
+	if (1) FinalizeViewCells(true);
+
 
 	// write view cells to disc
@@ -3967,4 +4013,5 @@
 		vm->mMaxPvsSize = (int)objects->size();
 
+		// create the meshes and compute volumes
 		vm->FinalizeViewCells(true);
 
@@ -3977,5 +4024,4 @@
 		DEL_PTR(vm);
 	}
-
 
 	return vm;
@@ -4061,6 +4107,6 @@
 		mVspBspTree->ConstructGeometry(leaf, geom);
 
-		float lVol = geom.GetVolume();
-		float lArea = geom.GetArea();
+		const float lVol = geom.GetVolume();
+		const float lArea = geom.GetArea();
 
 		//(*it)->SetVolume(vol);
