Index: /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 366)
+++ /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 367)
@@ -56,5 +56,5 @@
 
 Sampling {
-	totalSamples	20000000
+	totalSamples	300000
 	samplesPerPass  3
 }
@@ -82,5 +82,5 @@
 	#	input fromViewCells
 	#	input fromSceneGeometry
-		samples 100000
+		samples 10000
 		sideTolerance 0.005
 	}
@@ -97,4 +97,5 @@
 	# least ray splits     = 256
 	# balanced rays        = 512
+	# pvs                  = 1024
 
 	# least splits + balanced polygons
@@ -119,5 +120,5 @@
 	#splitPlaneStrategy 130
 	
-	splitPlaneStrategy 130
+	splitPlaneStrategy 1024
 	
 	maxCandidates 80
@@ -125,13 +126,13 @@
 	Termination {
 		# autopartition
-		maxRays 80
-		maxPolygons 0
+		maxRays 200
+		maxPolygons 5
 		maxDepth 100
 		
 		# axis aligned splits
 		AxisAligned {
-			maxPolys 500
-			maxRays 300
-			maxObjects 20
+			maxPolys 5000
+			maxRays 5000
+			maxObjects 2000
 			maxCostRatio 0.9
 			ct_div_ci 0.5
@@ -142,4 +143,8 @@
 		splitBorder 0.01
 	}
+	
+	PostProcessing {
+		samples 100000
+	}
 		
 	# if split polys are stored for visualization
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 366)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 367)
@@ -194,4 +194,5 @@
 		@param coincident returns the polygons coincident to the split plane
 		@param storePolys if the polygons should be stored in the node
+		
 		@returns the number of splits	
 	*/
@@ -250,10 +251,9 @@
 		@param sampleContributions the number contributions of the sampels
 		@param contributingSampels the number of contributing rays
-		@param storeRays if ray set should be stored in view cell
+		
 	*/
 	void GenerateViewCell(const BoundedRayContainer &rays, 
 					      int &sampleContributions,
-						  int &contributingSamples,
-						  const bool storeRays = false);
+						  int &contributingSamples);
 
 protected:
@@ -657,4 +657,11 @@
 
 	int CountPvs(const BoundedRayContainer &rays) const;
+	
+	float PvsValue(Intersectable &obj, 
+				   const int cf, 
+				   const int frontId, 
+				   const int backId, 
+				   const int frontAndBackId) const;
+	
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
@@ -729,4 +736,5 @@
 	static float sLeastRaySplitsFactor;
 	static float sBalancedRaysFactor;
+	static float sPvsFactor;
 
 	/// if polygons should be stored in the tree
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 366)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 367)
@@ -55,17 +55,5 @@
     
   };
-  
-  struct BspIntersection
-  {
-	  float mT;
-	  BspLeaf *leaf;
-	  BspIntersection(float t, BspLeaf *l): mT(t), leaf(l)
-	  {}
-
-	  bool operator<(const BspIntersection &b) const 
-	  {
-		  return mT	< b.mT;
-	  }
-  };
+
 
   // I should have some abstract cell data type !!! here
@@ -75,5 +63,5 @@
   
   vector<Intersection> intersections;
-  vector<BspIntersection> bspIntersections;
+  vector<BspLeaf *> bspLeaves;
   vector<KdLeaf *> kdLeaves;
   vector<MeshInstance *> meshes;
@@ -210,6 +198,4 @@
   int ClassifyPlane(const Plane3 &plane, const float minT, const float maxT) const;
 
-  void Insert(const BspIntersection &bspi);
-
 private:
   Vector3 loc, dir;		// Describes ray origin and vector
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 362)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 367)
@@ -1180,4 +1180,9 @@
 	  "100000");
 
+  RegisterOption("BspTree.PostProcessing.samples",
+	  optInt,
+	  "-bsp_postprocessing_samples=",
+	  "200000");
+
   RegisterOption("BspTree.Construction.sideTolerance",
 	  optFloat,
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 366)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 367)
@@ -41,4 +41,5 @@
 float BspTree::sLeastRaySplitsFactor = 1.0f;
 float BspTree::sBalancedRaysFactor = 1.0f;
+float BspTree::sPvsFactor = 1.0f;
 
 bool BspTree::sStoreSplitPolys = false;
@@ -194,5 +195,5 @@
 
 		// classify polygon
-		const int classification = poly->ClassifyPlane(mPlane);
+		const int cf = poly->ClassifyPlane(mPlane);
 
 		Polygon3 *front_piece = NULL;
@@ -201,5 +202,5 @@
 		VertexContainer splitVertices;
 
-		switch (classification)
+		switch (cf)
 		{
 			case Polygon3::COINCIDENT:
@@ -224,5 +225,5 @@
 				++ splits; // increase number of splits
 
-				//-- inherit rays from parent polygon
+				//-- inherit rays from parent polygon for blocked ray criterium
 				poly->InheritRays(*front_piece, *back_piece);
 				//Debug << "p: " << poly->mPiercingRays.size() << " f: " << front_piece->mPiercingRays.size() << " b: " << back_piece->mPiercingRays.size() << endl;
@@ -291,6 +292,5 @@
 void BspLeaf::GenerateViewCell(const BoundedRayContainer &rays, 
 							   int &sampleContributions,
-							   int &contributingSamples,
-							   const bool storeRays)
+							   int &contributingSamples)
 {
 	sampleContributions = 0;
@@ -321,8 +321,5 @@
 		}
 
-		ray->bspIntersections.push_back(BspIntersection(this, (*it)->mMinT);
-
-		if (storeRays)
-			mViewCell->mPiercingRays.push_back(ray);
+		ray->bspLeaves.push_back(this);
 	}
 }
@@ -628,12 +625,16 @@
 			if (it != facePolyMap.end()) 
 			{
-				(*it).second->mPiercingRays.push_back(ray);
+				//store rays if needed for heuristics
+				if (sSplitPlaneStrategy & BLOCKED_RAYS)
+					(*it).second->mPiercingRays.push_back(ray);
 			} 
 			else
-			{
+			{	//store rays if needed for heuristics
 				Polygon3 *poly = new Polygon3(face, obj->GetMesh());
 				poly->mParent = obj;
 				polys->push_back(poly);
-				poly->mPiercingRays.push_back(ray);
+
+				if (sSplitPlaneStrategy & BLOCKED_RAYS)
+					poly->mPiercingRays.push_back(ray);
 
 				facePolyMap[face] = poly;
@@ -642,4 +643,7 @@
 	}
 	
+	facePolyMap.clear();
+
+	// compue bounding box
 	Polygon3::IncludeInBox(*polys, mBox);
 
@@ -848,7 +852,9 @@
 	
 	// subdivide polygons with plane
-	mStat.splits += 
-		interior->SplitPolygons(polys, frontPolys, backPolys, 
-								coincident, sStoreSplitPolys);
+	mStat.splits += interior->SplitPolygons(polys, 
+		                                    frontPolys, 
+											backPolys, 
+											coincident, 
+											sStoreSplitPolys);
 
 	BspInterior *parent = leaf->GetParent();
@@ -1247,6 +1253,14 @@
 	float sumRaySplits = 0;
 	float pvsSize = 0;
-
+	float totalSize = 0;
+
+	// need three unique ids for small pvs criterium
 	Intersectable::NewMail();
+	const int backId = ViewCell::sMailId;
+	Intersectable::NewMail();
+	const int frontId = ViewCell::sMailId;
+	Intersectable::NewMail();
+	const int frontAndBackId = ViewCell::sMailId;
+	//Debug << "f " << frontId <<  " b " << backId << " fb " << frontAndBackId << endl;
 
 	BoundedRayContainer::const_iterator rit, rit_end = rays.end();
@@ -1258,15 +1272,15 @@
 		const float maxT = (*rit)->mMaxT;
 
-		const int classification = 
+		const int cf = 
 			ray->ClassifyPlane(candidatePlane, minT, maxT);
 
 		if (sSplitPlaneStrategy & LEAST_RAY_SPLITS)
 		{
-			sumBalancedRays += sBalancedRaysTable[classification];
+			sumBalancedRays += sBalancedRaysTable[cf];
 		}
 		
 		if (sSplitPlaneStrategy & BALANCED_RAYS)
 		{
-			sumRaySplits += sLeastRaySplitsTable[classification];
+			sumRaySplits += sLeastRaySplitsTable[cf];
 		}
 
@@ -1276,11 +1290,19 @@
 				it_end = ray->intersections.end();
 
-			for (it = ray->intersections.begin(); it != it_end; ++ it)
+			if (!ray->intersections.empty())
 			{
-				if (!(*it).mObject->Mailed())
-				{
-					(*it).mObject->Mail();
-				}
+
+				// assure that we only count a object 
+				// once for the front and once for the back side of the plane
+				pvsSize += PvsValue(*ray->intersections[0].mObject, 
+									cf, 
+									frontId, 
+									backId, 
+									frontAndBackId);
+
+				// always add 2 for each object (= maximal large PVS)
+				//if (inc > 0.01)	totalSize += 2.0;
 			}
+			//todo emerging obj
 		}
 	}
@@ -1294,5 +1316,59 @@
 			val += sBalancedRaysFactor * fabs(sumBalancedRays) / (float)rays.size();
 
+	if (sSplitPlaneStrategy & PVS)
+		if (!rays.empty()) // HACK (should be maximal possible pvs)
+			val += sPvsFactor * pvsSize / (float)rays.size(); 
+
+	//Debug << "pvs: " << pvsSize << " val " << val << endl;
 	return val;
+}
+
+
+float BspTree::PvsValue(Intersectable &obj, 
+					    const int cf, 
+					    const int frontId, 
+					    const int backId, 
+					    const int frontAndBackId) const
+{
+	float pvsVal = 0;
+
+	if (cf == Ray::COINCIDENT)
+		return pvsVal;
+
+	if (cf == Ray::FRONT)
+	{
+		if ((obj.mMailbox != frontId) && 
+			(obj.mMailbox != frontAndBackId))
+			pvsVal = 1.0;
+
+		if (obj.mMailbox != backId)
+			obj.mMailbox = frontId;
+		else
+			obj.mMailbox = frontAndBackId;					
+	}
+	else if (cf == Ray::BACK)
+	{
+		if ((obj.mMailbox != backId) &&
+			(obj.mMailbox != frontAndBackId))
+		{
+			pvsVal = 1.0;
+
+			if (obj.mMailbox != frontId)
+				obj.mMailbox = backId;
+			else
+				obj.mMailbox = frontAndBackId; 
+		}
+	}
+	else if ((cf == Ray::FRONT_BACK) || (cf == Ray::BACK_FRONT))
+	{
+		if ((obj.mMailbox == backId) || (obj.mMailbox == frontId))
+			pvsVal = 1.0;
+		else if (obj.mMailbox != frontAndBackId)
+			pvsVal = 2.0;
+			
+		obj.mMailbox = frontAndBackId;
+	}
+
+	return pvsVal;
 }
 
@@ -1324,5 +1400,6 @@
 	// the following criteria loop over all rays to find the cost value
 	if ((sSplitPlaneStrategy & BALANCED_RAYS)      ||
-		(sSplitPlaneStrategy & LEAST_RAY_SPLITS))
+		(sSplitPlaneStrategy & LEAST_RAY_SPLITS)   ||
+		(sSplitPlaneStrategy & PVS))
 	{
 		val += SplitPlaneCost(candidatePlane, rays);
@@ -1403,5 +1480,6 @@
 	if (sSplitPlaneStrategy & BLOCKED_RAYS)
 		Debug << "blocked rays ";
-
+	if (sSplitPlaneStrategy & PVS)
+		Debug << "pvs";
 	Debug << endl;
 }
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp	(revision 366)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp	(revision 367)
@@ -195,11 +195,4 @@
 
 
-void Ray::Insert(const BspIntersection &bspi)
-{
-	vector<BspIntersection>::iterator it;
-
-	while (it !=
-}
-
 ostream &
 operator<<(ostream &s, const PassingRaySet &set)
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 362)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 367)
@@ -25,5 +25,5 @@
   RayContainer mSampleRays;
   int mBspConstructionSamples;
-
+  int mPostProcessSamples;
 	
   SamplingPreprocessor();
@@ -65,5 +65,5 @@
 
 	/** Processes the BSP based view cells during a pass.
-		@param collectSamplesForBps if still in sample collection phase
+		
 		@param ray the current ray
 		@param object the currently processed object
@@ -75,6 +75,5 @@
 
 	*/
-	bool ProcessBspViewCells(bool collectSamplesForBsp,
-							 Ray &ray,
+	bool ProcessBspViewCells(Ray &ray,
 							 Intersectable *object,
 							 int faceIndex,
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 362)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 367)
@@ -351,4 +351,7 @@
 					       Polygon3 &back_piece) const
 {
+	if (mPiercingRays.empty())
+		return;
+
 	RayContainer::const_iterator it, 
 		it_end = mPiercingRays.end();
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 366)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 367)
@@ -14,5 +14,5 @@
   environment->GetIntValue("Sampling.totalSamples", mTotalSamples);
   environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
-
+  environment->GetIntValue("BspTree.PostProcessing.samples", mPostProcessSamples);
   mKdPvsDepth = 100;
   mStats.open("stats.log");
@@ -121,5 +121,5 @@
 		for (j=1; j < ((int)ray.bspLeaves.size() - 1); ++ j) 
 		{
-			BspLeaf *leaf = ray.bspIntersections.leaf;
+			BspLeaf *leaf = ray.bspLeaves[j];
 
 			if (leaf->GetViewCell() != &mUnbounded)
@@ -380,8 +380,5 @@
 		
 		int reverseSamples = 0;
-		bool collectSamplesForBsp = 
-			(ViewCell::sHierarchy == ViewCell::BSP) &&
-			(BspTree::sConstructionMethod == BspTree::FROM_RAYS) &&
-			(totalSamples < mBspConstructionSamples);
+		
 			
 		//cout << "totalSamples: "  << totalSamples << endl;
@@ -457,6 +454,5 @@
 					if (ViewCell::sHierarchy == ViewCell::BSP) 
 					{
-						ProcessBspViewCells(collectSamplesForBsp,
-											ray,
+						ProcessBspViewCells(ray,
 											object,
 											faceIndex,
@@ -523,5 +519,5 @@
 	if (mBspTree)
 	{
-		cout << "starting post processing ... ";
+		cout << "starting post processing using " << mSampleRays.size() << " samples ... ";
 
 		Debug << "original pvs size: " << mBspTree->CountViewCellPvs() << endl;
@@ -620,6 +616,5 @@
 }
 
-bool SamplingPreprocessor::ProcessBspViewCells(bool collectSamplesForBsp,
-											   Ray &ray,
+bool SamplingPreprocessor::ProcessBspViewCells(Ray &ray,
 											   Intersectable *object,
 											   int faceIndex,
@@ -628,5 +623,6 @@
 {
 	// save rays for bsp tree construction
-	if (collectSamplesForBsp)
+	if ((BspTree::sConstructionMethod == BspTree::FROM_RAYS) &&
+		(mSampleRays.size() < mBspConstructionSamples))
 	{
 		// also add origin to sample in order to extract it as input polygons
@@ -639,14 +635,25 @@
 	}
 	
-	// construct BSP tree using the samples
-	if (!mBspTree)
+	if (!mBspTree) // construct BSP tree using the samples
 	{
+        cout << "building bsp tree from " << mSampleRays.size() << " samples " << endl;
 		BuildBspTree();
 		
+		// add contributions of saved samples to PVS
 		contributingSamples += mBspTree->GetStat().contributingSamples;
 		sampleContributions += mBspTree->GetStat().sampleContributions;
 
 		BspTreeStatistics(Debug);	
+
 		if (0) Export("vc_bsptree.x3d", false, false, true);
+
+		// throw away samples because BSP leaves not stored in order 
+		// Need ordered rays for post processing => collect new rays
+		CLEAR_CONTAINER(mSampleRays);
+	}
+	
+	if ((int)mSampleRays.size() < mPostProcessSamples)
+	{
+		mSampleRays.push_back(new Ray(ray));
 	}
 
@@ -676,4 +683,5 @@
 		{
 			BspLeaf *leaf = *lit;
+
 			if (mBspTree->ShouldMerge(leaf, previousLeaf))
 			{			
