Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1586)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1603)
@@ -17,4 +17,5 @@
 #include "ViewCellsManager.h"
 #include "Beam.h"
+#include "IntersectableWrapper.h"
 
 
@@ -243,4 +244,7 @@
 								  MeshInstance *parent)
 {
+	if (!mesh)
+		return 0;
+
 	FaceContainer::const_iterator fi;
 
@@ -260,4 +264,5 @@
 		}
 	}
+
 	return (int)mesh->mFaces.size();
 }
@@ -268,5 +273,5 @@
 								 int maxObjects)
 {
-	int limit = (maxObjects > 0) ?
+	const int limit = (maxObjects > 0) ?
 		Min((int)viewCells.size(), maxObjects) : (int)viewCells.size();
 
@@ -277,5 +282,5 @@
 		Mesh *mesh = viewCells[i]->GetMesh();
 		if (mesh) 
-		{	// // copy the mesh into polygons and add to BSP tree aabb
+		{	// copy the mesh into polygons and add to BSP tree aabb
 			mBoundingBox.Include(viewCells[i]->GetBox()); 
 			polysSize += AddMeshToPolygons(mesh,
@@ -293,5 +298,5 @@
 								 int maxObjects)
 {
-	int limit = (maxObjects > 0) ?
+	const int limit = (maxObjects > 0) ?
 		Min((int)objects.size(), maxObjects) : (int)objects.size();
 
@@ -305,33 +310,38 @@
 		case Intersectable::MESH_INSTANCE:
 			mesh = dynamic_cast<MeshInstance *>(object)->GetMesh();
+			AddMeshToPolygons(mesh, polys, NULL);
 			break;
 		case Intersectable::VIEW_CELL:
 			mesh = dynamic_cast<ViewCell *>(object)->GetMesh();
+			AddMeshToPolygons(mesh, polys, NULL);
 			break;
 		case Intersectable::TRANSFORMED_MESH_INSTANCE:
 			{
-				TransformedMeshInstance *mi = dynamic_cast<TransformedMeshInstance *>(object);
-
-				if (!mi->GetMesh())	
-					break;
-				mesh = new Mesh();
-				mi->GetTransformedMesh(*mesh);
-				
+				TransformedMeshInstance *mi = 
+					dynamic_cast<TransformedMeshInstance *>(object);
+
+				Mesh mesh;
+				mi->GetTransformedMesh(mesh);
+				AddMeshToPolygons(&mesh, polys, NULL);
                 break;
 			}
+		case Intersectable::TRIANGLE_INTERSECTABLE:
+			{
+				TriangleIntersectable *intersect = 
+					dynamic_cast<TriangleIntersectable *>(object);
+
+				Polygon3 *poly = new Polygon3(intersect->GetItem());
+
+				if (poly->Valid(mEpsilon))	
+					polys.push_back(poly);
+				else
+					delete poly;
+			}
 		default:
-			Debug << "intersectable type not supported" << endl;
+				Debug << "intersectable type not supported" << endl;
 			break;
 		}
 
-        if (mesh) // copy the mesh data to polygons
-		{
-			mBoundingBox.Include(object->GetBox()); // add to BSP tree aabb
-			AddMeshToPolygons(mesh, polys, NULL);
-
-			// cleanup
-			if (object->Type() == Intersectable::TRANSFORMED_MESH_INSTANCE)
-				DEL_PTR(mesh);
-		}
+		mBoundingBox.Include(object->GetBox()); // add to BSP tree aabb
 	}
 
@@ -413,4 +423,5 @@
 						}
 						break;
+
 					case Intersectable::MESH_INSTANCE:
 						{
@@ -419,10 +430,21 @@
 						}
 						break;
+
 					case Intersectable::TRIANGLE_INTERSECTABLE:
 						{
-							// TODO
-							cout << "not implemented yet" << endl;
+							TriangleIntersectable *intersect = 
+									dynamic_cast<TriangleIntersectable *>(obj);
+
+							Polygon3 *poly = new Polygon3(intersect->GetItem());
+
+							if (poly->Valid(mEpsilon))	
+								polys.push_back(poly);
+							else
+								delete poly;
 						}
+						break;
+
 					default:
+						cout << "not implemented yet" << endl;
 						break;
 				}
@@ -430,7 +452,11 @@
 				++ numObj;
 
+				/////////
 				//-- compute bounding box
+
 				if (!forcedBoundingBox)
+				{
 					mBoundingBox.Include(ray->mTermination);
+				}
 			}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1582)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1603)
@@ -479,13 +479,4 @@
 	//////////////////////////////////////////////////////////////////
 
-
-	/** Returns true if the view cell is equivalent to a 
-		node of the spatial hierarchy. This function can be used for merged
-		view cell.
-		e.g. to see if the spatial tree can be reduced on this location
-		note: not implemented
-	*/
-	virtual bool EqualToSpatialNode(ViewCell *viewCell) const;
-
 	/** If true, the kd nodes are stored instead of the object pvs.
 	*/
@@ -966,9 +957,4 @@
 	void CollectMergeCandidates(const VssRayContainer &rays, vector<MergeCandidate> &candidates);
 
-	/** Returns true if this view cell is equivavalent to a spatial node.
-	*/
-	bool EqualToSpatialNode(ViewCell *viewCell) const;
-
-
 	void ExportSingleViewCells(
 		const ObjectContainer &objects,
@@ -986,9 +972,4 @@
 	int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const;
 	
-	/** Returns node of the spatial hierarchy corresponding to the view cell
-		if such a node exists.
-	*/
-	BspNode *GetSpatialNode(ViewCell *viewCell) const;
-
 	/** Merges view cells according to some criteria
 	*/
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1594)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1603)
@@ -258,10 +258,4 @@
 
 
-bool ViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const 
-{ 
-	return false;
-}
-
-
 int ViewCellsManager::CastPassSamples(const int samplesPerPass, 
 									  const int sampleType, 
@@ -851,5 +845,6 @@
 
 	// should directional sampling be used?
-	bool dirSamples = (mEvaluationSamplingType == SamplingStrategy::DIRECTION_BASED_DISTRIBUTION);
+	bool dirSamples = 
+		(mEvaluationSamplingType == SamplingStrategy::DIRECTION_BASED_DISTRIBUTION);
 
 	cout << "reseting pvs ... ";
@@ -914,5 +909,5 @@
 		cout << "compute new statistics ... " << endl;
 	
-		///////////////7
+		///////////////
 		//-- propagate pvs or pvs size information
 
@@ -3948,42 +3943,4 @@
 
 	mColorCode = savedColorCode;
-
-}
-
-
-bool VspBspViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const
-{
-	return GetSpatialNode(viewCell) != NULL;
-}
-
-
-BspNode *VspBspViewCellsManager::GetSpatialNode(ViewCell *viewCell) const
-{
-	if (!viewCell->IsLeaf())
-	{
-		BspViewCell *bspVc = dynamic_cast<BspViewCell *>(viewCell);
-		return bspVc->mLeaves[0];
- 	}
-	else
-	{
-		ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell);
-
-		// cannot be node of binary tree
-		if (interior->mChildren.size() != 2)
-			return NULL;
-
-		ViewCell *left = interior->mChildren[0];
-		ViewCell *right = interior->mChildren[1];
-
-		BspNode *leftNode = GetSpatialNode(left);
-		BspNode *rightNode = GetSpatialNode(right);
-
-		if (leftNode && rightNode && leftNode->IsSibling(rightNode))
-		{
-			return leftNode->GetParent(); 
-		}
-	}
-
-	return NULL;
 }
 
@@ -5713,4 +5670,17 @@
 	cout << "finished" << endl;
 
+	vector<int> storageFunc;
+	mViewCellsTree->GetStorageFunction(storageFunc);
+
+	vector<float> costFunc;
+	mViewCellsTree->GetCostFunction(costFunc);
+
+	ofstream outstr("out.txt");
+
+	for (int i = 0; i < storageFunc.size(); ++ i)
+		outstr << i << ": " << storageFunc[i] << endl;
+outstr << endl;
+	for (int i = 0; i < costFunc.size(); ++ i)
+		outstr << i << ": " << costFunc[i] << endl;
 	if (0)
 	for (int i = 0; i <50; ++ i)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1586)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1603)
@@ -621,8 +621,9 @@
 			const int numMergedViewCells = UpdateActiveViewCells(activeViewCells);
 		
-			
-			//-- resets / refines the view cells
+			/////////////////
+			//-- reset / refine the view cells
 			//-- priorities are recomputed
 			//-- the candidates are put back into merge queue
+
 			if (mRefineViewCells)
 				RefineViewCells(rays, objects);
@@ -687,5 +688,5 @@
 
 			// check if "siblings (back and front node of the same parent)
-			if (0 && mViewCellsManager->EqualToSpatialNode(mergedVc))
+			if (0)
 				++ mergeStats.siblings;
 			// set the coŽst for rendering a view cell
@@ -1531,9 +1532,5 @@
 
 	Debug << "******** Export stats **********" << endl;
-	/*Debug << "vsb volume: " << vol << endl;
-	Debug << "root volume: " << mRoot->GetVolume() << endl;
-	Debug << "root pvs: " << rootPvs << endl;
-	*/
-
+	
 	float totalRenderCost, avgRenderCost, expectedCost;
 
@@ -1547,5 +1544,7 @@
 	stats.open(mergeStats.c_str());
 
+	/////////////
 	//-- first view cell
+
 	UpdateStats(stats,
 				0, numViewCells, 0, totalRenderCost, 
@@ -1595,5 +1594,5 @@
 			}
 
-
+			// update stats for this view cell
 			const float costDecr = (parentCost - childCost) / vol;
 
@@ -2171,29 +2170,139 @@
 /** 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());
+void ViewCellsTree::GetCostFunction(vector<float> &costFunction)
+{
+	TraversalQueue tqueue;
+	tqueue.push(mRoot);
+
+	int numViewCells = 1;
+
+	const float vol = mViewCellsManager->GetViewSpaceBox().GetVolume();
+	const int rootPvs = GetPvsSize(mRoot);
+	
+	float totalRenderCost;
+
+	int totalPvs = rootPvs;
+	totalRenderCost = (float)rootPvs;
+
+	costFunction.push_back(totalRenderCost);
+
+	//-- 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())
+	{
+		ViewCell *vc = tqueue.top();
+		tqueue.pop();
+
+		if (!vc->IsLeaf()) 
+		{	
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+
+			const int parentPvs = GetPvsSize(interior);
+			const float parentCost = (float)parentPvs * interior->GetVolume();
+
+			-- numViewCells;
+
+			float childCost = 0;
+			int childPvs = 0;
+			
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it)
+			{
+				ViewCell *vc = *it;
+
+				const int pvsSize = GetPvsSize(vc);
+				
+				childCost += (float) pvsSize * vc->GetVolume();
+				childPvs += pvsSize;
+				
+				tqueue.push(vc);
+				++ numViewCells;
+			}
+
+			// update stats for this view cell
+			const float costDecr = (parentCost - childCost) / vol;
+			totalRenderCost -= costDecr;
+			const float expectedCost = totalRenderCost ;/// (float)numViewCells;
 		
-		ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
-		
-		for (it = interior->mChildren.begin(); it != it_end; ++ it) {
-		  tqueue.push(*it);
-		}
-		
-	  }
-	}
-}
+			costFunction.push_back(expectedCost);
+		}
+	}
+}
+
+
+/** Get storage costs resulting from each merge step. 
+*/
+void ViewCellsTree::GetStorageFunction(vector<int> &storageFunction)
+{
+	TraversalQueue tqueue;
+	tqueue.push(mRoot);
+
+	int numViewCells = 1;
+
+	const float vol = mViewCellsManager->GetViewSpaceBox().GetVolume();
+	const int rootEntries = GetPvsEntries(mRoot);
+
+	int entriesInPvs = rootEntries;
+    const int entryStorage = 1;//sizeof(PvsData) + sizeof(int); // one entry into the pvs
+
+	storageFunction.push_back(rootEntries);
+
+	////////////
+	//-- 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())
+	{
+		ViewCell *vc = tqueue.top();
+		tqueue.pop();
+
+		if (!vc->IsLeaf()) 
+		{	
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+
+			const int parentPvs = GetPvsSize(interior);
+			const int parentPvsEntries = GetPvsEntries(interior);
+            const float parentCost = (float)parentPvs * interior->GetVolume();
+
+			float childCost = 0;
+			int childPvs = 0;
+			int childPvsEntries = 0;
+
+			-- numViewCells;
+
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it)
+			{
+				ViewCell *vc = *it;
+
+				//const int pvsSize = GetPvsSize(vc);
+				const int pvsEntries = GetPvsEntries(vc);
+
+				//childPvs += pvsSize;
+				childPvsEntries += pvsEntries;
+
+				tqueue.push(vc);
+				++ numViewCells;
+			}
+
+			// update stats for this view cell
+			const float costDecr = (parentCost - childCost) / vol;
+
+			//totalPvs += childPvs - parentPvs;
+			entriesInPvs += childPvsEntries - parentPvsEntries;
+
+			const int storageCost = entriesInPvs * entryStorage;
+			storageFunction.push_back(storageCost);
+		}
+	}
+}
+
 
 
@@ -2358,4 +2467,6 @@
 }
 
+
+
 /**************************************************************************/
 /*                     MergeCandidate implementation                      */
@@ -2438,5 +2549,4 @@
 
 
-
 /************************************************************************/
 /*                    MergeStatistics implementation                    */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1586)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1603)
@@ -416,5 +416,9 @@
 	*/
 	void GetCostFunction(vector<float> &costFunction);
-  
+	
+	/** Returns storage cost resulting from each merge step.
+	*/
+	void GetStorageFunction(vector<int> &storageCost);
+
 	/** Returns optimal set of view cells for a given number of view cells.
 	*/
@@ -504,4 +508,5 @@
 	void SetViewCellsManager(ViewCellsManager *vcm);
 
+	void Update();
 
 protected:
