Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1159)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1161)
@@ -2225,5 +2225,5 @@
 					optInt,
 					"vsp_max_tests=",
-					"2000");
+					"5000");
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1160)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1161)
@@ -3985,10 +3985,10 @@
 	if (ViewCellsTreeConstructed() && mCompressViewCells)
 	{
-		int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
+		int pvsEntries = mViewCellsTree->GetStoredPvsEntriesNum(mViewCellsTree->GetRoot());
 		Debug << "number of entries before compress: " << pvsEntries << endl;
 
 		mViewCellsTree->SetViewCellsStorage(ViewCellsTree::COMPRESSED);
 
-		pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
+		pvsEntries = mViewCellsTree->GetStoredPvsEntriesNum(mViewCellsTree->GetRoot());
 		Debug << "number of entries after compress: " << pvsEntries << endl;
 	}
@@ -4589,5 +4589,5 @@
 {
 	int numSamples;
-
+	
 	Environment::GetSingleton()->GetIntValue("RenderSampler.samples", numSamples);
 	cout << "samples" << numSamples << endl;
@@ -4607,9 +4607,52 @@
 
 
-	// counting the pvss
+	// for each sample:
+	//    find view cells associated with the samples
+	//    store the sample pvs with the pvs associated with the view cell
+	// for each view cell:
+	//    compute difference point sampled pvs - view cell pvs
+	//    export geometry with color coded pvs difference
+	
+    std::map<ViewCell *, ObjectPvs> sampleMap;
+
 	vector<RenderCostSample>::const_iterator rit, rit_end = samples.end();
 
-	//std::map<ViewCell *, ObjectPvs> sampleMap;
-
+	for (rit = samples.begin(); rit != rit_end; ++ rit)
+	{
+		RenderCostSample sample = *rit;
+	
+		ViewCell *vc = GetViewCell(sample.mPosition);
+
+		std::map<ViewCell *, ObjectPvs>::iterator it = sampleMap.find(vc);
+
+		if (it == sampleMap.end())
+		{
+			sampleMap[vc] = sample.mPvs;
+		}
+		else
+		{
+			(*it).second.Merge(sample.mPvs);
+		}
+	}
+
+	// visualize the view cells
+	std::map<ViewCell *, ObjectPvs>::const_iterator vit, vit_end = sampleMap.end();
+
+	Material m;//= RandomMaterial();
+
+	for (vit = sampleMap.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = (*vit).first;
+		
+		const int pvsVc = mViewCellsTree->GetPvsEntries(vc);
+		const int pvs2 = (*vit).second.GetSize();
+
+        m.mDiffuseColor.r = (float) (pvsVc - pvs2);
+		m.mDiffuseColor.b = 1.0f;
+		//exporter->SetForcedMaterial(m);
+
+//		ExportViewCellGeometry(exporter, vc, mClipPlane);
+
+/*	// counting the pvss
 	for (rit = samples.begin(); rit != rit_end; ++ rit)
 	{
@@ -4622,10 +4665,6 @@
 		
 		DEL_PTR(hMesh);
-#if 0
-		if (!sampleMap.find(vc))
-			sampleMap.insert(vc, sample.mVisibleObjects);
-		else
-			sampleMap[vc].Merge(Merge(sample.mVisibleObjects);
-#endif
+
+*/
 	}
 }
@@ -5044,10 +5083,10 @@
 	if (ViewCellsTreeConstructed() && mCompressViewCells)
 	{
-		int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
+		int pvsEntries = mViewCellsTree->GetStoredPvsEntriesNum(mViewCellsTree->GetRoot());
 		Debug << "number of entries before compress: " << pvsEntries << endl;
 
 		mViewCellsTree->SetViewCellsStorage(ViewCellsTree::COMPRESSED);
 
-		pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
+		pvsEntries = mViewCellsTree->GetStoredPvsEntriesNum(mViewCellsTree->GetRoot());
 		Debug << "number of entries after compress: " << pvsEntries << endl;
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/common.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/common.h	(revision 1145)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/common.h	(revision 1161)
@@ -484,16 +484,16 @@
 
 // if the view cells should be exported and inported as gzstream
-#define ZIPPED_VIEWCELLS 0
-
-#endif
-
-
-
-
-
-
-
-
-
-
-
+#define ZIPPED_VIEWCELLS 1
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1160)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1161)
@@ -1437,8 +1437,10 @@
 
 	const int rootPvs = GetPvsSize(mRoot);
-
-	Debug << "vsb volume: " << vol << endl;
+	const int rootEntries = GetPvsEntries(mRoot);
+
+	/*Debug << "vsb volume: " << vol << endl;
 	Debug << "root volume: " << mRoot->GetVolume() << endl;
 	Debug << "root pvs: " << rootPvs << endl;
+	*/
 
 	int totalPvs;
@@ -1460,4 +1462,5 @@
 		<< "#TotalRenderCost\n" << totalRenderCost << endl
 		<< "#CurrentPvs\n" << rootPvs << endl
+		<< "#CurrentEntries\n" << rootEntries << endl
 		<< "#ExpectedCost\n" << expectedCost << endl
 		<< "#AvgRenderCost\n" << avgRenderCost << endl
@@ -1468,4 +1471,8 @@
 		<< endl;
 
+	//-- go through tree in the order of render cost decrease
+	//-- which is the same order as the view cells were merged
+	//-- or the reverse order of subdivision for subdivision-only 
+	//-- view cell hierarchies.
 
 	while (!tqueue.empty())
@@ -1628,8 +1635,8 @@
 }
 
-// TODO
+// TODO matt: implement for different storing methods
 void ViewCellsTree::GetPvs(ViewCell *vc, ObjectPvs &pvs) const
 {
-	// pvs is stored in each cell
+	// pvs is stored in each cell => just return pvs
 	if (mViewCellsStorage == PVS_IN_INTERIORS)
 	{
@@ -1638,6 +1645,7 @@
 	}
 
+
+	//-- pvs is not stored with the interiors => reconstruct
 	Intersectable::NewMail();
-
 
 	int pvsSize = 0;
@@ -1660,8 +1668,8 @@
 		tstack.pop();
 
-		// add new pvs
+		// add newly found pvs to merged pvs
 		pvs.AddPvs(vc->GetPvs());
 
-		if (!vc->IsLeaf())
+		if (!vc->IsLeaf()) // interior cells: go down to leaf level
 		{
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
@@ -1685,6 +1693,6 @@
 
 	////////////////////////////////////////////////
-	//-- for interiors, pvs can be stored using different methods
-	///////////////////////////////////////////////
+	//  for interiors, pvs can be stored using different methods
+	//
 
 	switch (mViewCellsStorage)
@@ -1697,5 +1705,51 @@
 				pvsSize = vc->GetPvs().CountPvs();
 			}
-	
+			else // interior node
+			{
+				// interior nodes: pvs is either stored as a scalar or
+				// has to be reconstructed from the leaves
+
+				// the stored pvs size is the valid pvs size => just return scalar
+				if (vc->mPvsSizeValid)
+				{
+					pvsSize = vc->mPvsSize;
+					break;
+				}
+		
+				//-- if no valid pvs size stored as a scalar => 
+				//-- compute current pvs size of interior from it's leaf nodes
+				ViewCellContainer leaves;
+				CollectLeaves(vc, leaves);
+
+				ViewCellContainer::const_iterator it, it_end = leaves.end();
+
+				Intersectable::NewMail();
+
+				// sum different intersectables
+				for (it = leaves.begin(); it != it_end; ++ it)
+				{
+					ObjectPvsMap::iterator oit, oit_end = (*it)->GetPvs().mEntries.end();
+
+					// mail all from first pvs
+					for (oit = (*it)->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+					{
+						Intersectable *intersect = (*oit).first;
+
+						if (!intersect->Mailed())
+						{
+							++ pvsSize;
+							intersect->Mail();					
+						}
+					}
+				}
+
+				break;
+			}
+		}
+	case COMPRESSED:
+		{
+			////////////////////////
+			//-- compressed pvs
+
 			// the stored pvs size is the valid pvs size => just return scalar
 			if (vc->mPvsSizeValid)
@@ -1704,32 +1758,112 @@
 				break;
 			}
-	
-			//-- if no valid pvs size stored as a scalar => compute new pvs size
-			ViewCellContainer leaves;
-			CollectLeaves(vc, leaves);
-
-			ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-			Intersectable::NewMail();
-
-			// sum different intersectables
-			for (it = leaves.begin(); it != it_end; ++ it)
+
+			// if no pvs size stored, compute new one
+			int pvsSize = 0;
+			ViewCell *root = vc;
+	
+			// also add pvs from this view cell to root
+			while (root->GetParent())
 			{
-				ObjectPvsMap::iterator oit, oit_end = (*it)->GetPvs().mEntries.end();
-
-				// mail all from first pvs
-				for (oit = (*it)->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+				root = root->GetParent();
+				// matt: bug! must evaluate kd pvss also
+				pvsSize += CountDiffPvs(root);
+			}
+
+			stack<ViewCell *> tstack;
+			tstack.push(vc);
+
+			while (!tstack.empty())
+			{
+				vc = tstack.top();
+				tstack.pop();
+	
+				pvsSize += CountDiffPvs(vc);
+
+				if (!vc->IsLeaf())
 				{
-					Intersectable *intersect = (*oit).first;
-
-					if (!intersect->Mailed())
+					ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+
+					ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+					for (it = interior->mChildren.begin(); it != it_end; ++ it)
 					{
-						++ pvsSize;
-						intersect->Mail();					
+						tstack.push(*it);
+					}		
+				}
+			}
+			break;
+		}
+	case PVS_IN_INTERIORS:
+	default:
+		// pvs is stored consistently in the tree up to the root
+		// just return pvs size 
+		pvsSize = vc->GetPvs().CountPvs();	
+		break;
+	}
+
+	return pvsSize;  
+}
+
+
+int ViewCellsTree::GetPvsEntries(ViewCell *vc) const
+{
+	int pvsSize = 0;
+
+	Intersectable::NewMail();
+
+	////////////////////////////////////////////////
+	// for interiors, pvs can be stored using different methods
+	
+	switch (mViewCellsStorage)
+	{
+	case PVS_IN_LEAVES: //-- store pvs only in leaves
+		{			
+			// pvs is always stored directly in leaves
+			if (vc->IsLeaf())
+			{
+				pvsSize = vc->GetPvs().GetSize();
+			}
+			else // interior node
+			{
+				// interior nodes: pvs is either stored as a scalar or
+				// has to be reconstructed from the leaves
+
+				// the stored pvs size is the valid pvs size => just return scalar
+				if (vc->mPvsSizeValid)
+				{
+					pvsSize = vc->mPvsSize;
+					break;
+				}
+		
+				// if no valid pvs size stored as a scalar => 
+				// compute current pvs size of interior from it's leaf nodes
+				ViewCellContainer leaves;
+				CollectLeaves(vc, leaves);
+
+				ViewCellContainer::const_iterator it, it_end = leaves.end();
+
+				Intersectable::NewMail();
+
+				// sum different intersectables
+				for (it = leaves.begin(); it != it_end; ++ it)
+				{
+					ObjectPvsMap::iterator oit, oit_end = (*it)->GetPvs().mEntries.end();
+
+					// mail all from first pvs
+					for (oit = (*it)->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+					{
+						Intersectable *intersect = (*oit).first;
+
+						if (!intersect->Mailed())
+						{
+							++ pvsSize;
+							intersect->Mail();					
+						}
 					}
 				}
-			}
-
-			break;
+
+				break;
+			}
 		}
 	case COMPRESSED:
@@ -1738,7 +1872,9 @@
 			//-- compressed pvs
 
+			// the stored pvs size is the valid pvs size => just return scalar
 			if (vc->mPvsSizeValid)
 			{
-				return vc->mPvsSize;
+				pvsSize = vc->mPvsSize;
+				break;
 			}
 
@@ -1780,6 +1916,8 @@
 	case PVS_IN_INTERIORS:
 	default:
-		Debug << "in interiors: " << vc->mPvsSize << " $$ " << vc->GetPvs().CountPvs() << endl;
-		pvsSize = vc->GetPvs().CountPvs();		
+		// pvs is stored consistently in the tree up to the root
+		// just return pvs size 
+		pvsSize = vc->GetPvs().GetSize();	
+		break;
 	}
 
@@ -1793,20 +1931,16 @@
 		sizeof(PvsData<Intersectable *>) + sizeof(Intersectable *);
 
-	return (float)GetNumPvsEntries(vc) * entrySize;
-}
-
-
-int ViewCellsTree::GetNumPvsEntries(ViewCell *vc) const
-{
-	int pvsSize = 0;
-	// only count leaves for uncompressed method for fairness
-	if ((mViewCellsStorage == PVS_IN_INTERIORS) || vc->IsLeaf())
-	{
-		pvsSize = vc->GetPvs().CountPvs();
-	}
-
-	if (!vc->IsLeaf())
-	{
-		ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+	return (float)GetStoredPvsEntriesNum(vc) * entrySize;
+}
+
+
+int ViewCellsTree::GetStoredPvsEntriesNum(ViewCell *root) const
+{
+	int pvsSize = root->GetPvs().GetSize();
+
+	// recursivly count leaves
+	if (!root->IsLeaf())
+	{
+		ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root);
 
 		ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
@@ -1814,5 +1948,5 @@
 		for (it = interior->mChildren.begin(); it != it_end; ++ it)
 		{
-			pvsSize += GetNumPvsEntries(*it);
+			pvsSize += GetStoredPvsEntriesNum(*it);
 		}
 	}
@@ -1926,31 +2060,35 @@
 
 
-/** Get costs resulting from each merge step. */
+/** Get costs resulting from each merge step. 
+*/
 void
 ViewCellsTree::GetCostFunction(vector<float> &costFunction)
 {
-  TraversalQueue tqueue;
-  tqueue.push(mRoot);
-  while (!tqueue.empty()) {
-	ViewCell *vc = tqueue.top();
-	tqueue.pop();
-	// save the view cells if it is a leaf or if enough view cells have already been traversed
-	// because of the priority queue, this will be the optimal set of v
-	if (!vc->IsLeaf()) {	
-	  ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
-	  costFunction.push_back(interior->GetMergeCost());
-	  
-	  ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
-	  
-	  for (it = interior->mChildren.begin(); it != it_end; ++ it) {
-		tqueue.push(*it);
-	  }
-	  
-	}
-  }
-}
-
-
-void  ViewCellsTree::UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat)
+	TraversalQueue tqueue;
+	tqueue.push(mRoot);
+	
+	while (!tqueue.empty()) 
+	{
+		ViewCell *vc = tqueue.top();
+		tqueue.pop();
+		// save the view cells if it is a leaf or if enough view cells have already been traversed
+		// because of the priority queue, this will be the optimal set of v
+		if (!vc->IsLeaf()) {	
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+			costFunction.push_back(interior->GetMergeCost());
+
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it) {
+				tqueue.push(*it);
+			}
+
+		}
+	}
+}
+
+
+void ViewCellsTree::UpdateViewCellsStats(ViewCell *vc, 
+										 ViewCellsStatistics &vcStat)
 {
 	++ vcStat.viewCells;
@@ -1972,4 +2110,5 @@
 		++ vcStat.invalid;
 }
+
 
 #if ZIPPED_VIEWCELLS
@@ -2004,4 +2143,5 @@
 		{
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+			
 			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
 			for (it = interior->mChildren.begin(); it != it_end; ++ it)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1160)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1161)
@@ -279,8 +279,12 @@
 	/// store pvs size, used for evaluation purpose when pvss are stored only in the leaves
 	int mPvsSize;
-	// stores number of entries in pvs
+	/** stores number of entries in pvs
+	    this variable has the same value as mPvsSize for object pvs, 
+		but usually not for kd cell based pvs
+	*/
 	int mEntriesInPvs;
 
-	/// if the pvs size scalar is up to date and corresponding to the real pvs size
+	/// if the pvs size scalar (+ entries into pvs)
+	/// is up to date and corresponding to the real pvs size
 	bool mPvsSizeValid;
 	
@@ -440,11 +444,17 @@
 	void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
 
-	/** Returns pvs size (i.e. the number of entries weighted by their "importance".
+	/** Returns pvs size (i.e. the number of stored objects
 	*/
 	int GetPvsSize(ViewCell *vc) const;
 
-	/** Returns actual number of object in this pvs and the children.
-	*/
-	int GetNumPvsEntries(ViewCell *vc) const;
+	/** Returns number of entries associated with this view cell. 
+		This returns the same value as the GetPvsSize function for object pvs,
+		but most likely different values for kd node based pvs.
+	*/
+	int GetPvsEntries(ViewCell *vc) const;
+
+	/** Returns the actual number of stored entries in the view cells sub tree.
+	*/
+	int GetStoredPvsEntriesNum(ViewCell *root) const;
 
 	/** Returns memory cost of this view cell.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1151)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1161)
@@ -7,4 +7,5 @@
 #include "Renderer.h"
 #include "Beam.h"
+#include "Pvs.h"
 
 
@@ -67,4 +68,6 @@
   // visible pixels
   int mVisiblePixels;
+
+  ObjectPvs mPvs;
   
 };
