Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 331)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 332)
@@ -9,7 +9,7 @@
 #	filename vienna.x3d
 #	filename ../data/vienna/vienna-simple.x3d
-#	filename ../data/vienna/vienna-buildings.x3d
+	filename ../data/vienna/vienna-buildings.x3d
 #	filename ../data/vienna/viewcells-25-sel.x3d
-	filename ../data/atlanta/atlanta2.x3d
+#	filename ../data/atlanta/atlanta2.x3d
 #	filename ../data/soda/soda.dat
 #	filename ../data/soda/soda5.dat
@@ -92,5 +92,7 @@
 	# vertical axis        = 64
 	# blocked rays         = 128
-	
+	# least ray splits     = 256
+	# balanced rays        = 512
+
 	# least splits + balanced polygons
 	#splitPlaneStrategy 12
@@ -108,13 +110,26 @@
 	#splitPlaneStrategy 72
 	
-	splitPlaneStrategy 8
+	# axis aligned + blocked rays
+	#splitPlaneStrategy 130
 	
-	maxCandidates 50
+	splitPlaneStrategy 66
+	
+	maxCandidates 130
 	
 	Termination {
+		# autopartition
+		maxRays -1
+		maxPolygons 4
+		maxDepth 100
+		
+		#axis aligned split
 		maxPolysForAxisAligned 100
-		maxPolygons 2
-		maxDepth 100
+		maxCostRatio 0.9
+		ct_div_ci 0.5
 	}
+	
+	#axis aligned split
+	splitBorder 0.01
+	
 	# if split polys are stored for visualization
 	storeSplitPolys false
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 331)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 332)
@@ -50,5 +50,8 @@
   /// number of view cells different to the view cell representing unbounded space.
   int viewCells;
-
+  /// size of the VPS
+  int pvs;
+  /// samples contributing to pvs
+  int contributingSamples;
   // Constructor
   BspTreeStatistics() 
@@ -72,4 +75,6 @@
 	  accumDepth = 0;
 	  viewCells = 0;
+	  pvs = 0;
+	  contributingSamples = 0;
   }
 
@@ -229,8 +234,8 @@
 	void SetViewCell(ViewCell *viewCell);
 
-	/** Generates new view cell and stores it back in the container.
-		@returns the number of sample contributions from the rays
-	*/
-	int GenerateViewCell(const RayContainer &rays, ViewCellContainer &viewCells);
+	/** Generates new view cell and adds rays to the PVS.
+		@returns the number of samples contributing to the pvs.
+	*/
+	int GenerateViewCell(const RayContainer &rays);
 
 protected:
@@ -300,14 +305,12 @@
 		Many leafs can point to the same viewcell.
 	*/
-	int Construct(const ViewCellContainer &viewCells);
+	void Construct(const ViewCellContainer &viewCells);
 
 	/** Constructs tree using the given list of objects. 
 	    @note the objects are not taken as view cells, but the view cells are
 		constructed from the subdivision: Each leaf is taken as one viewcell.
-
 		@param objects list of objects
-		@returns list of view cells.
-	*/
-	int Construct(const ObjectContainer &objects, ViewCellContainer *viewCells);
+	*/
+	void Construct(const ObjectContainer &objects);
 
 	/** Constructs the tree from a given set of rays.
@@ -316,6 +319,5 @@
 		created in the leafs and stored in the conatainer
 	*/
-	int Construct(const RayContainer &sampleRays, 
-	 		      ViewCellContainer *viewCells = NULL);
+	void Construct(const RayContainer &sampleRays);
 
 	/** Returns list of BSP leaves.
@@ -335,5 +337,8 @@
 	bool Export(const string filename);
 
-	void CollectViewCells(BspNode *n, ViewCellContainer &viewCells);
+	/** Collects the leaf view cells of the tree
+		@param viewCells returns the view cells 
+	*/
+	void CollectViewCells(ViewCellContainer &viewCells) const;
 
 	/** A ray is cast possible intersecting the tree.
@@ -343,6 +348,14 @@
 	int CastRay(Ray &ray);
 
+	/** Set true if view cells shall be generated in each leaf.
+	*/
+	void SetGenerateViewCells(int generateViewCells);
+
 	/// bsp tree construction types
 	enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_RAYS};
+
+	/** Returns statistics.
+	*/
+	BspTreeStatistics &GetStat();
 
 protected:
@@ -380,12 +393,9 @@
 	BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData);
 
-	/** Constructs the tree from the given list of polygons.
-		@param rayContainer stores bundle of rays on which subdivision may be based
-		@param viewCells if not NULL, new view cells are 
-		created in the leafs and stored in the conatainer
-	*/
-	int Construct(PolygonContainer *polys, 
-		          RayContainer *rays, 
-				  ViewCellContainer *viewCells = NULL);
+	/** Constructs the tree from the given list of polygons and rays.
+		@param polys stores set of polygons on which subdivision may be based
+		@param rays storesset of rays on which subdivision may be based
+	*/
+	void Construct(PolygonContainer *polys, RayContainer *rays);
 
 	/** Selects the best possible splitting plane. 
@@ -413,7 +423,6 @@
 	/** Inserts polygons down the tree. The polygons are filtered until a leaf is reached,
 		then further subdivided.
-		@param viewCellContainer if not null, a new viewcell is created and stored in the container
-	*/
-	void InsertPolygons(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
+	*/
+	void InsertPolygons(PolygonContainer *polys);
 
 	/** Subdivide leaf.
@@ -550,5 +559,7 @@
 		  LARGEST_POLY_AREA = 32,
 		  VERTICAL_AXIS = 64,
-		  BLOCKED_RAYS = 128
+		  BLOCKED_RAYS = 128,
+		  LEAST_RAY_SPLITS = 256,
+		  BALANCED_RAYS = 512
 		};
 
@@ -558,4 +569,6 @@
 	/// view cell corresponding to unbounded space
 	ViewCell *mRootCell;
+
+	bool mGenerateViewCells;
 
 public:
@@ -563,6 +576,8 @@
 	static void ParseEnvironment();
 
-	/// maximal number of polygons where tree construction is terminated
+	/// maximal number of polygons before subdivision termination
 	static int sTermMaxPolygons;
+	/// maximal number of rays before subdivision termination
+	static int sTermMaxRays;
 	/// maximal possible depth
 	static int sTermMaxDepth;
@@ -576,9 +591,10 @@
 	static int sTermMaxPolysForAxisAligned;
 
+	/// axis aligned split criteria
 	static float sCt_div_ci;
 	static float sSplitBorder;
 	static float sMaxCostRatio;
 
-	// factors to guid the split plane heuristics
+	// factors guiding the split plane heuristics
 	static float sLeastSplitsFactor;
 	static float sBalancedPolysFactor;
@@ -587,5 +603,7 @@
 	static float sLargestPolyAreaFactor;
 	static float sBlockedRaysFactor;
-	
+	static float sLeastRaySplitsFactor;
+	static float sBalancedRaysFactor;
+
 	/// if polygons should be stored in the tree
 	static bool sStoreSplitPolys;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 329)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 332)
@@ -1180,10 +1180,14 @@
 	  "0.002");
 
-
   RegisterOption("BspTree.Termination.maxPolygons",
 		 optInt,
 		 "-bsp_term_max_polygons=",
 		 "5");
-  
+
+   RegisterOption("BspTree.Termination.maxRays",
+		 optInt,
+		 "-bsp_term_max_rays=",
+		 "-1");
+
   RegisterOption("BspTree.Termination.maxPolysForAxisAligned",
 		 optInt,
@@ -1195,4 +1199,19 @@
 		 "-bsp_term_max_depth=",
 		 "100");
+  
+  RegisterOption("BspTree.Termination.maxCostRatio",
+		 optFloat,
+		 "-bsp_term_max_cost_ratio=",
+		 "1.5");
+
+  RegisterOption("BspTree.Termination.ct_div_ci",
+		 optFloat,
+		 "-bsp_term_ct_div_ci=",
+		 "1.0");
+
+  RegisterOption("BspTree.splitBorder",
+		 optFloat,
+		 "-bsp_split_border=",
+		 "0.1");
 
   RegisterOption("BspTree.storeSplitPolys",
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 331)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 332)
@@ -20,4 +20,5 @@
 int BspTree::sConstructionMethod = FROM_INPUT_VIEW_CELLS;
 int BspTree::sTermMaxPolysForAxisAligned = 50;
+int BspTree::sTermMaxRays = -1;
 
 float BspTree::sCt_div_ci = 1.0f;
@@ -34,4 +35,6 @@
 float BspTree::sLargestPolyAreaFactor = 1.0f;
 float BspTree::sBlockedRaysFactor = 1.0f;
+float BspTree::sLeastRaySplitsFactor = 1.0f;
+float BspTree::sBalancedRaysFactor = 1.0f;
 
 bool BspTree::sStoreSplitPolys = false;
@@ -50,8 +53,10 @@
 /****************************************************************/
 
-BspNode::BspNode(): mParent(NULL), mPolygons(NULL)//,mViewCellIdx(0)
+BspNode::BspNode(): 
+mParent(NULL), mPolygons(NULL)
 {}
 
-BspNode::BspNode(BspInterior *parent): mParent(parent), mPolygons(NULL)//,mViewCellIdx(0)
+BspNode::BspNode(BspInterior *parent): 
+mParent(parent), mPolygons(NULL)
 {}
 
@@ -343,12 +348,9 @@
 }
 
-int BspLeaf::GenerateViewCell(const RayContainer &rays, 
-							   ViewCellContainer &viewCells)
-{
-	int sampleContri = 0;
-	ViewCell *viewCell = new ViewCell();
-	viewCells.push_back(viewCell);
-				
-    mViewCell = viewCell;
+int BspLeaf::GenerateViewCell(const RayContainer &rays)
+{
+	int contributingSamples = 0;
+
+	mViewCell = new ViewCell();
 
     RayContainer::const_iterator it, it_end = rays.end();
@@ -357,8 +359,12 @@
 	for (it = rays.begin(); it != it_end; ++ it)
 	{
-		for (int i = 0; i < (int)(*it)->intersections.size(); ++ i)
-			sampleContri = viewCell->GetPvs().AddSample((*it)->intersections[i].mObject);
-	}
-	return sampleContri;
+		if (!(*it)->intersections.empty())
+		{	
+            if (mViewCell->GetPvs().AddSample((*it)->intersections[0].mObject) > 0)
+				++ contributingSamples;
+		}
+	}
+
+	return contributingSamples;
 }
 
@@ -369,6 +375,5 @@
 
 BspTree::BspTree(ViewCell *viewCell): 
-mRoot(NULL), 
-mRootCell(viewCell)
+mRootCell(viewCell), mRoot(NULL), mGenerateViewCells(false)
 {
 	Randomize(); // initialise random generator for heuristics
@@ -404,4 +409,6 @@
 
 	app << "#N_INPUT_POLYGONS (number of input polygons )\n" <<	polys << endl;
+
+	app << "#N_PVS: " << pvs << endl;
 
 	app << "#N_ROUTPUT_INPUT_POLYGONS ( ratio polygons after subdivision / input polygons )\n" <<
@@ -447,12 +454,13 @@
 }
 
-void BspTree::InsertPolygons(PolygonContainer *polys, ViewCellContainer *viewCells)
+void BspTree::InsertPolygons(PolygonContainer *polys)
 {	
 	std::stack<BspTraversalData> tStack;
 	
 	// traverse existing tree or create new tree
-    BspNode *firstNode = mRoot ? mRoot : new BspLeaf();
-
-	tStack.push(BspTraversalData(firstNode, polys, 0, mRootCell, new RayContainer()));
+    if (!mRoot)
+		mRoot = new BspLeaf();
+
+	tStack.push(BspTraversalData(mRoot, polys, 0, mRootCell, new RayContainer()));
 
 	while (!tStack.empty())
@@ -486,5 +494,5 @@
 				ViewCell *backViewCell = mRootCell;
 	
-				if (!viewCells)
+				if (!mGenerateViewCells)
 				{
 					ExtractViewCells(&backViewCell,
@@ -518,17 +526,8 @@
 			DEL_PTR(tData.mPolygons);
 		}
-		else // reached leaf => subdivide current viewcell
-		{
-			// root of the new subtree
-			BspNode *subRoot = Subdivide(tStack, tData);		
-
-			int sampleContri = 0;
-
-			// generate new view cell for each leaf
-			if (viewCells && subRoot->IsLeaf())
-				sampleContri += dynamic_cast<BspLeaf *>(subRoot)->
-					GenerateViewCell(*tData.mRays, *viewCells);
-
-			DEL_PTR(tData.mRays);
+		else
+		{
+			// reached leaf => subdivide current viewcell
+			BspNode *subRoot = Subdivide(tStack, tData);
 		}
 	}
@@ -604,5 +603,5 @@
 }
 
-int BspTree::Construct(const ViewCellContainer &viewCells)
+void BspTree::Construct(const ViewCellContainer &viewCells)
 {
 	mStat.nodes = 1;
@@ -614,9 +613,9 @@
 
 	// construct tree from the view cell polygons
-	return Construct(polys, new RayContainer());
-}
-
-
-int BspTree::Construct(const ObjectContainer &objects, ViewCellContainer *viewCells)
+	Construct(polys, new RayContainer());
+}
+
+
+void BspTree::Construct(const ObjectContainer &objects)
 {
 	mStat.nodes = 1;
@@ -629,9 +628,8 @@
 
 	// construct tree from polygon soup
-	return Construct(polys, new RayContainer(), viewCells);
-}
-
-int BspTree::Construct(const RayContainer &sampleRays, 
-						ViewCellContainer *viewCells)
+	Construct(polys, new RayContainer());
+}
+
+void BspTree::Construct(const RayContainer &sampleRays)
 {
 	mStat.nodes = 1;
@@ -648,5 +646,5 @@
 	std::map<Face *, Polygon3 *> facePolyMap;
 
-	//-- extract polygons from faces stored in the rays
+	//-- extract polygons intersected by the rays
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
 	{
@@ -655,10 +653,11 @@
 		rays->push_back(ray);
 
-		for (int i = 0; i < (int)ray->intersections.size(); ++ i)
-		{
-			MeshInstance *obj = dynamic_cast<MeshInstance *>(ray->intersections[i].mObject);
-			Face *face = obj->GetMesh()->mFaces[ray->intersections[i].mFace];
-
-			// store rays piercing a face with the polygon representing the face
+		// get ray-face intersection. Store polygon representing the rays together
+		// with rays intersecting the face.
+		if (!ray->intersections.empty())
+		{
+			MeshInstance *obj = dynamic_cast<MeshInstance *>(ray->intersections[0].mObject);
+			Face *face = obj->GetMesh()->mFaces[ray->intersections[0].mFace];
+
 			std::map<Face *, Polygon3 *>::iterator it= facePolyMap.find(face);
 
@@ -671,5 +670,4 @@
 				Polygon3 *poly = new Polygon3(face, obj->GetMesh());
 				polys->push_back(poly);
-				Debug << "poly: " << *poly << endl;
 				poly->AddPiercingRay(ray);
 
@@ -683,17 +681,17 @@
 
 	Debug << "**** Finished polygon extraction ****" << endl;
-	Debug << polys->size() << " polys extracted from " << rays->size() << " rays" << endl;
+	Debug << (int)polys->size() << " polys extracted from " << (int)rays->size() << " rays" << endl;
 	Debug << "extraction time: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
 
-	return Construct(polys, rays, viewCells);
-}
-
-int BspTree::Construct(PolygonContainer *polys, 
-					   RayContainer *rays, 
-					   ViewCellContainer *viewCells)
+	Construct(polys, rays);
+}
+
+void BspTree::Construct(PolygonContainer *polys, RayContainer *rays)
 {
 	std::stack<BspTraversalData> tStack;
 
-	BspTraversalData tData(new BspLeaf(), polys, 0, mRootCell, rays);
+	mRoot = new BspLeaf();
+
+	BspTraversalData tData(mRoot, polys, 0, mRootCell, rays);
 	tStack.push(tData);
 
@@ -701,6 +699,4 @@
 	cout << "**** Contructing bsp tree ****\n";
 
-	int sampleContri = 0;
-
 	while (!tStack.empty()) 
 	{
@@ -710,14 +706,8 @@
 		// subdivide leaf node
 		BspNode *subRoot = Subdivide(tStack, tData);
-
-		if (viewCells && subRoot->IsLeaf())
-			sampleContri += dynamic_cast<BspLeaf *>(subRoot)->
-					GenerateViewCell(*tData.mRays, *viewCells);
-		DEL_PTR(tData.mRays);
 	}
 
 	cout << "**** Finished tree construction ****\n";
 	Debug << "BSP tree contruction time: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
-	return sampleContri;
 }
 
@@ -726,22 +716,26 @@
 {
 	//-- terminate traversal  
-	if ((tData.mPolygons->size() <= sTermMaxPolygons) || (tData.mDepth >= sTermMaxDepth))
-	{
-//#ifdef _DEBUG
-		Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " 
-			  << (int)tData.mPolygons->size() << endl;
-//#endif
+	if (((int)tData.mPolygons->size() <= sTermMaxPolygons) || 
+		((int)tData.mRays->size() <= sTermMaxRays) ||
+		(tData.mDepth >= sTermMaxDepth))
+		
+	{
+		BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
+	
+		// generate new view cell for each leaf
+		if (mGenerateViewCells)
+			mStat.contributingSamples += leaf->GenerateViewCell(*tData.mRays);
+		else
+			// add view cell to leaf
+			leaf->SetViewCell(tData.mViewCell);
+		
 		EvaluateLeafStats(tData);
-		BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
-
-		// add view cell to leaf
-		leaf->SetViewCell(tData.mViewCell);
-		
+
 		//-- clean up
-
 		// remaining polygons are discarded or added to node
 		leaf->ProcessPolygons(tData.mPolygons, sStoreSplitPolys);
 		DEL_PTR(tData.mPolygons);
-	
+		DEL_PTR(tData.mRays);
+
 		return leaf;
 	}
@@ -762,8 +756,8 @@
 										  *frontPolys,
 										  *backPolys,
-										   coincident,
-										   *tData.mRays,
-										   *frontRays,
-										   *backRays);
+										  coincident,
+										  *tData.mRays,
+										  *frontRays,
+										  *backRays);
 	ViewCell *frontViewCell = mRootCell;
 	ViewCell *backViewCell = mRootCell;
@@ -778,10 +772,13 @@
 	// extract view cells from coincident polygons according to plane normal
     // only if front or back polygons are empty
-   	ExtractViewCells(&backViewCell,
-					 &frontViewCell,
-					 coincident,
-					 interior->mPlane,
-					 backPolys->empty(),
-					 frontPolys->empty());
+	if (!mGenerateViewCells)
+	{
+   		ExtractViewCells(&backViewCell,
+						 &frontViewCell,
+						 coincident,
+						 interior->mPlane,
+						 backPolys->empty(),
+						 frontPolys->empty());
+	}
 	
 	// don't need coincident polygons anymore
@@ -804,5 +801,6 @@
 	DEL_PTR(tData.mNode);
 	DEL_PTR(tData.mPolygons);
-	
+	DEL_PTR(tData.mRays);
+
 	return interior;
 }
@@ -1102,6 +1100,4 @@
 	}
 
-	// strategies where the effect of the split plane is tested
-	// on all input polygons 
 	if (!((sSplitPlaneStrategy & BALANCED_POLYS)      ||
 		  (sSplitPlaneStrategy & LEAST_SPLITS)        ||
@@ -1113,4 +1109,7 @@
 	}
 
+	// -- strategies where the effect of the split plane is tested
+	// on all input polygons 
+
 	float sumBalancedPolys = 0;
 	float sumSplits = 0;
@@ -1118,5 +1117,4 @@
 	float sumBalancedViewCells = 0;
 	float sumBlockedRays = 0;
-
 	float totalBlockedRays = 0;
 	//float totalArea = 0;
@@ -1144,13 +1142,12 @@
 			//totalArea += area;
 		}
-
 		
 		if (sSplitPlaneStrategy & BLOCKED_RAYS)
 		{
 			float blockedRays = (float)(*it)->GetPiercingRays()->size();
+		
 			if (classification == Plane3::COINCIDENT)
-			{
 				sumBlockedRays += blockedRays;
-			}
+			Debug << "adding rays: " << blockedRays << endl;
 
 			totalBlockedRays += blockedRays;
@@ -1219,4 +1216,27 @@
 			(float)(frontViewCells.size() + backViewCells.size());
 	}
+
+	float sumBalancedRays = 0;
+	float sumRaySplits = 0;
+
+	RayContainer::const_iterator rit, rit_end = rays.end();
+
+	for (rit = rays.begin(); rit != rays.end(); ++ rit)
+	{
+		if (sSplitPlaneStrategy & LEAST_RAY_SPLITS)
+		{
+		}
+
+		if (sSplitPlaneStrategy & BALANCED_RAYS)
+		{
+		}
+	}
+	if (sSplitPlaneStrategy & LEAST_RAY_SPLITS)
+		if (!rays.empty())
+			val += sLeastRaySplitsFactor * sumRaySplits / (float)rays.size();
+
+	if (sSplitPlaneStrategy & BALANCED_RAYS)
+		if (!rays.empty())
+			val += sBalancedRaysFactor * fabs(sumBalancedRays) / (float)rays.size();
 
 	// return linear combination of the sums
@@ -1247,16 +1267,20 @@
 	Debug << "Construction method: " << constructionMethodStr << endl;
 
+	//-- termination criteria for autopartition
 	environment->GetIntValue("BspTree.Termination.maxDepth", sTermMaxDepth);
 	environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons);
+	environment->GetIntValue("BspTree.Termination.maxRays", sTermMaxRays);
+
+	//-- termination criteria for axis aligned split
+	environment->GetFloatValue("BspTree.Termination.ct_div_ci", sCt_div_ci);
+	environment->GetFloatValue("BspTree.Termination.maxCostRatio", sMaxCostRatio);
 	environment->GetIntValue("BspTree.Termination.maxPolysForAxisAligned", 
 							 sTermMaxPolysForAxisAligned);
+	
+	//-- partition criteria
 	environment->GetIntValue("BspTree.maxCandidates", sMaxCandidates);
 	environment->GetIntValue("BspTree.splitPlaneStrategy", sSplitPlaneStrategy);
-
-	// need kdtree criteria for axis aligned split
-	environment->GetFloatValue("MeshKdTree.Termination.ct_div_ci", sCt_div_ci);
-	environment->GetFloatValue("MeshKdTree.splitBorder", sSplitBorder);
-	environment->GetFloatValue("MeshKdTree.Termination.maxCostRatio", sMaxCostRatio);
-
+	environment->GetFloatValue("BspTree.splitBorder", sSplitBorder);
+	
 	environment->GetBoolValue("BspTree.storeSplitPolys", sStoreSplitPolys);
 
@@ -1341,12 +1365,15 @@
 
 	if (leaf->mViewCell != mRootCell)
+	{	
 		++ mStat.viewCells;
-
-#ifdef _DEBUG
-	Debug << "BSP Traversal data. Depth: " << data.mDepth 
-		  << " (max: " << mTermMaxDepth << "), #polygons: " 
-		  << data.mPolygons->size() << " (max: " 
-		  << sTermMaxPolygons << ")" << endl;
-#endif
+		mStat.pvs += leaf->mViewCell->GetPvs().GetSize();
+	}
+	
+//#ifdef _DEBUG
+	Debug << "BSP stats: "
+		  << "Depth: " << data.mDepth << " (max: " << sTermMaxDepth << "), "
+		  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << sTermMaxPolygons << "), "
+		  << "#rays: " << (int)data.mRays->size() << " (max: " << sTermMaxRays << ")" << endl;
+//#endif
 }
 
@@ -1474,9 +1501,10 @@
 }
 
-void BspTree::CollectViewCells(BspNode *n, ViewCellContainer &viewCells)
+void BspTree::CollectViewCells(ViewCellContainer &viewCells) const
 {
 	stack<BspNode *> nodeStack;
-
-	nodeStack.push(n);
+	nodeStack.push(mRoot);
+
+	ViewCell::NewMail();
 
 	while (!nodeStack.empty()) 
@@ -1498,4 +1526,5 @@
 		{
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
+
 			nodeStack.push(interior->mFront);
 			nodeStack.push(interior->mBack);
@@ -1504,4 +1533,11 @@
 }
 
-
-//} // GtpVisibilityPreprocessor
+void BspTree::SetGenerateViewCells(int generateViewCells)
+{
+	mGenerateViewCells = generateViewCells;
+}
+
+BspTreeStatistics &BspTree::GetStat()
+{
+	return mStat;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 331)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 332)
@@ -60,4 +60,5 @@
 	
 	  p->BuildBspTree();
+	
 	  p->Export("vc_bsptree.x3d", false, false, true);
 	  p->BspTreeStatistics(Debug);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 331)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 332)
@@ -58,14 +58,21 @@
 	{
 	case BspTree::FROM_INPUT_VIEW_CELLS:
+		mBspTree->SetGenerateViewCells(false);
 		mBspTree->Construct(mViewCells);
 		break;
 	case BspTree::FROM_SCENE_GEOMETRY:
 		DeleteViewCells(); // we generate new view cells
+		mBspTree->SetGenerateViewCells(true);
 		mSceneGraph->CollectObjects(&objects);
-		mBspTree->Construct(objects, &mViewCells);	
+		mBspTree->Construct(objects);
+		Debug << "collecting view cells" << endl;
+		mBspTree->CollectViewCells(mViewCells);
 		break;
 	case BspTree::FROM_RAYS:
 		DeleteViewCells(); // we generate new view cells
-		mBspTree->Construct(mSampleRays, &mViewCells);
+		mBspTree->SetGenerateViewCells(true);
+		mBspTree->Construct(mSampleRays);
+		Debug << "collecting view cells" << endl;
+		mBspTree->CollectViewCells(mViewCells);
 		break;
 	default:
@@ -407,5 +414,4 @@
 							(totalSamples < mBspConstructionSamples))
 						{
-							//cout << "pushing back sampling ray << " << mSampleRays.size() << endl;
 							mSampleRays.push_back(new Ray(ray));
 						}
@@ -417,14 +423,12 @@
 								BuildBspTree();
 
+								cout << "generated " << (int)mViewCells.size() << " view cells" << endl;
+								passContributingSamples += mBspTree->GetStat().contributingSamples;
+								passSampleContributions += mBspTree->GetStat().pvs;
+
 								BspTreeStatistics(Debug);	
 								Export("vc_bsptree.x3d", false, false, true);
 							}
-							// check whether we can add this to the rays
-							for (int k = 0; k < ray.viewCells.size(); ++ k)
-								for (int j = 0; j < (int)pvsViewCells.size(); ++ j) 
-									if (pvsViewCells[j] == ray.viewCells[k]) 
-									{
-										vcRays[j].push_back(ray);
-									}
+													
 							// some random view cells for output
 							if (pvsViewCells.empty())
@@ -438,4 +442,12 @@
 									pvsViewCells.push_back(mViewCells[Random((int)mViewCells.size())]);
 								}
+							}
+							else
+							{
+								// check whether we can add the current ray to the rays
+								for (int k = 0; k < (int)ray.viewCells.size(); ++ k)
+									for (int j = 0; j < (int)pvsViewCells.size(); ++ j) 
+										if (pvsViewCells[j] == ray.viewCells[k]) 
+											vcRays[j].push_back(ray);							
 							}
 						}				
