Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 568)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 573)
@@ -30,5 +30,5 @@
 VssPreprocessor {
 	samplesPerPass  100000
-	initialSamples 2000000
+	initialSamples 6000000
 	vssSamples 0
 	vssSamplesPerPass 500000
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 564)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 573)
@@ -411,10 +411,10 @@
 		@returns the cost of the candidate split plane
 	*/
-	float SplitPlaneCost(const Plane3 &candidatePlane, 
-						 const VspBspTraversalData &data,
-						 BspNodeGeometry &geomFront,
-						 BspNodeGeometry &geomBack,
-						 float &pFront,
-						 float &pBack) const;
+	float EvalSplitPlaneCost(const Plane3 &candidatePlane, 
+							 const VspBspTraversalData &data,
+							 BspNodeGeometry &geomFront,
+							 BspNodeGeometry &geomBack,
+							 float &pFront,
+							 float &pBack) const;
 
 	/** Subdivide leaf.
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 556)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 573)
@@ -133,7 +133,8 @@
 	std::map<T, PvsData<T>, LtSample<T> >::const_iterator it;
 
+	mEntries = a.mEntries;
 	// todo: copy all elements instead of inserting
-	for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
-		mEntries.insert(*it);
+	//for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
+	//	mEntries.insert(*it);
 	
 	for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 570)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 573)
@@ -306,4 +306,8 @@
 protected:
 
+	int CastPassSamples(int samplesPerPass, 
+						int sampleType, 
+						VssRayContainer *outRays) const;
+
 	void ParseEnvironment();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 570)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 573)
@@ -942,7 +942,8 @@
 				else
 				{
-					nCostRatio[axis] = SplitPlaneCost(Plane3(normal, nPosition[axis]), 
-													  tData, *nFrontGeom[axis], *nBackGeom[axis],
-													  nProbFront[axis], nProbBack[axis]);
+					nCostRatio[axis] = 
+						EvalSplitPlaneCost(Plane3(normal, nPosition[axis]), 
+										   tData, *nFrontGeom[axis], *nBackGeom[axis],
+										   nProbFront[axis], nProbBack[axis]);
 				}
 			}
@@ -1123,5 +1124,5 @@
 		float fArea, bArea;
 		plane = poly->GetSupportingPlane();
-		candidateCost = SplitPlaneCost(plane, data, fGeom, bGeom, fArea, bArea);
+		candidateCost = EvalSplitPlaneCost(plane, data, fGeom, bGeom, fArea, bArea);
 		
 		if (candidateCost < lowestCost)
@@ -1263,10 +1264,10 @@
 
 
-float VspBspTree::SplitPlaneCost(const Plane3 &candidatePlane,
-								 const VspBspTraversalData &data,
-								 BspNodeGeometry &geomFront,
-								 BspNodeGeometry &geomBack,
-								 float &pFront,
-								 float &pBack) const
+float VspBspTree::EvalSplitPlaneCost(const Plane3 &candidatePlane,
+									 const VspBspTraversalData &data,
+									 BspNodeGeometry &geomFront,
+									 BspNodeGeometry &geomBack,
+									 float &pFront,
+									 float &pBack) const
 {
 	float cost = 0;
@@ -1377,6 +1378,17 @@
 	if (mSplitPlaneStrategy & PVS)
 	{
-		const float oldCost = pOverall * (float)totalPvs + Limits::Small;
-		cost += mPvsFactor * (pvsFront * pFront + pvsBack * pBack) / oldCost;
+		if (1)
+		{
+			const float oldCost = pOverall * (float)totalPvs + Limits::Small;
+			cost += mPvsFactor * (pvsFront * pFront + pvsBack * pBack) / oldCost;
+		}
+		else
+		{
+			// try to equalize render differences
+			const float oldCost = pOverall * (float)totalPvs + Limits::Small;
+			float newCost = fabs(pvsFront * pFront - pvsBack * pBack);
+
+			cost += mPvsFactor * newCost / oldCost;
+		}
 	}
 
@@ -2573,7 +2585,9 @@
 	}
 
+	// important so other merge candidates sharing this view cell
+	// are notified that the merge cost must be updated!!
 	vc->Mail();
 
-	// clean up old view cells
+	//-- clean up old view cells
 	if (mExportMergedViewCells)
 	{
@@ -2581,6 +2595,7 @@
 		DEL_PTR(bVc);
 	}
-	else // throw them into old view cells container
-	{
+	else 
+	{
+		// old view cells container needed for visualization
 		//fVc->mMailbox = -1;
 		//bVc->mMailbox = -1;
@@ -3204,4 +3219,5 @@
 		return 1e15f;
 
+#if 1
 	float p1, p2;
 
@@ -3217,6 +3233,10 @@
 	}
 
-	const float cost1 = (float)pvs1;// * p1;
-	const float cost2 = (float)pvs2;// * p2;
+	const float cost1 = pvs1 * p1;
+	const float cost2 = pvs2 * p2;
+#else
+	const float cost1 = pvs1;
+	const float cost2 = pvs2;
+#endif
 
 	return cost1 + cost2;
@@ -3270,8 +3290,8 @@
 	BspViewCell *vc2 = leaf2->GetViewCell();
 
-	float cost1 = vc1->GetPvs().GetSize(); 
-	float cost2 = vc2->GetPvs().GetSize(); 
-
-	/*if (mUseAreaForPvs)
+	float cost1, cost2;
+
+#if 1
+	if (mUseAreaForPvs)
 	{
 		cost1 = vc1->GetPvs().GetSize() * vc1->GetArea();
@@ -3282,5 +3302,9 @@
 		cost1 = vc1->GetPvs().GetSize() * vc1->GetVolume();
 		cost2 = vc2->GetPvs().GetSize() * vc2->GetVolume();
-	}*/
+	}
+#else
+	cost1 = vc1->GetPvs().GetSize(); 
+	cost2 = vc2->GetPvs().GetSize(); 
+#endif
 
 	const float oldCost = cost1 + cost2;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 556)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 573)
@@ -201,4 +201,5 @@
 }
 
+
 bool BspLeaf::IsLeaf() const 
 { 
@@ -206,7 +207,8 @@
 }
 
-/****************************************************************/
-/*                  class BspTree implementation                */
-/****************************************************************/
+
+/******************************************************************/
+/*                    class BspTree implementation                */
+/******************************************************************/
 
 BspTree::BspTree():  
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 563)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 573)
@@ -118,4 +118,7 @@
 			   );
   
+  virtual void CastRays(SimpleRayContainer &rays,
+	  VssRayContainer &vssRays) {};
+
   /// scene graph loaded from file
   SceneGraph *mSceneGraph;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 572)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 573)
@@ -88,69 +88,101 @@
 
 
+int ViewCellsManager::CastPassSamples(int samplesPerPass, 
+									  int sampleType, 
+									  VssRayContainer *outRays) const
+{
+	VssRayContainer passSamples;
+	SimpleRayContainer simpleRays;
+
+	preprocessor->GenerateRays(samplesPerPass,
+							   sampleType,
+							   simpleRays);
+
+	// shoot simple ray and add it to importance samples
+	preprocessor->CastRays(simpleRays, passSamples);
+
+	const int numSamples = (int)passSamples.size();
+
+	if (outRays)
+	{
+		while (!passSamples.empty())
+			outRays->push_back(passSamples.back());
+	}
+	else
+	{
+		CLEAR_CONTAINER(passSamples);
+	}
+
+	return numSamples;
+}
+
+
 int ViewCellsManager::Construct(Preprocessor *preprocessor, VssRayContainer *outRays)
 {
+	int numSamples = 0;
 	SimpleRayContainer simpleRays;
-	VssRayContainer constructionRays;
-
-	preprocessor->GenerateRays(mConstructionSamples,
-							   Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION,
-							   simpleRays);
-
-	Construct(preprocessor->mObjects, constructionRays);
-
-	int numRays = (int)simpleRays.size();
-
-	static Ray traversalRay;
-
-	// shoot simple ray and add it to construction rays
-	while (!simpleRays.empty())
-	{
-		SimpleRay sray = simpleRays.back();
-
-		// TODO: shoot into kdtree
-		constructionRays.push_back(new VssRay(traversalRay));
-
-		if (outRays)
-			outRays->push_back(constructionRays.back());
-
-		simpleRays.pop_back();
-	}
-
-	if (!outRays)
-		CLEAR_CONTAINER(constructionRays);
-
-	// guided rays
-	VssRayContainer importanceRays;
-	const int desiredImportanceRays = max(1000000, mPostProcessSamples);
-	preprocessor->GenerateRays(desiredImportanceRays,
-							   Preprocessor::RSS_BASED_DISTRIBUTION,
-							   simpleRays);
-
-	numRays += (int)simpleRays.size();
-
-	// shoot simple ray and add it to construction rays
-	while (!simpleRays.empty())
-	{
-		SimpleRay sray = simpleRays.back();
-
-		// TODO: shoot into kdtree
-		importanceRays.push_back(new VssRay(traversalRay));
-
-		if (outRays)
-			outRays->push_back(importanceRays.back());
-
-		simpleRays.pop_back();
-	}
-
-	if (!outRays)
-		CLEAR_CONTAINER(importanceRays);
-
+	
+	VssRayContainer constructionSamples;
+
+	//-- construction rays => we use uniform samples for this
+	CastPassSamples(mConstructionSamples, 
+					Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION, 
+					&constructionSamples);
+	
+	// construct view cells
+	const int initialSamples = Construct(preprocessor->mObjects, constructionSamples);
+
+	numSamples += initialSamples;
+
+	if (outRays)
+	{
+		while (!constructionSamples.empty())
+			outRays->push_back(constructionSamples.back());
+	}
+	else
+	{
+		CLEAR_CONTAINER(constructionSamples);
+	}
+
+
+	//-- guided rays are used for further sampling
+	const int desiredImportanceSamples = 5000000;
+	const int importanceRayPerPass = 1000000;
+
+	const int n = desiredImportanceSamples; //+initialSamples;
+
+	while (numSamples < n)
+	{
+		numSamples += CastPassSamples(importanceRayPerPass, 
+									  Preprocessor::RSS_BASED_DISTRIBUTION, 
+									  //Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION,
+									  outRays);
+	}
+	
+
+	//-- post processing
+	VssRayContainer postProcessSamples;
+
+	//-- construction rays => we use uniform samples for this
+	CastPassSamples(max(mPostProcessSamples, mVisualizationSamples),
+				    Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION, 
+					&postProcessSamples);
+	
 	// merge the view cells
-	PostProcess(preprocessor->mObjects, importanceRays);
-
-	Visualize(preprocessor->mObjects, importanceRays);
-
-
-	return numRays;
+	PostProcess(preprocessor->mObjects, postProcessSamples);
+	// several visualizations
+	Visualize(preprocessor->mObjects, postProcessSamples);
+
+	if (outRays)
+	{
+		while (!postProcessSamples.empty())
+			outRays->push_back(postProcessSamples.back());
+	}
+	else
+	{
+		CLEAR_CONTAINER(postProcessSamples);
+	}
+
+	return numSamples;
 }
 
