Index: GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp	(revision 542)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp	(revision 704)
@@ -119,5 +119,5 @@
 	left = -right;
 
-	top = yDirRange * 0.5;
+	top = yDirRange * 0.5f;
 	bottom = -top;
 }
@@ -165,6 +165,6 @@
 
 	// box should not never remove part of beam polygons
-	Vector3 bmin = mBox.Min() - Vector3(zfar * 2.0);
-	Vector3 bmax = mBox.Max() + Vector3(zfar * 2.0);
+	Vector3 bmin = mBox.Min() - Vector3(zfar * 2.0f);
+	Vector3 bmax = mBox.Max() + Vector3(zfar * 2.0f);
 
 	AxisAlignedBox3 bbox(bmin, bmax);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 695)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 704)
@@ -109,5 +109,5 @@
 
   /** Compute continuous PVS difference */
-  void ComputeContinuousPvsDifference(const Pvs<T> &pvs,
+  void ComputeContinuousPvsDifference(Pvs<T> &pvs,
 									  float &pvsReduction,
 									  float &pvsEnlargement);
@@ -115,5 +115,5 @@
 
   /** Compute continuous PVS difference */
-  float GetPvsHomogenity(const Pvs<T> &pvs) {
+  float GetPvsHomogenity(Pvs<T> &pvs) {
 	float 
 	  pvsReduction,
@@ -142,19 +142,20 @@
 template <typename T>
 void
-Pvs<T>::ComputeContinuousPvsDifference(const Pvs<T> &b,
+Pvs<T>::ComputeContinuousPvsDifference(Pvs<T> &b,
 									   float &pvsReduction,
 									   float &pvsEnlargement)
 {
   // Uses sum of log differences, which corresponds to entropy
-  std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
-  
-  for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it) {
+  std::map<T, PvsData<T>, LtSample<T> >::iterator it;
+  
+  for (it = b.mEntries.begin(); 
+	  it != b.mEntries.end(); ++ it) {
 	float bSumPdf = (*it).second.mSumPdf;
 	float aSumPdf = 0.0f;
 	PvsData<T> *data = Find((*it).first);		
 	if (data) {
-	  aSumPdf = data->second.mSumPdf;
+	  aSumPdf = data->mSumPdf;
 	  // mark this entry as processed to avoid double counting
-	  data->second.mSumPdf = -aSumPdf;
+	  data->mSumPdf = -aSumPdf;
 	}
 	float diff = bSumPdf - aSumPdf;
@@ -177,5 +178,5 @@
 	  PvsData<T> *data = b.Find((*it).first);
 	  if (data) {
-		bSumPdf = data->second.mSumPdf;
+		bSumPdf = data->mSumPdf;
 	  }
 	  float diff = bSumPdf - aSumPdf;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/UnigraphicsParser.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/UnigraphicsParser.cpp	(revision 697)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/UnigraphicsParser.cpp	(revision 704)
@@ -14,5 +14,5 @@
 
 
-#define ROTATE_SCENE 1
+#define ROTATE_SCENE 0
 // HACK
 static void RotateMesh(Mesh *mesh)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 703)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 704)
@@ -38,8 +38,10 @@
 {
 public:
-  /// viewcells
-  ViewCellContainer mViewCells;
+  /// root of view cells tree
+  ViewCell *mViewCell;
+
+  //ViewCellContainer mViewCells;
   /// aggregated pvs
-  ObjectPvs mPvs;
+  //ObjectPvs mPvs;
 
   // input parameter is the render budget for the PrVS
@@ -488,4 +490,9 @@
 	virtual void PrepareLoadedViewCells() {};
 
+	/** Constructs local view cell merge hierarchy.
+	*/
+	ViewCell *ConstructLocalMergeTree(ViewCell *currentViewCell, 
+									  const ViewCellContainer &viewCells);
+
 	/** Creates clip plane for visualization.
 	*/
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 697)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 704)
@@ -2951,29 +2951,36 @@
 int BspNodeGeometry::ComputeIntersection(const AxisAlignedBox3 &box) const
 {
-	AxisAlignedBox3 boundingBox;
-	GetBoundingBox(boundingBox);
-
-	const bool overlap = Overlap(boundingBox, box);
-
-	// no intersections with bounding box
-	if (!overlap)
-	{
-		return 1;
-	}
-	int result = -1;
-
 	// 1: box does not intersect geometry
 	// 0: box intersects geometry
 	// -1: box contains geometry
-	for (int i = 0; i < 6; ++ i) 
+
+	AxisAlignedBox3 boundingBox;
+	GetBoundingBox(boundingBox);
+
+	// no intersections with bounding box
+	if (!Overlap(box, boundingBox))
+	{
+		return 1;
+	}
+
+	// box cotains bounding box of geometry >=> contains geometry
+	if (box.Includes(boundingBox))
+		return -1;
+
+	int result = 0;
+
+	// test geometry planes for intersections
+	vector<Plane3>::const_iterator it, it_end = mPlanes.end();
+
+	for (it = mPlanes.begin(); it != it_end; ++ it)
 	{		
-		const int side = Side(box.GetPlane(i));
+		const int side = box.Side(*it);
 		
 		// box does not intersects geometry
 		if (side == 1)
+		{
 			return 1;
-
-		if (side == 0)
-            result = 0;
+		}
+		//if (side == 0) result = 0;
   }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 697)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 704)
@@ -1790,5 +1790,5 @@
 									float &maxT) const
 {
-	maxT = 1e15;
+	maxT = 1e15f;
 	minT = 0;
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 703)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 704)
@@ -544,201 +544,67 @@
 }
 
-/*
-int ViewCellsManager::ConstructLocalMergeTree(vector<LocalMergeCandidate> candidates)
-											 
-{
-	while(!candidates.empty())
-	{
-		MergeCandidate mc = candidates.back();
-		candidates.pop_back();
-		EvalMergeCost(mc);
-		mergeQueue.push(mc);
-	}
-
-	ViewCell::NewMail();
-
-	
-	long startTime = GetTime();
-
-	mergeStats.candidates = (int)mMergeQueue.size();
-
-	// passes are needed for statistics, because we don't want to record
-	// every merge
-	int pass = 0;
-	int mergedPerPass = 0;
-	float realExpectedCost = mExpectedCost;
-	float realAvgRenderCost = mAvgRenderCost;
-	int realNumActiveViewCells = mNumActiveViewCells;
-	
-	 reset.
-
-	int numMergedViewCells = 0;
-
-	environment->GetIntValue("ViewCells.PostProcess.maxMergesPerPass", maxMergesPerPass);
-	environment->GetFloatValue("ViewCells.PostProcess.avgCostMaxDeviation", avgCostMaxDeviation);
-
-	cout << "actual merge starts now ... " << endl;
-
+
+inline float EvalMergeCost(ViewCell *root, ViewCell *candidate)
+{
+	return root->GetPvs().GetPvsHomogenity(candidate->GetPvs());
+}
+
+
+int GetBestViewCellIdx(ViewCell *root, const ViewCellContainer &neighborhood)
+{
+	int bestViewCellIdx = -1;;
+
+	float mergeCost = Limits::Infinity;
+	int i = 0;
+
+	ViewCellContainer::const_iterator it, it_end = neighborhood.end();
+
+	for (it = neighborhood.begin(); it != it_end; ++ it, ++ i)
+	{
+		const float mc = EvalMergeCost(root, *it);
+
+		if (mc > mergeCost)
+		{
+			mergeCost = mc;
+			bestViewCellIdx = i;
+		}
+	}
+
+	return bestViewCellIdx;
+}
+
+
+ViewCell *ViewCellsManager::ConstructLocalMergeTree(ViewCell *currentViewCell, 
+													const ViewCellContainer &viewCells)
+{
+	ViewCell *root = currentViewCell;
+	ViewCellContainer neighborhood = viewCells;
+
+	ViewCellContainer::const_iterator it, it_end = neighborhood.end();
+
+	const int n = min(mMaxFilterSize, (int)neighborhood.size());
 	//-- use priority queue to merge leaf pairs
 
+
 	//const float maxAvgCost = 350;
-	while (!mMergeQueue.empty())//NumActiveViewCells > mMergeMinViewCells))
-	{
-		//-- reset merge queue if the ratio of current expected cost / real expected cost
-		//   too small or after a given number of merges
-		if ((mergedPerPass > maxMergesPerPass) ||
-			(avgCostMaxDeviation > mAvgRenderCost / realAvgRenderCost))
-		{
-			// adjust render cost
-			++ pass;
-
-			mergedPerPass = 0;
-			mExpectedCost = realExpectedCost;
-					
-			
+	for (int nMergedViewCells = 0; nMergedViewCells < n; ++ nMergedViewCells)
+	{
+		const int bestViewCellIdx = GetBestViewCellIdx(root, neighborhood);
 		
-			// refines the view cells
-			// then priorities are recomputed
-			// and the candidates are put back into merge queue
-			if (mRefineViewCells)
-				RefineViewCells(rays, objects);
-			else
-				ResetMergeQueue();
-
-			Debug << "Values after reset: "  
-				  << " erc: " << mExpectedCost 
-				  << " avg: " << mAvgRenderCost 
-				  << " dev: " << mDeviation << endl;
-
-			if (mExportMergedViewCells)
-			{
-				ExportMergedViewCells(activeViewCells, objects, numMergedViewCells);
-			}
-		}
-
-
-		MergeCandidate mc = mMergeQueue.top();
-		mMergeQueue.pop();
-	
-		// both view cells equal
-		// NOTE: do I really still need this? probably cannot happen!!
-		if (mc.mLeftViewCell == mc.mRightViewCell)
-			continue;
-
-		if (mc.IsValid())
-		{
-			ViewCell::NewMail();
-
-			//-- update statistical values
-			-- realNumActiveViewCells;
-			++ mergeStats.merged;
-			++ mergedPerPass;
-
-			const float renderCostIncr = mc.GetRenderCost();
-			const float mergeCostIncr = mc.GetMergeCost();
-
-			totalRenderCost += renderCostIncr;
-			mDeviation += mc.GetDeviationIncr();
-			
-			
-			// merge the view cells of leaf1 and leaf2
-			int pvsDiff;
-			ViewCellInterior *mergedVc = 
-				MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff);
-
-
-			// total render cost and deviation has changed
-			// real expected cost will be larger than expected cost used for the
-			// cost heuristics, but cannot recompute costs on each increase of the 
-			// expected cost
-			totalPvs += pvsDiff;
-			realExpectedCost = totalRenderCost / (float)realNumActiveViewCells;
-			realAvgRenderCost = (float)totalPvs / (float)realNumActiveViewCells;
-	
-			// set merge cost to this node
-			mergedVc->SetMergeCost(totalRenderCost);
-
-			//if (mViewCellsManager->EqualToSpatialNode(mergedVc))
-			//	++ mergeStats.siblings;
-			mergedVc->SetCost(realExpectedCost);
-
-			if ((mergeStats.merged % statsOut) == 0)
-				cout << "merged " << mergeStats.merged << " view cells" << endl;
-
-		}
-		else
-		{ 
-			// merge candidate not valid, because one of the leaves was already
-			// merged with another one => validate and reinsert into queue
-			if (ValidateMergeCandidate(mc))
-			{
-				EvalMergeCost(mc);
-				mMergeQueue.push(mc);
-			}
-		}
+		ViewCell *bestViewCell = neighborhood[bestViewCellIdx];
 		
-	}
-
-	
-	// adjust stats and reset queue one final time
-	mExpectedCost = realExpectedCost;
-	mAvgRenderCost = realAvgRenderCost;
-	mNumActiveViewCells = realNumActiveViewCells;
-
-	UpdateActiveViewCells(activeViewCells);
-
-	
-	// refine view cells and reset costs
-	if (mRefineViewCells)
-		RefineViewCells(rays, objects);
-	else
-		ResetMergeQueue();
-
-	// create a root node if the merge was not done till root level,
-	// else take the single node as new root
-	if ((int)activeViewCells.size() > 1)
-	{
-		Debug << "creating root of view cell hierarchy for " 
-			  << (int)activeViewCells.size() << " view cells" << endl;
+		// remove from vector
+		swap(neighborhood[bestViewCellIdx], neighborhood.back());
+		neighborhood.pop_back();
 		
-		ViewCellInterior *root = mViewCellsManager->MergeViewCells(activeViewCells);
-		root->SetMergeCost(totalRenderCost);
-		// $$JB keep this 0 temporarilly
-		root->SetCost(0.0f);
-
-		mRoot = root;
-	}
-	else if ((int)activeViewCells.size() == 1)
-	{
-		Debug << "setting root of the merge history" << endl;
-		mRoot = activeViewCells[0];
-	}
-
-	//-- empty merge queue just in case
-	while (!mMergeQueue.empty())
-	{
-		mMergeQueue.pop();
-	}
-
-	// TODO delete because makes no sense here
-	mergeStats.expectedRenderCost = realExpectedCost;
-	mergeStats.deviation = mDeviation;
-
-	// we want to optimize this heuristics
-	mergeStats.heuristics = 
-		mDeviation * (1.0f - mRenderCostWeight) + 
-		mExpectedCost * mRenderCostWeight;
-
-	mergeStats.mergeTime = TimeDiff(startTime, GetTime());
-	mergeStats.Stop();
-	Debug << mergeStats << endl << endl;
-
-	// assign colors for the view cells so that at least one is always consistent
-	AssignRandomColors();
-	
-	//TODO: should return sample contributions?
-	return mergeStats.merged;
-}
-*/
+		if (!bestViewCell || !root)
+			cout << "warning!!" << endl;
+		// create new root of the hierarchy
+		root = MergeViewCells(root, bestViewCell);
+	}
+
+	return root;	
+}
+
 
 bool ViewCellsManager::CheckValidity(ViewCell *vc,
@@ -771,8 +637,13 @@
 	const AxisAlignedBox3 box = GetFilterBBox(viewPoint, mFilterWidth);
 
+	ViewCell *currentViewCell = GetViewCell(viewPoint);
+
 	ViewCellContainer viewCells;
 	ComputeBoxIntersections(box, viewCells);
 
-		
+	ViewCell *root = ConstructLocalMergeTree(currentViewCell, viewCells);
+
+	prvs.mViewCell = root;
+	//prvs.mPvs = root->GetPvs();
 }
 
@@ -2050,5 +1921,5 @@
 		subdivVol += (*it)->GetVolume();
 
-		float thres = 0.9;
+		float thres = 0.9f;
 		if ((lVol < ((*it)->GetVolume() * thres)) ||
 			(lVol * thres > ((*it)->GetVolume())))
@@ -4106,5 +3977,5 @@
 		subdivVol += (*it)->GetVolume();
 		
-		float thres = 0.9;
+		float thres = 0.9f;
 		if ((lVol < ((*it)->GetVolume() * thres)) || (lVol * thres > ((*it)->GetVolume())))
 			Debug << "warning: " << lVol << " " << (*it)->GetVolume() << endl;
@@ -4129,32 +4000,29 @@
 	Exporter *exporter = Exporter::GetExporter("filter.x3d");
 
+	Vector3 bsize = mViewSpaceBox.Size();
+	const Vector3 viewPoint(mViewSpaceBox.Center());
+	const Vector3 width = Vector3(mFilterWidth);
+	
+	PrVs testPrVs;
+	
 	if (exporter)
 	{
-		AxisAlignedBox3 testBox = mViewSpaceBox;
-		Vector3 bsize = mViewSpaceBox.Size();
-
-		testBox.Enlarge(Vector3(-bsize[0] * 0.3, 0, -bsize[2] * 0.4));
-		
 		ViewCellContainer viewCells;
-        
-		mVspBspTree->ComputeBoxIntersections(testBox, viewCells);
-		cout << "view cells: " << viewCells.size() << endl;
-		
+	
+        const AxisAlignedBox3 tbox = GetFilterBBox(viewPoint, mFilterWidth);
+
+		GetPrVS(viewPoint, testPrVs);
+
 		exporter->SetWireframe();
 
 		exporter->SetForcedMaterial(RgbColor(1,1,1));
-		exporter->ExportBox(testBox);
+		exporter->ExportBox(tbox);
 		
 		exporter->SetFilled();
 		exporter->ResetForcedMaterial();
-        for (int i = 0; i < viewCells.size(); ++ i)
-		{
-			BspNodeGeometry geom;
-				
-			mVspBspTree->ConstructGeometry(viewCells[i], geom);
-			exporter->ExportPolygons(geom.GetPolys());
-		}		
-
-		exporter->SetForcedMaterial(RgbColor(1,0,0));
+
+		ExportViewCellGeometry(exporter, testPrVs.mViewCell);
+
+     	exporter->SetForcedMaterial(RgbColor(1,0,0));
 		exporter->ExportGeometry(objects);
 
