Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1695)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1713)
@@ -1427,4 +1427,9 @@
 					"0");
 
+	RegisterOption("ViewCells.Evaluation.stepSize",
+					optInt,
+					"view_cells_evaluation_step_size=",
+					"100");
+
 	RegisterOption("ViewCells.maxPvsRatio",
 					optFloat,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1701)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1713)
@@ -313,5 +313,5 @@
 	ObjectContainer::const_iterator oit, oit_end = objects.end();
 
-	//AxisAlignedBox3 bbox = mSceneGraph->GetBox(); bbox.Enlarge(30.0);
+	AxisAlignedBox3 bbox = mSceneGraph->GetBox(); bbox.Enlarge(30.0);
 	for (oit = objects.begin(); oit != oit_end; ++ oit)
 	{
@@ -321,10 +321,9 @@
 		{
 			Triangle3 tri = dynamic_cast<TriangleIntersectable *>(obj)->GetItem();
-
 			//if (bbox.IsInside(tri.mVertices[0]) && bbox.IsInside(tri.mVertices[1]) && bbox.IsInside(tri.mVertices[2]))
 			//{
-			samplesOut << "v " << tri.mVertices[0].x << " " << tri.mVertices[0].y << " " << tri.mVertices[0].z << endl;
-			samplesOut << "v " << tri.mVertices[1].x << " " << tri.mVertices[1].y << " " << tri.mVertices[1].z << endl;
-			samplesOut << "v " << tri.mVertices[2].x << " " << tri.mVertices[2].y << " " << tri.mVertices[2].z << endl;
+				samplesOut << "v " << tri.mVertices[0].x << " " << tri.mVertices[0].y << " " << tri.mVertices[0].z << endl;
+				samplesOut << "v " << tri.mVertices[1].x << " " << tri.mVertices[1].y << " " << tri.mVertices[1].z << endl;
+				samplesOut << "v " << tri.mVertices[2].x << " " << tri.mVertices[2].y << " " << tri.mVertices[2].z << endl;
 			//}
 		}
@@ -337,11 +336,16 @@
 	// write faces
 	int i = 1;
-	for (oit = objects.begin(); oit != oit_end; ++ oit, i += 3)
+	for (oit = objects.begin(); oit != oit_end; ++ oit)
 	{
 		Intersectable *obj = *oit;
 		if (obj->Type() == Intersectable::TRIANGLE_INTERSECTABLE)
 		{
-			Triangle3 tri = dynamic_cast<TriangleIntersectable *>(obj)->GetItem();
-			samplesOut << "f " << i << " " << i + 1 << " " << i + 2 << endl;
+			//Triangle3 tri = dynamic_cast<TriangleIntersectable *>(obj)->GetItem();
+			//if (bbox.IsInside(tri.mVertices[0]) && bbox.IsInside(tri.mVertices[1]) && bbox.IsInside(tri.mVertices[2]))
+			//{
+				Triangle3 tri = dynamic_cast<TriangleIntersectable *>(obj)->GetItem();
+				samplesOut << "f " << i << " " << i + 1 << " " << i + 2 << endl;
+				i += 3;
+			//}
 		}
 		else
@@ -484,4 +488,5 @@
 			}
 
+			// temporare hack
 			//if (!strstr(filename.c_str(), "plane")) mSceneGraph->GetRoot()->UpdateBox();
 
@@ -507,7 +512,13 @@
 		mObjects.reserve(intersectables);
 		mSceneGraph->CollectObjects(&mObjects);
+		
+		// temp hack
+		//ExportObj("cropped_vienna.obj", mObjects);
+
 		mSceneGraph->GetRoot()->UpdateBox();
-
+				
 		cout << "finished loading" << endl;
+
+		
 		if (0)
 		{
@@ -1141,4 +1152,5 @@
 		pertub.y = RandomValue(0.0f, pertubDir);
 		pertub.z = RandomValue(0.0f, pertubDir);
+
 		const Vector3 newDir = mainRay.mDirection + pertub;
 		//const Vector3 newDir = mainRay.mDirection;
@@ -1147,4 +1159,5 @@
 		pertub.y = RandomValue(0.0f, pertubOrigin);
 		pertub.z = RandomValue(0.0f, pertubOrigin);
+
 		const Vector3 newOrigin = mainRay.mOrigin + pertub;
 		//const Vector3 newOrigin = mainRay.mOrigin;
@@ -1159,13 +1172,11 @@
 void Preprocessor::SetupRay(Ray &ray,
 							const Vector3 &point,
-							const Vector3 &direction
-							) const
+							const Vector3 &direction) const
 {
 	ray.Clear();
 	// do not store anything else then intersections at the ray
-	ray.Init(point, direction, Ray::LOCAL_RAY);
-	
-}
-
-
-}
+	ray.Init(point, direction, Ray::LOCAL_RAY);	
+}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1710)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1713)
@@ -241,7 +241,5 @@
 
 	void EvaluateSubdivision2(ofstream &splitsStats,
-							  ofstream &memStats,
-							  const int splitsStepSize,
-							  const float memStepSize);
+							  const int splitsStepSize);
 
 
@@ -461,9 +459,9 @@
 						vector<BvhNode *> &bvhNodes);
 
-	bool ExtractStatistics(const int maxSplits,
-						   const float maxMemoryCost,
-						   float &renderCost,
-						   float &memory,
-						   int &pvsEntries);
+	int ExtractStatistics(const int maxSplits,
+						  const float maxMemoryCost,
+						  float &renderCost,
+						  float &memory,
+						  int &pvsEntries);
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1709)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1713)
@@ -822,4 +822,5 @@
 #endif
 
+#if 1
 
 float BvHierarchy::EvalSah(const BvhTraversalData &tData,
@@ -930,4 +931,159 @@
 		const bool noValidSplit = ((objectsLeft <= Limits::Small) || (objectsRight <= Limits::Small));
 
+		const float sum =  noValidSplit ? 1e25 : objectsLeft * al + objectsRight * ar;
+      
+		/*cout << "pos=" << (*cit).mPos << "\t q=(" << objectsLeft << "," << objectsRight <<")\t r=(" 
+			 << lbox.SurfaceArea() << "," << rbox.SurfaceArea() << ")" << endl;
+		cout << "minborder: " << minBorder << " maxborder: " << maxBorder << endl;
+	    cout << "cost= " << sum << endl;
+*/
+	
+		if (sum < minSum) 
+		{	//cout <<" sum: " << sum;
+			minSum = sum;
+			areaLeft = al;
+			areaRight = ar;
+
+			// objects belong to left side now
+			for (; currentPos != (cit + 1); ++ currentPos);
+		}
+	}
+
+	////////////////////////////////////////////
+	//-- assign object to front and back volume
+
+	// belongs to back bv
+	for (cit = mSubdivisionCandidates->begin(); cit != currentPos; ++ cit)
+		objectsBack.push_back((*cit).mObject);
+	
+	// belongs to front bv
+	for (cit = currentPos; cit != cit_end; ++ cit)
+		objectsFront.push_back((*cit).mObject);
+
+	float newCost = minSum / boxArea;
+	float ratio = newCost / totalRenderCost;
+  
+#ifdef _DEBUG
+	cout << "\n\nobjects=(" << (int)objectsBack.size() << "," << (int)objectsFront.size() << " of " 
+		 << (int)tData.mNode->mObjects.size() << ")\t area=(" 
+		 << areaLeft << ", " << areaRight << ", " << boxArea << ")" << endl
+		 << "cost= " << newCost << " oldCost=" << totalRenderCost / boxArea << endl;
+#endif
+
+	return ratio;
+}
+#else
+
+float BvHierarchy::EvalSah(const BvhTraversalData &tData,
+						   const int axis,
+						   ObjectContainer &objectsFront,
+						   ObjectContainer &objectsBack)
+{
+	// go through the lists, count the number of objects left and right
+	// and evaluate the following cost funcion:
+	// C = ct_div_ci  + (ol + or) / queries
+	PrepareLocalSubdivisionCandidates(tData, axis);
+
+	const float totalRenderCost = EvalAbsCost(tData.mNode->mObjects);
+	float objectsLeft = 0, objectsRight = totalRenderCost;
+  
+	const AxisAlignedBox3 nodeBbox = tData.mNode->GetBoundingBox();
+
+	const float minBox = nodeBbox.Min(axis);
+	const float maxBox = nodeBbox.Max(axis);
+	const float boxArea = nodeBbox.SurfaceArea();
+
+	float minSum = 1e20f;
+  
+	Vector3 minBorder = nodeBbox.Max();
+	Vector3 maxBorder = nodeBbox.Min();
+
+	float areaLeft = 0, areaRight = 0;
+
+	SortableEntryContainer::const_iterator currentPos =
+		mSubdivisionCandidates->begin();
+	
+	vector<Vector3> bordersRight;
+
+	if (mUseBboxAreaForSah)
+	{
+		// we keep track of both borders of the bounding boxes =>
+		// store the events in descending order
+		bordersRight.resize(mSubdivisionCandidates->size());
+
+		SortableEntryContainer::reverse_iterator rcit = 
+			mSubdivisionCandidates->rbegin(), rcit_end = mSubdivisionCandidates->rend();
+	
+		vector<Vector3>::reverse_iterator rbit = bordersRight.rbegin();
+	
+		for (; rcit != rcit_end; ++ rcit, ++ rbit) 
+		{
+			Intersectable *obj = (*rcit).mObject;
+			const AxisAlignedBox3 obox = obj->GetBox();
+
+			for (int i = 0; i < 3; ++ i)
+			{
+				if (obox.Min(i) < minBorder[i])
+				{
+					minBorder[i] = obox.Min(i);
+				}
+			}
+
+			(*rbit) = minBorder;
+		}
+	}
+
+	// temporary surface areas
+	float al = 0;
+	float ar = boxArea;
+
+	vector<Vector3>::const_iterator bit = bordersRight.begin();
+	SortableEntryContainer::const_iterator cit, cit_end = mSubdivisionCandidates->end();
+
+	for (cit = mSubdivisionCandidates->begin(); cit != cit_end; ++ cit, ++ bit) 
+	{
+		Intersectable *obj = (*cit).mObject;
+
+		const float renderCost = mViewCellsManager->EvalRenderCost(obj);
+		
+		objectsLeft += renderCost;
+		objectsRight -= renderCost;
+
+		const AxisAlignedBox3 obox = obj->GetBox();
+
+		if (mUseBboxAreaForSah)
+		{
+			AxisAlignedBox3 lbox = nodeBbox;
+			AxisAlignedBox3 rbox = nodeBbox;
+	
+			// the borders of the bounding boxes have changed
+			for (int i = 0; i < 3; ++ i)
+			{
+				if (obox.Max(i) > maxBorder[i])
+				{
+					maxBorder[i] = obox.Max(i);
+				}
+			}
+
+			minBorder = (*bit);
+
+			lbox.SetMax(maxBorder);
+			rbox.SetMin(minBorder);
+	
+			al = lbox.SurfaceArea();
+			ar = rbox.SurfaceArea();
+		}
+		else
+		{
+			// just add up areas of the objects itself
+			// (as we are not sampling volumetric visibility,
+			// this should provide better heuristics
+			const float area = obj->GetArea();//obox.SurfaceArea();
+
+			al += area;
+			ar -= area;
+		}
+
+		const bool noValidSplit = ((objectsLeft <= Limits::Small) || (objectsRight <= Limits::Small));
 		const float sum =  noValidSplit ? 1e25 : objectsLeft * al + objectsRight * ar;
       
@@ -971,7 +1127,8 @@
 #endif
 
-  return ratio;
-}
-
+	return ratio;
+}
+
+#endif
 
 static bool PrepareOutput(const int axis,
@@ -1480,5 +1637,5 @@
 	// probability that view point lies in a view cell which sees this node
 	const float p = EvalViewCellsVolume(objects) / viewSpaceVol;
-    float objRenderCost = EvalAbsCost(objects);
+    const float objRenderCost = EvalAbsCost(objects);
 	
 	return objRenderCost * p;
@@ -2161,10 +2318,9 @@
 	// sets the pointers to the currently active view cells
 	CollectLeaves(node, leaves);
-
-	vector<BvhLeaf *>::const_iterator bit, bit_end = leaves.end();
-
-	for (bit = leaves.begin(); bit != bit_end; ++ bit)
-	{
-		(*bit)->SetActiveNode(node);
+	vector<BvhLeaf *>::const_iterator lit, lit_end = leaves.end();
+
+	for (lit = leaves.begin(); lit != lit_end; ++ lit)
+	{
+		(*lit)->SetActiveNode(node);
 	}
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1710)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1713)
@@ -3384,5 +3384,5 @@
 		
 	// evaluate merge cost for priority traversal
-	const float mergeCost = 1.0f / (float)root->mTimeStamp;
+	const float mergeCost =  -(float)root->mTimeStamp;
 	vcRoot->SetMergeCost(mergeCost);
 
@@ -3428,5 +3428,5 @@
 		
 	// evaluate merge cost for priority traversal
-	float mergeCost = 1.0f / (float)root->mTimeStamp;
+	const float mergeCost = -(float)root->mTimeStamp;
 	viewCellInterior->SetMergeCost(mergeCost);
 
@@ -5048,5 +5048,5 @@
 		
 	// evaluate merge cost for priority traversal
-	float mergeCost = 1.0f / (float)root->mTimeStamp;
+	const float mergeCost = -(float)root->mTimeStamp;
 	viewCellInterior->SetMergeCost(mergeCost);
 
@@ -5747,8 +5747,11 @@
 	int numSamples;
 	int castSamples = 0;
+	int splitsStepSize;
+
 	char str[64]; 
-
+	
 	Environment::GetSingleton()->GetIntValue("ViewCells.Evaluation.samplesPerPass", samplesPerPass);
 	Environment::GetSingleton()->GetIntValue("ViewCells.Evaluation.samples", numSamples);
+	Environment::GetSingleton()->GetIntValue("ViewCells.Evaluation.stepSize", splitsStepSize);
 
 	char statsPrefix[100];
@@ -5782,8 +5785,8 @@
     cout << "Evaluating view cell partition ... " << endl;
 
-	VssRayContainer evaluationSamples;
-
 	while (castSamples < numSamples)
 	{		
+		VssRayContainer evaluationSamples;
+
 		///////////////
 		//-- we have to use uniform sampling strategy for construction rays
@@ -5822,21 +5825,13 @@
 		//-- output stats
 
-		const int splitsStepSize = 500;
-		const float memStepSize = 1.0f;
-
-		sprintf(str, "-splits-%09d-eval.log", castSamples);
+		sprintf(str, "-%09d-eval.log", castSamples);
 		const string splitsFilename = string(statsPrefix) + string(str);
-		
-		sprintf(str, "-mem-%09d-eval.log", castSamples);
-		const string memFilename = string(statsPrefix) + string(str);
 
 		ofstream splitsStr(splitsFilename.c_str());
-		ofstream memStr(memFilename.c_str());
-		
-		mHierarchyManager->EvaluateSubdivision2(splitsStr, memStr, splitsStepSize, memStepSize);
+		mHierarchyManager->EvaluateSubdivision2(splitsStr, splitsStepSize);
 
 		timeDiff = TimeDiff(startTime, GetTime());
 		cout << "finished in " << timeDiff * 1e-3 << " secs" << endl;
-		Debug << "statistis compted in " << timeDiff * 1e-3 << " secs" << endl;
+		Debug << "statistics computed in " << timeDiff * 1e-3 << " secs" << endl;
 	
 		disposeRays(evaluationSamples, NULL);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1709)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1713)
@@ -1707,9 +1707,8 @@
 	}
 
-
+	////////////////
 	//-- pvs is not stored with the interiors => reconstruct
 	Intersectable::NewMail();
 
-	int pvsSize = 0;
 	ViewCell *root = vc;
 	
@@ -1736,5 +1735,4 @@
 		{
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
-
 			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1703)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1713)
@@ -244,9 +244,17 @@
 		}
 	}
-//	Exporter *exporter= Exporter::GetExporter("test1.wrl");
-//	AxisAlignedBox3 bbox = preprocessor->mKdTree->GetBox(); 
-//	bbox.Scale(Vector3(1, 1, 0.5));
-//exporter->ExportGeometry(preprocessor->mObjects);cout<<"here2"<<endl;
-
+	if (0){
+	Exporter *exporter= Exporter::GetExporter("test1.wrl");
+	AxisAlignedBox3 bbox = preprocessor->mKdTree->GetBox(); 
+	bbox.Scale(Vector3(0.5, 1, 0.5));
+    exporter->SetWireframe();
+	exporter->ExportBox(preprocessor->mKdTree->GetBox());
+	exporter->ExportBox(bbox);
+	exporter->SetFilled();
+	exporter->ExportGeometry(preprocessor->mObjects, true, &bbox);
+	delete exporter;
+	}
+	
+	
 	// parse view cells related options
 	if (!preprocessor->PrepareViewCells())
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1710)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1713)
@@ -1747,5 +1747,5 @@
 		HierarchyNodeWrapper *nodeWrapper = tqueue.top();
 		tqueue.pop();
-
+		//cout << "priority: " << nodeWrapper->GetMergeCost() << endl;
 		// 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
@@ -1755,6 +1755,7 @@
 			)
 		{
-			if (nodeWrapper->Type() == HierarchyNodeWrapper::VSP_NODE)
+			if (nodeWrapper->Type() == HierarchyNodeWrapper::VIEW_CELL)
 			{
+				//cout << "1";
 				ViewCellWrapper *viewCellWrapper = dynamic_cast<ViewCellWrapper *>(nodeWrapper);
 				viewCells.push_back(viewCellWrapper->mViewCell);
@@ -1762,4 +1763,5 @@
 			else
 			{
+				//cout << "0";
 				BvhNodeWrapper *bvhNodeWrapper = dynamic_cast<BvhNodeWrapper *>(nodeWrapper);
 				bvhNodes.push_back(bvhNodeWrapper->mNode);
@@ -1776,9 +1778,9 @@
 
 
-bool HierarchyManager::ExtractStatistics(const int maxSplits,
-										 const float maxMemoryCost,
-										 float &renderCost,
-										 float &memory,
-										 int &pvsEntries)
+int HierarchyManager::ExtractStatistics(const int maxSplits,
+										const float maxMemoryCost,
+										float &renderCost,
+										float &memory,
+										int &pvsEntries)
 {
 	ViewCellContainer viewCells;
@@ -1787,7 +1789,8 @@
 	// collect best set of view cells for this #splits
     CollectBestSet(maxSplits, maxMemoryCost, viewCells, bvhNodes);
-
+	//cout << "here5 " << bvhNodes.size() << endl;
 	vector<BvhNode *>::const_iterator bit, bit_end = bvhNodes.end();
 	
+	// set new nodes to be active
 	for (bit = bvhNodes.begin(); bit != bit_end; ++ bit)
 	{
@@ -1797,13 +1800,16 @@
 	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
 
-	int numEntries = 0;
-	float pvsCost = 0.0f;
-
+	pvsEntries = 0;
+	renderCost = 0.0f;
+
+	//BvhNode::NewMail();
+	//int dummy = 0;
 	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
 	{
+		float rc = 0;
 		ViewCell *vc = *vit;
 		ObjectPvs pvs;
 		mVspTree->mViewCellsTree->GetPvs(vc, pvs);
-
+		//dummy+=pvs.GetSize();
 		BvhNode::NewMail();
 
@@ -1814,4 +1820,5 @@
 		{
 			BvhIntersectable *intersect = dynamic_cast<BvhIntersectable *>((*oit).first);
+
 			BvhLeaf *leaf = intersect->GetItem();
 			BvhNode *activeNode = leaf->GetActiveNode();
@@ -1821,11 +1828,23 @@
 				activeNode->Mail();
 
-				++ numEntries;
-				pvsCost += mBvHierarchy->EvalAbsCost(leaf->mObjects);
+				ObjectContainer objects;
+				activeNode->CollectObjects(objects);
+
+				++ pvsEntries;
+				rc += mBvHierarchy->EvalAbsCost(objects);
+				//cout << " pvs: " << mBvHierarchy->EvalAbsCost(leaf->mObjects);
 			}
 		}
-	}
-
-	return ((int)(viewCells.size() + bvhNodes.size()) < mHierarchyStats.Leaves());
+
+		rc *= vc->GetVolume();
+		renderCost += rc;
+	}
+
+	renderCost /= mVspTree->mViewCellsManager->GetViewSpaceBox().GetVolume();
+
+	memory = pvsEntries * ObjectPvs::GetEntrySize();
+	//cout << "viewCells: " << (int)viewCells.size() << " nodes: " << (int)bvhNodes.size() << " rc: " << renderCost << " entries: " << pvsEntries << endl;
+
+	return viewCells.size() + bvhNodes.size();
 }
 
@@ -1984,10 +2003,7 @@
 
 void HierarchyManager::EvaluateSubdivision2(ofstream &splitsStats,
-											ofstream &memStats,
-											const int splitsStepSize,
-											const float memStepSize)
+											const int splitsStepSize)
 {
 	int splits = 0;
-	float mem = 15;
 
 	float renderCost;
@@ -1997,23 +2013,13 @@
 	while (1)
 	{
-		if (!ExtractStatistics(splits, 99999.0, renderCost, memory, pvsEntries))
+		const int numSplits = ExtractStatistics(splits, 99999.0, renderCost, memory, pvsEntries);
+		
+		UpdateStats(splitsStats, numSplits, renderCost, pvsEntries, memory, 0);
+		splits += splitsStepSize;
+
+		if (numSplits == mHierarchyStats.Leaves())
 			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;
-	}
-
-}
-
-}
+	}
+}
+
+}
