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)
