Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/scripts/Plugin_VisibilitySceneManager.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/scripts/Plugin_VisibilitySceneManager.vcproj	(revision 727)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/scripts/Plugin_VisibilitySceneManager.vcproj	(revision 728)
@@ -267,7 +267,4 @@
 					RelativePath="..\src\OgreVisibilitySceneManagerDll.cpp">
 				</File>
-				<File
-					RelativePath="..\src\ViewCellBspTree.cpp">
-				</File>
 			</Filter>
 		</Filter>
Index: GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj	(revision 726)
+++ GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj	(revision 728)
@@ -20,5 +20,5 @@
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include..\support;&quot;..\include  ..\support&quot;;..\include;&quot;$(GTPDIR)\NonGTP\Devil\include&quot;;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(GTPDIR)\NonGTP\Xerces&quot;;&quot;$(CG_INC_PATH)&quot;;&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\QtOpenGl&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(GTPDIR)\NonGTP\Zlib\include&quot;"
+				AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include..\support;&quot;..\include  ..\support&quot;;..\include;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(CG_INC_PATH)&quot;;&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\QtOpenGl&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(GTPDIR)\NonGTP\Zlib\include&quot;;..\..\..\..\..\..\NonGTP\Xerces;..\..\..\..\..\..\NonGTP\Devil\include"
 				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
 				MinimalRebuild="TRUE"
@@ -67,5 +67,4 @@
 				InlineFunctionExpansion="2"
 				FavorSizeOrSpeed="1"
-				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="..\support;..\support\devil\include;..\support\zlib\include;..\include;&quot;$(QTDIR)\include\QtCore&quot;;&quot;$(QTDIR)\include\QtGui&quot;;&quot;$(QTDIR)\include&quot;;&quot;$(QTDIR)\include\QtOpenGl&quot;;..\src;&quot;$(CG_INC_PATH)&quot;;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces"
 				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
@@ -84,4 +83,5 @@
 				AdditionalDependencies="xerces-c_2.lib zdll.lib zziplib.lib devil.lib qtmain.lib QtOpenGL4.lib QtCore4.lib QtGui4.lib Qt3Supportd4.lib QAxContainer.lib glut32.lib OpenGL32.Lib glu32.lib cg.lib cgGL.lib"
 				AdditionalLibraryDirectories="..\support\xercesc\lib\;..\support\zlib\lib\;..\support\devil\lib;&quot;$(QTDIR)\lib&quot;;..\include;..\src\GL;&quot;$(CG_LIB_PATH)&quot;;&quot;$(GTPDIR)\NonGTP\Xerces&quot;;&quot;$(GTPDIR)\NonGTP\Xerces\xercesc\lib&quot;;&quot;$(GTPDIR)\NonGTP\zlib\lib&quot;;&quot;$(GTPDIR)\NonGTP\Devil\lib&quot;"
+				GenerateDebugInformation="TRUE"
 				LargeAddressAware="2"/>
 			<Tool
Index: GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env	(revision 697)
+++ GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env	(revision 728)
@@ -177,5 +177,5 @@
 	# samples used for view cell construction
 	Construction {
-		samples 100000
+		samples 1000000
 		samplesPerPass 200000
 	}
@@ -199,5 +199,8 @@
 	#percentage of total visible objects where pvs is considered invalid
 	maxPvsRatio 1.0
-		
+
+	renderCostEvaluationType perobject
+	#renderCostEvaluationType pertriangle
+
 	pruneEmptyViewCells false
 	processOnlyValidViewCells false
@@ -242,10 +245,10 @@
 	}
 
-	showVisualization true	
+	showVisualization false
 	evaluateViewCells false
 	
 	Evaluation {
 		samplesPerPass 800000
-		samples 1000000
+		samples 800000
 		statsPrefix ../scripts/viewCells
 	}
@@ -308,5 +311,5 @@
 VspBspTree {
 	Construction {
-		samples 200000
+		samples 50000
 		epsilon 0.00005
 		randomize false
@@ -363,5 +366,5 @@
 		
 		AxisAligned {
-			minRays 		50000
+			minRays 		5000
 			maxRayContribution	9.9
 		}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp	(revision 667)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp	(revision 728)
@@ -2203,5 +2203,5 @@
 	if (!vc) return false;
 // TODO
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 	// set new size of view cell
 	vc->SetVolume(fVc->GetVolume() + bVc->GetVolume());
@@ -2342,5 +2342,5 @@
 
 			VspKdViewCell *viewCell = leaf->GetViewCell();
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 			if (!viewCell->Mailed())
 			{
@@ -2486,6 +2486,5 @@
 {
 	// compute new pvs and area
-	//	TODO
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 	vc1->GetPvs().SubtractPvs(*leaf->mPvs);
 	vc2->GetPvs().AddPvs(*leaf->mPvs);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 720)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 728)
@@ -39,14 +39,13 @@
 
 // pvs penalty can be different from pvs size
-inline float EvalPvsPenalty(const int pvs, 
-							const int lower,
-							const int upper)
+inline float EvalPvsPenalty(const int pvs, const int lower, const int upper)
 {
 	// clamp to minmax values
-	/*if (pvs < lower)
+#if HAS_TO_BE_REDONE
+	if (pvs < lower)
 		return (float)lower;
 	if (pvs > upper)
 		return (float)upper;
-*/
+#endif
 	return (float)pvs;
 }
@@ -204,4 +203,10 @@
 {
 	mMergeCost = mergeCost;
+}
+
+
+float ViewCell::GetRenderCost() const
+{
+	return (float)mPvs.GetSize() * GetVolume();
 }
 
@@ -791,7 +796,7 @@
 	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
 	{
-		int lower = mViewCellsManager->GetMinPvsSize();
-		int upper = mViewCellsManager->GetMaxPvsSize();
-		float penalty = EvalPvsPenalty((*vit)->GetPvs().GetSize(), lower, upper);
+		const int lower = mViewCellsManager->GetMinPvsSize();
+		const int upper = mViewCellsManager->GetMaxPvsSize();
+		const float penalty = EvalPvsPenalty((*vit)->GetPvs().GetSize(), lower, upper);
 		
 		mDeviation += fabs(mAvgRenderCost - penalty);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 722)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 728)
@@ -57,53 +57,19 @@
 class ViewCellsManager
 {
-
 public:
-  struct PvsStatistics {
-	int minPvs;
-	int maxPvs;
-	float avgPvs;
-	int viewcells;
+	struct PvsStatistics 
+	{
+		int minPvs;
+		int maxPvs;
+		float avgPvs;
+		int viewcells;
   };
+
+	/// view cell container types
+	enum {BSP, KD, VSP_KD, VSP_BSP};
   
-  /**
-	Candidate for leaf merging based on priority.
-	*/
-	class LocalMergeCandidate
-	{  
-	public:
-		LocalMergeCandidate(ViewCell *l, ViewCell *r);
-
-		/** If this merge pair is still valid.
-		*/
-		//bool IsValid() const;
-	
-		friend bool operator<(const LocalMergeCandidate &leafa, const LocalMergeCandidate &leafb)
-		{
-			return leafb.GetMergeCost() < leafa.GetMergeCost();
-		}
-
-		void SetLeftViewCell(ViewCell *l) {mLeftViewCell = l;}
-		void SetRightViewCell(ViewCell *l) {mRightViewCell = l;}
-
-		ViewCell *GetLeftViewCell() const {return mLeftViewCell;}
-		ViewCell *GetRightViewCell() const { return mRightViewCell;}
-
-		float GetMergeCost() const {return mMergeCost;} 
-		void SetMergeCost(const float cost) {mMergeCost = cost;} 
-
-	protected:
-
-		/// render cost increase by this merge
-		float mMergeCost;
-	
-		ViewCell *mLeftViewCell;
-		ViewCell *mRightViewCell;
-	};
-
-
-
-  /// view cell container types
-  enum {BSP, KD, VSP_KD, VSP_BSP};
-  
+	/// view cells evaluation type
+	enum {PER_OBJECT, PER_TRIANGLE};
+
 	/** Constructor taking the initial and construction samples.
 		@param initialSamples the maximal number of samples used for creating the hierarchy
@@ -277,5 +243,5 @@
 	/** Returns render cost of a single view cell given the render cost of an object.
 	*/
-	float GetRendercost(ViewCell *viewCell, float objRendercost) const;
+	float GetRendercost(ViewCell *viewCell) const;
 
 	/** Returns reference to container of loaded / generated view cells.
@@ -427,13 +393,20 @@
 	void EvalViewCellPartition(Preprocessor *preprocessor);
 
-  void SetMaxFilterSize(const int size) {
-	mMaxFilterSize = size;
-  }
-
-  /** deletes interior nodes from the tree which have negative merge cost set (local merge) */
-  void
-  DeleteLocalMergeTree(ViewCell *vc
-					   ) const;
+	/** Sets maximal size of a view cell filter.
+	*/
+	void SetMaxFilterSize(const int size);
+
+	/** Deletes interior nodes from the tree which have negative merge cost set (local merge) 
+	*/
+	void DeleteLocalMergeTree(ViewCell *vc) const;
   
+	/** Evaluautes histogram for a given number of view cells.
+	*/
+	void EvalViewCellHistogram(const string filename, const int nViewCells);
+
+	/** Evaluates the render cost of a view cell.
+	*/
+	float EvalRenderCost(Intersectable *obj) const;
+
 protected:
 
@@ -591,4 +564,6 @@
 
 	ViewCellContainer mEmptyViewCells;
+
+	int mRenderCostEvaluationType;
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 727)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 728)
@@ -2078,4 +2078,5 @@
 	if (!obj)
 		return;
+
 	// new object
 	if ((obj->mMailbox != sFrontId) &&
@@ -2330,5 +2331,5 @@
 {
 // TODO
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 	stack<BspNode *> nodeStack;
 
@@ -3274,5 +3275,5 @@
 {
 // TODO
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 	if (node->IsLeaf())
 		return node;
@@ -3317,5 +3318,5 @@
 	int collapsed = 0;
 	//TODO
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 	(void)CollapseTree(mRoot, collapsed);
 
@@ -3330,5 +3331,5 @@
 {
 // TODO
-#if VC_HISTORY
+#if HAS_TO_BE_REDONE
 	// list not valid anymore => clear
 	stack<BspNode *> nodeStack;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 722)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 728)
@@ -1223,5 +1223,10 @@
 					"view_cells_evaluation_stats_prefix=",
 					"viewCells");
-	
+
+	RegisterOption("ViewCells.renderCostEvaluationType",
+					optString,
+					"view_cells_render_cost_evaluation=",
+					"perobject");
+
 	RegisterOption("ViewCells.active",
 					optInt,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 703)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 728)
@@ -147,4 +147,7 @@
 	bool GetValid() const;
 
+	/** Returns estimated render cost of this view cell.
+	*/
+	float GetRenderCost() const;
 
   /** set color for visiualizations */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RenderSimulator.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RenderSimulator.cpp	(revision 605)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RenderSimulator.cpp	(revision 728)
@@ -105,5 +105,5 @@
 		// that view point is in view cell
 		const float vcCost = pInVc * 
-			mViewCellsManager->GetRendercost(vc, mObjRenderCost);
+			mViewCellsManager->GetRendercost(vc/*, mObjRenderCost*/);
 	
 		renderTime += vcCost;
@@ -113,4 +113,5 @@
 		loadPvsOverhead += GetCrossVcProbability() * mVcOverhead;
 		
+
 		//-- update statistics
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.cpp	(revision 492)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.cpp	(revision 728)
@@ -123,5 +123,5 @@
   ViewN = -N; // forwards
 #ifdef _DEBUG
-  const float eps = 1e-3;
+  const float eps = 1e-3f;
   if (fabs(Magnitude(ViewU) - 1.0) > eps) {
     Debug << "ViewU magnitude error= " << Magnitude(ViewU) << "\n";
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 727)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 728)
@@ -91,4 +91,5 @@
 	environment->GetIntValue("ViewCells.Filter.maxSize", mMaxFilterSize);
 	environment->GetFloatValue("ViewCells.Filter.width", mFilterWidth);
+	environment->GetIntValue("ViewCells.mRenderCostEvaluationType", mRenderCostEvaluationType);
 
 	char buf[100];
@@ -119,4 +120,20 @@
 	{
 		mEvaluationSamplingType = Preprocessor::DIRECTION_BASED_DISTRIBUTION;
+	}
+	else 
+	{
+		Debug << "error! wrong sampling type" << endl;
+		exit(0);
+	}
+
+	environment->GetStringValue("ViewCells.renderCostEvaluationType", buf);
+	
+	if (strcmp(buf, "box") == 0)
+	{
+		mRenderCostEvaluationType = ViewCellsManager::PER_OBJECT;
+	}
+	else if (strcmp(buf, "directional") == 0)
+	{
+		mRenderCostEvaluationType = ViewCellsManager::PER_TRIANGLE;
 	}
 	else 
@@ -162,4 +179,6 @@
 	Debug << "evaluate view cells: " << mEvaluateViewCells << endl;
 	Debug << "sampling type: " << mSamplingType << endl;
+	Debug << "render cost evaluation type" << mRenderCostEvaluationType << endl;
+	Debug << "evaluation sampling type: " << mEvaluationSamplingType << endl;
 	Debug << "show visualization: " << mShowVisualization << endl;
 	Debug << "filter width: " << mFilterWidth << endl;
@@ -219,5 +238,6 @@
 			{
 				Ray *pray = (*it)->mPiercingRays[0];
-				Debug << "view cell " << (*it)->GetId() << " not empty, pvs: " << (*it)->GetPvs().GetSize() << " " << (int)pray->intersections.size() << endl;
+				Debug << "view cell " << (*it)->GetId() << " not empty, pvs: " 
+					  << (*it)->GetPvs().GetSize() << " " << (int)pray->intersections.size() << endl;
 
 				exporter->ExportRays((*it)->mPiercingRays);
@@ -493,4 +513,61 @@
 
 	return numSamples;
+}
+
+
+void ComputeMinMaxRenderCost(float &minRenderCost,
+							 float &maxRenderCost, 
+							 const ViewCellContainer &viewCells)
+{
+	minRenderCost = 1e20f;
+	maxRenderCost = -1;
+
+	ViewCellContainer::const_iterator it, it_end = viewCells.end();
+
+	for (it = viewCells.begin(); it != it_end; ++ it)
+	{
+		const float renderCost = (float)(*it)->GetPvs().GetSize() * (*it)->GetVolume();
+		if (renderCost > maxRenderCost)
+			maxRenderCost = renderCost;
+		else if (renderCost < minRenderCost)
+			minRenderCost = renderCost;
+	}
+}
+
+void ViewCellsManager::EvalViewCellHistogram(const string filename, const int nViewCells)
+{
+	std::ofstream outstream;
+	outstream.open(filename.c_str());
+
+	ViewCellContainer viewCells;
+	mViewCellsTree->CollectBestViewCellSet(mViewCells, nViewCells);
+
+	float maxRenderCost, minRenderCost;
+	/// find out the range for valid render cost
+	ComputeMinMaxRenderCost(minRenderCost, maxRenderCost, viewCells);
+
+	const int intervals = 10000;
+	const float range = maxRenderCost - minRenderCost;
+	int currentRenderCost = (int)ceil(minRenderCost);
+	const int stepSize = (int)((float)range / (float)intervals);
+
+	for (; currentRenderCost < (int)maxRenderCost; currentRenderCost += stepSize)
+	{
+		ViewCellContainer::const_iterator it, it_end = viewCells.end();		
+
+		int smallerCost = 0;
+
+		for (it = viewCells.begin(); it != viewCells.end(); ++ it)
+		{
+			ViewCell *vc = *it;
+
+			if (EvalRenderCost(vc) < currentRenderCost)
+				++ smallerCost;
+		}
+		
+		outstream << "#RenderCost: " << currentRenderCost << endl;
+		outstream << "#ViewCells: " << smallerCost << endl;		
+	}
+
 }
 
@@ -578,4 +655,9 @@
 		disposeRays(evaluationSamples, NULL);
 	}
+	
+	string filename = "histogram.log";
+	int nViewCells = 5000;
+
+	EvalViewCellHistogram(filename, nViewCells);
 
 	// find empty view cells bug
@@ -593,4 +675,5 @@
 
 
+// Returns index of the best view cells of the neighborhood
 int GetBestViewCellIdx(ViewCell *root, const ViewCellContainer &neighborhood)
 {
@@ -614,4 +697,37 @@
 
 	return bestViewCellIdx;
+}
+
+
+void ViewCellsManager::SetMaxFilterSize(const int size) 
+{
+	mMaxFilterSize = size;
+}
+
+
+float ViewCellsManager::EvalRenderCost(Intersectable *obj) const
+{
+	switch (mRenderCostEvaluationType)
+	{
+	case PER_OBJECT:
+		return 1;
+	
+	case PER_TRIANGLE:
+		{
+			// HACK
+			MeshInstance *mi = dynamic_cast<MeshInstance *>(obj);
+
+			// HACK: assume meshes are triangles
+			if (mi->GetMesh())
+			{
+				return mi->GetMesh()->mFaces.size();
+			}
+		}
+	default:
+		return 1;
+	}
+
+	// should not come here
+	return 0;
 }
 
@@ -691,5 +807,5 @@
   //cout << "neighborhood: " << neighborhood.size() << endl;
   for (int nMergedViewCells = 0; nMergedViewCells < n; ++ nMergedViewCells)
-	{
+  {
 	  ViewCell *bestViewCell = neighborhood[nMergedViewCells].mViewCell;
 	  //cout <<nMergedViewCells<<":"<<"homogenity=" <<neighborhood[nMergedViewCells].mValue<<endl;
@@ -698,5 +814,5 @@
 	  // set negative cost so that this view cell gets deleted
 	  root->SetMergeCost(-1.0f);
-	}
+  }
   
   return root;	
@@ -1453,7 +1569,16 @@
 
 
-float ViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
-{
-	return mViewCellsTree->GetPvsSize(viewCell) * objRendercost;
+float ViewCellsManager::GetRendercost(ViewCell *viewCell) const
+{
+	const ObjectPvs &pvs = viewCell->GetPvs();
+
+	ObjectPvsMap::iterator it, it_end = viewCell->GetPvs().mEntries.end();
+
+	for (it = viewCell->GetPvs().mEntries.begin(); it != it_end; ++ it)
+	{
+		
+	}
+
+	return mViewCellsTree->GetPvsSize(viewCell);
 }
 
@@ -1463,5 +1588,7 @@
 	// if already computed
 	if (mTotalAreaValid)
+	{
 		return mTotalArea;
+	}
 
 	mTotalArea = 0;
@@ -2548,5 +2675,5 @@
 			exporter->ExportKdTree(*mKdTree);
 
-			for (i=0; i < pvsOut; i++)
+			for (i = 0; i < pvsOut; i++)
 				exporter->ExportRays(rays[i], RgbColor(1, 0, 0));
 
