Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1709)
@@ -64,6 +64,6 @@
 	struct PvsStatistics 
 	{
-		int minPvs;
-		int maxPvs;
+		float minPvs;
+		float maxPvs;
 		float avgPvs;
 		int viewcells;
@@ -77,4 +77,5 @@
 
 	friend class X3dViewCellsParseHandlers;
+
 	/** Default constructor.
 	*/
@@ -90,7 +91,6 @@
 	/** Constructs view cell container with a given number of samples.
 	*/
-	virtual int ConstructSubdivision(
-		const ObjectContainer &objects, 
-		const VssRayContainer &rays) = 0;
+	virtual int ConstructSubdivision(const ObjectContainer &objects,
+									 const VssRayContainer &rays) = 0;
 
 	/** Computes sample contributions of the rays to the view cells PVS.
@@ -360,5 +360,5 @@
 								  float &deviation,
 								  float &variance,
-								  int &totalPvs,
+								  float &totalPvs,
 								  float &avgRenderCost);
 
@@ -414,5 +414,5 @@
 		of the hierarchy.
 	*/
-	void UpdateScalarPvsSize(ViewCell *vc, const int pvsSize, const int entriesInPvs) const;
+	void UpdateScalarPvsSize(ViewCell *vc, const float pvsCost, const int entriesInPvs) const;
 
 	/** Returns bounding box of a view cell.
@@ -1107,7 +1107,7 @@
 protected:
 
-//#if TEST_EVALUATION
-	//virtual void EvalViewCellPartition();
-//#endif
+#if 1//TEST_EVALUATION
+	virtual void EvalViewCellPartition();
+#endif
 
 	/** Exports view cell geometry.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1709)
@@ -240,4 +240,7 @@
 							 const string &filename);
 
+	void EvaluateSubdivision2(ofstream &stats);
+
+
 	float mInitialRenderCost;
 
@@ -452,13 +455,14 @@
 	void CollectBestSet(const int maxSplits,
 						const float maxMemoryCost,
-						//vector<VspNode *> &vspNodes,
 						ViewCellContainer &viewCells,
 						vector<BvhNode *> &bvhNodes);
 
-	void ExtractStatistics(const int maxSplits,
+	bool ExtractStatistics(const int maxSplits,
 						   const float maxMemoryCost,
 						   float &renderCost,
 						   float &memory,
 						   int &pvsEntries);
+
+
 protected:
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1709)
@@ -52,4 +52,5 @@
 mTimeStamp(0)
 {
+	
 }
 
@@ -103,6 +104,8 @@
 
 BvhLeaf::BvhLeaf(const AxisAlignedBox3 &bbox):
-BvhNode(bbox), mSubdivisionCandidate(NULL)
-{
+BvhNode(bbox), 
+mSubdivisionCandidate(NULL)
+{
+	mActiveNode = this;
 }
 
@@ -111,4 +114,5 @@
 BvhNode(bbox, parent)
 {
+	mActiveNode = this;
 }
 
@@ -120,4 +124,5 @@
 {
 	mObjects.reserve(numObjects);
+	mActiveNode = this;
 }
 
@@ -1399,6 +1404,5 @@
 void BvHierarchy::PrintSubdivisionStats(const SubdivisionCandidate &sc)
 {
-	const float costDecr = 
-		sc.GetRenderCostDecrease();// / mHierarchyManager->GetViewSpaceBox().GetVolume();	
+	const float costDecr = sc.GetRenderCostDecrease();	
 
 	mSubdivisionStats 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1708)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1709)
@@ -296,15 +296,20 @@
 	int stype;
 	
+	const int numStrategies = 3;
+
 	stype = SamplingStrategy::OBJECT_BASED_DISTRIBUTION;
-	mPreprocessor->GenerateRays(samplesPerPass / 4, sampleType, simpleRays);
+	mPreprocessor->GenerateRays(samplesPerPass / numStrategies, sampleType, simpleRays);
 	
 	stype = SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION;
-	mPreprocessor->GenerateRays(samplesPerPass / 4, sampleType, simpleRays);
-	
-	stype = SamplingStrategy::DIRECTION_BASED_DISTRIBUTION;
-	mPreprocessor->GenerateRays(samplesPerPass / 4, sampleType, simpleRays);
+	mPreprocessor->GenerateRays(samplesPerPass / numStrategies, sampleType, simpleRays);
+	
+	if (0)
+	{
+		stype = SamplingStrategy::DIRECTION_BASED_DISTRIBUTION;
+		mPreprocessor->GenerateRays(samplesPerPass / numStrategies, sampleType, simpleRays);
+	}
 
 	stype = SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION;
-	mPreprocessor->GenerateRays(samplesPerPass / 4, sampleType, simpleRays);
+	mPreprocessor->GenerateRays(samplesPerPass / numStrategies, sampleType, simpleRays);
 
 	cout << "generated " << samplesPerPass << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
@@ -516,5 +521,4 @@
 	if (mEvaluateViewCells)
 	{
-cout << "here42 ***********" << endl;
 		EvalViewCellPartition();
 	}
@@ -794,10 +798,10 @@
 	mViewCellsTree->CollectBestViewCellSet(viewCells, nViewCells);
 
-	int maxPvs, maxVal, minVal;
+	float maxPvs, maxVal, minVal;
 
 	// sort by pvs size
 	sort(viewCells.begin(), viewCells.end(), ViewCell::SmallerPvs);
 
-	maxPvs = mViewCellsTree->GetPvsSize(viewCells.back());
+	maxPvs = mViewCellsTree->GetPvsCost(viewCells.back());
 	minVal = 0;
 
@@ -805,5 +809,5 @@
 	int histoMaxVal;
 	Environment::GetSingleton()->GetIntValue("Preprocessor.histogram.maxValue", histoMaxVal);
-	maxVal = max(histoMaxVal, maxPvs);
+	maxVal = max((float)histoMaxVal, maxPvs);
 		
 	Debug << "histogram minpvssize: " << minVal << " maxpvssize: " << maxVal 
@@ -814,6 +818,6 @@
 	const int intervals = min(histoIntervals, (int)viewCells.size());
 
-	const int range = maxVal - minVal;
-	int stepSize = range / intervals;
+	const float range = maxVal - minVal;
+	int stepSize = (int)(range / intervals);
 
 	// set step size to avoid endless loop
@@ -825,5 +829,5 @@
 	const float totalVol = GetViewSpaceBox().GetVolume();
 
-	int currentPvs = minVal;//(int)ceil(minRenderCost);
+	float currentPvs = minVal;
 	
 	int i = 0;
@@ -840,5 +844,5 @@
 
 		while ((i < (int)viewCells.size()) && 
-			   (mViewCellsTree->GetPvsSize(viewCells[i]) < currentPvs))
+			   (mViewCellsTree->GetPvsCost(viewCells[i]) < currentPvs))
 		{
 			volDif += viewCells[i]->GetVolume();
@@ -851,5 +855,5 @@
 		
 		if (0 && (i < (int)viewCells.size()))
-			Debug << "new pvs size increase: " << mViewCellsTree->GetPvsSize(viewCells[i]) 
+			Debug << "new pvs cost increase: " << mViewCellsTree->GetPvsCost(viewCells[i]) 
 			<< " " << currentPvs << endl;
 	
@@ -864,6 +868,4 @@
 		outstream << "#VolumeSum\n" << volRatioSum << endl << endl;
 	
-		//if ((i >= (int)viewCells.size()) || (currentPvs >= maxPvs))	break;
-
 		//-- increase current pvs size to define next interval
 		currentPvs += stepSize;
@@ -1009,5 +1011,5 @@
 			ObjectPvs pvs;
 
-			cout << "updating pvs for contribution ... " << endl;
+			cout << "updating pvs for evaluation ... " << endl;
 
 			UpdatePvsForEvaluation(mViewCellsTree->GetRoot(), pvs);
@@ -1499,5 +1501,5 @@
 												float &deviation,
 												float &variance,
-												int &totalPvs,
+												float &totalCost,
 												float &avgRenderCost)
 {
@@ -1506,5 +1508,5 @@
 
 	totalRenderCost = 0;
-	totalPvs = 0;
+	totalCost = 0;
 
 	ViewCellContainer::const_iterator it, it_end = mViewCells.end();
@@ -1514,5 +1516,5 @@
 		ViewCell *vc = *it;
 		totalRenderCost += vc->GetPvs().EvalPvsCost() * vc->GetVolume();
-		totalPvs += (int)vc->GetPvs().EvalPvsCost();
+		totalCost += (int)vc->GetPvs().EvalPvsCost();
 	}
 
@@ -1520,5 +1522,5 @@
 	totalRenderCost /= mViewSpaceBox.GetVolume();
 	expectedRenderCost = totalRenderCost / (float)mViewCells.size();
-	avgRenderCost = totalPvs / (float)mViewCells.size();
+	avgRenderCost = totalCost / (float)mViewCells.size();
 
 
@@ -1744,34 +1746,32 @@
 void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
 {
-  // update pvs of view cells tree if necessary
-  UpdatePvs();
-  
-  ViewCellContainer::const_iterator it = mViewCells.begin();
-  
-  stat.viewcells = 0;
-  stat.minPvs = 100000000;
-  stat.maxPvs = 0;
-  stat.avgPvs = 0.0f;
-  
-  for (; it != mViewCells.end(); ++ it) 
-	{
-	  ViewCell *viewcell = *it;
-
-	  //	  bool mCountKdPvs = false;
-	  const int pvsSize = mViewCellsTree->GetPvsSize(viewcell);
-
-
-	  if (pvsSize < stat.minPvs)
-		stat.minPvs = pvsSize;
-	  if (pvsSize > stat.maxPvs)
-		stat.maxPvs = pvsSize;
-	  
-	  stat.avgPvs += pvsSize;
-	  
-	  ++ stat.viewcells;
-	}
-  
-  if (stat.viewcells)
-	stat.avgPvs/=stat.viewcells;
+	// update pvs of view cells tree if necessary
+	UpdatePvs();
+
+	ViewCellContainer::const_iterator it = mViewCells.begin();
+
+	stat.viewcells = 0;
+	stat.minPvs = 100000000;
+	stat.maxPvs = 0;
+	stat.avgPvs = 0.0f;
+
+	for (; it != mViewCells.end(); ++ it) 
+	{
+		ViewCell *viewcell = *it;
+
+		const float pvsCost = mViewCellsTree->GetPvsCost(viewcell);
+
+		if (pvsCost < stat.minPvs)
+			stat.minPvs = pvsCost;
+		if (pvsCost > stat.maxPvs)
+			stat.maxPvs = pvsCost;
+
+		stat.avgPvs += pvsCost;
+
+		++ stat.viewcells;
+	}
+
+	if (stat.viewcells)
+		stat.avgPvs/=stat.viewcells;
 }
 
@@ -2053,5 +2053,5 @@
 float ViewCellsManager::GetRendercost(ViewCell *viewCell) const
 {
-	return (float)mViewCellsTree->GetPvsSize(viewCell);
+	return (float)mViewCellsTree->GetPvsCost(viewCell);
 }
 
@@ -2327,8 +2327,8 @@
 
 void ViewCellsManager::UpdateScalarPvsSize(ViewCell *vc, 
-										   const int pvsSize, 
+										   const float pvsCost, 
 										   const int entriesInPvs) const
 {
-	vc->mPvsSize = pvsSize;
+	vc->mPvsCost = pvsCost;
 	vc->mEntriesInPvs = entriesInPvs;
 
@@ -2525,5 +2525,5 @@
 			{
 				importance = 
-					(float)mViewCellsTree->GetPvsSize(vc) / 
+					(float)mViewCellsTree->GetPvsCost(vc) / 
 					(float)mCurrentViewCellsStats.maxPvs;
 			}
@@ -2578,11 +2578,13 @@
 	if (root->IsLeaf())
 	{ 
+		//cout << "updating leaf" << endl;
 		// we assume that pvs is explicitly stored in leaves
 		pvs = root->GetPvs();
 		UpdateScalarPvsSize(root, pvs.EvalPvsCost(), pvs.GetSize());
-		
 		return;
 	}
-	
+
+	//cout << "recursivly updating pvs" << endl;
+
 	////////////////
 	//-- interior node => propagate pvs up the tree
@@ -2597,19 +2599,15 @@
 	// pvss of child nodes
 	vector<ObjectPvs> pvsList;
+	pvsList.resize((int)interior->mChildren.size());
 
 	ViewCellContainer::const_iterator vit, vit_end = interior->mChildren.end();
-	pvsList.resize((int)interior->mChildren.size());
+	
 	int i = 0;
+
 	for (vit = interior->mChildren.begin(); vit != vit_end; ++ vit, ++ i)
 	{
-		//ObjectPvs objPvs;
-		
 		//////////////////
 		//-- recursivly compute child pvss
-
 		UpdatePvsForEvaluation(*vit, pvsList[i]/*objPvs*/);
-
-		// store pvs in vector
-		//pvsList.push_back(objPvs);
 	}
 
@@ -3047,5 +3045,5 @@
 		Exporter *exporter = Exporter::GetExporter(s);
 		
-		cout << "view cell " << idx << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl;
+		cout << "view cell " << idx << ": pvs cost=" << (int)mViewCellsTree->GetPvsCost(vc) << endl;
 
 		if (exportRays)
@@ -4400,6 +4398,6 @@
 		Exporter *exporter = Exporter::GetExporter(s);
 		
-		const int pvsSize = (int)mViewCellsTree->GetPvsSize(vc);
-		cout << "view cell " << vc->GetId() << ": pvs size=" << pvsSize << endl;
+		const float pvsCost = mViewCellsTree->GetPvsCost(vc);
+		cout << "view cell " << vc->GetId() << ": pvs cost=" << pvsCost << endl;
 
 		if (exportRays)
@@ -5285,5 +5283,5 @@
 		Exporter *exporter = Exporter::GetExporter(s);
 		
-		cout << "view cell " << vc->GetId() << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl;
+		cout << "view cell " << vc->GetId() << ": pvs cost=" << mViewCellsTree->GetPvsCost(vc) << endl;
 
 		if (exportPvs)
@@ -5661,5 +5659,5 @@
 
 
-#if 0
+#if 1
 #if TEST_EVALUATION
 void VspOspViewCellsManager::EvalViewCellPartition()
@@ -5730,7 +5728,7 @@
 	{
 		ViewCell *vc = *vit;
-		int pvs = vc->GetPvs().EvalPvsCost();
-		float vol = vc->GetVolume();
-		rc += pvs * vol;
+		const float pvsCost = vc->GetPvs().EvalPvsCost();
+		const float vol = vc->GetVolume();
+		rc += pvsCost * vol;
 	}
 
@@ -5826,6 +5824,6 @@
 		sprintf(str, "-%09d-eval.log", castSamples);
 		string filename = string(statsPrefix) + string(str);
-
-		mHierarchyManager->EvaluateSubdivision(evaluationSamples, mPreprocessor->mObjects, filename);
+		ofstream ofstr(filename.c_str());
+		mHierarchyManager->EvaluateSubdivision2(ofstr);
 
 		timeDiff = TimeDiff(startTime, GetTime());
@@ -5833,9 +5831,6 @@
 		Debug << "statistis compted in " << timeDiff * 1e-3 << " secs" << endl;
 	
-		//disposeRays(evaluationSamples, NULL);
-	}
-	
-	disposeRays(evaluationSamples, NULL);
-
+		disposeRays(evaluationSamples, NULL);
+	}
 }
 #endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1709)
@@ -42,7 +42,7 @@
 
 // pvs penalty can be different from pvs size
-inline static float EvalPvsPenalty(const int pvs, 
-								   const int lower, 
-								   const int upper)
+inline static float EvalPvsPenalty(const float pvs, 
+								   const float lower, 
+								   const float upper)
 {
 	// clamp to minmax values
@@ -76,8 +76,8 @@
 
 /// Fast computation of merged pvs size
-static int ComputeMergedPvsSize(const ObjectPvs &pvs1, const ObjectPvs &pvs2)
+static float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2)
 {
 	// add first pvs
-	int pvs = pvs1.GetSize();
+	float pvs = (float)pvs1.GetSize();
 
 	ObjectPvsMap::const_iterator it, it_end =  pvs1.mEntries.end();
@@ -112,8 +112,7 @@
 mParent(NULL),
 mMergeCost(0),
-mPvsSize(0),
+mPvsCost(0),
 mEntriesInPvs(0),
 mPvsSizeValid(false)
-//mMailbox(0)
 {
 	mId = -100;
@@ -127,5 +126,5 @@
 mParent(NULL),
 mMergeCost(0),
-mPvsSize(0),
+mPvsCost(0),
 mPvsSizeValid(false)
 //mMailbox(0)
@@ -244,6 +243,5 @@
 float ViewCell::GetRenderCost() const
 {
-	//return (float)mPvs.GetSize() * GetVolume();
-	return (float)mPvsSize * GetVolume();
+	return mPvsCost * GetVolume();
 }
 
@@ -352,5 +350,7 @@
 	//app << "#N_CTIME  ( Construction time [s] )\n" << Time() << " \n";
 
-	app << "#N_OVERALLPVS ( objects in PVS )\n" << pvsSize << endl;
+	app << "#N_OVERALLPVS ( cost of the PVS )\n" << pvsCost << endl;
+
+	//app << "#N_PVSENTRIES ( entries in the PVS)\n" << pvsEntries << endl;
 
 	app << "#N_PMAXPVS ( largest PVS )\n" << maxPvs << endl;
@@ -520,5 +520,5 @@
 
 	float variance = 0;
-	int totalPvs = 0;
+	float totalPvs = 0;
 	float totalRenderCost = 0;
 
@@ -669,8 +669,7 @@
 						
 			//-- merge the view cells of leaf1 and leaf2
-			int pvsDiff;
+			float pvsDiff;
 			ViewCellInterior *mergedVc = 
-				MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff);
-			
+				MergeViewCells(mc.mLeftViewCell, mc.mRightViewCell, pvsDiff);	
 
 			// total render cost and deviation has changed
@@ -926,6 +925,6 @@
 	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
 	{
-		const int lower = mViewCellsManager->GetMinPvsSize();
-		const int upper = mViewCellsManager->GetMaxPvsSize();
+		const float lower = (float)mViewCellsManager->GetMinPvsSize();
+		const float upper = (float)mViewCellsManager->GetMaxPvsSize();
 
 		const float penalty = EvalPvsPenalty((*vit)->GetPvs().EvalPvsCost(), lower, upper);
@@ -992,5 +991,5 @@
 ViewCellInterior *ViewCellsTree::MergeViewCells(ViewCell *left, 
 												ViewCell *right, 
-												int &pvsDiff) //const
+												float &pvsDiff) //const
 {
 	// create merged view cell
@@ -1183,9 +1182,9 @@
 {
 	//const int pvs1 = SubtractedPvsSize(vc1, leaf, *leaf->mPvs);
-	const int pvs1 = SubtractedPvsSize(vc1->GetPvs(), leaf->GetPvs());
-	const int pvs2 = AddedPvsSize(vc2->GetPvs(), leaf->GetPvs());
-
-	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
-	const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize();
+	const float pvs1 = (float)SubtractedPvsSize(vc1->GetPvs(), leaf->GetPvs());
+	const float pvs2 = (float)AddedPvsSize(vc2->GetPvs(), leaf->GetPvs());
+
+	const float lowerPvsLimit = (float)mViewCellsManager->GetMinPvsSize();
+	const float upperPvsLimit = (float)mViewCellsManager->GetMaxPvsSize();
 
 	const float pvsPenalty1 = 
@@ -1311,11 +1310,11 @@
 float ViewCellsTree::GetVariance(ViewCell *vc) const
 {
-	const int upper = mViewCellsManager->GetMaxPvsSize();
-	const int lower = mViewCellsManager->GetMinPvsSize();
+	const float upper = (float)mViewCellsManager->GetMaxPvsSize();
+	const float lower = (float)mViewCellsManager->GetMinPvsSize();
 
 	if (1)
 	{
 		const float penalty = 
-			EvalPvsPenalty(vc->GetPvs().GetSize(), lower, upper);
+			EvalPvsPenalty(GetPvsCost(vc), lower, upper);
 
 		return (mAvgRenderCost - penalty) * (mAvgRenderCost - penalty) / 
@@ -1330,10 +1329,10 @@
 float ViewCellsTree::GetDeviation(ViewCell *vc) const
 {
-	const int upper = mViewCellsManager->GetMaxPvsSize();
-	const int lower = mViewCellsManager->GetMinPvsSize();
+	const float upper = (float)mViewCellsManager->GetMaxPvsSize();
+	const float lower = (float)mViewCellsManager->GetMinPvsSize();
 
 	if (1)
 	{
-		const float penalty = EvalPvsPenalty(vc->GetPvs().EvalPvsCost(), lower, upper);
+		const float penalty = EvalPvsPenalty(GetPvsCost(vc), lower, upper);
 		return fabs(mAvgRenderCost - penalty) / (float)mNumActiveViewCells;
 	}
@@ -1386,18 +1385,13 @@
 	//-- compute pvs difference
 
-	int newPvs;
-	
-	if (1) // not valid if not using const cost per object!!
-	{
-		newPvs = ComputeMergedPvsSize(mc.mLeftViewCell->GetPvs(), mc.mRightViewCell->GetPvs());
-	}
-	else
-	{
-		newPvs = (int)ComputeMergedPvsCost(mc.mLeftViewCell->GetPvs(), mc.mRightViewCell->GetPvs());
-	}
+	float newPvs;
+	
+	// not valid if not using const cost per object!!
+	newPvs = ComputeMergedPvsCost(mc.mLeftViewCell->GetPvs(), mc.mRightViewCell->GetPvs());
+
 
 	const float newPenalty = EvalPvsPenalty(newPvs, 
-											mViewCellsManager->GetMinPvsSize(),
-											mViewCellsManager->GetMaxPvsSize());
+											(float)mViewCellsManager->GetMinPvsSize(),
+											(float)mViewCellsManager->GetMaxPvsSize());
 
 	ViewCell *vc1 = mc.mLeftViewCell;
@@ -1485,31 +1479,19 @@
 
 void ViewCellsTree::UpdateStats(ofstream &stats,
-								const int pass,
-								const int viewCells,
-								const float renderCostDecrease,
-								const float totalRenderCost,
-								const int currentPvs,
-								const float expectedCost,
-								const float avgRenderCost,
-								const float deviation,
-								const int totalPvs,
-								const int entriesInPvs,
-								const float memoryCost,
-								const int pvsSizeDecr,
-								const float volume)
-{
-	 stats << "#Pass\n" << pass << endl
-		   << "#Splits\n" << viewCells << endl 
-		   << "#RenderCostDecrease\n" << renderCostDecrease << endl // TODO
-		   << "#TotalRenderCost\n" << totalRenderCost << endl
-		   << "#CurrentPvs\n" << currentPvs << endl
-		   << "#ExpectedCost\n" << expectedCost << endl
-		   << "#AvgRenderCost\n" << avgRenderCost << endl
-		   << "#Deviation\n" << deviation << endl
-		   << "#TotalPvs\n" << totalPvs << endl
-		   << "#TotalEntriesInPvs\n" << entriesInPvs << endl
-		   << "#Memory\n" << memoryCost << endl
-		   << "#PvsSizeDecrease\n" << pvsSizeDecr << endl
-		   << "#Volume\n" << volume << endl
+								const ViewCellsTreeStats &vcStats)
+{
+	 stats << "#Pass\n" << vcStats.mPass << endl
+		   << "#Splits\n" << vcStats.mNumViewCells << endl 
+		   << "#RenderCostDecrease\n" << vcStats.mRenderCostDecrease << endl // TODO
+		   << "#TotalRenderCost\n" << vcStats.mTotalRenderCost << endl
+		   << "#CurrentPvs\n" << vcStats.mCurrentPvsCost << endl
+		   << "#ExpectedCost\n" << vcStats.mExpectedCost << endl
+		   << "#AvgRenderCost\n" << vcStats.mAvgRenderCost << endl
+		   << "#Deviation\n" << vcStats.mDeviation << endl
+		   << "#TotalPvs\n" << vcStats.mTotalPvsCost << endl
+		   << "#TotalEntriesInPvs\n" << vcStats.mEntriesInPvs << endl
+		   << "#Memory\n" << vcStats.mMemoryCost << endl
+		   << "#PvsSizeDecrease\n" << vcStats.mPvsSizeDecr << endl
+		   << "#Volume\n" << vcStats.mVolume << endl
 		   << endl;
 }
@@ -1521,44 +1503,34 @@
 	tqueue.push(mRoot);
 
+	ViewCellsTreeStats vcStats;
+	vcStats.Reset();
+
 	//cout << "exporting stats ... " << endl;
-	int numViewCells = 1;
+	vcStats.mNumViewCells = 1;
 	
 	const AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
 	const float vol = box.GetVolume();
 
-	const int rootPvs = GetPvsSize(mRoot);
+	const float rootPvs = GetPvsCost(mRoot);
 	const int rootEntries = GetPvsEntries(mRoot);
-	float totalRenderCost, avgRenderCost, expectedCost;
-
-	float deviation = 0;
-	int totalPvs = rootPvs;
-	int entriesInPvs = rootEntries;
-
-	totalRenderCost = avgRenderCost = expectedCost = (float)rootPvs;
+	
+	vcStats.mTotalPvsCost = rootPvs;
+	vcStats.mTotalRenderCost = rootPvs;
+	vcStats.mAvgRenderCost = rootPvs;
+	vcStats.mExpectedCost = rootPvs;
+	
+	vcStats.mEntriesInPvs = rootEntries;
 
 	ofstream stats;
 	stats.open(mergeStats.c_str());
 
-	const float memoryCost = (float)entriesInPvs * ObjectPvs::GetEntrySize();
+	vcStats.mMemoryCost = (float)vcStats.mEntriesInPvs * ObjectPvs::GetEntrySize();
 
 	/////////////
 	//-- first view cell
 
-	UpdateStats(stats,
-				0, 
-				numViewCells, 
-				0, 
-				totalRenderCost, 
-				rootPvs, 
-				expectedCost, 
-				avgRenderCost, 
-				deviation,
-				totalPvs, 
-				entriesInPvs,
-				memoryCost,
-				0, 
-				mRoot->GetVolume());
+	UpdateStats(stats, vcStats);
+				
 		
-
 	//-- go through tree in the order of render cost decrease
 	//-- which is the same order as the view cells were merged
@@ -1575,13 +1547,13 @@
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
 
-			const int parentPvs = GetPvsSize(interior);
+			const float parentCost = GetPvsCost(interior);
 			const int parentPvsEntries = GetPvsEntries(interior);
-            const float parentCost = (float)parentPvs * interior->GetVolume();
-
+            const float parentExpCost = (float)parentCost * interior->GetVolume();
+
+			float childExpCost = 0;
 			float childCost = 0;
-			int childPvs = 0;
 			int childPvsEntries = 0;
 
-			-- numViewCells;
+			-- vcStats.mNumViewCells;
 
 			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
@@ -1591,41 +1563,28 @@
 				ViewCell *vc = *it;
 
-				const int pvsSize = GetPvsSize(vc);
+				const float pvsCost = GetPvsCost(vc);
 				const int pvsEntries = GetPvsEntries(vc);
 
-				childCost += (float) pvsSize * vc->GetVolume();
-				childPvs += pvsSize;
+				childExpCost += childCost * vc->GetVolume();
+				childCost += pvsCost;
 				childPvsEntries += pvsEntries;
 
 				tqueue.push(vc);
-				++ numViewCells;
+				++ vcStats.mNumViewCells;
 			}
 
 			// update stats for this view cell
-			const float costDecr = (parentCost - childCost) / vol;
-
-			totalRenderCost -= costDecr;
-			totalPvs += childPvs - parentPvs;
-			entriesInPvs += childPvsEntries - parentPvsEntries;
-
-			expectedCost = totalRenderCost / (float)numViewCells;
-			avgRenderCost = (float)totalPvs / (float)numViewCells;
-
-			const float memoryCost = (float)entriesInPvs * ObjectPvs::GetEntrySize();
-
-			UpdateStats(stats,
-						0, 
-						numViewCells, 
-						costDecr, 
-						totalRenderCost,
-						parentPvs, 
-						expectedCost, 
-						avgRenderCost, 
-						deviation,
-                        totalPvs, 
-						entriesInPvs, 
-						memoryCost,
-						childPvs - parentPvs,
-						vc->GetVolume());
+			const float costDecr = (parentExpCost - childExpCost) / vol;
+
+			vcStats.mTotalRenderCost -= costDecr;
+			vcStats.mTotalPvsCost += childCost - parentCost;
+			vcStats.mEntriesInPvs += childPvsEntries - parentPvsEntries;
+
+			vcStats.mExpectedCost = vcStats.mTotalRenderCost / (float)vcStats.mNumViewCells;
+			vcStats.mAvgRenderCost = vcStats.mTotalPvsCost / (float)vcStats.mNumViewCells;
+
+			vcStats.mMemoryCost = vcStats.mEntriesInPvs * ObjectPvs::GetEntrySize();
+
+			UpdateStats(stats, vcStats);
 		}
 	}
@@ -1789,5 +1748,5 @@
 
 
-int ViewCellsTree::GetPvsSizeForLeafStorage(ViewCell *vc) const
+float ViewCellsTree::GetPvsCostForLeafStorage(ViewCell *vc) const
 {
 	// pvs is always stored directly in leaves
@@ -1802,5 +1761,5 @@
 	if (vc->mPvsSizeValid)
 	{
-		return vc->mPvsSize;
+		return vc->mPvsCost;
 	}
 	
@@ -1886,7 +1845,7 @@
 
 
-int ViewCellsTree::GetPvsSizeForCompressedStorage(ViewCell *vc) const
-{
-	int pvsSize = 0;
+float ViewCellsTree::GetPvsCostForCompressedStorage(ViewCell *vc) const
+{
+	float pvsCost = 0;
 
 	/////////////
@@ -1896,5 +1855,5 @@
 	if (vc->mPvsSizeValid)
 	{
-		pvsSize = vc->mPvsSize;
+		pvsCost = vc->mPvsCost;
 	}
 
@@ -1908,5 +1867,5 @@
 	
 		// matt: bug! must evaluate kd pvss also
-		pvsSize += CountPvsContribution(root);
+		pvsCost += CountPvsContribution(root);
 	}
 
@@ -1918,11 +1877,11 @@
 		vc = tstack.top();
 		tstack.pop();
+
 		// matt: bug! must evaluate kd pvss also
-		pvsSize += CountPvsContribution(vc);
+		pvsCost += CountPvsContribution(vc);
 
 		if (!vc->IsLeaf())
 		{
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
-
 			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
 
@@ -1934,5 +1893,5 @@
 	}
 
-	return pvsSize;
+	return pvsCost;
 }
 
@@ -1990,7 +1949,7 @@
 
 
-int ViewCellsTree::GetPvsSize(ViewCell *vc) const
-{
-	int pvsSize = 0;
+float ViewCellsTree::GetPvsCost(ViewCell *vc) const
+{
+	float pvsCost = 0;
 	Intersectable::NewMail();
 
@@ -2003,8 +1962,8 @@
 	case PVS_IN_LEAVES: 
 		// pvs is stored only in leaves
-		pvsSize = GetPvsSizeForLeafStorage(vc);			
+		pvsCost = GetPvsCostForLeafStorage(vc);			
 		break;
 	case COMPRESSED:
-		pvsSize = GetPvsSizeForCompressedStorage(vc);
+		pvsCost = GetPvsCostForCompressedStorage(vc);
 		break;
 	case PVS_IN_INTERIORS:
@@ -2012,9 +1971,9 @@
 		// pvs is stored consistently in the tree up to the root
 		// just return pvs size 
-		pvsSize = vc->GetPvs().EvalPvsCost();	
+		pvsCost = vc->GetPvs().EvalPvsCost();	
 		break;
 	}
 
-	return pvsSize;  
+	return pvsCost;  
 }
 
@@ -2194,9 +2153,9 @@
 
 	const float vol = mViewCellsManager->GetViewSpaceBox().GetVolume();
-	const int rootPvs = GetPvsSize(mRoot);
+	const float rootPvs = GetPvsCost(mRoot);
 	
 	float totalRenderCost;
 
-	int totalPvs = rootPvs;
+	float totalPvsCost = rootPvs;
 	totalRenderCost = (float)rootPvs;
 
@@ -2217,11 +2176,11 @@
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
 
-			const int parentPvs = GetPvsSize(interior);
-			const float parentCost = (float)parentPvs * interior->GetVolume();
+			const float parentCost = GetPvsCost(interior);
+			const float parentExpCost = parentCost * interior->GetVolume();
 
 			-- numViewCells;
 
+			float childExpCost = 0;
 			float childCost = 0;
-			int childPvs = 0;
 			
 			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
@@ -2231,8 +2190,8 @@
 				ViewCell *vc = *it;
 
-				const int pvsSize = GetPvsSize(vc);
+				const float pvsCost = GetPvsCost(vc);
 				
-				childCost += (float) pvsSize * vc->GetVolume();
-				childPvs += pvsSize;
+				childExpCost += (float) pvsCost * vc->GetVolume();
+				childCost += pvsCost;
 				
 				tqueue.push(vc);
@@ -2241,9 +2200,8 @@
 
 			// update stats for this view cell
-			const float costDecr = (parentCost - childCost) / vol;
+			const float costDecr = (parentExpCost - childExpCost) / vol;
 			totalRenderCost -= costDecr;
-			const float expectedCost = totalRenderCost ;/// (float)numViewCells;
-		
-			costFunction.push_back(expectedCost);
+			
+			costFunction.push_back(totalRenderCost);
 		}
 	}
@@ -2283,9 +2241,9 @@
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
 
-			const int parentPvs = GetPvsSize(interior);
+			const float parentPvsCost = GetPvsCost(interior);
 			const int parentPvsEntries = GetPvsEntries(interior);
-            const float parentCost = (float)parentPvs * interior->GetVolume();
-
-			float childCost = 0;
+            const float parentExpCost = (float)parentPvsCost * interior->GetVolume();
+
+			float childExpCost = 0;
 			int childPvs = 0;
 			int childPvsEntries = 0;
@@ -2299,8 +2257,5 @@
 				ViewCell *vc = *it;
 
-				//const int pvsSize = GetPvsSize(vc);
 				const int pvsEntries = GetPvsEntries(vc);
-
-				//childPvs += pvsSize;
 				childPvsEntries += pvsEntries;
 
@@ -2310,7 +2265,6 @@
 
 			// update stats for this view cell
-			const float costDecr = (parentCost - childCost) / vol;
-
-			//totalPvs += childPvs - parentPvs;
+			const float costDecr = (parentExpCost - childExpCost) / vol;
+
 			entriesInPvs += childPvsEntries - parentPvsEntries;
 
@@ -2328,16 +2282,16 @@
 	++ vcStat.viewCells;
 		
-	const int pvsSize = GetPvsSize(vc);
-
-	vcStat.pvsSize += pvsSize;
-
-	if (pvsSize == 0)
+	const float pvsCost = GetPvsCost(vc);
+
+	vcStat.pvsCost += pvsCost;
+
+	if (pvsCost < Limits::Small)
 		++ vcStat.emptyPvs;
 
-	if (pvsSize > vcStat.maxPvs)
-		vcStat.maxPvs = pvsSize;
-
-	if (pvsSize < vcStat.minPvs)
-		vcStat.minPvs = pvsSize;
+	if (pvsCost > vcStat.maxPvs)
+		vcStat.maxPvs = pvsCost;
+
+	if (pvsCost < vcStat.minPvs)
+		vcStat.minPvs = pvsCost;
 
 	if (!vc->GetValid())
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1709)
@@ -35,10 +35,10 @@
 	/// number of view cells
 	int viewCells;
-	/// size of the PVS
-	int pvsSize;
+	/// cost of the PVS
+	float pvsCost;
 	/// largest PVS of all view cells
-	int maxPvs;
+	float maxPvs;
 	/// smallest PVS of all view cells
-	int minPvs;
+	float minPvs;
 	/// view cells with empty PVS
 	int emptyPvs;
@@ -57,10 +57,10 @@
 
 	double AvgLeaves() const {return (double)leaves / (double)viewCells;};
-	double AvgPvs() const {return (double)pvsSize / (double)viewCells;};
+	double AvgPvs() const {return (double)pvsCost / (double)viewCells;};
 
 	void Reset()
 	{
 		viewCells = 0;
-		pvsSize = 0;
+		pvsCost = 0;
 		maxPvs = 0;
 
@@ -75,4 +75,62 @@
 
 	friend ostream &operator<<(ostream &s, const ViewCellsStatistics &stat)
+	{
+		stat.Print(s);
+		return s;
+	}
+};
+
+
+class ViewCellsTreeStats
+{
+public:
+	int mPass;
+    
+	int mNumViewCells;
+		
+	float mRenderCostDecrease;
+
+    float mTotalRenderCost;
+    
+	float mCurrentPvsCost;
+							
+	float mExpectedCost;
+    
+	float mAvgRenderCost;
+	
+	float mDeviation;
+			
+	float mTotalPvsCost;
+	
+	int mEntriesInPvs;
+    
+	float mMemoryCost;
+	
+	int mPvsSizeDecr;
+	
+	float mVolume;
+
+
+	void Reset()
+	{
+		mPass = 0;
+		mNumViewCells = 0;
+		mRenderCostDecrease = 0;
+		mTotalRenderCost = 0;
+		mCurrentPvsCost = 0;
+		mExpectedCost = 0;
+		mAvgRenderCost = 0;
+		mDeviation = 0;
+		mTotalPvsCost = 0;
+		mEntriesInPvs = 0;
+		mMemoryCost = 0;
+		mPvsSizeDecr = 0;
+		mVolume = 0;
+	}
+
+
+	void Print(ostream &app) const;
+
+	friend ostream &operator<<(ostream &s, const ViewCellsTreeStats &stat)
 	{
 		stat.Print(s);
@@ -181,5 +239,5 @@
 		// HACK: take scalar value because pvs may not have been stored properly
 #if 1
-		return a->mPvsSize < b->mPvsSize;
+		return a->mPvsCost < b->mPvsCost;
 #else
 		return a->GetPvs().EvalPvsCost() < b->GetPvs().EvalPvsCost();
@@ -251,5 +309,5 @@
 	RgbColor mColor;
 	/// store pvs size, used for evaluation purpose when pvss are stored only in the leaves
-	int mPvsSize;
+	float mPvsCost;
 	/** stores number of entries in pvs
 	    this variable has the same value as mPvsSize for object pvs, 
@@ -421,7 +479,7 @@
 	void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
 
-	/** Returns pvs size (i.e. the number of stored objects)
-	*/
-	int GetPvsSize(ViewCell *vc) const;
+	/** Returns pvs size (i.e. the render cost of the stored objects)
+	*/
+	float GetPvsCost(ViewCell *vc) const;
 
 	/** Returns number of entries associated with this view cell. 
@@ -538,5 +596,5 @@
 		@returns difference in pvs size
 	*/
-	ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
+	ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, float &pvsDiff); //const;
 
 	/** Shuffles, i.e. takes border leaf from view cell 1 and adds it 
@@ -601,10 +659,10 @@
 		The pvs is assumed to be stored using lossless compression.
 	*/
-	int GetPvsSizeForCompressedStorage(ViewCell *vc) const;
+	float GetPvsCostForCompressedStorage(ViewCell *vc) const;
 	
 	/** Computes pvs size of this view cell.
 		The pvs is assumed to be stored in the leaves.
 	*/
-	int GetPvsSizeForLeafStorage(ViewCell *vc) const;
+	float GetPvsCostForLeafStorage(ViewCell *vc) const;
 
 	/** Counts the logical number of entries in the pvs this view cell.
@@ -616,17 +674,5 @@
 	*/
 	void UpdateStats(ofstream &stats,
-					 const int pass,
-					 const int viewCells,
-					 const float renderCostDecrease,
-					 const float totalRenderCost,
-					 const int currentPvs,
-					 const float expectedCost,
-					 const float avgRenderCost,
-					 const float deviation,
-					 const int totalPvs,
-					 const int entriesInPvs,
-					 const float memoryCost,
-					 const int pvsSizeDecr,
-					 const float volume);
+					 const ViewCellsTreeStats &vcStats);
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1709)
@@ -1619,76 +1619,213 @@
 
 
-void HierarchyManager::EvaluateSubdivision(const VssRayContainer &sampleRays,											 							   
-										   const ObjectContainer &objects,
-										   const string &filename)
-{
-	VspTree *oldVspTree = mVspTree;
-	ViewCellsManager *vm = mVspTree->mViewCellsManager;
-	BvHierarchy *oldHierarchy = mBvHierarchy;
-
-	mBvHierarchy = new BvHierarchy();
-	mBvHierarchy->mHierarchyManager = this;
-	mBvHierarchy->mViewCellsManager = vm;
-
-	mVspTree = new VspTree();
-	mVspTree->mHierarchyManager = this;
-	mVspTree->mViewCellsManager = vm;
-
-	// create first nodes
-	mVspTree->Initialise(sampleRays, &oldVspTree->mBoundingBox);
-	InitialiseObjectSpaceSubdivision(objects);
-
-	const long startTime = GetTime();
-	cout << "Constructing evaluation hierarchies ... \n";
-	
-	ofstream stats;
-	stats.open(filename.c_str());
-	SplitQueue tQueue;
-
-	BvhNode *oldBvhRoot = oldHierarchy->GetRoot();
-	VspNode *oldVspRoot = oldVspTree->GetRoot();
-
-	RayInfoContainer *viewSpaceRays = new RayInfoContainer();
-	
-	SubdivisionCandidate *firstVsp = mVspTree->PrepareConstruction(sampleRays, *viewSpaceRays);
-	SubdivisionCandidate *firstBvh = mBvHierarchy->PrepareConstruction(sampleRays, objects);
-
-    firstVsp->mEvaluationHack = oldVspRoot;
-	firstBvh->mEvaluationHack = oldBvhRoot;
-
-	firstVsp->SetPriority((float)-oldVspRoot->mTimeStamp);
-	firstBvh->SetPriority((float)-oldBvhRoot->mTimeStamp);
-
-	tQueue.Push(firstVsp);
-	tQueue.Push(firstBvh);
-
-	ExportStats(stats, tQueue, objects);
-
-	cout << "\nfinished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-	RemoveRayRefs(objects);
-
-	// view cells needed only for evaluation
+class HierarchyNodeWrapper;
+
+
+template <typename T> class myless
+{
+public:
+	bool operator() (T v1, T v2) const
+	{
+		return (v1->GetMergeCost() < v2->GetMergeCost());
+	}
+};
+
+
+typedef priority_queue<HierarchyNodeWrapper *, vector<HierarchyNodeWrapper *>, 
+					   myless<vector<HierarchyNodeWrapper *>::value_type> > HierarchyNodeQueue;
+
+class HierarchyNodeWrapper
+{
+public:
+	enum {VSP_NODE, BVH_NODE, VIEW_CELL};
+
+	virtual float GetMergeCost() const = 0;
+	virtual int Type() const  = 0;
+	virtual bool IsLeaf() const = 0;
+
+	virtual void PushChildren(HierarchyNodeQueue &tQueue) = 0;
+};
+
+
+class VspNodeWrapper: public HierarchyNodeWrapper
+{
+public:
+	VspNodeWrapper(VspNode *node): mNode(node) {}
+
+	int Type() const { return VSP_NODE; }
+
+	float GetMergeCost() const { return (float) -mNode->mTimeStamp; };
+
+	bool IsLeaf() const { return mNode->IsLeaf(); }
+
+	void PushChildren(HierarchyNodeQueue &tQueue)
+	{
+		if (!mNode->IsLeaf())
+		{
+			VspInterior *interior = dynamic_cast<VspInterior *>(mNode);
+
+			tQueue.push(new VspNodeWrapper(interior->GetFront()));
+			tQueue.push(new VspNodeWrapper(interior->GetBack()));
+		}
+	}
+
+	VspNode *mNode;
+};
+
+
+class BvhNodeWrapper: public HierarchyNodeWrapper
+{
+public:
+	BvhNodeWrapper(BvhNode *node): mNode(node) {}
+	
+	int Type()  const { return BVH_NODE; }
+
+	float GetMergeCost() const { return (float)-mNode->mTimeStamp; };
+
+	bool IsLeaf() const { return mNode->IsLeaf(); }
+
+	void PushChildren(HierarchyNodeQueue &tQueue)
+	{
+		if (!mNode->IsLeaf())
+		{
+			BvhInterior *interior = dynamic_cast<BvhInterior *>(mNode);
+
+			tQueue.push(new BvhNodeWrapper(interior->GetFront()));
+			tQueue.push(new BvhNodeWrapper(interior->GetBack()));
+		}
+	}
+
+	BvhNode *mNode;
+};
+
+
+class ViewCellWrapper: public HierarchyNodeWrapper
+{
+public:
+
+	ViewCellWrapper(ViewCell *vc): mViewCell(vc) {}
+	
+	int Type()  const { return VIEW_CELL; }
+
+	float GetMergeCost() const { return mViewCell->GetMergeCost(); };
+
+	bool IsLeaf() const { return mViewCell->IsLeaf(); }
+
+	void PushChildren(HierarchyNodeQueue &tQueue)
+	{
+		if (!mViewCell->IsLeaf())
+		{
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(mViewCell);
+
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it)
+			{
+				tQueue.push(new ViewCellWrapper(*it));
+			}
+		}
+	}
+
+	ViewCell *mViewCell;
+};
+
+
+void HierarchyManager::CollectBestSet(const int maxSplits,
+									  const float maxMemoryCost,
+									  ViewCellContainer &viewCells,
+									  vector<BvhNode *> &bvhNodes)
+{
+	HierarchyNodeQueue tqueue;
+	//tqueue.push(new VspNodeWrapper(mVspTree->GetRoot()));
+	tqueue.push(new ViewCellWrapper(mVspTree->mViewCellsTree->GetRoot()));
+	tqueue.push(new BvhNodeWrapper(mBvHierarchy->GetRoot()));
+	
+	float memCost = 0;
+
+	while (!tqueue.empty())
+	{
+		HierarchyNodeWrapper *nodeWrapper = 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 (nodeWrapper->IsLeaf() || 
+			((viewCells.size() + bvhNodes.size() + tqueue.size() + 1) >= maxSplits) ||
+			(memCost > maxMemoryCost)
+			)
+		{
+			if (nodeWrapper->Type() == HierarchyNodeWrapper::VSP_NODE)
+			{
+				ViewCellWrapper *viewCellWrapper = dynamic_cast<ViewCellWrapper *>(nodeWrapper);
+				viewCells.push_back(viewCellWrapper->mViewCell);
+			}
+			else
+			{
+				BvhNodeWrapper *bvhNodeWrapper = dynamic_cast<BvhNodeWrapper *>(nodeWrapper);
+				bvhNodes.push_back(bvhNodeWrapper->mNode);
+			}
+		}
+		else 
+		{	
+			nodeWrapper->PushChildren(tqueue);
+		}
+
+		delete nodeWrapper;
+	}
+}
+
+
+bool HierarchyManager::ExtractStatistics(const int maxSplits,
+										 const float maxMemoryCost,
+										 float &renderCost,
+										 float &memory,
+										 int &pvsEntries)
+{
 	ViewCellContainer viewCells;
-	mVspTree->CollectViewCells(viewCells, false);
-	
-	// helper trees can be destroyed
-	DEL_PTR(mVspTree);
-	DEL_PTR(mBvHierarchy);
-
-	CLEAR_CONTAINER(viewCells);
-
-	// reset hierarchies
-	mVspTree = oldVspTree;
-	mBvHierarchy = oldHierarchy;
-
-	// reinstall old bv refs
-	vector<BvhLeaf *> leaves;
-	mBvHierarchy->CollectLeaves(mBvHierarchy->GetRoot(), leaves);
-	vector<BvhLeaf *>::const_iterator bit, bit_end = leaves.end();
-
-	for (bit = leaves.begin(); bit != bit_end; ++ bit)
-	{
-		mBvHierarchy->AssociateObjectsWithLeaf(*bit);
-	}
+	vector<BvhNode *> bvhNodes;
+
+	// collect best set of view cells for this #splits
+    CollectBestSet(maxSplits, maxMemoryCost, viewCells, bvhNodes);
+
+	vector<BvhNode *>::const_iterator bit, bit_end = bvhNodes.end();
+	
+	for (bit = bvhNodes.begin(); bit != bit_end; ++ bit)
+	{
+		mBvHierarchy->SetActive(*bit);
+	}
+
+	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+
+	int numEntries = 0;
+	float pvsCost = 0.0f;
+
+	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+	{
+		ViewCell *vc = *vit;
+		ObjectPvs pvs;
+		mVspTree->mViewCellsTree->GetPvs(vc, pvs);
+
+		BvhNode::NewMail();
+
+		// hack: should not be done here
+		ObjectPvsMap::const_iterator oit, oit_end = pvs.mEntries.end();
+
+		for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit)
+		{
+			BvhIntersectable *intersect = dynamic_cast<BvhIntersectable *>((*oit).first);
+			BvhLeaf *leaf = intersect->GetItem();
+			BvhNode *activeNode = leaf->GetActiveNode();
+
+			if (!activeNode->Mailed())
+			{
+				activeNode->Mail();
+
+				++ numEntries;
+				pvsCost += mBvHierarchy->EvalAbsCost(leaf->mObjects);
+			}
+		}
+	}
+
+	return (viewCells.size() + bvhNodes.size() < mHierarchyStats.Leaves());
 }
 
@@ -1707,4 +1844,5 @@
 	/////////////
 	//-- first view cell
+
 	UpdateStats(stats, 2, totalRenderCost, entriesInPvs, memoryCost, true);
 
@@ -1770,331 +1908,112 @@
 
 
-
-class HierarchyNodeWrapper;
-
-
-template <typename T> class myless
-{
-public:
-	bool operator() (T v1, T v2) const
-	{
-		return (v1->GetMergeCost() < v2->GetMergeCost());
-	}
-};
-
-typedef priority_queue<HierarchyNodeWrapper *, vector<HierarchyNodeWrapper *>, 
-					   myless<vector<HierarchyNodeWrapper *>::value_type> > HierarchyNodeQueue;
-
-class HierarchyNodeWrapper
-{
-public:
-	enum {VSP_NODE, BVH_NODE, VIEW_CELL};
-
-	virtual float GetMergeCost() const = 0;
-	virtual int Type() const  = 0;
-	virtual bool IsLeaf() const = 0;
-
-	virtual void PushChildren(HierarchyNodeQueue &tQueue) = 0;
-};
-
-
-class VspNodeWrapper: public HierarchyNodeWrapper
-{
-public:
-	VspNodeWrapper(VspNode *node): mNode(node) {}
-
-	int Type() const { return VSP_NODE; }
-
-	float GetMergeCost() const { return (float) -mNode->mTimeStamp; };
-
-	bool IsLeaf() const { return mNode->IsLeaf(); }
-
-	void PushChildren(HierarchyNodeQueue &tQueue)
-	{
-		if (!mNode->IsLeaf())
-		{
-			VspInterior *interior = dynamic_cast<VspInterior *>(mNode);
-
-			tQueue.push(new VspNodeWrapper(interior->GetFront()));
-			tQueue.push(new VspNodeWrapper(interior->GetBack()));
-		}
-	}
-
-	VspNode *mNode;
-};
-
-
-class BvhNodeWrapper: public HierarchyNodeWrapper
-{
-public:
-	BvhNodeWrapper(BvhNode *node): mNode(node) {}
-	
-	int Type()  const { return BVH_NODE; }
-
-	float GetMergeCost() const { return (float)-mNode->mTimeStamp; };
-
-	bool IsLeaf() const { return mNode->IsLeaf(); }
-
-	void PushChildren(HierarchyNodeQueue &tQueue)
-	{
-		if (!mNode->IsLeaf())
-		{
-			BvhInterior *interior = dynamic_cast<BvhInterior *>(mNode);
-
-			tQueue.push(new BvhNodeWrapper(interior->GetFront()));
-			tQueue.push(new BvhNodeWrapper(interior->GetBack()));
-		}
-	}
-
-	BvhNode *mNode;
-};
-
-
-class ViewCellWrapper: public HierarchyNodeWrapper
-{
-public:
-
-	ViewCellWrapper(ViewCell *vc): mViewCell(vc) {}
-	
-	int Type()  const { return VIEW_CELL; }
-
-	float GetMergeCost() const { return mViewCell->GetMergeCost(); };
-
-	bool IsLeaf() const { return mViewCell->IsLeaf(); }
-
-	void PushChildren(HierarchyNodeQueue &tQueue)
-	{
-		if (!mViewCell->IsLeaf())
-		{
-			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(mViewCell);
-
-			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
-
-			for (it = interior->mChildren.begin(); it != it_end; ++ it)
-			{
-				tQueue.push(new ViewCellWrapper(*it));
-			}
-		}
-	}
-
-	ViewCell *mViewCell;
-};
-
-
-void HierarchyManager::CollectBestSet(const int maxSplits,
-									  const float maxMemoryCost,
-				//					  vector<VspNode *> &vspNodes,
-									  ViewCellContainer &viewCells,
-									  vector<BvhNode *> &bvhNodes)
-{
-	HierarchyNodeQueue tqueue;
-	//tqueue.push(new VspNodeWrapper(mVspTree->GetRoot()));
-	tqueue.push(new ViewCellWrapper(mVspTree->mViewCellsTree->GetRoot()));
-	tqueue.push(new BvhNodeWrapper(mBvHierarchy->GetRoot()));
-	
-	float memCost = 0;
-
-	while (!tqueue.empty())
-	{
-		HierarchyNodeWrapper *nodeWrapper = 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 (nodeWrapper->IsLeaf() || 
-			((viewCells.size() + bvhNodes.size() + tqueue.size() + 1) >= maxSplits) ||
-			(memCost > maxMemoryCost)
-			)
-		{
-			if (nodeWrapper->Type() == HierarchyNodeWrapper::VSP_NODE)
-			{
-				ViewCellWrapper *viewCellWrapper = dynamic_cast<ViewCellWrapper *>(nodeWrapper);
-				viewCells.push_back(viewCellWrapper->mViewCell);
-			}
-			else
-			{
-				BvhNodeWrapper *bvhNodeWrapper = dynamic_cast<BvhNodeWrapper *>(nodeWrapper);
-				bvhNodes.push_back(bvhNodeWrapper->mNode);
-			}
-		}
-		else 
-		{	
-			nodeWrapper->PushChildren(tqueue);
-		}
-
-		delete nodeWrapper;
-	}
-}
-
-
-void HierarchyManager::ExtractStatistics(const int maxSplits,
-										 const float maxMemoryCost,
-										 float &renderCost,
-										 float &memory,
-										 int &pvsEntries)
-{
-	//vector<VspNode *> vspNodes;
+void HierarchyManager::EvaluateSubdivision(const VssRayContainer &sampleRays,											 							   
+										   const ObjectContainer &objects,
+										   const string &filename)
+{
+	VspTree *oldVspTree = mVspTree;
+	ViewCellsManager *vm = mVspTree->mViewCellsManager;
+	BvHierarchy *oldHierarchy = mBvHierarchy;
+
+	mBvHierarchy = new BvHierarchy();
+	mBvHierarchy->mHierarchyManager = this;
+	mBvHierarchy->mViewCellsManager = vm;
+
+	mVspTree = new VspTree();
+	mVspTree->mHierarchyManager = this;
+	mVspTree->mViewCellsManager = vm;
+
+	// create first nodes
+	mVspTree->Initialise(sampleRays, &oldVspTree->mBoundingBox);
+	InitialiseObjectSpaceSubdivision(objects);
+
+	const long startTime = GetTime();
+	cout << "Constructing evaluation hierarchies ... \n";
+	
+	ofstream stats;
+	stats.open(filename.c_str());
+	SplitQueue tQueue;
+
+	BvhNode *oldBvhRoot = oldHierarchy->GetRoot();
+	VspNode *oldVspRoot = oldVspTree->GetRoot();
+
+	RayInfoContainer *viewSpaceRays = new RayInfoContainer();
+	
+	SubdivisionCandidate *firstVsp = mVspTree->PrepareConstruction(sampleRays, *viewSpaceRays);
+	SubdivisionCandidate *firstBvh = mBvHierarchy->PrepareConstruction(sampleRays, objects);
+
+    firstVsp->mEvaluationHack = oldVspRoot;
+	firstBvh->mEvaluationHack = oldBvhRoot;
+
+	firstVsp->SetPriority((float)-oldVspRoot->mTimeStamp);
+	firstBvh->SetPriority((float)-oldBvhRoot->mTimeStamp);
+
+	tQueue.Push(firstVsp);
+	tQueue.Push(firstBvh);
+
+	ExportStats(stats, tQueue, objects);
+
+	cout << "\nfinished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+	RemoveRayRefs(objects);
+
+	// view cells needed only for evaluation
 	ViewCellContainer viewCells;
-	vector<BvhNode *> bvhNodes;
-
-    CollectBestSet(maxSplits, maxMemoryCost, viewCells, bvhNodes);
-
-	vector<BvhNode *>::const_iterator bit, bit_end = bvhNodes.end();
-	
-	for (bit = bvhNodes.begin(); bit != bit_end; ++ bit)
-	{
-		mBvHierarchy->SetActive(*bit);
-	}
-
-	//vector<VspNode *>::const_iterator vit, vit_end = vspNodes.end();
-
-	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
-
-	int numEntries = 0;
-	float pvsCost = 0.0f;
-
-	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
-	{
-		ViewCell *vc = *vit;
-		ObjectPvs pvs;
-		mVspTree->mViewCellsTree->GetPvs(vc, pvs);
-
-		BvhNode::NewMail();
-
-		// hack: should not be done here
-		ObjectPvsMap::const_iterator oit, oit_end = pvs.mEntries.end();
-
-		for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit)
-		{
-			BvhIntersectable *intersect = dynamic_cast<BvhIntersectable *>((*oit).first);
-			BvhLeaf *leaf = intersect->GetItem();
-			BvhNode *activeNode = leaf->GetActiveNode();
-
-			if (!activeNode->Mailed())
-			{
-				activeNode->Mail();
-
-				++ numEntries;
-				pvsCost += mBvHierarchy->EvalAbsCost(leaf->mObjects);
-			}
-		}
-	}
-
-	/*TraversalQueue tqueue;
-	tqueue.push(mRoot);
-
-	//cout << "exporting stats ... " << endl;
-	int numViewCells = 1;
-	
-	const AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
-	const float vol = box.GetVolume();
-
-	const int rootPvs = GetPvsSize(mRoot);
-	const int rootEntries = GetPvsEntries(mRoot);
-	float totalRenderCost, avgRenderCost, expectedCost;
-
-	float deviation = 0;
-	int totalPvs = rootPvs;
-	int entriesInPvs = rootEntries;
-
-	totalRenderCost = avgRenderCost = expectedCost = (float)rootPvs;
-
-	ofstream stats;
-	stats.open(mergeStats.c_str());
-
-	const float memoryCost = (float)entriesInPvs * ObjectPvs::GetEntrySize();
-
-	/////////////
-	//-- first view cell
-
-	UpdateStats(stats,
-				0, 
-				numViewCells, 
-				0, 
-				totalRenderCost, 
-				rootPvs, 
-				expectedCost, 
-				avgRenderCost, 
-				deviation,
-				totalPvs, 
-				entriesInPvs,
-				memoryCost,
-				0, 
-				mRoot->GetVolume());
-		
-
-	//-- 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);
-
-				childCost += (float) pvsSize * vc->GetVolume();
-				childPvs += pvsSize;
-				childPvsEntries += pvsEntries;
-
-				tqueue.push(vc);
-				++ numViewCells;
-			}
-
-			// update stats for this view cell
-			const float costDecr = (parentCost - childCost) / vol;
-
-			totalRenderCost -= costDecr;
-			totalPvs += childPvs - parentPvs;
-			entriesInPvs += childPvsEntries - parentPvsEntries;
-
-			expectedCost = totalRenderCost / (float)numViewCells;
-			avgRenderCost = (float)totalPvs / (float)numViewCells;
-
-			const float memoryCost = (float)entriesInPvs * ObjectPvs::GetEntrySize();
-
-			UpdateStats(stats,
-						0, 
-						numViewCells, 
-						costDecr, 
-						totalRenderCost,
-						parentPvs, 
-						expectedCost, 
-						avgRenderCost, 
-						deviation,
-                        totalPvs, 
-						entriesInPvs, 
-						memoryCost,
-						childPvs - parentPvs,
-						vc->GetVolume());
-		}
-	}
-
-	stats.close();
-	*/
-}
-	
-}
+	mVspTree->CollectViewCells(viewCells, false);
+	
+	// helper trees can be destroyed
+	DEL_PTR(mVspTree);
+	DEL_PTR(mBvHierarchy);
+
+	CLEAR_CONTAINER(viewCells);
+
+	// reset hierarchies
+	mVspTree = oldVspTree;
+	mBvHierarchy = oldHierarchy;
+
+	// reinstall old bv refs
+	vector<BvhLeaf *> leaves;
+	mBvHierarchy->CollectLeaves(mBvHierarchy->GetRoot(), leaves);
+	vector<BvhLeaf *>::const_iterator bit, bit_end = leaves.end();
+
+	for (bit = leaves.begin(); bit != bit_end; ++ bit)
+	{
+		mBvHierarchy->AssociateObjectsWithLeaf(*bit);
+	}
+}
+
+
+void HierarchyManager::EvaluateSubdivision2(ofstream &splitsStats,
+											ofstream &memStats,
+											const int splitsStepSize,
+											const float memStepSize)
+{
+	int splits = 0;
+	float mem = 15;
+
+	float renderCost;
+	float memory;
+	int pvsEntries;
+
+	while (1)
+	{
+		if (!ExtractStatistics(i, 99999999, renderCost, memory, pvsEntries))
+			break;
+
+		UpdateStats(splitsStats, splits, renderCost, pvsEntries, memory, 0);
+
+		splits += splitsStepSize
+	}
+
+	while (1)
+	{
+		if (!ExtractStatistics(99999999, mem, renderCost, memory, pvsEntries))
+			break;
+
+		UpdateStats(splitsStats, splits, renderCost, pvsEntries, memory, 0);
+
+		mem += memStepSize
+	}
+
+}
+
+}
