Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 318)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 319)
@@ -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
@@ -66,5 +66,5 @@
 	#hierarchyType kdTree
 	#hierarchyType sceneDependent
-	filename ../data/atlanta/atlanta_viewcells_large.x3d
+#	filename ../data/atlanta/atlanta_viewcells_large.x3d
 #	filename ../data/vienna/viewcells-25-sel.x3d
 	filename ../data/vienna/viewcells-25.x3d
@@ -84,6 +84,6 @@
 	# largest polygon area = 32
 	# vertical axis        = 64
+	# blocked rays         = 128
 	
-	splitPlaneStrategy 66
 	# least splits + balanced polygons
 	#splitPlaneStrategy 12
@@ -101,4 +101,6 @@
 	#splitPlaneStrategy 72
 	
+	splitPlaneStrategy 66
+	
 	maxCandidates 50
 	
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 317)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 319)
@@ -87,4 +87,12 @@
 	int CastRay(const Ray &ray, float &t, const float nearestT);
 
+	/** Returns piercing rays container.
+	*/
+	RayContainer *GetPiercingRays();
+
+	/** Adds a ray to the ray container.
+	*/
+	void AddPiercingRay(Ray *ray);
+
 	/// vertices are connected in counterclockwise order.
 	VertexContainer mVertices;
@@ -95,4 +103,7 @@
 	/// pointer to the mesh instance this polygon is derived from
 	MeshInstance *mParent;
+
+	/// Rays piercing this polygon
+	RayContainer *mPiercingRays;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 318)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 319)
@@ -254,13 +254,10 @@
 		/// the view cell associated with this subdivsion
 		ViewCell *mViewCell;
-		/// rays piercing this node
-		RayContainer *mRays;
-
+		
 		BspTraversalData():
 		mNode(NULL),
 		mPolygons(NULL),
 		mDepth(0),
-		mViewCell(NULL),
-		mRays(NULL)
+		mViewCell(NULL)
 		{}
 		
@@ -268,11 +265,9 @@
 						 PolygonContainer *polys, 
 						 const int depth, 
-						 ViewCell *viewCell,
-						 RayContainer *rays = NULL): 
+						 ViewCell *viewCell): 
 		mNode(node), 
 		mPolygons(polys), 
 		mDepth(depth), 
-		mViewCell(viewCell),
-		mRays(rays)
+		mViewCell(viewCell)
 		{}
     };
@@ -299,6 +294,6 @@
 
 	/** Constructs tree using the given list of objects. 
-	    Note that the objects are not taken as view cells, but the view cells are
-		constructed from the subdivision: Each leaf is taken as one viewcell;
+	    @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
@@ -307,12 +302,23 @@
 	void Construct(const ObjectContainer &objects, ViewCellContainer *viewCells);
 
-	/** Constructs tree using the given number of rays
-	    @param objects list of objects
-		@returns list of view cells.
-	*/
-	void Construct(const RayContainer &rays, ViewCellContainer *viewCells);
-
-	int CollectLeafPvs();
-
+	/** Constructs the tree from the given list of polygons.
+		@param viewCells if not NULL, new view cells are 
+		created in the leafs and stored in the conatainer
+	*/
+	void Construct(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
+	
+	/** Constructs the tree from a list of scene geometry and a 
+		given bundle of rays.
+		@param objects list of objects
+		@param rays the bundle of sample rays
+		@param viewCells if not NULL, new view cells are 
+		created in the leafs and stored in the conatainer
+	*/
+	void Construct(const ObjectContainer &objects,
+				   const RayContainer &rays, 
+				   ViewCellContainer *viewCells = NULL);
+
+	/** Returns list of BSP leaves.
+	*/
 	void CollectLeaves(vector<BspLeaf *> &leaves);
 
@@ -366,10 +372,4 @@
 	};
 
-	/** Constructs the tree from the given list of polygons.
-		@param viewCells if not NULL, new view cells are 
-		created in the leafs and stored in the conatainer
-	*/
-	void Construct(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
-
 	/** Evaluates the contribution of the candidate split plane.
 		@note the polygons can be reordered in the process.
@@ -377,6 +377,5 @@
 	*/
 	float EvalSplitPlane(PolygonContainer &polys, 
-						 const Plane3 &candidatePlane,
-						 const RayContainer &rays);
+						 const Plane3 &candidatePlane);
 
 	/** Evaluates tree stats in the BSP tree leafs.
@@ -391,13 +390,11 @@
 	BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData);
 
-	/** Selects a splitting plane. 
+	/** Selects the best possible splitting plane. 
 		@param leaf the leaf to be split
 		@param polys the polygon list on which the split decition is based
-		@param rays ray container on which selection may be based
-		Returns the split plane
+		@Returns the split plane
 	*/
 	Plane3 SelectPlane(BspLeaf *leaf, 
-					   PolygonContainer &polys,
-					   const RayContainer &ray);
+					   PolygonContainer &polys);
 
 	/** Filters next view cell down the tree and inserts it into the appropriate leaves
@@ -417,5 +414,4 @@
 		@param backPolys returns the polygons in the back of the split plane
 		@param coincident returns the polygons coincident to the split plane
-		@param rays ray container used to guide the split process
 		@returns the root of the subdivision
 	*/
@@ -424,6 +420,5 @@
 							   PolygonContainer &frontPolys,
 							   PolygonContainer &backPolys, 
-							   PolygonContainer &coincident,
-							   const RayContainer &rays);
+							   PolygonContainer &coincident);
 
 	/** Filters polygons down the tree.
@@ -433,6 +428,8 @@
 		@param backPolys returns the polygons in the back of the split plane
 	*/
-	void FilterPolygons(BspInterior *node, PolygonContainer *polys, 
-						PolygonContainer *frontPolys, PolygonContainer *backPolys);
+	void FilterPolygons(BspInterior *node, 
+						PolygonContainer *polys, 
+						PolygonContainer *frontPolys, 
+						PolygonContainer *backPolys);
 
 	/** Selects the split plane in order to construct a tree with
@@ -440,10 +437,8 @@
 		2.5d aligned)
 		@param polygons container of polygons
-		@param rays bundle of rays on which the split can be based
 		@param maxTests the maximal number of candidate tests
 	*/
 	Plane3 SelectPlaneHeuristics(PolygonContainer &polys, 
-								 const RayContainer &rays,
-								 const int maxTests);
+								const int maxTests);
 
 	/** Extracts the meshes of the objects and adds them to polygons. 
@@ -519,15 +514,4 @@
 							 vector<SortableEntry> &splitCandidates) const;
 
-	/** Splits the rays into front and back rays according to split plane
-		@param rays contains the rays to be split. The rays are 
-			   distributed to front and back rays.
-		@param frontRays returns rays on the front side of the plane
-		@param backRays returns rays on the back side of the plane
-	*/
-	void BspTree::SplitRays(const Plane3 plane,
-							RayContainer &rays, 
-							RayContainer &frontRays, 
-							RayContainer &backRays);
-
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
@@ -546,5 +530,6 @@
 		  BALANCED_VIEW_CELLS = 16,
 		  LARGEST_POLY_AREA = 32,
-		  VERTICAL_AXIS = 64
+		  VERTICAL_AXIS = 64,
+		  BLOCKED_RAYS = 128
 		};
 
@@ -585,5 +570,6 @@
 	static float sVerticalSplitsFactor;
 	static float sLargestPolyAreaFactor;
-	
+	static float sBlockedRaysFactor;
+
 private:
 	/** Evaluates split plane classification with respect to the plane's 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 318)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 319)
@@ -16,5 +16,5 @@
 int BspTree::sTermMaxDepth = 20;
 int BspTree::sMaxCandidates = 10;
-int BspTree::sSplitPlaneStrategy = NEXT_POLYGON; 
+int BspTree::sSplitPlaneStrategy = BALANCED_POLYS; 
 int BspTree::sConstructionMethod = FROM_INPUT_VIEW_CELLS;
 int BspTree::sTermMaxPolysForAxisAligned = 50;
@@ -30,4 +30,5 @@
 float BspTree::sVerticalSplitsFactor = 1.0f; // very important criterium for 2.5d scenes
 float BspTree::sLargestPolyAreaFactor = 1.0f;
+float BspTree::sBlockedRaysFactor = 1.0f;
 
 /** Evaluates split plane classification with respect to the plane's 
@@ -552,7 +553,41 @@
 }
 
-void BspTree::Construct(const RayContainer &rays, ViewCellContainer *viewCells)
-{
-	// TODO
+void BspTree::Construct(const ObjectContainer &objects,
+						const RayContainer &rays, 
+						ViewCellContainer *viewCells)
+{
+	PolygonContainer *polys = new PolygonContainer();
+	
+	// copy mesh instance polygons into one big polygon soup
+	mStat.polys = AddToPolygonSoup(objects, *polys);
+
+	RayContainer::const_iterator rit, rit_end = rays.end();
+
+	long startTime = GetTime();
+	Debug << "**** Casting rays into polygons ****\n";
+
+	//-- cast rays into all polygons
+	for (rit = rays.begin(); rit != rays.end(); ++ rit)
+	{
+		Ray *ray = *rit;
+
+		PolygonContainer::const_iterator pit, pit_end = polys->end();
+		
+		for (pit = polys->begin(); pit != pit_end; ++ pit)
+		{
+			Polygon3 *poly = *pit;
+			
+			float t = 0;
+			float nearestT = 0;
+
+			if (poly->CastRay(*ray, t, nearestT) > 0)
+				poly->AddPiercingRay(ray);
+		}
+	}
+
+	Debug << "**** Finished ray casting ****\n";
+	Debug << "ray casting time: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+
+	Construct(polys, viewCells);
 }
 
@@ -565,5 +600,5 @@
 
 	long startTime = GetTime();
-	Debug << "**** Contructing tree using objects ****\n";
+	Debug << "**** Contructing tree using scene geometry ****\n";
 	while (!tStack.empty()) 
 	{
@@ -607,12 +642,8 @@
 		leaf->SetViewCell(tData.mViewCell);
 		
-		//-- clean up
-
+		// clean up
 		// remaining polygons are discarded or added to node
 		leaf->ProcessPolygons(tData.mPolygons, mStoreSplitPolys);
 		DEL_PTR(tData.mPolygons);
-
-        CLEAR_CONTAINER(*tData.mRays);
-		DEL_PTR(tData.mRays);
 
 		return leaf;
@@ -629,6 +660,5 @@
 										  *frontPolys,
 										  *backPolys, 
-										  coincident,
-										  *tData.mRays);
+										  coincident);
 
 	ViewCell *frontViewCell = mRootCell;
@@ -644,8 +674,8 @@
 	// extract view cells from coincident polygons according to plane normal
     // only if front or back polygons are empty
-   	ExtractViewCells(&backViewCell, 
-					 &frontViewCell, 
-					 coincident, 
-					 interior->mPlane, 
+   	ExtractViewCells(&backViewCell,
+					 &frontViewCell,
+					 coincident,
+					 interior->mPlane,
 					 backPolys->empty(),
 					 frontPolys->empty());
@@ -653,17 +683,4 @@
 	// don't need coincident polygons anymore
 	interior->ProcessPolygons(&coincident, mStoreSplitPolys);
-
-	// split rays
-	RayContainer *frontRays = NULL;
-	RayContainer *backRays = NULL;
-
-	if (tData.mRays->size() > 0)
-	{
-		RayContainer *frontRays = new RayContainer();
-		RayContainer *backRays = new RayContainer();
-
-		Plane3 plane;
-		SplitRays(plane, *tData.mRays, *frontRays, *backRays);
-	}
 
 	// push the children on the stack
@@ -671,17 +688,14 @@
 								 backPolys, 
 								 tData.mDepth + 1, 
-								 backViewCell, 
-								 backRays));
+								 backViewCell));
 
 	tStack.push(BspTraversalData(interior->GetFront(), 
 								 frontPolys, 
 								 tData.mDepth + 1, 
-								 frontViewCell, 
-								 frontRays));
+								 frontViewCell));
 
 	// cleanup
 	DEL_PTR(tData.mNode);
 	DEL_PTR(tData.mPolygons);
-	DEL_PTR(tData.mRays);
 
 	return interior;
@@ -720,11 +734,10 @@
 									PolygonContainer &frontPolys,
 									PolygonContainer &backPolys, 
-									PolygonContainer &coincident,
-									const RayContainer &rays)
+									PolygonContainer &coincident)
 {
 	mStat.nodes += 2;
 
 	// add the new nodes to the tree + select subdivision plane
-	BspInterior *interior = new BspInterior(SelectPlane(leaf, polys, rays)); 
+	BspInterior *interior = new BspInterior(SelectPlane(leaf, polys)); 
 
 #ifdef _DEBUG
@@ -863,6 +876,5 @@
 
 Plane3 BspTree::SelectPlane(BspLeaf *leaf, 
-							PolygonContainer &polys, 
-							const RayContainer &rays)
+							PolygonContainer &polys)
 {
 	if (polys.size() == 0)
@@ -917,9 +929,8 @@
 
 	// use heuristics to find appropriate plane
-	return SelectPlaneHeuristics(polys, rays, sMaxCandidates);
+	return SelectPlaneHeuristics(polys, sMaxCandidates);
 }
 
 Plane3 BspTree::SelectPlaneHeuristics(PolygonContainer &polys,
-									  const RayContainer &rays,
 									  const int maxTests)
 {
@@ -938,5 +949,5 @@
 		
 		// evaluate current candidate
-		float candidateCost = EvalSplitPlane(polys, candidatePlane, rays);
+		float candidateCost = EvalSplitPlane(polys, candidatePlane);
 			
 		if (candidateCost < lowestCost)
@@ -966,6 +977,5 @@
 
 float BspTree::EvalSplitPlane(PolygonContainer &polys, 
-							  const Plane3 &candidatePlane, 
-							  const RayContainer &rays)
+							  const Plane3 &candidatePlane)
 {
 	float val = 0;
@@ -980,21 +990,29 @@
 	}
 
-	//-- strategies where the effect of the split plane on the polygons is tested
-	if (!((sSplitPlaneStrategy & BALANCED_POLYS) ||
-		  (sSplitPlaneStrategy & LEAST_SPLITS)   ||
-		  (sSplitPlaneStrategy & LARGEST_POLY_AREA) ||
-		  (sSplitPlaneStrategy & BALANCED_VIEW_CELLS)))
+	// strategies where the effect of the split plane is tested
+	// on all input polygons 
+	if (!((sSplitPlaneStrategy & BALANCED_POLYS)      ||
+		  (sSplitPlaneStrategy & LEAST_SPLITS)        ||
+		  (sSplitPlaneStrategy & LARGEST_POLY_AREA)   ||
+		  (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) ||
+		  (sSplitPlaneStrategy & BLOCKED_RAYS)))
+	{
 		return val;
-	
-	PolygonContainer::const_iterator it, it_end = polys.end();
+	}
+
 	float sumBalancedPolys = 0;
 	float sumSplits = 0;
 	float sumPolyArea = 0;
 	float sumBalancedViewCells = 0;
+	float sumBlockedRays = 0;
+
+	float totalBlockedRays = 0;
 	//float totalArea = 0;
 
-	// container for view cells
+	// container for balanced view cells criterium
 	ObjectContainer frontViewCells;
 	ObjectContainer backViewCells;
+
+	PolygonContainer::const_iterator it, it_end = polys.end();
 
 	for (it = polys.begin(); it != it_end; ++ it)
@@ -1019,4 +1037,16 @@
 		}
 
+		
+		if (sSplitPlaneStrategy & BLOCKED_RAYS)
+		{
+			float blockedRays = (float)(*it)->GetPiercingRays()->size();
+			if (classification == Polygon3::COINCIDENT)
+			{
+				sumBlockedRays += blockedRays;
+			}
+
+			totalBlockedRays += blockedRays;
+		}
+
 		// assign view cells to back or front according to classificaion
 		if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS)
@@ -1031,4 +1061,6 @@
 	}
 
+	// all values should be approx. between 0 and 1 so they can be combined
+	// and scaled with the factors according to their importance
 	if (sSplitPlaneStrategy & BALANCED_POLYS)
 		val += sBalancedPolysFactor * fabs(sumBalancedPolys) / (float)polys.size();
@@ -1038,5 +1070,10 @@
 
 	if (sSplitPlaneStrategy & LARGEST_POLY_AREA) 
-		val += sLargestPolyAreaFactor * (float)polys.size() / sumPolyArea; // HACK
+		// HACK (polys.size should be totalArea)
+		val += sLargestPolyAreaFactor * (float)polys.size() / sumPolyArea;
+
+	if (sSplitPlaneStrategy & BLOCKED_RAYS)
+		if (totalBlockedRays > 0)
+			val += sBlockedRaysFactor * sumBlockedRays / totalBlockedRays;
 
 	if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS)
@@ -1133,4 +1170,6 @@
 	if (sSplitPlaneStrategy & VERTICAL_AXIS)
 		Debug << "vertical axis ";
+	if (sSplitPlaneStrategy & BLOCKED_RAYS)
+		Debug << "blocked rays ";
 
 	Debug << endl;
@@ -1357,14 +1396,3 @@
 	}
 }
-
-void BspTree::SplitRays(const Plane3 plane,
-						RayContainer &rays, 
-						RayContainer &frontRays, 
-						RayContainer &backRays)
-{
-	while (!rays.empty())
-	{
-		//TODO
-	}
-}
 //} // GtpVisibilityPreprocessor
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 313)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 319)
@@ -168,6 +168,7 @@
 		break;
 	case BspTree::FROM_RAYS:
-		DeleteViewCells(); // we generate new view cells	
-		mBspTree->Construct(rays, &mViewCells);
+		DeleteViewCells(); // we generate new view cells
+		mSceneGraph->CollectObjects(&objects);
+		mBspTree->Construct(objects, rays, &mViewCells);
 		break;
 	default:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 318)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 319)
@@ -38,5 +38,6 @@
   p->ParseViewCellsOptions();
 
-  if (p->mViewCellsType == Preprocessor::BSP_VIEW_CELLS)
+  if (p->mViewCellsType == Preprocessor::BSP_VIEW_CELLS &&
+	  !(BspTree::sConstructionMethod == BspTree::FROM_RAYS)) // construct tree later
   {
 	  if (BspTree::sConstructionMethod == BspTree::FROM_INPUT_VIEW_CELLS)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 318)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 319)
@@ -6,16 +6,15 @@
 #include "Ray.h"
 
-Polygon3::Polygon3(): mMaterial(NULL), mParent(NULL)
+Polygon3::Polygon3(): 
+mMaterial(NULL), mParent(NULL), mPiercingRays(NULL)
 {}
 
-Polygon3::Polygon3(const VertexContainer &vertices): mVertices(vertices), mMaterial(NULL), mParent(NULL)
+Polygon3::Polygon3(const VertexContainer &vertices): 
+mVertices(vertices), mMaterial(NULL), mParent(NULL), mPiercingRays(NULL)
 {}
 
-Polygon3::Polygon3(MeshInstance *parent): mMaterial(NULL), mParent(parent)
+Polygon3::Polygon3(MeshInstance *parent): 
+mMaterial(NULL), mParent(parent)
 {}
-
-// creates an "infinite" polygon from this plane
-//Polygon3::Polygon3(Plane3 plane)
-//{}
 
 Polygon3::Polygon3(Face *face, Mesh *parentMesh)
@@ -27,4 +26,9 @@
 		mMaterial = parentMesh->mMaterial;
 	}
+}
+
+Polygon3::~Polygon3()
+{
+	DEL_PTR(mPiercingRays);
 }
 
@@ -352,2 +356,17 @@
 }
 
+RayContainer *Polygon3::GetPiercingRays()
+{
+	if (!mPiercingRays)
+		mPiercingRays = new RayContainer();
+	return mPiercingRays;
+}
+
+void Polygon3::AddPiercingRay(Ray *ray)
+{
+	if (!mPiercingRays)
+		mPiercingRays = new RayContainer();
+	//if (binary_search(mPiercingRays.begin(), mPiercingRays.end(), ray)) return false;
+	
+	mPiercingRays->push_back(ray);
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 318)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 319)
@@ -236,4 +236,6 @@
   vector<Ray> vcRays[5];
 
+  const int fromRaysBspThresh = 1000;
+
   while (totalSamples < mTotalSamples) {
 		int passContributingSamples = 0;
@@ -241,5 +243,12 @@
 		int passSamples = 0;
 		int index = 0;
-				
+			
+		// construct Bsp tree if not
+		if ((mViewCellsType == Preprocessor::BSP_VIEW_CELLS) &&
+			!mBspTree->GetRoot() && (passSamples > fromRaysBspThresh))
+		{
+			BuildBspTree();
+		}
+
 		for (i = 0; i < objects.size(); i++) {
 			KdNode *nodeToSample = NULL;
