Index: /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 550)
+++ /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 551)
@@ -30,5 +30,5 @@
 	samplesPerPass  100000
 	initialSamples 300000
-	vssSamples 700000
+	vssSamples 1500000
 	vssSamplesPerPass 100000
 	useImportanceSampling true
@@ -180,7 +180,7 @@
 	
 	height 5.0
-	maxViewCells 100000
+	maxViewCells 3000
 	#percentage of total visible objects where pvs is considered invalid
-	maxPvsRatio 0.9
+	maxPvsRatio 1.0
 		
 	delayedConstruction true
@@ -189,5 +189,5 @@
 	PostProcess {
 		# how much samples are used for post processing
-		samples 200000
+		samples 300000
 	}
 
@@ -195,8 +195,8 @@
 		# how much samples we use for visualization
 		samples 5000
-		colorCode PVS
+		#colorCode PVS
 		#colorCode MergedLeaves
 		#colorCode MergedTreeDiff
-		#colorCode Random
+		colorCode Random
 		exportRays false
 		exportGeometry true
@@ -259,5 +259,5 @@
 VspBspTree {
 	Construction {
-		samples 500000
+		samples 1200000
 		epsilon 0.005
 		randomize false
@@ -292,5 +292,5 @@
 	Termination {
 		# parameters used for autopartition
-		minRays 		400
+		minRays 		100
 		minPolygons 		-1
 		maxDepth		30
@@ -298,10 +298,10 @@
 		#minProbability		0.0001
 		minProbability 		-1
-		maxRayContribution	0.2
-		maxCostRatio		0.9
+		maxRayContribution	0.6
+		maxCostRatio		0.99
 		missTolerance		3
 		#maxAccRayLength	100
 		
-		maxViewCells		2501
+		maxViewCells		3501
 		
 		# used for pvs criterium
@@ -322,7 +322,7 @@
 	
 	PostProcess {
-		maxCostRatio 0.000001
-		minViewCells 80
-		useRaysForMerge true
+		maxCostRatio 0.1
+		minViewCells 200
+		useRaysForMerge false
 	}
 }
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 547)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 551)
@@ -611,4 +611,6 @@
 	float GetMemUsage() const;
 
+	float GetShuffledVcCost(BspLeaf *leaf, BspViewCell *vc1, BspViewCell *vc2) const;
+
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 547)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 551)
@@ -10,6 +10,6 @@
 MeshInstance(NULL), 
 mPiercingRays(0),
-mArea(0),
-mVolume(0),
+mArea(-1),
+mVolume(-1),
 mValid(true)
 {
@@ -19,6 +19,6 @@
 MeshInstance(mesh), 
 mPiercingRays(0),
-mArea(0),
-mVolume(0),
+mArea(-1),
+mVolume(-1),
 mValid(true)
 {
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 547)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 551)
@@ -216,5 +216,5 @@
 	virtual float GetArea(ViewCell *viewCell) const;
 
-	/** Returns volume of view cells.
+	/** Returns volume of view cell.
 	*/
 	virtual float GetVolume(ViewCell *viewCell) const;
@@ -259,9 +259,10 @@
 	int GetMaxPvsSize() const;
 
-
 	/** Exports view cell geometry.
 	*/
 	virtual void ExportVcGeometry(Exporter *exporter, ViewCell *vc) const = 0;
 
+	virtual void FinalizeViewCells(const bool createMesh);
+
 protected:
 
@@ -271,4 +272,8 @@
 	*/
 	void CreateUniqueViewCellIds();
+
+	/** Finalizes, i.e., creates mesh, volume, area etc. for the view cell.
+	*/
+	virtual void Finalize(ViewCell *viewCell, const bool createMesh);
 
 	/** Recollects view cells and resets statistics.
@@ -599,4 +604,8 @@
 	void ExportVcGeometry(Exporter *exporter, ViewCell *vc) const;
 
+	//float GetVolume(ViewCell *viewCell) const;
+
+	void Finalize(ViewCell *viewCell);
+
 protected:
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 548)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 551)
@@ -83,8 +83,10 @@
 	// maximum and minimum number of view cells
 	environment->GetIntValue("VspBspTree.Termination.maxViewCells", mMaxViewCells);
+
+	environment->GetBoolValue("VspBspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis);
+
+	//-- merge options
 	environment->GetIntValue("VspBspTree.PostProcess.minViewCells", mMergeMinViewCells);
 	environment->GetFloatValue("VspBspTree.PostProcess.maxCostRatio", mMergeMaxCostRatio);
-
-	environment->GetBoolValue("VspBspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis);
 	environment->GetBoolValue("VspBspTree.PostProcess.useRaysForMerge", mUseRaysForMerge);
 
@@ -116,5 +118,6 @@
 	Debug << "max plane candidates: " << mMaxRayCandidates << endl;
 	Debug << "randomize: " << randomize << endl;
-
+	Debug << "minimum view cells: " << mMergeMinViewCells << endl;
+	Debug << "using area for pvs: " << mUseAreaForPvs << endl;
 	Debug << "Split plane strategy: ";
 	if (mSplitPlaneStrategy & RANDOM_POLYGON)
@@ -870,5 +873,5 @@
 	
 	//TODO: for kd split geometry already is box
-	if (1 && mUseAreaForPvs)
+	if (1)
 	{
 		PolygonContainer::const_iterator it, it_end = tData.mGeometry->mPolys.end();
@@ -1012,6 +1015,7 @@
 	{   // volume
 		pBack = pFront = pOverall * 0.5f;
+		
+#if 0
 		// box length substitute for probability
-#if 0
 		const float minBox = box.Min(axis);
 		const float maxBox = box.Max(axis);
@@ -1603,5 +1607,6 @@
 {
 	ViewCell::NewMail();
-	CollectViewCells(mRoot, onlyValid, viewCells);
+	
+	CollectViewCells(mRoot, onlyValid, viewCells, true);
 }
 
@@ -1901,13 +1906,14 @@
 
 
+typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
+
 int VspBspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
 						   const bool onlyUnmailed) const
 {
-	BspNodeGeometry geom;
-	ConstructGeometry(n, geom);
-
-	stack<BspNode *> nodeStack;
-	nodeStack.push(mRoot);
-
+	stack<bspNodePair> nodeStack;
+	
+	BspNodeGeometry nodeGeom;
+	ConstructGeometry(n, nodeGeom);
+	
 	// split planes from the root to this node
 	// needed to verify that we found neighbor leaf
@@ -1915,57 +1921,90 @@
 	ExtractHalfSpaces(n, halfSpaces);
 
+
+	BspNodeGeometry *rgeom = new BspNodeGeometry();
+	ConstructGeometry(mRoot, *rgeom);
+
+	nodeStack.push(bspNodePair(mRoot, rgeom));
+
+
 	while (!nodeStack.empty())
 	{
-		BspNode *node = nodeStack.top();
+		BspNode *node = nodeStack.top().first;
+		BspNodeGeometry *geom = nodeStack.top().second;
+
 		nodeStack.pop();
 
-		if (node->IsLeaf())
-
-		{	// test if this leaf is in valid view space
-            if (node->TreeValid() &&
-				node != n && 
-				(!onlyUnmailed || !node->Mailed()))
+		bool isAdjacent = true;
+
+		// test all planes of current node if still adjacent
+		for (int i = 0; (i < halfSpaces.size()) && isAdjacent && (node != n); ++ i)
+		{
+			const int cf =
+				Polygon3::ClassifyPlane(geom->mPolys,
+										halfSpaces[i],
+										mEpsilon);
+
+			if (cf == Polygon3::BACK_SIDE)
 			{
-				// test all planes of current node if candidate really
-				// is neighbour
-				BspNodeGeometry neighborCandidate;
-				ConstructGeometry(node, neighborCandidate);
-
-				bool isAdjacent = true;
-				for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i)
+				isAdjacent = false;
+			}
+		}
+
+		if (isAdjacent)
+		{
+		
+			if (node->IsLeaf())
+			{	
+				// test if this leaf is in valid view space
+				if (node->TreeValid() &&
+					node != n && 
+					(!onlyUnmailed || !node->Mailed()))
 				{
-					const int cf =
-						Polygon3::ClassifyPlane(neighborCandidate.mPolys,
-												halfSpaces[i],
-												mEpsilon);
-
-					if (cf == Polygon3::BACK_SIDE)
-						isAdjacent = false;
+					// neighbor was found
+					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
 				}
-				// neighbor was found
-				if (isAdjacent)
-					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
 			}
-		}
-		else
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
-			const int cf = Polygon3::ClassifyPlane(geom.mPolys,
-												   interior->GetPlane(),
-												   mEpsilon);
-
-			if (cf == Polygon3::FRONT_SIDE)
-				nodeStack.push(interior->GetFront());
 			else
-				if (cf == Polygon3::BACK_SIDE)
-					nodeStack.push(interior->GetBack());
+			{
+				BspInterior *interior = dynamic_cast<BspInterior *>(node);
+
+				const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys,
+													   interior->GetPlane(),
+													   mEpsilon);
+			
+				BspNode *front = interior->GetFront();
+				BspNode *back = interior->GetBack();
+            
+				BspNodeGeometry *fGeom = new BspNodeGeometry();
+				BspNodeGeometry *bGeom = new BspNodeGeometry();
+
+				geom->SplitGeometry(*fGeom,
+									*bGeom,
+									interior->GetPlane(),
+									mBox,
+									mEpsilon);
+		
+				if (cf == Polygon3::FRONT_SIDE)
+				{
+					nodeStack.push(bspNodePair(interior->GetFront(), fGeom));
+					DEL_PTR(bGeom);
+				}
 				else
 				{
-					// random decision
-					nodeStack.push(interior->GetBack());
-					nodeStack.push(interior->GetFront());
+					if (cf == Polygon3::BACK_SIDE)
+					{
+						nodeStack.push(bspNodePair(interior->GetBack(), bGeom));
+						DEL_PTR(fGeom);
+					}
+					else
+					{	// random decision
+						nodeStack.push(bspNodePair(front, fGeom));
+						nodeStack.push(bspNodePair(back, bGeom));
+					}
 				}
-		}
+			}
+		}
+
+		DEL_PTR(geom);
 	}
 
@@ -2642,4 +2681,5 @@
 	if (0)
 	{
+		cout << "finding additional merge candidates using geometry" << endl;
 		vector<BspLeaf *> leaves;
 		CollectLeaves(leaves, true);
@@ -2702,10 +2742,14 @@
 	mergeStats.Start();
 	// TODO: REMOVE LATER for performance!
-	const bool showMergeStats = true;
+	const bool showMergeStats = false;
 	//BspMergeCandidate::sOverallCost = mBox.SurfaceArea() * mStat.maxPvs;
 	long startTime = GetTime();
 
 	if (mUseRaysForMerge)
+	{
+		cout << "collecting merge candidates (rays) ... ";
 		mergeStats.nodes = CollectMergeCandidates(rays);
+		cout << "fininshed collecting candidates" << endl;
+	}
 	else
 	{
@@ -2714,4 +2758,5 @@
 		mergeStats.nodes = CollectMergeCandidates(leaves);
 	}
+	
 
 	mergeStats.collectTime = TimeDiff(startTime, GetTime());
@@ -2722,4 +2767,6 @@
 	int pass = 0;
 	const int nextPass = 200;
+
+	cout << "starting merge ... ";
 
 	//-- use priority queue to merge leaf pairs
@@ -2744,6 +2791,5 @@
 
 			MergeViewCells(mc.GetLeaf1(), mc.GetLeaf2());
-			-- nViewCells;
-			
+						
 			
 			// increase absolute merge cost
@@ -2774,7 +2820,9 @@
 						<< "#CurrentPvs\n" << mc.GetLeaf1()->GetViewCell()->GetPvs().GetSize() << endl;
 
+					cout << "exporting view cells ... ";
 					ViewCellContainer viewCells;	
 					CollectViewCells(mRoot, false, viewCells);
 			
+					
 					char s[64];
 					sprintf(s, "merged_viewcells%07d.x3d", nViewCells);
@@ -2784,5 +2832,5 @@
 					{
 						exporter->ExportGeometry(objects);
-						Debug << "vc size " << viewCells.size() << endl;
+						Debug << "vc size " << (int)viewCells.size() << " merge queue size: " << (int)mMergeQueue.size() << endl;
 						ViewCellContainer::const_iterator it, it_end = viewCells.end();
 		
@@ -2794,8 +2842,10 @@
 						delete exporter;
 					}
+					cout << "finished " << endl;
 				}
 			}
+
+			-- nViewCells;
 			++ mergeStats.merged;
-
 		}
 		// merge candidate not valid, because one of the leaves was already
@@ -2807,5 +2857,5 @@
 		}
 	}
-
+	cout << "finished merge" << endl;
 	mergeStats.mergeTime = TimeDiff(startTime, GetTime());
 	mergeStats.Stop();
@@ -2911,5 +2961,5 @@
 
 
-float GetShuffledVcCost(BspLeaf *leaf, BspViewCell *vc1, BspViewCell *vc2, bool useArea)
+float VspBspTree::GetShuffledVcCost(BspLeaf *leaf, BspViewCell *vc1, BspViewCell *vc2) const
 {
 	//const int pvs1 = SubtractedPvsSize(vc1, leaf, *leaf->mPvs);
@@ -2917,7 +2967,10 @@
 	const int pvs2 = AddedPvsSize(vc2->GetPvs(), *leaf->mPvs);
 
+	if (pvs1 + pvs2 > mViewCellsManager->GetMaxPvsSize())
+		return 1e15f;
+
 	float p1, p2;
 
-    if (useArea)
+    if (mUseAreaForPvs)
 	{
 		p1 = vc1->GetArea() - leaf->mProbability;
@@ -3004,7 +3057,7 @@
 	// the view cell should not be empty after the shuffle
 	if (vc1->mLeaves.size() > 1)
-		shuffledCost1 = GetShuffledVcCost(leaf1, vc1, vc2, mUseAreaForPvs);
+		shuffledCost1 = GetShuffledVcCost(leaf1, vc1, vc2);
 	if (vc2->mLeaves.size() > 1)
-		shuffledCost2 = GetShuffledVcCost(leaf2, vc2, vc1, mUseAreaForPvs);
+		shuffledCost2 = GetShuffledVcCost(leaf2, vc2, vc1);
 
 	// shuffling unsuccessful
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 547)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 551)
@@ -1509,4 +1509,5 @@
 }
 
+
 float BspTree::SplitPlaneCost(const Plane3 &candidatePlane, 
 							  const BoundedRayContainer &rays,
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 497)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 551)
@@ -77,4 +77,5 @@
 		// probability of view cell
 		const float pInVc = mViewCellsManager->GetProbability(vc);
+
 		// compute render time of PVS times probability
 		// that view point is in view cell
@@ -82,6 +83,6 @@
 			mViewCellsManager->GetRendercost(vc, mObjRenderCost);
 	
-		// crossing the border of a view cell is depending on the move speed
-		// and the probability that a view cell border is crossed
+		// crossing the border of a view cell is depending on the move 
+		// speed and the probability that a view cell border is crossed
 		loadPvsOverhead += GetCrossVcProbability() * mVcOverhead;
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.cpp	(revision 549)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/RssTree.cpp	(revision 551)
@@ -219,8 +219,8 @@
     maxDepthNodes*100/(double)Leaves()<<endl;
 
-  app << "#N_PMINPVSLEAVES  ( Percentage of leaves with minCost )\n"<<
+  app << "#N_PMINPVSLEAVES  ( Percentage of leaves with minPvs )\n"<<
     minPvsNodes*100/(double)Leaves()<<endl;
 
-  app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minCost )\n"<<
+  app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minRays )\n"<<
     minRaysNodes*100/(double)Leaves()<<endl;
 	
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp	(revision 485)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp	(revision 551)
@@ -177,8 +177,8 @@
     maxDepthNodes*100/(double)Leaves()<<endl;
 
-  app << "#N_PMINPVSLEAVES  ( Percentage of leaves with minCost )\n"<<
+  app << "#N_PMINPVSLEAVES  ( Percentage of leaves with minPvs )\n"<<
     minPvsNodes*100/(double)Leaves()<<endl;
 
-  app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minCost )\n"<<
+  app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minRays )\n"<<
     minRaysNodes*100/(double)Leaves()<<endl;
 	
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 540)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 551)
@@ -506,4 +506,5 @@
 
   cout<<"mUseViewSpaceBox="<<mUseViewSpaceBox<<endl;
+  Debug << "use view space box=" << mUseViewSpaceBox << endl;
   if (mUseViewSpaceBox)
   {
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 547)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 551)
@@ -252,4 +252,20 @@
 
 
+void ViewCellsManager::FinalizeViewCells(const bool createMesh)
+{
+	ViewCellContainer::const_iterator it, it_end = mViewCells.end();
+	for (it = mViewCells.begin(); it != it_end; ++ it)
+	{
+		Finalize(*it, createMesh);
+	}
+}
+
+
+void ViewCellsManager::Finalize(ViewCell *viewCell, const bool createMesh)
+{
+	// implemented in subclasses
+}
+
+
 ViewCell *ViewCellsManager::MergeViewCells(ViewCell &front, ViewCell &back) const
 {
@@ -1145,8 +1161,9 @@
 void BspViewCellsManager::CreateMesh(ViewCell *vc)
 {
-}
-
-ViewCell *
-BspViewCellsManager::GetViewCell(const Vector3 &point)
+	// TODO
+}
+
+
+ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point)
 {
   if (!mBspTree)
@@ -1445,4 +1462,5 @@
 void KdViewCellsManager::CreateMesh(ViewCell *vc)
 {
+	// TODO
 }
 
@@ -1793,4 +1811,5 @@
 void VspKdViewCellsManager::CreateMesh(ViewCell *vc)
 {
+	//TODO
 }
 
@@ -1816,5 +1835,5 @@
 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell)
 {
-	if (mVspBspTree->mUseAreaForPvs)
+	if (0 && mVspBspTree->mUseAreaForPvs)
 		return GetArea(viewCell) / GetAccVcArea();
 	else
@@ -1865,4 +1884,5 @@
 	VssRayContainer savedRays;
 
+	Debug << "construction samples: " << mConstructionSamples << " rays: " << rays.size() << endl;
 	GetRaySets(rays, mConstructionSamples, constructionRays, &savedRays);
 
@@ -1973,6 +1993,8 @@
 		if (exporter)
 		{
-			//exporter->SetWireframe();
-			exporter->SetFilled();
+			if (1)
+				exporter->SetWireframe();
+			else
+				exporter->SetFilled();
 			ExportViewCellsForViz(exporter);
 
@@ -2031,4 +2053,5 @@
 	if (mViewCellsFinished)
 	{
+		FinalizeViewCells(true);
 		EvaluateViewCellsStats();
 		return 0;
@@ -2049,5 +2072,10 @@
 
 
-	//-- merge the individual view cells: Should be done here because it makes
+	if (1)
+	{
+		FinalizeViewCells(false);
+	}
+
+	//-- merge the individual view cells
 	MergeViewCells(postProcessRays, objects);
 	//-- refines the merged view cells
@@ -2059,5 +2087,6 @@
 
 	// real meshes are only contructed only at this stage
-	CreateViewCellMeshes();
+	//CreateViewCellMeshes();
+	FinalizeViewCells(true);
 
 	// write view cells to disc
@@ -2497,2 +2526,27 @@
 	return mVspBspTree->CastBeam(beam);
 }
+
+
+void VspBspViewCellsManager::Finalize(ViewCell *viewCell)
+{
+	BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCell);
+	CreateMesh(vc);
+
+	vector<BspLeaf *>::const_iterator it, it_end = vc->mLeaves.end();
+
+	float area = 0;
+	float volume = 0;
+
+	for (it = vc->mLeaves.begin(); it != it_end; ++ it)
+	{
+		BspNodeGeometry geom;
+		BspLeaf *leaf = *it;
+		mVspBspTree->ConstructGeometry(leaf, geom);
+
+		area += geom.GetArea();
+		volume += geom.GetVolume();
+	}
+
+	viewCell->SetVolume(volume);
+	viewCell->SetArea(area);
+}
