Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 583)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 584)
@@ -305,5 +305,6 @@
 mRoot(NULL),
 mUseAreaForPvs(false),
-mViewCellsManager(vcm)
+mViewCellsManager(vcm),
+mIsCompressed(false)
 {
 	environment->GetBoolValue("ViewCells.Visualization.exportMergedViewCells", mExportMergedViewCells);
@@ -666,5 +667,5 @@
 
 
-ViewCell *ViewCellsTree::GetRoot()
+ViewCell *ViewCellsTree::GetRoot() const
 {
 	return mRoot;
@@ -710,5 +711,5 @@
 	int numMergedViewCells = 0;
 
-	Debug << "updating active vc: " << viewCells.size() << endl;
+	Debug << "updating active vc: " << (int)viewCells.size() << endl;
 	// find all already merged view cells and remove them from view cells
 		
@@ -1240,22 +1241,27 @@
 }
 
-
 void ViewCellsTree::CompressViewCellsPvs()
 {
-	stack<ViewCell *> tstack;
-	
-	while (!tstack.empty())
-	{
-		ViewCell *viewCell = tstack.top();
-		tstack.pop();
-
-		if (!viewCell->IsLeaf())
-		{
-		
-			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell);
-			Debug << "compressing " << interior->GetPvs().GetSize() << endl;
-			ComputeCommonPvs(interior);
-			Debug << "compressed " << interior->GetPvs().GetSize() << endl;
-		}
+	if (!mIsCompressed)
+	{
+		mIsCompressed = true;
+		CompressViewCellsPvs(mRoot);
+	}
+}
+
+void ViewCellsTree::CompressViewCellsPvs(ViewCell *root)
+{
+	if (!root->IsLeaf())
+	{
+		ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(root);
+
+        ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+		// compress child sets first
+		for (it = interior->mChildren.begin(); it != it_end; ++ it)
+		{
+			CompressViewCellsPvs(*it);
+		}
+
+		PropagateUpVisibility(interior);
 	}
 }
@@ -1295,7 +1301,7 @@
 	
 
-void ViewCellsTree::ComputeCommonPvs(ViewCellInterior *interior)
-{
-	Intersectable::NewMail();
+void ViewCellsTree::PropagateUpVisibility(ViewCellInterior *interior)
+{
+	Intersectable::NewMail((int)interior->mChildren.size());
 
 	ViewCellContainer::const_iterator cit, cit_end = interior->mChildren.end();
@@ -1304,4 +1310,6 @@
 
 	// mail all objects in the leaf sets
+	// we are interested in the objects which are present in all leaves
+	// => count how often an object is part of a child set
 	for (cit = interior->mChildren.begin(); cit != cit_end; ++ cit)
 	{
@@ -1312,17 +1320,18 @@
 		for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
 		{
-			if (!(*oit).first->Mailed())
-				(*oit).first->Mail();
+			Intersectable *obj = (*oit).first;
+			if ((cit == interior->mChildren.begin()) && !obj->Mailed())
+				obj->Mail();
 			
-			(*oit).first->IncMail();
+			int incm = obj->IncMail();
 		}
 	}
 
 	interior->GetPvs().mEntries.clear();
-    cit_end = interior->mChildren.end();
+	
 	
 	// only the objects which are present in all leaf pvs 
 	// should remain in the parent pvs
-
+	// these are the objects which have been mailed in all children
 	for (cit = interior->mChildren.begin(); cit != cit_end; ++ cit)
 	{
@@ -1333,6 +1342,9 @@
 		for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
 		{
+			Debug << "mail: " << (*oit).first->mMailbox << endl;
+
 			if ((*oit).first->Mailed((int)interior->mChildren.size()))
 			{	
+				//Debug << "adding sample" << endl;
 				interior->GetPvs().AddSample((*oit).first, (*oit).second.mSumPdf);
 				//(*oit)->remove();
@@ -1341,6 +1353,7 @@
 	}
 
-	// delete all the objects from the leaf sets which were moved
-	// to parent pvs
+
+
+	// delete all the objects from the leaf sets which were moved to parent pvs
 	ObjectPvsMap::const_iterator oit_end = interior->GetPvs().mEntries.end();
 
@@ -1349,7 +1362,94 @@
 		for (cit = interior->mChildren.begin(); cit != cit_end; ++ cit)
 		{
-			(*cit)->GetPvs().RemoveSample((*oit).first, Limits::Infinity);
-		}
-	}
+			if (!(*cit)->GetPvs().RemoveSample((*oit).first, Limits::Infinity))
+				Debug << "should not come here!" << endl;
+		}
+	}
+}
+
+
+void ViewCellsTree::GetPvs(ViewCell *vc, ObjectPvs &pvs) const
+{
+	if (mIsCompressed)
+	{
+		ObjectPvsMap::const_iterator oit, oit_end = vc->GetPvs().mEntries.end();
+
+		for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+		{
+			pvs.AddSample((*oit).first, (*oit).second.mSumPdf);
+		}
+
+		if (!vc->IsLeaf())
+		{
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it)
+			{
+				GetPvs(*it, pvs);
+			}
+		}
+	}
+	else
+	{
+		pvs = vc->GetPvs();
+	}
+}
+
+
+int ViewCellsTree::GetPvsSize(ViewCell *vc) const
+{
+	int pvsSize = vc->GetPvs().GetSize();
+
+	//Debug << "current size: " << pvsSize << endl;
+	if (mIsCompressed && !vc->IsLeaf())
+	{
+		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 += GetPvsSize(*it);
+		}
+	}
+
+	return pvsSize;  
+
+}
+
+
+float ViewCellsTree::GetMemoryCost(ViewCell *vc) const
+{
+	const float entrySize = 
+		sizeof(PvsData<Intersectable *>) + sizeof(Intersectable *);
+
+	return (float)GetNumPvsEntries(vc) * entrySize;
+}
+
+
+int ViewCellsTree::GetNumPvsEntries(ViewCell *vc) const
+{
+	int pvsSize = vc->GetPvs().GetSize();
+
+	if (!vc->IsLeaf())
+	{
+		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 += GetNumPvsEntries(*it);
+		}
+	}
+
+	return pvsSize;    	
+}
+
+
+bool ViewCellsTree::IsCompressed() const
+{
+	return mIsCompressed;
 }
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 582)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 584)
@@ -285,15 +285,39 @@
 	int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
 
-	/** Compresses the pvs of the view cells.
+	
+
+	/** Returns optimal set of view cells for a given number of view cells.
+	*/
+	void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
+
+	/** Root of view cells tree.
+	*/
+	ViewCell *GetRoot() const;
+
+	/** Returns pvs of view cell.
+		@note pvs is returned per reference if tree is not compressed,
+		per copy else.
+	*/
+	void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
+
+	/** Returns pvs size of view cell.
+	*/
+	int GetPvsSize(ViewCell *vc) const;
+
+	/** Returns actual number of object in this pvs and the children.
+	*/
+	int GetNumPvsEntries(ViewCell *vc) const;
+
+	/** Returns memory cost of this view cell.
+	*/
+	float GetMemoryCost(ViewCell *vc) const;
+
+	/** Compresses the pvs of the view cells from the root.
 	*/
 	void CompressViewCellsPvs();
 
-	/** Returns optimal set of view cells for a given number of view cells.
-	*/
-	void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
-
-	/** Root of view cells tree.
-	*/
-	ViewCell *GetRoot();
+	/** If view cells in this tree have compressed pvs.
+	*/
+	bool IsCompressed() const;
 
 protected:
@@ -365,6 +389,7 @@
 	int UpdateActiveViewCells(ViewCellContainer &viewCells);
 
-	void ComputeCommonPvs(ViewCellInterior *interior);
-
+	void PropagateUpVisibility(ViewCellInterior *interior);
+
+	void CompressViewCellsPvs(ViewCell *root);
 
 	/** Returns memory usage of view cells.
@@ -373,5 +398,6 @@
 
 
-
+	/// if the view cell tree hold compressed pvs
+	bool mIsCompressed;
 
 	ViewCellsManager *mViewCellsManager;
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 583)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 584)
@@ -1244,5 +1244,5 @@
 		}
 
-		Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
+		Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc)
 			  << ", piercing rays=" << (int)vcRays.size() << endl;
 			 // << ", leaves=" << (int)vc->mLeaves.size() << endl;
@@ -2066,5 +2066,6 @@
 
 
-void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, vector<MergeCandidate> &candidates)
+void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 
+												   vector<MergeCandidate> &candidates)
 {
 	// TODO
@@ -2365,5 +2366,39 @@
 	RefineViewCells(postProcessRays, objects);
 
+	ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();
+
+	int pvsSize = 0;
+	int numPvsEntries = 0;
+
+	int vidx = 0;
+	for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		const int vcPvs = mViewCellsTree->GetPvsSize(*vit);
+		const int pvsEntries = mViewCellsTree->GetNumPvsEntries(*vit);
+
+		pvsSize += vcPvs;
+		numPvsEntries += pvsEntries;
+		Debug << "Viewcell " << vidx ++ << ": " << vcPvs << endl;
+	}
+
+	Debug << "pvs size before compress: " << pvsSize << endl;
+	Debug << "number of entries before compress: " << numPvsEntries << endl;
+
 	mViewCellsTree->CompressViewCellsPvs();
+
+	pvsSize = numPvsEntries = vidx = 0;
+
+	for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		const int vcPvs = mViewCellsTree->GetPvsSize(*vit);
+		const int pvsEntries = mViewCellsTree->GetNumPvsEntries(*vit);
+		
+		pvsSize += vcPvs;
+		numPvsEntries += pvsEntries;
+		Debug << "Viewcell " << vidx ++ << ": " << vcPvs << endl;	
+	}
+
+	Debug << "pvs size after compress: " << pvsSize << endl;
+	Debug << "number of entries after compress: " << numPvsEntries << endl;
 
 	if (1)
