Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 425)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 426)
@@ -62,5 +62,5 @@
 
 Sampling {
-	totalSamples	300000
+	totalSamples	1000000
 	samplesPerPass  3
 }
@@ -152,6 +152,6 @@
 	Termination {
 		# parameters used for autopartition
-		maxRays 200
-		maxPolygons -1
+		minRays 200
+		minPolygons -1
 		maxDepth 40
 		minPvs 35
@@ -159,4 +159,5 @@
 		maxRayContribution 0.005
 		#maxAccRayLength 100
+		
 		# used for pvs criterium
 		ct_div_ci 0.0
@@ -164,7 +165,7 @@
 		# axis aligned splits
 		AxisAligned {
-			maxPolys 5000
-			maxRays 500
-			maxObjects 10
+			minPolys 5000
+			minRays 500
+			minObjects 10
 			maxCostRatio 0.9
 			ct_div_ci 0.5
@@ -218,14 +219,14 @@
 
 	Construction {
-		samples 200000
-	}
-	
-	Termination {
-		maxDepth 	20
-		minPvs		200
-		minRays		100
-		minSize		0.001
+		samples 1000000
+	}
+	
+	Termination {
+		maxDepth 	30
+		minPvs		50
+		minRays		10
+		minSize		0.1
 		maxCostRatio	0.95
-		maxRayContribution 0.1
+		maxRayContribution 0.2
 	}
 	
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 425)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 426)
@@ -241,4 +241,8 @@
 }
 
+RayInfoContainer &VspKdTreeLeaf::GetRays()
+{
+	return mRays;
+}
 /*********************************************************/
 /*            class VspKdTree implementation             */
@@ -313,64 +317,66 @@
 void VspKdStatistics::Print(ostream &app) const
 {
-  app << "===== VspKdTree statistics ===============\n";
-
-  app << "#N_RAYS ( Number of rays )\n"
-      << rays <<endl;
-  
-  app << "#N_INITPVS ( Initial PVS size )\n"
-      << initialPvsSize <<endl;
-  
-  app << "#N_NODES ( Number of nodes )\n" << nodes << "\n";
-
-  app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n";
-
-  app << "#N_SPLITS ( Number of splits in axes x y z dx dy dz \n";
-  for (int i=0; i<7; i++)
-    app << splits[i] <<" ";
-  app <<endl;
-
-  app << "#N_RAYREFS ( Number of rayRefs )\n" <<
-    rayRefs << "\n";
-
-  app << "#N_RAYRAYREFS  ( Number of rayRefs / ray )\n" <<
-    rayRefs/(double)rays << "\n";
-
-  app << "#N_LEAFRAYREFS  ( Number of rayRefs / leaf )\n" <<
-    rayRefs/(double)Leaves() << "\n";
-
-  app << "#N_MAXRAYREFS  ( Max number of rayRefs / leaf )\n" <<
-    maxRayRefs << "\n";
-
+	app << "===== VspKdTree statistics ===============\n";
+
+	app << "#N_RAYS ( Number of rays )\n"
+		<< rays << endl;
+  
+	app << "#N_INITPVS ( Initial PVS size )\n"
+		<< initialPvsSize << endl;
+  
+	app << "#N_NODES ( Number of nodes )\n" << nodes << "\n";
+
+	app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n";
+
+	app << "#N_SPLITS ( Number of splits in axes x y z dx dy dz \n";
+  
+	for (int i=0; i<7; i++)
+		app << splits[i] <<" ";
+	app << endl;
+
+	app << "#N_RAYREFS ( Number of rayRefs )\n" <<
+		rayRefs << "\n";
+
+	app << "#N_RAYRAYREFS  ( Number of rayRefs / ray )\n" <<
+		rayRefs / (double)rays << "\n";
+
+	app << "#N_LEAFRAYREFS  ( Number of rayRefs / leaf )\n" <<
+		rayRefs / (double)Leaves() << "\n";
+
+	app << "#N_MAXRAYREFS  ( Max number of rayRefs / leaf )\n" <<
+		maxRayRefs << "\n";
 
   //  app << setprecision(4);
 
-  app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maxdepth )\n"<<
-    maxDepthNodes*100/(double)Leaves()<<endl;
-
-  app << "#N_PMINPVSLEAVES  ( Percentage of leaves with minCost )\n"<<
-    minPvsNodes*100/(double)Leaves()<<endl;
-
-  app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minCost )\n"<<
-    minRaysNodes*100/(double)Leaves()<<endl;
-	
+	app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maxdepth )\n" <<
+		maxDepthNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINPVSLEAVES  ( Percentage of leaves with mininimal PVS )\n" <<
+		minPvsNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minimal number of rays)\n" <<
+		minRaysNodes * 100 / (double)Leaves() << endl;
+
 	app << "#N_PMINSIZELEAVES  ( Percentage of leaves with minSize )\n"<<
-    minSizeNodes*100/(double)Leaves()<<endl;
-
-	app << "#N_PMAXRAYCONTRIBLEAVES  ( Percentage of leaves with maximal ray contribution )\n"<<
-    maxRayContribNodes*100/(double)Leaves()<<endl;
-
-  app << "#N_ADDED_RAYREFS  (Number of dynamically added ray references )\n"<<
-    addedRayRefs<<endl;
-
-  app << "#N_REMOVED_RAYREFS  (Number of dynamically removed ray references )\n"<<
-    removedRayRefs<<endl;
-
-  //  app << setprecision(4);
-
-  app << "#N_CTIME  ( Construction time [s] )\n"
-      << Time() << " \n";
-
-  app << "===== END OF VspKdTree statistics ==========\n";
-
+		minSizeNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMAXRAYCONTRIBLEAVES  ( Percentage of leaves with maximal ray contribution )\n" <<
+		maxRayContribNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_ADDED_RAYREFS  ( Number of dynamically added ray references )\n"<<
+		addedRayRefs << endl;
+
+	app << "#N_REMOVED_RAYREFS  ( Number of dynamically removed ray references )\n"<<
+		removedRayRefs << endl;
+
+	//  app << setprecision(4);
+
+	app << "#N_MAXPVS ( Maximal PVS size / leaf)\n"
+		<< maxPvsSize << endl;
+
+	app << "#N_CTIME  ( Construction time [s] )\n"
+		<< Time() << " \n";
+
+	app << "===== END OF VspKdTree statistics ==========\n";
 }
 
@@ -876,23 +882,25 @@
 	VspKdTreeLeaf *leaf = dynamic_cast<VspKdTreeLeaf *>(data.mNode);
 
+	if (leaf->GetPvsSize() > mStat.maxPvsSize)
+		mStat.maxPvsSize = leaf->GetPvsSize();
+
+	if ((int)(leaf->mRays.size()) > mStat.maxRayRefs)
+		mStat.maxRayRefs = (int)leaf->mRays.size();
+
+
 	if (data.mDepth >= mTermMaxDepth)
 		++ mStat.maxDepthNodes;
   
-	//  if ( (int)(leaf->mRays.size()) < termMinCost)
-	//    stat.minCostNodes++;
 	if (leaf->GetPvsSize() < mTermMinPvs)
 		++ mStat.minPvsNodes;
 
-	if (leaf->GetPvsSize() < mTermMinRays)
+	if ((int)leaf->GetRays().size() < mTermMinRays)
 		++ mStat.minRaysNodes;
 
-	if (0 && leaf->GetAvgRayContribution() > mTermMaxRayContribution)
+	if (leaf->GetAvgRayContribution() > mTermMaxRayContribution)
 		++ mStat.maxRayContribNodes;
 	
 	if (SqrMagnitude(data.mBox.Size()) <= mTermMinSize) 
 		++ mStat.minSizeNodes;
-
-//	if ((int)(leaf->mRays.size()) > stat.maxRayRefs)
-//		mStat.maxRayRefs = (int)leaf->mRays.size();
 }
 
@@ -902,6 +910,6 @@
 {
 	return ((leaf->GetPvsSize() < mTermMinPvs) || 
-		    //(leaf->mRays.size() < mTermMinRays) ||
-			// (leaf->GetAvgRayContribution() > termMaxRayContribution ) ||
+		    (leaf->mRays.size() < mTermMinRays) ||
+			(leaf->GetAvgRayContribution() > mTermMaxRayContribution ) ||
 			(leaf->mDepth >= mTermMaxDepth) || 
 			(SqrMagnitude(box.Size()) <= mTermMinSize));
@@ -923,6 +931,5 @@
 				Debug << "Bbox: " << GetBBox(leaf) << endl;
 			}
-		
-			Debug << "depth: " << (int)leaf->mDepth << " pvs: " << leaf->GetPvsSize() << " rays: " << leaf->mRays.size() << endl;
+			//Debug << "depth: " << (int)leaf->mDepth << " pvs: " << leaf->GetPvsSize() << " rays: " << leaf->mRays.size() << endl;
 		}
 		return leaf;
@@ -939,5 +946,5 @@
 	const int axis = SelectPlane(leaf, box, position, raysBack, raysFront, pvsBack, pvsFront);
 
-	Debug << "rays back=" << raysBack << " rays front=" << raysFront << " pvs back=" << pvsBack << " pvs front=" <<	pvsFront << endl;
+	//Debug << "rays back=" << raysBack << " rays front=" << raysFront << " pvs back=" << pvsBack << " pvs front=" <<	pvsFront << endl;
 
 	if (axis == -1) 
@@ -1695,5 +1702,6 @@
 }
 
-int VspKdTree::ComputePvsSize(VspKdTreeNode *node, const RayInfoContainer &globalRays) const
+int VspKdTree::ComputePvsSize(VspKdTreeNode *node, 
+							  const RayInfoContainer &globalRays) const
 {
 	int pvsSize = 0;
@@ -1703,7 +1711,8 @@
 	RayInfoContainer::const_iterator it, it_end = globalRays.end();
 
+	// warning: implicit conversion from VssRay to Ray
 	for (it = globalRays.begin(); it != globalRays.end(); ++ it)
-		;//pvsSize += box.GetMinMaxT((*it).mRay, NULL, NULL);
-
+		pvsSize += box.GetMinMaxT(*(*it).mRay, NULL, NULL);
+	
 	return pvsSize;
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 424)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 426)
@@ -85,6 +85,18 @@
 	// minimal depth
 	int minDepth;
+	
 	// max depth nodes
 	int maxDepthNodes;
+	// minimum depth nodes
+	int minDepthNodes;
+	// max depth nodes
+	int minPvsNodes;
+	// nodes with minimum PVS
+	int minRaysNodes;
+	// max ray contribution nodes
+	int maxRayContribNodes;
+	// minimum area nodes
+	int minAreaNodes;
+
 	// max number of rays per node
 	int maxObjectRefs;
@@ -117,5 +129,5 @@
 		nodes = 0;
 		splits = 0;
-		maxDepthNodes = 0;
+		
 		maxDepth = 0;
 		minDepth = 99999;
@@ -123,4 +135,10 @@
 		accumDepth = 0;
         
+		maxDepthNodes = 0;
+		minPvsNodes = 0;
+		minRaysNodes = 0;
+		maxRayContribNodes = 0;
+		minAreaNodes = 0;
+
 		contributingSamples = 0;
 		sampleContributions = 0;
@@ -783,7 +801,7 @@
 
 	/// maximal number of polygons before subdivision termination
-	int mTermMaxPolygons;
+	int mTermMinPolys;
 	/// maximal number of rays before subdivision termination
-	int mTermMaxRays;
+	int mTermMinRays;
 	/// maximal possible depth
 	int mTermMaxDepth;
@@ -792,4 +810,17 @@
 	/// mininum PVS
 	int mTermMinPvs;
+
+	/// minimal number of polygons for axis aligned split
+	int mTermMinPolysForAxisAligned;
+	/// minimal number of rays for axis aligned split
+	int mTermMinRaysForAxisAligned;
+	/// minimal number of objects for axis aligned split
+	int mTermMinObjectsForAxisAligned;
+	/// maximal contribution per ray
+	float mTermMaxRayContribution;
+	/// minimal accumulated ray length
+	float mTermMinAccRayLength;
+
+
 	/// strategy to get the best split plane
 	int mSplitPlaneStrategy;
@@ -799,15 +830,4 @@
 	int mMaxRayCandidates;
 	
-	/// maximal number of polygons for axis aligned split
-	int mTermMaxPolysForAxisAligned;
-	/// maximal number of rays for axis aligned split
-	int mTermMaxRaysForAxisAligned;
-	/// maximal number of objects for axis aligned split
-	int mTermMaxObjectsForAxisAligned;
-	/// maximal contribution per ray
-	float mTermMaxRayContribution;
-	/// maximal accumulated ray length
-	float mTermMaxAccRayLength;
-
 	float mCtDivCi;
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 406)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 426)
@@ -13,4 +13,5 @@
 class ViewCell;
 class BspLeaf;
+class VssRay;
 
 // -------------------------------------------------------------------
@@ -101,4 +102,8 @@
   // dummy constructor
   Ray() {}
+
+  /** Construct ray from a vss ray.
+  */
+  Ray(const VssRay &vssRay);	
 	
   Intersectable *GetIntersectionObject(const int i) const {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 424)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 426)
@@ -1240,7 +1240,7 @@
 	  "0.002");
 
-  RegisterOption("BspTree.Termination.maxPolygons",
-		 optInt,
-		 "-bsp_term_max_polygons=",
+  RegisterOption("BspTree.Termination.minPolygons",
+		 optInt,
+		 "-bsp_term_min_polygons=",
 		 "5");
 
@@ -1260,12 +1260,12 @@
 		 "0.005");
 
-  RegisterOption("BspTree.Termination.maxAccRayLenght",
-		 optFloat,
-		 "-bsp_term_max_acc_ray_length=",
+  RegisterOption("BspTree.Termination.minAccRayLenght",
+		 optFloat,
+		 "-bsp_term_min_acc_ray_length=",
 		 "50");
 
-   RegisterOption("BspTree.Termination.maxRays",
-		 optInt,
-		 "-bsp_term_max_rays=",
+   RegisterOption("BspTree.Termination.minRays",
+		 optInt,
+		 "-bsp_term_min_rays=",
 		 "-1");
 
@@ -1295,17 +1295,17 @@
 		 "0.1");
 
-  RegisterOption("BspTree.Termination.AxisAligned.maxPolys",
+  RegisterOption("BspTree.Termination.AxisAligned.minPolys",
 		 optInt,
 		 "-bsp_term_axis_aligned_max_polygons=",
 		 "50");
 
-   RegisterOption("BspTree.Termination.AxisAligned.maxObjects",
-		 optInt,
-		 "-bsp_term_max_objects=",
+   RegisterOption("BspTree.Termination.AxisAligned.minObjects",
+		 optInt,
+		 "-bsp_term_min_objects=",
 		 "3");
 
-  RegisterOption("BspTree.Termination.AxisAligned.maxRays",
-		 optInt,
-		 "-bsp_term_axis_aligned_max_rays=",
+  RegisterOption("BspTree.Termination.AxisAligned.minRays",
+		 optInt,
+		 "-bsp_term_axis_aligned_min_rays=",
 		 "-1");
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 424)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 426)
@@ -282,9 +282,9 @@
 	environment->GetIntValue("BspTree.Termination.maxDepth", mTermMaxDepth);
 	environment->GetIntValue("BspTree.Termination.minPvs", mTermMinPvs);
-	environment->GetIntValue("BspTree.Termination.maxPolygons", mTermMaxPolygons);
-	environment->GetIntValue("BspTree.Termination.maxRays", mTermMaxRays);
+	environment->GetIntValue("BspTree.Termination.minPolygons", mTermMinPolys);
+	environment->GetIntValue("BspTree.Termination.minRays", mTermMinRays);
 	environment->GetFloatValue("BspTree.Termination.minArea", mTermMinArea);	
 	environment->GetFloatValue("BspTree.Termination.maxRayContribution", mTermMaxRayContribution);
-	environment->GetFloatValue("BspTree.Termination.maxAccRayLenght", mTermMaxAccRayLength);
+	environment->GetFloatValue("BspTree.Termination.minAccRayLenght", mTermMinAccRayLength);
 
 	//-- factors for bsp tree split plane heuristics
@@ -303,10 +303,10 @@
 	environment->GetFloatValue("BspTree.Termination.AxisAligned.ct_div_ci", mAaCtDivCi);
 	environment->GetFloatValue("BspTree.Termination.AxisAligned.maxCostRatio", mMaxCostRatio);
-	environment->GetIntValue("BspTree.Termination.AxisAligned.maxPolys", 
-							 mTermMaxPolysForAxisAligned);
+	environment->GetIntValue("BspTree.Termination.AxisAligned.minPolys", 
+							 mTermMinPolysForAxisAligned);
 	environment->GetIntValue("BspTree.Termination.AxisAligned.maxRays", 
-							 mTermMaxRaysForAxisAligned);
+							 mTermMinRaysForAxisAligned);
 	environment->GetIntValue("BspTree.Termination.AxisAligned.maxObjects", 
-							 mTermMaxObjectsForAxisAligned);
+							 mTermMinObjectsForAxisAligned);
 	//-- partition criteria
 	environment->GetIntValue("BspTree.maxPolyCandidates", mMaxPolyCandidates);
@@ -326,6 +326,6 @@
 	Debug << "BSP min PVS: " << mTermMinPvs << endl;
 	Debug << "BSP min area: " << mTermMinArea << endl;
-	Debug << "BSP max polys: " << mTermMaxPolygons << endl;
-	Debug << "BSP max rays: " << mTermMaxRays << endl;
+	Debug << "BSP max polys: " << mTermMinPolys << endl;
+	Debug << "BSP max rays: " << mTermMinRays << endl;
 	Debug << "BSP max polygon candidates: " << mMaxPolyCandidates << endl;
 	Debug << "BSP max plane candidates: " << mMaxRayCandidates << endl;
@@ -403,6 +403,21 @@
 	app << "#N_SPLITS ( Number of splits )\n" << splits << "\n";
 
-	app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maxdepth )\n"<<
-	maxDepthNodes * 100 / (double)Leaves() << endl;
+	app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n" 
+		<<	maxDepthNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n" 
+		<<	maxDepthNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINPVSLEAVES  ( Percentage of leaves with mininimal PVS )\n" 
+		<< minPvsNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINRAYSLEAVES  ( Percentage of leaves with minimal number of rays)\n" 
+		<<	minRaysNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMINAREALEAVES  ( Percentage of leaves with mininum area )\n"
+		<< minAreaNodes * 100 / (double)Leaves() << endl;
+
+	app << "#N_PMAXRAYCONTRIBLEAVES  ( Percentage of leaves with maximal ray contribution )\n" 
+		<<	maxRayContribNodes * 100 / (double)Leaves() << endl;
 
 	app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl;
@@ -735,6 +750,6 @@
 {
 	return 
-		(((int)data.mPolygons->size() <= mTermMaxPolygons) || 
-		 ((int)data.mRays->size() <= mTermMaxRays) ||
+		(((int)data.mPolygons->size() <= mTermMinPolys) || 
+		 ((int)data.mRays->size() <= mTermMinRays) ||
 		 (data.mPvs <= mTermMinPvs) ||
 		 (data.mArea <= mTermMinArea) ||
@@ -1105,8 +1120,8 @@
 	
 	if ((mSplitPlaneStrategy & AXIS_ALIGNED) &&
-		((int)data.mPolygons->size() > mTermMaxPolysForAxisAligned) &&
-		((int)data.mRays->size() > mTermMaxRaysForAxisAligned) &&
-		((mTermMaxObjectsForAxisAligned < 0) || 
-		  (Polygon3::ParentObjectsSize(*data.mPolygons) > mTermMaxObjectsForAxisAligned)))
+		((int)data.mPolygons->size() > mTermMinPolysForAxisAligned) &&
+		((int)data.mRays->size() > mTermMinRaysForAxisAligned) &&
+		((mTermMinObjectsForAxisAligned < 0) || 
+		  (Polygon3::ParentObjectsSize(*data.mPolygons) > mTermMinObjectsForAxisAligned)))
 	{
 		Plane3 plane;
@@ -1699,7 +1714,4 @@
 	BspLeaf *leaf = dynamic_cast<BspLeaf *>(data.mNode);
 
-	if (data.mDepth >= mTermMaxDepth)
-		++ mStat.maxDepthNodes;
-	
 	// store maximal and minimal depth
 	if (data.mDepth > mStat.maxDepth)
@@ -1712,4 +1724,20 @@
 	mStat.accumDepth += data.mDepth;
 	
+
+	if (data.mDepth >= mTermMaxDepth)
+		++ mStat.maxDepthNodes;
+
+	if (data.mPvs < mTermMinPvs)
+		++ mStat.minPvsNodes;
+
+	if ((int)data.mRays->size() < mTermMinRays)
+		++ mStat.minRaysNodes;
+
+	if (data.GetAvgRayContribution() > mTermMaxRayContribution)
+		++ mStat.maxRayContribNodes;
+	
+	if (data.mGeometry->GetArea() <= mTermMinArea) 
+		++ mStat.minAreaNodes;
+
 #ifdef _DEBUG
 	Debug << "BSP stats: "
@@ -1717,6 +1745,6 @@
 		  << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), "
 		  << "Area: " << data.mArea << " (min: " << mTermMinArea << "), "
-		  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << mTermMaxPolygons << "), "
-		  << "#rays: " << (int)data.mRays->size() << " (max: " << mTermMaxRays << "), " 
+		  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << mTermMinPolys << "), "
+		  << "#rays: " << (int)data.mRays->size() << " (max: " << mTermMinRays << "), " 
 		  << "#pvs: " << leaf->GetViewCell()->GetPvs().GetSize() << "=, "
 		  << "#avg ray contrib (pvs): " << (float)data.mPvs / (float)data.mRays->size() << endl;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp	(revision 406)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp	(revision 426)
@@ -1,4 +1,5 @@
 #include "Ray.h"
 #include "Plane3.h"
+#include "VssRay.h"
 
 // =========================================================
@@ -219,2 +220,10 @@
   return s;
 }
+
+Ray::Ray(const VssRay &vssRay):
+loc(vssRay.mOrigin),
+sourceObject(0, vssRay.mOriginObject, 0),
+dir(vssRay.GetDir())
+{
+	intersections.push_back(Intersection(vssRay.mT, vssRay.mTerminationObject, 0));
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h	(revision 422)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h	(revision 426)
@@ -62,20 +62,26 @@
 	
 	VssRay(const Ray &ray):
-		mOrigin(ray.GetLoc()), 
-		mOriginObject(ray.sourceObject.mObject),
 		mRefCount(0),
 		mFlags(0),
-		mMailbox(-1)
+		mMailbox(-1),
+		mOriginObject(ray.sourceObject.mObject)
 	{
+		if (ray.sourceObject.mObject)
+			mOrigin = ray.Extrap(ray.sourceObject.mT);
+		else
+			mOrigin = ray.GetLoc(); 
+
 		if (!ray.intersections.empty())
 		{
-			mTermination = ray.intersections[0].mT;
+			mTermination = ray.Extrap(ray.intersections[0].mT);
 			mTerminationObject = ray.intersections[0].mObject;
 		}
 		else
 		{
-			mTermination = Limits::Infinity;
+			mTermination = 1e6;
 			mTerminationObject = NULL;
 		}
+
+		Precompute();
 	}
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 411)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 426)
@@ -7,4 +7,6 @@
 #include "Preprocessor.h"
 #include "VssRay.h"
+
+class Exporter;
 
 /** Sampling based visibility preprocessing. The implementation is based on heuristical
@@ -85,4 +87,8 @@
 	void ExportBspPvs(const ObjectContainer &objects);
 
+	/** Export scene geometry.
+	*/
+	void ExportSceneGeometry(Exporter *exporter, const ObjectContainer &objects);
+
 	/** Post processes view cells (i.e., merges or subdivides view cells based
 		on the PVS and the ray sets.
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 425)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 426)
@@ -154,8 +154,8 @@
   for (; ri != rays.end(); ri++) {
     Vector3 a = (*ri)->GetOrigin();
-    
-    Vector3 b = (*ri)->GetTermination();
+	Vector3 b = (*ri)->mTerminationObject ? (*ri)->GetTermination() : a + 1000 * Normalize(b - a);
+	
     stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
-    stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
+	stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
   }
   
@@ -585,7 +585,4 @@
 bool X3dExporter::ExportVspKdTree(const VspKdTree &tree, const int maxPvs)
 {
-	 //if (mExportRayDensity) {	 
-	 //return ExportKdTreeRayDensity(tree); }
-
 	stack<VspKdTreeNode *> tStack;
 
@@ -602,40 +599,46 @@
     
 		tStack.pop();
-		AxisAlignedBox3 box = tree.GetBBox(node);
-
-		Mesh *mesh = new Mesh;
-
-		// add 6 vertices of the box
-		int index = (int)mesh->mVertices.size();
-
-		for (int i=0; i < 8; ++ i) 
-		{
-			Vector3 v;
-			box.GetVertex(i, v);
-			mesh->mVertices.push_back(v);
-		}
-
-		mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
-		mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
-		mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
-
-		mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
-		mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
-		mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
-
-		if (maxPvs > 0)
-		{
-            mForcedMaterial.mDiffuseColor.b = 1.0f;
-			const float importance = maxPvs;
-  			//float importance = (float)(*it)->GetPvs().GetSize() / (float)maxPvs;
-
-			mForcedMaterial.mDiffuseColor.r = importance;
-			mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
-		}
-
-		ExportMesh(mesh);
-		DEL_PTR(mesh);
-
-        if (!node->IsLeaf()) 
+
+		if (node->IsLeaf())
+		{
+			AxisAlignedBox3 box = tree.GetBBox(node);
+
+			Mesh *mesh = new Mesh;
+
+			// add 6 vertices of the box
+			int index = (int)mesh->mVertices.size();
+
+			for (int i=0; i < 8; ++ i) 
+			{
+				Vector3 v;
+				box.GetVertex(i, v);
+				mesh->mVertices.push_back(v);
+			}
+
+			mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
+			mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
+			mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
+
+			mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
+			mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
+			mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
+
+			if (maxPvs > 0)
+			{
+				VspKdTreeLeaf *leaf = dynamic_cast<VspKdTreeLeaf *>(node);
+
+				mForcedMaterial.mDiffuseColor.b = 1.0f;
+				
+				leaf->UpdatePvsSize();
+			
+				const float importance = (float)leaf->GetPvsSize() / (float)maxPvs;
+				mForcedMaterial.mDiffuseColor.r = importance;
+				mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
+			}
+
+			ExportMesh(mesh);
+			DEL_PTR(mesh);
+		}
+		else  
 		{
 			VspKdTreeInterior *interior = dynamic_cast<VspKdTreeInterior *>(node);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h	(revision 425)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h	(revision 426)
@@ -57,4 +57,5 @@
 	// max depth nodes
 	int minPvsNodes;
+	// nodes with minimum PVS
 	int minRaysNodes;
 	// max ray contribution nodes
@@ -65,4 +66,7 @@
 	// max number of rays per node
 	int maxRayRefs;
+	// maximal PVS size / leaf
+	int maxPvsSize;
+
 	// number of dynamically added ray refs
 	int addedRayRefs;
@@ -86,12 +90,16 @@
 		rays = queryDomains = 0;
 		rayRefs = 0;
+		
 		maxDepthNodes = 0;
 		minPvsNodes = 0;
-		minRaysNodes = 0; 
+		minRaysNodes = 0;
+		maxRayContribNodes = 0;
+		minSizeNodes = 0;
+
 		maxRayRefs = 0;
 		addedRayRefs = removedRayRefs = 0;
+		
 		initialPvsSize = 0;
-		maxRayContribNodes = 0;
-		minSizeNodes = 0;
+		maxPvsSize = 0;
 	}
 
@@ -146,4 +154,5 @@
 	*/
 	VspKdTreeInterior *GetParent() const;
+
 	/** Sets parent node.
 	*/
@@ -251,5 +260,4 @@
 	*/
 	int GetPvsSize() const;
-	void SetPvsSize(const int s);
 
 	/** If PVS is not valid, this function recomputes the leaf 
@@ -258,4 +266,6 @@
 	void UpdatePvsSize();
 
+	RayInfoContainer &GetRays();
+
 	/** Returns average contribution of a ray to the PVS
 	*/
@@ -278,5 +288,10 @@
 
 protected:
-	
+
+	/** Manually sets PVS size.
+		@param s the PVS size
+	*/
+	void SetPvsSize(const int s);
+
 	int mMailbox;
   
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 425)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 426)
@@ -591,14 +591,6 @@
 				//exporter->ExportBspViewCellPartition(*mBspTree, 0);
 				
-				if (1) // export scene geometry
-				{
-					Material m;//= RandomMaterial();
-					m.mDiffuseColor = RgbColor(0, 1, 0);
-					exporter->SetForcedMaterial(m);
-					exporter->SetWireframe();
-	
-					for (int j = 0; j < objects.size(); ++ j)
-						exporter->ExportIntersectable(objects[j]);
-				}
+				if (1)
+					ExportSceneGeometry(exporter, objects);
 					
 				delete exporter;
@@ -676,6 +668,30 @@
 	{
 		Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d"); 
-		exporter->SetWireframe();
-		exporter->ExportVspKdTree(*mVspKdTree, 300);
+		//exporter->SetWireframe();
+		exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
+
+		Debug << "average PVS size: " << mVspKdTree->GetAvgPvsSize() << endl;
+
+		if (1) ExportSceneGeometry(exporter, objects);
+
+		bool exportRays = false;
+
+		if (exportRays) 
+		{
+			int raysSize = 500;
+			float prob = raysSize / (float)mVspSampleRays.size();
+		
+			exporter->SetWireframe();
+			
+			VssRayContainer rays;
+			for (int i = 0; i < mVspSampleRays.size(); ++ i)
+			{
+				if (RandomValue(0,1) < prob)
+					rays.push_back(mVspSampleRays[i]);
+			}
+
+			exporter->ExportRays(rays, RgbColor(1, 0, 0));
+		}
+
 		delete exporter;
 	}
@@ -758,4 +774,5 @@
 			// also add origin to sample
 			sRay->mOriginObject = object;
+			sRay->mOrigin = ray.GetLoc();
 		}
 		else
@@ -872,4 +889,16 @@
 
 	return merged;
+}
+
+// export scene geometry
+void SamplingPreprocessor::ExportSceneGeometry(Exporter *exporter, const ObjectContainer &objects)
+{
+	Material m;//= RandomMaterial();
+	m.mDiffuseColor = RgbColor(0, 1, 0);
+	exporter->SetForcedMaterial(m);
+	exporter->SetWireframe();
+
+	for (int j = 0; j < objects.size(); ++ j)
+		exporter->ExportIntersectable(objects[j]);
 }
 
@@ -911,15 +940,6 @@
 		}
 
-		// export scene geometry
 		if (1)
-		{
-			Material m;//= RandomMaterial();
-			m.mDiffuseColor = RgbColor(0, 1, 0);
-			exporter->SetForcedMaterial(m);
-            exporter->SetWireframe();
-
-			for (int j = 0; j < objects.size(); ++ j)
-				exporter->ExportIntersectable(objects[j]);
-		}
+			ExportSceneGeometry(exporter, objects);
 
 		delete exporter;
