Index: GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env	(revision 649)
+++ GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env	(revision 650)
@@ -331,6 +331,6 @@
 		missTolerance		6
 		
-		maxViewCells		10000
-		
+		maxViewCells		100
+	
 		# used for pvs criterium
 		ct_div_ci 0.0
@@ -354,5 +354,5 @@
 BspTree {
 	Construction {
-		samples 500000
+		samples 50000
 		epsilon 0.005
 	}
@@ -420,5 +420,5 @@
 		minProbability 0.00001
 		maxRayContribution 9999
-		maxViewCells	10000
+		maxViewCells	100
 
 		# used for pvs criterium
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 649)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 650)
@@ -249,8 +249,8 @@
 
 
-void ViewCellInterior::SetupChildLink(ViewCell *l)
-{
-    mChildren.push_back(l);
-    l->mParent = this;
+void ViewCellInterior::SetupChildLink(ViewCell *vc)
+{
+    mChildren.push_back(vc);
+    vc->mParent = this;
 }
 
@@ -333,6 +333,4 @@
 
 	MergeCandidate::sRenderCostWeight = mRenderCostWeight;
-
-	mStats.open("mergeStats.log");
 }
 
@@ -473,5 +471,5 @@
 
 	// frequency stats are updated
-	const int statsOut = 1;
+	const int statsOut = 500;
 
 	// passes are needed for statistics, because we don't want to record
@@ -493,19 +491,4 @@
 
 	cout << "actual merge starts now ... " << endl;
-	
-	mStats << "#Pass\n" << pass << endl
-		   << "#Merged\n" << mergeStats.merged << endl 
-		   << "#ViewCells\n" << realNumActiveViewCells << endl 
-		   << "#RenderCostIncrease\n" << 0 << endl
-		   << "#TotalRenderCost\n" << totalRenderCost << endl
-		   << "#CurrentPvs\n" << 0 << endl
-		   << "#ExpectedCost\n" << realExpectedCost << endl
-		   << "#AvgRenderCost\n" << realAvgRenderCost << endl
-		   << "#Deviation\n" << mDeviation << endl
-		   << "#TotalPvs\n" << totalPvs << endl
-		   << "#PvsSizeDecrease\n0" << endl
-		   << "#Volume\n0" << endl
-		   //<< "#Siblings\n" << mergeStats.siblings << endl
-		   << endl;
 
 	//-- use priority queue to merge leaf pairs
@@ -604,25 +587,7 @@
 			mergedVc->SetCost(realExpectedCost);
 
-			if (((mergeStats.merged % statsOut) == 0) || 
-			(realNumActiveViewCells == mMergeMinViewCells))
-			{
+			if ((mergeStats.merged % statsOut) == 0)
 				cout << "merged " << mergeStats.merged << " view cells" << endl;
 
-				mStats 
-					<< "#Pass\n" << pass << endl
-					<< "#Merged\n" << mergeStats.merged << endl 
-					<< "#ViewCells\n" << realNumActiveViewCells << endl 
-                    << "#RenderCostIncrease\n" << renderCostIncr << endl
-					<< "#TotalRenderCost\n" << totalRenderCost << endl
-					<< "#CurrentPvs\n" << mergedVc->GetPvs().GetSize() << endl
-                    << "#ExpectedCost\n" << realExpectedCost << endl
-					<< "#AvgRenderCost\n" << realAvgRenderCost << endl
-					<< "#Deviation\n" << mDeviation << endl
-					<< "#TotalPvs\n" << totalPvs << endl
-					<< "#PvsSizeDecrease\n" << -pvsDiff << endl
-					<< "#Volume\n" << mergedVc->GetVolume() << endl
-					<< endl;
-				
-			}
 		}
 		else
@@ -663,19 +628,4 @@
 		// $$JB keep this 0 temporarilly
 		root->SetCost(0.0f);
-		
-		mStats 
-			<< "#Pass\n" << pass << endl
-			<< "#Merged\n" << mergeStats.merged << endl 
-			<< "#ViewCells\n" << realNumActiveViewCells << endl 
-            << "#RenderCostIncrease\n" << 0 << endl // TODO
-			<< "#TotalRenderCost\n" << totalRenderCost << endl
-			<< "#CurrentPvs\n" << root->GetPvs().GetSize() << endl
-            << "#ExpectedCost\n" << realExpectedCost << endl
-			<< "#AvgRenderCost\n" << realAvgRenderCost << endl
-			<< "#Deviation\n" << mDeviation << endl
-			<< "#TotalPvs\n" << totalPvs << endl
-			<< "#PvsSizeDecrease\n" << 0 << endl // TODO
-			<< "#Volume\n" << root->GetVolume() << endl
-			<< endl;
 
 		mRoot = root;
@@ -705,5 +655,4 @@
 	mergeStats.mergeTime = TimeDiff(startTime, GetTime());
 	mergeStats.Stop();
-
 	Debug << mergeStats << endl << endl;
 
@@ -1302,4 +1251,130 @@
 
 
+void ViewCellsTree::ExportStats()
+{
+	TraversalQueue tqueue;
+
+	tqueue.push(mRoot);
+	int numViewCells = 1;
+	
+	const AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
+	const float vol = box.GetVolume();
+
+	int totalPvs;
+	float totalRenderCost, float avgRenderCost, float expectedCost;
+
+	float deviation = 0;
+	totalPvs = (int)mRoot->GetPvs().GetSize();
+	totalRenderCost = avgRenderCost = expectedCost = (float)mRoot->GetPvs().GetSize();
+
+	ofstream stats;
+	stats.open("mergeStats.log");
+
+	Debug << "here343" << endl;
+
+	stats 
+		<< "#Pass\n" << 0 << endl
+		//<< "#Merged\n" << mergeStats.merged << endl 
+		<< "#ViewCells\n" << numViewCells << endl 
+        << "#RenderCostDecrease\n" << 0 << endl // TODO
+		<< "#TotalRenderCost\n" << totalRenderCost << endl
+		<< "#CurrentPvs\n" << mRoot->GetPvs().GetSize() << endl
+		<< "#ExpectedCost\n" << expectedCost << endl
+		<< "#AvgRenderCost\n" << avgRenderCost << endl
+		<< "#Deviation\n" << deviation << endl
+		<< "#TotalPvs\n" << totalPvs << endl
+		<< "#PvsSizeDecrease\n" << 0 << endl // TODO
+		<< "#Volume\n" << mRoot->GetVolume() << endl
+		<< endl;
+
+
+	while (!tqueue.empty())
+	{
+		ViewCell *vc = tqueue.top();
+		tqueue.pop();
+
+		if (!vc->IsLeaf()) 
+		{	
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+			
+			const int parentPvs = interior->GetPvs().GetSize();
+			const float parentCost = (float)parentPvs * interior->GetVolume();
+			float childCost = 0;
+			int childPvs = 0;
+
+			-- numViewCells;
+
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it)
+			{
+				childCost += (float)(*it)->GetPvs().GetSize() * (*it)->GetVolume();
+				childPvs += (*it)->GetPvs().GetSize();
+
+				tqueue.push(*it);
+				++ numViewCells;
+			}
+
+		
+			const float costDecr = (parentCost - childCost) / vol;
+
+			totalRenderCost -= costDecr;
+			totalPvs += childPvs - parentPvs;
+			
+			expectedCost = totalRenderCost / (float)numViewCells;
+			avgRenderCost = (float)totalPvs / (float)numViewCells;
+
+			stats 
+				<< "#Pass\n" << 0 << endl
+				//<< "#Merged\n" << mergeStats.merged << endl 
+				<< "#ViewCells\n" << numViewCells << endl 
+				<< "#RenderCostDecrease\n" << costDecr << endl // TODO
+				<< "#TotalRenderCost\n" << totalRenderCost << endl
+				<< "#CurrentPvs\n" << vc->GetPvs().GetSize() << endl
+				<< "#ExpectedCost\n" << expectedCost << endl
+				<< "#AvgRenderCost\n" << avgRenderCost << endl
+				<< "#Deviation\n" << deviation << endl
+				<< "#TotalPvs\n" << totalPvs << endl
+				<< "#PvsSizeDecrease\n" << childPvs - parentPvs << endl // TODO
+				<< "#Volume\n" << vc->GetVolume() << endl
+				<< endl;
+
+		}
+	}
+
+	stats.close();
+}
+
+
+/*float ViewCellsTree::ComputeVolume(ViewCell *vc)
+{
+	if (vc->IsLeaf())
+	{
+		return vc->GetVolume();
+	}
+	else
+	{
+		ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+
+		ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+		float volume = 0;
+
+		for (it = interior->mChildren.begin(); it != it_end; ++ it)
+		{
+			volume += ComputeVolume(*it);	
+		}
+
+		interior->SetVolume(volume);
+		return volume;
+	}
+}*/
+
+
+void ViewCellsTree::SetRoot(ViewCell *root)
+{
+	mRoot = root;
+}
+
 void ViewCellsTree::CollectBestViewCellSet(ViewCellContainer &viewCells, 
 										   const int numViewCells)
@@ -1311,8 +1386,9 @@
 	{
 		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() || ((viewCells.size() + tqueue.size()) >= numViewCells))
+		if (vc->IsLeaf() || ((viewCells.size() + tqueue.size() + 1) >= numViewCells))
 		{
 			// todo: should be done with a function taking the active flag and some 
@@ -1333,6 +1409,4 @@
 			}
 		}
-
-		tqueue.pop();
 	}
 }
@@ -1411,9 +1485,4 @@
 
 
-void ViewCellsTree::ExportStats()
-{
-
-}
-
 void ViewCellsTree::GetPvs(ViewCell *vc, ObjectPvs &pvs) const
 {
@@ -1562,6 +1631,5 @@
 
 
-void
-ViewCellsTree::AssignRandomColors()
+void ViewCellsTree::AssignRandomColors()
 {
   TraversalQueue tqueue;
@@ -1571,5 +1639,6 @@
 	{
 	  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
@@ -1593,6 +1662,5 @@
 		
 	  }
-	  
-	  tqueue.pop();
+	 
 	}
 }
@@ -1606,5 +1674,5 @@
   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
@@ -1620,6 +1688,4 @@
 	  
 	}
-	
-	tqueue.pop();
   }
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 649)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 650)
@@ -352,7 +352,4 @@
 	void CollectViewCells(const int n);
 
-
-	virtual int ConstructSpatialMergeTree() { return 0;};
-	
 	virtual bool EqualToSpatialNode(ViewCell *viewCell) const { return false;}
 
@@ -529,5 +526,5 @@
 	bool ExportViewCells(const string filename);
 
-	int ConstructSpatialMergeTree();
+	ViewCell *ConstructSpatialMergeTree(BspNode *root);
 
 
@@ -815,5 +812,5 @@
 	void PrepareLoadedViewCells();
 
-	int ConstructSpatialMergeTree();
+	ViewCell *ConstructSpatialMergeTree(BspNode *root);
 
 	/// the view space partition BSP tree.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 648)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 650)
@@ -71,5 +71,5 @@
 mRenderCostWeight(0.5),
 mUseRandomAxis(false),
-mTimeStamp(0)
+mTimeStamp(1)
 {
 	bool randomize = false;
@@ -575,5 +575,5 @@
 						<< "#RenderCostDecrease\n" << -costDecr << endl 
 						<< "#TotalRenderCost\n" << mTotalCost << endl
-						<< "#AvgRenderCost\n" << mTotalPvsSize / mBspStats.Leaves() << endl;
+						<< "#AvgRenderCost\n" << (float)mTotalPvsSize / (float)mBspStats.Leaves() << endl;
 			}
 
@@ -766,6 +766,7 @@
 	backData.mNode = interior->GetBack();
 
-	frontData.mNode->mTimeStamp = mTimeStamp;
-	backData.mNode->mTimeStamp = mTimeStamp ++;
+	interior->mTimeStamp = mTimeStamp ++;
+	//frontData.mNode->mTimeStamp = ++ mTimeStamp;
+	//backData.mNode->mTimeStamp = mTimeStamp;
 
 	//DEL_PTR(leaf);
@@ -2966,7 +2967,10 @@
 		// the same leaves must not be part of two merge candidates
 		leaf->Mail();
+		
 		vector<BspLeaf *> neighbors;
-		FindNeighbors(leaf, neighbors, true);
-		//FindApproximateNeighbors(leaf, neighbors, true);
+		if (0)
+			FindNeighbors(leaf, neighbors, true);
+		else
+			FindApproximateNeighbors(leaf, neighbors, true);
 		vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end();
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 649)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 650)
@@ -53,4 +53,5 @@
 {}
 
+
 BspNode::BspNode(BspInterior *parent): 
 mParent(parent), mTreeValid(true)
@@ -217,5 +218,5 @@
 mUseAreaForPvs(false),
 mGenerateViewCells(true),
-mTimeStamp(0)
+mTimeStamp(1)
 {
 	Randomize(); // initialise random generator for heuristics
@@ -1182,9 +1183,6 @@
 	backData.mNode = interior->GetBack();
 	
-	interior->mTimeStamp = leaf->mTimeStamp;
-	frontData.mNode->mTimeStamp = mTimeStamp;
-	backData.mNode->mTimeStamp = mTimeStamp ++;
-
-	Debug << "time stamp: " << mTimeStamp << endl;
+	interior->mTimeStamp = mTimeStamp ++;
+	
 	//DEL_PTR(leaf);
 	return interior;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 649)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 650)
@@ -361,4 +361,10 @@
 	void ExportStats();
 
+	/** Sets root of hierarchy.
+	*/
+	void SetRoot(ViewCell *root);
+
+	//float ComputeVolume(ViewCell *vc);
+
 protected:
 
@@ -480,6 +486,4 @@
 	/// maximal cost ratio for the merge
 	float mMergeMaxCostRatio;
-
-	ofstream mStats;
 
 	typedef priority_queue<MergeCandidate> MergeQueue;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 649)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 650)
@@ -1142,6 +1142,4 @@
 
 	//-- merge view cells
-	int merged;
-	
 	cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
 	long startTime = GetTime();
@@ -1153,5 +1151,5 @@
 	{
 		Debug << "constructing visibility based merge tree" << endl;
-		merged = mViewCellsTree->ConstructMergeTree(rays, objects);
+		mViewCellsTree->ConstructMergeTree(rays, objects);
 	}
 	else
@@ -1159,13 +1157,15 @@
 		Debug << "constructing spatial merge tree" << endl;
 		// create spatial merge hierarchy
-		merged = ConstructSpatialMergeTree();
-	}
+		mViewCellsTree->SetRoot(ConstructSpatialMergeTree(mBspTree->GetRoot()));
+	}
+
+	mViewCellsTree->ExportStats();
 
 	//-- stats and visualizations
 	cout << "finished" << endl;
-	cout << "merged " << merged << " view cells in "
+	cout << "merged view cells in "
 		 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
 
-	Debug << "Postprocessing: Merged " << merged << " view cells in "
+	Debug << "Postprocessing: Merged view cells in "
 		<< TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
 	
@@ -1240,5 +1240,5 @@
 	}
 
-	return merged;
+	return 0;
 }
 
@@ -1682,104 +1682,48 @@
 
 
-int BspViewCellsManager::ConstructSpatialMergeTree()
-{
-	TraversalQueue tQueue;
-
-	tQueue.push(TraversalData(mBspTree->GetRoot(), NULL));
-
-	int merged = 0;
-
-	int numViewCells = (int)mViewCells.size();
-
-	float var = 0;
-	float dev = 0;
-	int totalPvs = 0;
-	float totalRenderCost = 0;
-	float avgRenderCost = 0;
-	float expCost = 0;
-
-	//-- compute statistics values of initial view cells
-	EvaluateRenderStatistics(totalRenderCost,
-						     expCost,
-							 dev,
-							 var,
-							 totalPvs,
-							 avgRenderCost);
-
-	Debug/*mStats*/ << "#Pass\n" << 0 << endl
-		   << "#Merged\n" << merged << endl 
-		   << "#ViewCells\n" << numViewCells << endl 
-		   << "#RenderCostIncrease\n" << 0 << endl
-		   << "#TotalRenderCost\n" << totalRenderCost << endl
-		   << "#CurrentPvs\n" << 0 << endl
-		   << "#ExpectedCost\n" << expCost << endl
-		   << "#AvgRenderCost\n" << avgRenderCost << endl
-		   << "#Deviation\n" << dev << endl
-		   << "#TotalPvs\n" << totalPvs << endl
-		   << "#PvsSizeDecrease\n0" << endl
-		   << "#Volume\n0" << endl
-		   //<< "#Siblings\n" << mergeStats.siblings << endl
-		   << endl;
-	
-
-	while (!tQueue.empty())
-	{
-		TraversalData tData = tQueue.top();
-		tQueue.pop();
-
-		if (tData.mNode->IsLeaf())
-		{
-			ViewCell *viewCell = dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell();
-			viewCell->SetMergeCost((float)tData.mNode->mTimeStamp);
-
-			Debug << "leaf time stamp: " << tData.mNode->mTimeStamp << endl;
-
-			if (tData.mParentViewCell)
-			{
-				tData.mParentViewCell->SetupChildLink(viewCell);
-				// propagate up pvs: could be redone as propagepvs, which propagates pvs up and down
-				mViewCellsTree->PropagateUpPvs(viewCell);
-			}
-		}
-		else
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
-			ViewCellInterior *viewCellInterior = new ViewCellInterior();
-
-			++ merged;
-			-- numViewCells;
-
-			avgRenderCost = totalPvs / numViewCells;
-
-			Debug//mStats 
-				<< "#Pass\n" << 0 << endl
-				<< "#Merged\n" << merged << endl 
-				<< "#ViewCells\n" << numViewCells << endl 
-                << "#RenderCostIncrease\n" << 0 << endl
-				<< "#TotalRenderCost\n" << totalRenderCost << endl
-				<< "#CurrentPvs\n" << 0 << endl
-                << "#ExpectedCost\n" << 0 << endl
-				<< "#AvgRenderCost\n" << avgRenderCost << endl
-				<< "#Deviation\n" << dev << endl
-				<< "#TotalPvs\n" << totalPvs << endl
-				<< "#PvsSizeDecrease\n" << 0 << endl
-				<< "#Volume\n" << 0 << endl
-				<< endl;
-
-			Debug << "interior time stamp: " << tData.mNode->mTimeStamp << endl;
-
-			viewCellInterior->SetMergeCost((float)tData.mNode->mTimeStamp);
-
-
-			tQueue.push(TraversalData(interior->GetBack(), viewCellInterior));
-			tQueue.push(TraversalData(interior->GetFront(), viewCellInterior));
-
-			if (tData.mParentViewCell)
-				tData.mParentViewCell->SetupChildLink(viewCellInterior);
-		}
-	}
-
-	return merged;
-}
+ViewCell *BspViewCellsManager::ConstructSpatialMergeTree(BspNode *root)
+{
+	if (root->IsLeaf())
+	{
+		ViewCell *viewCell = dynamic_cast<BspLeaf *>(root)->GetViewCell();
+
+		viewCell->SetMergeCost(0.0f);
+
+		return viewCell;
+	}
+	
+	BspInterior *interior = dynamic_cast<BspInterior *>(root);
+	ViewCellInterior *viewCellInterior = new ViewCellInterior();
+		
+	float mergeCost = 1.0f / (float)root->mTimeStamp;
+	//Debug << "timestamp: " << root->mTimeStamp;
+	//Debug << "merge cost: " << mergeCost << endl;
+
+	viewCellInterior->SetMergeCost(mergeCost);
+
+	float volume = 0;
+	
+	BspNode *front = interior->GetFront();
+	BspNode *back = interior->GetBack();
+
+	// recursivly compute child hierarchies
+	ViewCell *backVc = ConstructSpatialMergeTree(back);
+	ViewCell *frontVc = ConstructSpatialMergeTree(front);
+
+	viewCellInterior->SetupChildLink(frontVc);
+	viewCellInterior->SetupChildLink(backVc);
+
+
+	viewCellInterior->GetPvs().Merge(backVc->GetPvs());
+	viewCellInterior->GetPvs().Merge(frontVc->GetPvs());
+
+	volume += backVc->GetVolume();
+	volume += frontVc->GetVolume();	
+
+	viewCellInterior->SetVolume(volume);
+
+	return viewCellInterior;
+}
+
 
 /************************************************************************/
@@ -2635,23 +2579,32 @@
     Debug << ss << endl;
 
-	//-- merge or subdivide view cells
-	int merged = 0;
+	//-- merge view cells
+	
+	cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl;
+	long startTime = GetTime();
+
+
 	if (mMergeViewCells)
 	{
-		cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl;
-		long startTime = GetTime();
-
-	
+		Debug << "merging view cells" << endl;
 		// TODO: should be done BEFORE the ray casting
-		merged = mViewCellsTree->ConstructMergeTree(rays, objects);
-
-		//-- stats and visualizations
-		cout << "finished merging" << endl;
-		cout << "merged " << merged << " view cells in "
-			 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
-
-		Debug << "Postprocessing: Merged " << merged << " view cells in "
-			  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
-	}
+		mViewCellsTree->ConstructMergeTree(rays, objects);
+	}
+	else
+	{
+		Debug << "spatial merge" << endl;
+		mViewCellsTree->SetRoot(ConstructSpatialMergeTree(mVspBspTree->GetRoot()));
+	}
+
+	mViewCellsTree->ExportStats();
+
+	//-- stats and visualizations
+	cout << "finished merging" << endl;
+	cout << "merged view cells in "
+		 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
+
+	Debug << "Postprocessing: Merged view cells in "
+		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
+	
 
 	int savedColorCode = mColorCode;
@@ -2908,41 +2861,46 @@
 
 
-int VspBspViewCellsManager::ConstructSpatialMergeTree()
-{
-	TraversalQueue tQueue;
-	tQueue.push(TraversalData(mVspBspTree->GetRoot(), NULL));
-
-	int merged = 0;
-
-	while (!tQueue.empty())
-	{
-		TraversalData tData = tQueue.top();
-		tQueue.pop();
-
-		if (tData.mNode->IsLeaf())
-		{
-			ViewCell *viewCell = dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell();
-
-			if (tData.mParentViewCell)
-			{
-				tData.mParentViewCell->SetupChildLink(viewCell);
-				// probagate up pvs
-				mViewCellsTree->PropagateUpPvs(viewCell);
-			}
-		}
-		else
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
-			ViewCellInterior *viewCellInterior = new ViewCellInterior();
-			++ merged;
-
-			tQueue.push(TraversalData(interior->GetBack(), viewCellInterior));
-			tQueue.push(TraversalData(interior->GetFront(), viewCellInterior));
-
-			if (tData.mParentViewCell)
-				tData.mParentViewCell->SetupChildLink(viewCellInterior);
-		}
-	}
-	return merged;
+ViewCell *VspBspViewCellsManager::ConstructSpatialMergeTree(BspNode *root)
+{
+	if (root->IsLeaf())
+	{
+		ViewCell *viewCell = dynamic_cast<BspLeaf *>(root)->GetViewCell();
+
+		viewCell->SetMergeCost(0.0f);
+
+		return viewCell;
+	}
+	
+	BspInterior *interior = dynamic_cast<BspInterior *>(root);
+	ViewCellInterior *viewCellInterior = new ViewCellInterior();
+		
+	float mergeCost = 1.0f / (float)root->mTimeStamp;
+	//Debug << "timestamp: " << root->mTimeStamp;
+	//Debug << "merge cost: " << mergeCost << endl;
+
+	viewCellInterior->SetMergeCost(mergeCost);
+
+	float volume = 0;
+	
+	BspNode *front = interior->GetFront();
+	BspNode *back = interior->GetBack();
+
+	// recursivly compute child hierarchies
+	ViewCell *backVc = ConstructSpatialMergeTree(back);
+	ViewCell *frontVc = ConstructSpatialMergeTree(front);
+
+	viewCellInterior->SetupChildLink(frontVc);
+	viewCellInterior->SetupChildLink(backVc);
+
+
+	viewCellInterior->GetPvs().Merge(backVc->GetPvs());
+	viewCellInterior->GetPvs().Merge(frontVc->GetPvs());
+
+	volume += backVc->GetVolume();
+	volume += frontVc->GetVolume();	
+
+	viewCellInterior->SetVolume(volume);
+
+	return viewCellInterior;
 }
 
