Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 501)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 503)
@@ -13,7 +13,7 @@
 #;../data/vienna/vienna-plane.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
+#	filename ../data/soda/soda5.dat
 }
 
@@ -30,10 +30,9 @@
 	samplesPerPass  100000
 	initialSamples 500000
-	vssSamples 200000
+	vssSamples 2000000
 	vssSamplesPerPass 100000
 	useImportanceSampling true
 	loadInitialSamples  false
 	storeInitialSamples false
-	useViewSpaceBox true
 }
 
@@ -181,7 +180,4 @@
 	
 	PostProcess {
-		minPvsDif 100
-		minPvs 10
-		maxPvs 150
 		# how much samples are used for post processing
 		samples 100000
@@ -196,5 +192,5 @@
 		colorCode Random
 		exportRays false
-		exportGeometry true
+		exportGeometry false
 	}
 	
@@ -223,8 +219,8 @@
 	Termination {
 		maxDepth	 	40
-		minPvs			1
-		minRays			100
-		minSize			0.0001
-		maxCostRatio		0.95
+		minPvs			50
+		minRays			300
+		minSize			0.001
+		maxCostRatio		0.9
 		missTolerance		4
 		maxRayContribution 	0.5
@@ -232,5 +228,5 @@
 	
 	maxTotalMemory	100
-	maxStaticMemory	80
+	maxStaticMemory	50
 
 	splitType 	regular
@@ -283,16 +279,16 @@
 	Termination {
 		# parameters used for autopartition
-		minRays 		100
+		minRays 		200
 		minPolygons 		-1
 		maxDepth		30
-		minPvs 			2
+		minPvs 			20
 		#minArea 		0.0001
 		minArea 		0.000
-		maxRayContribution	0.005
+		maxRayContribution	0.05
 		maxCostRatio		0.9
-		missTolerance		4
+		missTolerance		5
 		#maxAccRayLength	100
 		
-		maxViewCells		8000
+		maxViewCells		20000
 		
 		# used for pvs criterium
@@ -309,7 +305,7 @@
 	PostProcess {
 		maxCostRatio 0.1
-		minViewCells 200
+		minViewCells 500
 		maxPvsSize   1000
-		useRaysForMerge false
+		useRaysForMerge true
 	}
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 501)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 503)
@@ -56,6 +56,5 @@
 		/// how often this branch has missed the max-cost ratio
 		int mMaxCostMisses;
-
-
+	
 		/** Returns average ray contribution.
 		*/
@@ -164,7 +163,12 @@
 				   AxisAlignedBox3 *forcedBoundingBox);
 
-	/** Returns list of BSP leaves.
-	*/
-	void CollectLeaves(vector<BspLeaf *> &leaves) const;
+	/** Returns list of BSP leaves with pvs smaller than
+		a certain threshold.
+		@param onlyUnmailed if only the unmailed leaves should be considered
+		@param maxPvs the maximal pvs (-1 means unlimited)
+	*/
+	void CollectLeaves(vector<BspLeaf *> &leaves, 
+					   const bool onlyUnmailed = false,
+					   const int maxPvs = -1) const;
 
 	/** Returns box which bounds the whole tree.
@@ -203,14 +207,9 @@
 		leading to this node.
 	*/
-	void ConstructGeometry(BspNode *n, PolygonContainer &cell) const;
-
-	/** Constructs geometry associated with the half space intersections 
-		leading to this node.
-	*/
-	void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const;
-
-	/** Construct geometry and stores it in a geometry node container.
-	*/
-	void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
+	void ConstructGeometry(BspNode *n, BspNodeGeometry &geom) const;
+	
+	/** Construct geometry of view cell.
+	*/
+	void ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const;
 
 	/** Returns random leaf of BSP tree.
@@ -284,4 +283,12 @@
 	*/
 	BspViewCell *GetOutOfBoundsCell() const;
+
+	/** Writes tree to disc.
+	*/
+	bool WriteVspBspTree();
+
+	/** Loads tree from disc.
+	*/
+	bool LoadVspBspTree();
 
 protected:
@@ -457,5 +464,5 @@
 	/** Evaluates cost ratio for axis aligned splits.
 	*/
-	float EvalCostRatio(const VspBspTraversalData &tData,
+	/*float EvalCostRatio(const VspBspTraversalData &tData,
 						const AxisAlignedBox3 &box,
 						const int axis,
@@ -464,5 +471,5 @@
 						int &raysFront,
 						int &pvsBack,
-						int &pvsFront);
+						int &pvsFront);*/
 
 	/** Selects an axis aligned split plane.
@@ -542,7 +549,8 @@
 
 	/** Collects candidates for the merge in the merge queue.
+		@param leaves the leaves to be merged
 		@returns number of leaves in queue
 	*/
-	int CollectMergeCandidates();
+	int CollectMergeCandidates(const vector<BspLeaf *> leaves);
 	/** Collects candidates for the merge in the merge queue.
 		@returns number of leaves in queue
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 501)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 503)
@@ -2007,4 +2007,5 @@
 	}
 }
+
 
 int VspKdTree::FindNeighbors(VspKdLeaf *n,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 485)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 503)
@@ -23,4 +23,5 @@
 }
 
+
 const ObjectPvs &ViewCell::GetPvs() const
 {
@@ -33,8 +34,10 @@
 }
 
+
 int ViewCell::Type() const 
 { 
 	return VIEW_CELL; 
 }
+
 
 void ViewCell::AddPassingRay(const Ray &ray, const int contributions)
@@ -54,4 +57,11 @@
 	mVolume = volume;
 }
+
+
+void ViewCell::SetMesh(Mesh *mesh)
+{
+	mMesh = mesh;
+}
+
 
 void ViewCell::UpdateViewCellsStats(ViewCellsStatistics &vcStat)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 448)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 503)
@@ -98,5 +98,8 @@
 	int CastRay(const Ray &ray, float &t, const float nearestT);
 
-	
+	/** The polygon is triangulated.
+	*/
+	void Triangulate(vector<Triangle3> &triangles);
+
 	/** The piercing rays of the polygon are inherited by the child fragments
 		@parm front_piece the front fragment inheriting the front rays
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 492)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 503)
@@ -44,8 +44,16 @@
 	*/
 	void ComputeBoundingBox(AxisAlignedBox3 &box);
+
 	/** Splits the polygon and returns the part of the polygon inside of the node geometry.
 	*/
 	Polygon3 *SplitPolygon(Polygon3 *poly, const float epsilon) const;
 
+	/** Adds node geometry to mesh.
+		@note the mesh vertices will not be connected
+	*/
+	void AddToMesh(Mesh &mesh);
+
+	/** The polygons the geometry consists of.
+	*/
 	PolygonContainer mPolys;
 };
@@ -132,4 +140,6 @@
 	/// polygon splits 
 	int polySplits;
+	/// accumulated number of rays refs
+	int accumRays;
 
 	// Constructor
@@ -145,5 +155,6 @@
 	// TODO: computation wrong
 	double AvgDepth() const { return accumDepth / (double)Leaves();}; 
-  
+	double AvgRays() const { return accumRays / (double)Leaves();}; 
+
 	void Reset() 
 	{
@@ -170,4 +181,5 @@
 		invalidLeaves = 0;
 		polySplits = 0;
+		accumRays = 0;
 	}
 
@@ -458,16 +470,13 @@
 		@returns the number of intersections with objects stored in the tree.
 	*/
-  int
-  _CastRay(Ray &ray);
-
-
-  int
-  CastLineSegment(const Vector3 &origin,
-				  const Vector3 &termination,
-				  ViewCellContainer &viewcells
-				  );
-
-  ViewCell *
-  GetViewCell(const Vector3 &point);
+	int	_CastRay(Ray &ray);
+
+
+	int	CastLineSegment(const Vector3 &origin,
+						const Vector3 &termination,
+						ViewCellContainer &viewcells
+						);
+
+	ViewCell *GetViewCell(const Vector3 &point);
   
 	/// bsp tree construction types
@@ -483,16 +492,11 @@
 					  const bool onlyUnmailed) const;
 
-	/** Constructs geometry associated with the half space intersections 
-		leading to this node.
-	*/
-	void ConstructGeometry(BspNode *n, PolygonContainer &cell) const;
+	/** Constructs geometry of view cell returning a BSP node geometry type.
+	*/
+	void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
 	
 	/** Construct geometry of view cell.
 	*/
-	void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const;
-
-	/** Constructs geometry of view cell returning a BSP node geometry type.
-	*/
-	void ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const;
+	void ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const;
 
 	/** Returns random leaf of BSP tree.
@@ -788,5 +792,5 @@
 	void AddToPvs(BspLeaf *leaf,
 				  const BoundedRayContainer &rays, 
-				  int &sampleContributions,
+				  int &sampleContributions,	
 				  int &contributingSamples);
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 502)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 503)
@@ -25,4 +25,5 @@
 class ViewCellsStatistics;
 class Exporter;
+
 struct BspRay;
 
@@ -171,9 +172,8 @@
 	virtual void GetPvsStatistics(PvsStatistics &stat);
 
-  /** Get a viewcell containing the specified point */
-  virtual ViewCell *GetViewCell(const Vector3 &point) = 0;
+	/** Get a viewcell containing the specified point */
+	virtual ViewCell *GetViewCell(const Vector3 &point) = 0;
   
-  virtual void
-  PrintPvsStatistics(ostream &s);
+	virtual void PrintPvsStatistics(ostream &s);
 
 	/** Returns probability that view point lies in one view cell.
@@ -233,4 +233,7 @@
 	void SetViewSpaceBox(const AxisAlignedBox3 &box);
 
+	/** Creates mesh for this view cell.
+	*/
+	virtual void CreateMesh(ViewCell *vc) = NULL;
 
 protected:
@@ -265,4 +268,8 @@
 	*/
 	virtual void ExportVcGeometry(Exporter *exporter, ViewCell *vc) const = 0;
+
+	/** Creates meshes from the view cells.
+	*/
+	void CreateViewCellsMeshes();
 
 	/// the view cell corresponding to space ouside the valid view space
@@ -291,4 +298,6 @@
 	/// the scene bounding box
 	AxisAlignedBox3 mSceneBox;
+
+	MeshContainer mMeshContainer;
 
 	//-- visualization options
@@ -343,6 +352,8 @@
 	AxisAlignedBox3 GetSceneBbox() const;
 
-  /** Get a viewcell containing the specified point */
-  ViewCell *GetViewCell(const Vector3 &point);
+	/** Get a viewcell containing the specified point */
+	ViewCell *GetViewCell(const Vector3 &point);
+
+	void CreateMesh(ViewCell *vc);
 
 protected:
@@ -411,11 +422,13 @@
 	/** Prints out statistics of this approach.
 	*/
-  //  virtual void PrintStatistics(ostream &s) const;
-  ViewCell *GetViewCell(const Vector3 &point) { return NULL; }
-
-  float GetProbability(ViewCell *viewCell);
-  float GetRendercost(ViewCell *viewCell, float objRendercost) const;
+	//  virtual void PrintStatistics(ostream &s) const;
+	ViewCell *GetViewCell(const Vector3 &point) { return NULL; }
+
+	float GetProbability(ViewCell *viewCell);
+	float GetRendercost(ViewCell *viewCell, float objRendercost) const;
   
-  AxisAlignedBox3 GetSceneBbox() const;
+	AxisAlignedBox3 GetSceneBbox() const;
+
+	void CreateMesh(ViewCell *vc);
 
 protected:
@@ -468,5 +481,5 @@
 						ViewCellContainer &viewcells);
 
-  ViewCell *GetViewCell(const Vector3 &point) { return NULL; }
+	ViewCell *GetViewCell(const Vector3 &point) { return NULL; }
 
 	float GetProbability(ViewCell *viewCell);
@@ -474,4 +487,7 @@
 
 	AxisAlignedBox3 GetSceneBbox() const;
+
+	void CreateMesh(ViewCell *vc);
+
 protected:
 
@@ -526,18 +542,20 @@
 	
 	AxisAlignedBox3 GetSceneBbox() const;
-
-  ViewCell *GetViewCell(const Vector3 &point);
+	
+	ViewCell *GetViewCell(const Vector3 &point);
 
 	bool GetViewPoint(Vector3 &viewPoint) const;
 
 	bool ViewPointValid(const Vector3 &viewPoint) const;
+
+	void CreateMesh(ViewCell *vc);
+
 protected:
-	/** DEPRECATED
-	*/
-	int MergeViewCells(const VssRayContainer &rays) const;
-
-	/** Returns true if front and back leaf should be merged.
-	*/
-	bool ShouldMerge(BspLeaf *front, BspLeaf *back) const;
+
+	/** Merges the view cells.
+	*/
+	void MergeViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
+	
+	void RefineViewCells(const VssRayContainer &rays);
 
 	void CollectViewCells();
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 501)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 503)
@@ -835,4 +835,5 @@
 
 
+/*
 float VspBspTree::EvalCostRatio(const VspBspTraversalData &tData,
 								const AxisAlignedBox3 &box,
@@ -949,5 +950,5 @@
 	return  (mCtDivCi + newCost) / oldCost;
 }
-
+*/
 
 
@@ -1304,5 +1305,7 @@
 
 
-void VspBspTree::CollectLeaves(vector<BspLeaf *> &leaves) const
+void VspBspTree::CollectLeaves(vector<BspLeaf *> &leaves, 
+							   const bool onlyUnmailed,
+							   const int maxPvsSize) const
 {
 	stack<BspNode *> nodeStack;
@@ -1317,7 +1320,9 @@
 		{
 			// test if this leaf is in valid view space
-			if (node->TreeValid())
+			BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
+			if (leaf->TreeValid() && 
+				(!onlyUnmailed || leaf->Mailed()) &&
+				((maxPvsSize < 0) || (leaf->GetViewCell()->GetPvs().GetSize() <= maxPvsSize)))
 			{
-				BspLeaf *leaf = (BspLeaf *)node;
 				leaves.push_back(leaf);
 			}
@@ -1641,12 +1646,5 @@
 
 void VspBspTree::ConstructGeometry(BspNode *n,
-								   BspNodeGeometry &cell) const
-{
-	ConstructGeometry(n, cell.mPolys);
-}
-
-
-void VspBspTree::ConstructGeometry(BspNode *n,
-								   PolygonContainer &cell) const
+								   BspNodeGeometry &geom) const
 {
 	vector<Plane3> halfSpaces;
@@ -1726,5 +1724,5 @@
 
 		if (candidatePolys[i])
-			cell.push_back(candidatePolys[i]);
+			geom.mPolys.push_back(candidatePolys[i]);
 	}
 }
@@ -1732,5 +1730,5 @@
 
 void VspBspTree::ConstructGeometry(BspViewCell *vc, 
-								   PolygonContainer &vcGeom) const
+								   BspNodeGeometry &vcGeom) const
 {
 	vector<BspLeaf *> leaves = vc->mLeaves;
@@ -1745,5 +1743,5 @@
 						   const bool onlyUnmailed) const
 {
-	PolygonContainer geom;
+	BspNodeGeometry geom;
 	ConstructGeometry(n, geom);
 
@@ -1770,5 +1768,5 @@
 				// test all planes of current node if candidate really
 				// is neighbour
-				PolygonContainer neighborCandidate;
+				BspNodeGeometry neighborCandidate;
 				ConstructGeometry(node, neighborCandidate);
 
@@ -1777,5 +1775,5 @@
 				{
 					const int cf =
-						Polygon3::ClassifyPlane(neighborCandidate,
+						Polygon3::ClassifyPlane(neighborCandidate.mPolys,
 												halfSpaces[i],
 												mEpsilon);
@@ -1787,6 +1785,4 @@
 				if (isAdjacent)
 					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
-
-				CLEAR_CONTAINER(neighborCandidate);
 			}
 		}
@@ -1795,5 +1791,5 @@
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
 
-			const int cf = Polygon3::ClassifyPlane(geom,
+			const int cf = Polygon3::ClassifyPlane(geom.mPolys,
 												   interior->GetPlane(),
 												   mEpsilon);
@@ -1813,5 +1809,4 @@
 	}
 
-	CLEAR_CONTAINER(geom);
 	return (int)neighbors.size();
 }
@@ -1837,13 +1832,12 @@
 		{
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
 			BspNode *next;
-
-			PolygonContainer geom;
+			BspNodeGeometry geom;
 
 			// todo: not very efficient: constructs full cell everytime
 			ConstructGeometry(interior, geom);
 
-			const int cf = Polygon3::ClassifyPlane(geom, halfspace, mEpsilon);
+			const int cf = 
+				Polygon3::ClassifyPlane(geom.mPolys, halfspace, mEpsilon);
 
 			if (cf == Polygon3::BACK_SIDE)
@@ -2248,10 +2242,6 @@
 
 
-int VspBspTree::CollectMergeCandidates()
-{
-	vector<BspLeaf *> leaves;
-
-	// collect the leaves, e.g., the "voxels" that will build the view cells
-	CollectLeaves(leaves);
+int VspBspTree::CollectMergeCandidates(const vector<BspLeaf *> leaves)
+{
 	BspLeaf::NewMail();
 
@@ -2291,10 +2281,12 @@
 	vector<BspRay *> bspRays;
 
+	long startTime = GetTime();
 	ConstructBspRays(bspRays, rays);
+	Debug << (int)bspRays.size() << " bsp rays constructed in " << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
+
 	map<BspLeaf *, vector<BspLeaf*> > neighborMap;
-
 	vector<BspIntersection>::const_iterator iit;
 
-	int leaves = 0;
+	int numLeaves = 0;
 	
 	BspLeaf::NewMail();
@@ -2321,5 +2313,5 @@
 				leaf->mArea * leaf->mPvs->GetSize();
 			
-			++ leaves;
+			++ numLeaves;
 		}
 		
@@ -2345,5 +2337,5 @@
 					leaf->mArea * leaf->mPvs->GetSize();
 
-				++ leaves;
+				++ numLeaves;
 			}
 		
@@ -2379,10 +2371,16 @@
 	Debug << "neighbormap size: " << (int)neighborMap.size() << endl;
 	Debug << "mergequeue: " << (int)mMergeQueue.size() << endl;
-	Debug << "leaves in queue: " << leaves << endl;
+	Debug << "leaves in queue: " << numLeaves << endl;
 	Debug << "overall cost: " << BspMergeCandidate::sOverallCost << endl;
 
 	CLEAR_CONTAINER(bspRays);
 
-	return leaves;
+	//-- collect the leaves which haven't been found by ray casting
+	vector<BspLeaf *> leaves;
+	CollectLeaves(leaves, true, mMaxPvs);
+	Debug << "found " << (int)leaves.size() << " new leaves" << endl;
+	//CollectMergeCandidates(leaves);
+
+	return numLeaves;
 }
 
@@ -2440,5 +2438,9 @@
 		mergeStats.nodes = CollectMergeCandidates(rays);
 	else
-		mergeStats.nodes = CollectMergeCandidates();
+	{
+		vector<BspLeaf *> leaves;
+		CollectLeaves(leaves);
+		mergeStats.nodes = CollectMergeCandidates(leaves);
+	}
 
 	mergeStats.collectTime = TimeDiff(startTime, GetTime());
@@ -2735,4 +2737,138 @@
 }
 
+#define USE_ASCII 0
+bool VspBspTree::WriteVspBspTree()
+{
+	char fileName[100];
+	environment->GetStringValue("VspBspTree.viewCellsFilename", fileName);
+	
+	/*VssRayContainer::const_iterator it, it_end = samples.end();
+	
+#if USE_ASCII
+	ofstream samplesOut(fileName);
+	if (!samplesOut.is_open())
+		return false;
+
+	for (it = samples.begin(); it != it_end; ++ it)
+	{
+		VssRay *ray = *it;
+		int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;		
+		int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;	
+
+		samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " " 
+				   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " " 
+				   << sourceid << " " << termid << "\n";
+	}
+#else
+	ofstream samplesOut(fileName, ios::binary);
+	if (!samplesOut.is_open())
+		return false;
+
+	for (it = samples.begin(); it != it_end; ++ it)
+	{	
+		VssRay *ray = *it;
+		Vector3 origin(ray->GetOrigin());
+		Vector3 termination(ray->GetTermination());
+		
+		int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;		
+		int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;		
+
+		samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
+		samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
+		samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
+		samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
+    }
+#endif
+
+	samplesOut.close();
+	*/
+	return true;
+}
+
+bool VspBspTree::LoadVspBspTree()
+{
+	/*std::stable_sort(objects.begin(), objects.end(), ilt);
+	char fileName[100];
+	environment->GetStringValue("Preprocessor.samplesFilename", fileName);
+	
+    Vector3 origin, termination;
+	// HACK: needed only for lower_bound algorithm to find the 
+	// intersected objects
+	MeshInstance sObj(NULL);
+	MeshInstance tObj(NULL);
+
+#if USE_ASCII
+	ifstream samplesIn(fileName, ios::binary);
+	if (!samplesIn.is_open())
+		return false;
+
+	string buf;
+	while (!(getline(samplesIn, buf)).eof())
+	{
+		sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d", 
+			   &origin.x, &origin.y, &origin.z,
+			   &termination.x, &termination.y, &termination.z, 
+			   &(sObj.mId), &(tObj.mId));
+		
+		Intersectable *sourceObj = NULL;
+		Intersectable *termObj = NULL;
+		
+		if (sObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &sObj, ilt);
+			sourceObj = *oit;
+		}
+		
+		if (tObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &tObj, ilt);
+			termObj = *oit;
+		}
+
+		samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
+	}
+#else
+	ifstream samplesIn(fileName, ios::binary);
+	if (!samplesIn.is_open())
+		return false;
+
+	while (1)
+	{
+		 samplesIn.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
+		 samplesIn.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
+		 samplesIn.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
+		 samplesIn.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
+		
+		 if (samplesIn.eof())
+			break;
+
+		Intersectable *sourceObj = NULL;
+		Intersectable *termObj = NULL;
+		
+		if (sObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &sObj, ilt);
+			sourceObj = *oit;
+		}
+		
+		if (tObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &tObj, ilt);
+			termObj = *oit;
+		}
+
+		samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
+	}
+
+#endif
+	samplesIn.close();
+*/
+	return true;
+}
+
 
 /************************************************************************/
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 501)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 503)
@@ -1229,20 +1229,5 @@
 				 "view_cells_max_pvs=",
 				 "300");
-
-  RegisterOption("ViewCells.PostProcess.minPvsDif",
-				 optInt,
-				 "view_cells_post_process_min_pvs_dif=",
-				 "10");
-
-  RegisterOption("ViewCells.PostProcess.maxPvs",
-				 optInt,
-				 "view_cells_post_process_max_pvs=",
-				 "300");
-
-  RegisterOption("ViewCells.PostProcess.minPvs",
-				 optString,
-				 "view_cells_post_process_min_pvs",
-				 "10");
-  
+ 
   RegisterOption("ViewCells.filename",
 		 optString,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 502)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 503)
@@ -8,4 +8,6 @@
 #include "Ray.h"
 #include "AxisAlignedBox3.h"
+#include "Triangle3.h"
+
 #include <stack>
 
@@ -423,4 +425,5 @@
 	app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl;
 
+	app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl;
 	//app << "#N_PVS: " << pvs << endl;
 
@@ -776,9 +779,9 @@
 
 	// constrruct root node geometry
-	BspNodeGeometry *cell = new BspNodeGeometry();
-	ConstructGeometry(mRoot, *cell);
+	BspNodeGeometry *geom = new BspNodeGeometry();
+	ConstructGeometry(mRoot, *geom);
 
 	BspTraversalData tData(mRoot, polys, 0, mRootCell, rays, 
-						   ComputePvsSize(*rays), cell->GetArea(), cell);
+						   ComputePvsSize(*rays), geom->GetArea(), geom);
 
 	tStack.push(tData);
@@ -1809,5 +1812,6 @@
 	// accumulate depth to compute average depth
 	mStat.accumDepth += data.mDepth;
-	
+	// accumulate rays to compute rays /  leaf
+	mStat.accumRays += (int)data.mRays->size();
 
 	if (data.mDepth >= mTermMaxDepth)
@@ -2196,12 +2200,5 @@
 }
 
-void BspTree::ConstructGeometry(BspNode *n, BspNodeGeometry &cell) const
-{
-	PolygonContainer polys;
-	ConstructGeometry(n, polys);
-	cell.mPolys = polys;
-}
-
-void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const
+void BspTree::ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const
 {
 	vector<BspLeaf *> leaves = vc->mLeaves;
@@ -2210,9 +2207,9 @@
 
 	for (it = leaves.begin(); it != it_end; ++ it)
-		ConstructGeometry(*it, cell);
-}
-
-
-void BspTree::ConstructGeometry(BspNode *n, PolygonContainer &cell) const
+		ConstructGeometry(*it, geom);
+}
+
+
+void BspTree::ConstructGeometry(BspNode *n, BspNodeGeometry &geom) const
 {
 	vector<Plane3> halfSpaces;
@@ -2291,5 +2288,5 @@
 		
 		if (candidates[i])
-			cell.push_back(candidates[i]);
+			geom.mPolys.push_back(candidates[i]);
 	}
 }
@@ -2299,7 +2296,6 @@
 						   const bool onlyUnmailed) const
 {
-	PolygonContainer cell;
-
-	ConstructGeometry(n, cell);
+	BspNodeGeometry geom;
+	ConstructGeometry(n, geom);
 
 	stack<BspNode *> nodeStack;
@@ -2319,8 +2315,8 @@
             if (node != n && (!onlyUnmailed || !node->Mailed()))
 			{
-				// test all planes of current node if candidate really
-				// is neighbour
-				PolygonContainer neighborCandidate;
-				ConstructGeometry(node, neighborCandidate);
+				// test all planes of current node if neighbour 
+				// candidate really is neighbour
+				BspNodeGeometry candidateGeom;
+				ConstructGeometry(node, candidateGeom);
 				
 				bool isAdjacent = true;
@@ -2328,5 +2324,5 @@
 				{
 					const int cf = 
-						Polygon3::ClassifyPlane(neighborCandidate, 
+						Polygon3::ClassifyPlane(candidateGeom.mPolys, 
 												halfSpaces[i],
 												mEpsilon);
@@ -2338,6 +2334,4 @@
 				if (isAdjacent)
 					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
-
-				CLEAR_CONTAINER(neighborCandidate);
 			}
 		}
@@ -2346,5 +2340,5 @@
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
 	
-			const int cf = Polygon3::ClassifyPlane(cell, 
+			const int cf = Polygon3::ClassifyPlane(geom.mPolys, 
 												   interior->mPlane,
 												   mEpsilon);
@@ -2364,7 +2358,7 @@
 	}
 	
-	CLEAR_CONTAINER(cell);
 	return (int)neighbors.size();
 }
+
 
 BspLeaf *BspTree::GetRandomLeaf(const Plane3 &halfspace)
@@ -2387,13 +2381,11 @@
 		{
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-			
 			BspNode *next;
 	
-			PolygonContainer cell;
-
+			BspNodeGeometry geom;
 			// todo: not very efficient: constructs full cell everytime
-			ConstructGeometry(interior, cell);
-
-			const int cf = Polygon3::ClassifyPlane(cell, 
+			ConstructGeometry(interior, geom);
+
+			const int cf = Polygon3::ClassifyPlane(geom.mPolys, 
 												   halfspace, 
 												   mEpsilon);
@@ -2534,8 +2526,10 @@
 /*************************************************************/
 
+
 BspNodeGeometry::~BspNodeGeometry()
 {
 	CLEAR_CONTAINER(mPolys);
 }
+
 
 float BspNodeGeometry::GetArea() const 
@@ -2543,4 +2537,31 @@
 	return Polygon3::GetArea(mPolys);
 }
+
+
+void BspNodeGeometry::AddToMesh(Mesh &mesh)
+{
+	PolygonContainer::const_iterator it, it_end = mPolys.end();
+	int vcount = 0;
+
+	for (it = mPolys.begin(); it != mPolys.end(); ++ it)
+	{
+		Polygon3 *poly = *it;
+		
+		vector<Triangle3> triangles;
+		poly->Triangulate(triangles);
+		vector<Triangle3>::const_iterator tit, tit_end = triangles.end();
+	
+		for (tit = triangles.begin(); tit != tit_end; ++ tit)
+		{
+			mesh.mVertices.push_back((*tit).mVertices[0]);
+			mesh.mVertices.push_back((*tit).mVertices[1]);
+			mesh.mVertices.push_back((*tit).mVertices[2]);
+
+			Face *face = new Face(vcount ++, vcount ++, vcount ++);
+			mesh.AddFace(face);
+		}
+	}
+}
+
 
 void BspNodeGeometry::SplitGeometry(BspNodeGeometry &front,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 479)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 503)
@@ -116,4 +116,7 @@
 	*/
 	void SetArea(float area);
+
+	/** Updates the view cell statstics for this particular view cell.
+	*/
 	virtual void UpdateViewCellsStats(ViewCellsStatistics &vcStat);
 
@@ -123,4 +126,8 @@
 	/// Rays piercing this view cell.
 	RayContainer mPiercingRays;
+
+	/** Sets the mesh for this view cell.
+	*/
+	void SetMesh(Mesh *mesh);
 
 protected:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp	(revision 502)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp	(revision 503)
@@ -692,6 +692,6 @@
 
 	
-	totalSamples += rays.size();
-	rssSamples += vssRays.size();
+	totalSamples += (int)rays.size();
+	rssSamples += (int)vssRays.size();
 
 	
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 492)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 503)
@@ -964,10 +964,8 @@
 	for (it = leaves.begin(); it != it_end; ++ it)
 	{
-		PolygonContainer cell;
-		tree.ConstructGeometry(*it, cell);
+		BspNodeGeometry geom;
+		tree.ConstructGeometry(*it, geom);
 		
-		ExportPolygons(cell);
-
-		CLEAR_CONTAINER(cell);
+		ExportPolygons(geom.mPolys);
 	}
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 483)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 503)
@@ -1,7 +1,7 @@
 #include "Polygon3.h"
-#include "Mesh.h"
 #include "Mesh.h"
 #include "AxisAlignedBox3.h"
 #include "Ray.h"
+#include "Triangle3.h"
 
 Polygon3::Polygon3(): 
@@ -471,2 +471,21 @@
 	return revPoly;
 }
+
+
+void Polygon3::Triangulate(vector<Triangle3> &triangles)
+{
+	int i = 1;
+	int j = 0;
+	int k = mVertices.size() - 1;
+	int count = 0;
+
+	while (i < k)
+	{
+		triangles.push_back(Triangle3(mVertices[i], mVertices[j], mVertices[k]));
+
+		if ((count ++) % 2)
+			j = i ++;
+		else
+			j = k --;
+	}
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h	(revision 372)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Containers.h	(revision 503)
@@ -13,4 +13,5 @@
 class Polygon3;
 class Ray;
+class Mesh;
 
 /** Container storing polygons used during BSP tree construction.
@@ -40,7 +41,7 @@
 typedef vector<HierarchyNode *> NodeContainer;
 
-
 typedef vector<SceneGraphNode *> SceneGraphNodeContainer;
 
+typedef vector<Mesh *> MeshContainer;
 
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.cpp	(revision 492)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.cpp	(revision 503)
@@ -1786,6 +1786,6 @@
   
   Vector3 invDirection;
-  const float eps = 1e-6;
-  const float invEps = 1e6;
+  const float eps = 1e-6f;
+  const float invEps = 1e6f;
   
   // it does change the ray direction very slightly,
@@ -1793,5 +1793,5 @@
   
   if (fabs(direction.x) < eps) {
-    if (direction.x < 0.0)
+    if (direction.x < 0.0f)
       invDirection.x = -invEps;
     else
@@ -1799,5 +1799,5 @@
   }
   else
-    invDirection.x = 1.0 / direction.x;
+    invDirection.x = 1.0f / direction.x;
   
   if (fabs(direction.y) < eps) {
@@ -1808,8 +1808,8 @@
   }
   else
-    invDirection.y = 1.0 / direction.y;
+    invDirection.y = 1.0f / direction.y;
   
   if (fabs(direction.z) < eps) {
-    if (direction.z < 0.0)
+    if (direction.z < 0.0f)
       invDirection.z = -invEps;
     else
@@ -1817,9 +1817,9 @@
   }
   else
-    invDirection.z = 1.0 / direction.z;
-
-
-  
-  if (fabs(direction.x) < 0.001) {
+    invDirection.z = 1.0f / direction.z;
+
+
+  
+  if (fabs(direction.x) < 0.001f) {
     if (mMin.x < origin.x && mMax.x > origin.x) {
       minx = -MAXFLOAT;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 502)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 503)
@@ -37,16 +37,12 @@
 void ViewCellsManager::ParseEnvironment()
 {
-	// post processing stuff
-	environment->GetIntValue("ViewCells.PostProcess.minPvsDif", mMinPvsDif);
-	environment->GetIntValue("ViewCells.PostProcess.minPvs", mMinPvs);
-	environment->GetIntValue("ViewCells.PostProcess.maxPvs", mMaxPvs);
-
+	// visualization stuff
 	environment->GetBoolValue("ViewCells.Visualization.exportRays", mExportRays);
 	environment->GetBoolValue("ViewCells.Visualization.exportGeometry", mExportGeometry);
 
 	char buf[50];
-	
+
 	environment->GetStringValue("ViewCells.Visualization.colorCode", buf);
-	
+
 	if (strcmp(buf, "PVS") == 0)
 		mColorCode = 1;
@@ -65,6 +61,6 @@
 {
 	DEL_PTR(mRenderer);
-
 	CLEAR_CONTAINER(mViewCells);
+	CLEAR_CONTAINER(mMeshContainer);
 }
 
@@ -73,7 +69,7 @@
 {
 	X3dParser parser;
-	
+
 	environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
-	
+
 	bool success = parser.ParseFile(filename, *this);
 	Debug << (int)mViewCells.size() << " view cells loaded" << endl;
@@ -102,9 +98,9 @@
 	if (!ViewCellsConstructed())
 		return;
-  
+
 	VssRayContainer::const_iterator it, it_end = rays.end();
 
-	for (it = rays.begin(); it != it_end; ++ it) 
-	{	
+	for (it = rays.begin(); it != it_end; ++ it)
+	{
 		ComputeSampleContributions(*(*it));
 	}
@@ -143,10 +139,10 @@
 
 
-void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects, 
-									   ViewCellContainer &viewCells, 
+void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects,
+									   ViewCellContainer &viewCells,
 									   const int maxViewCells) const
 {
 	// maximal max viewcells
-	int limit = maxViewCells > 0 ? 
+	int limit = maxViewCells > 0 ?
 		Min((int)objects.size(), maxViewCells) : (int)objects.size();
 
@@ -154,5 +150,5 @@
 	{
 		Intersectable *object = objects[i];
-		
+
 		// extract the mesh instances
 		if (object->Type() == Intersectable::MESH_INSTANCE)
@@ -168,13 +164,13 @@
 
 
-ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri, 
+ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri,
 											const float height) const
 {
 	// one mesh per view cell
 	Mesh *mesh = new Mesh();
-	
+
 	//-- construct prism
 
-	// bottom 
+	// bottom
 	mesh->mFaces.push_back(new Face(2,1,0));
 	// top
@@ -188,14 +184,14 @@
 	Vector3 triNorm = baseTri.GetNormal();
 
-	Triangle3 topTri;	
+	Triangle3 topTri;
 
 	// add base vertices and calculate top vertices
 	for (int i = 0; i < 3; ++ i)
 		mesh->mVertices.push_back(baseTri.mVertices[i]);
-	
-	// add top vertices	
+
+	// add top vertices
 	for (int i = 0; i < 3; ++ i)
 		mesh->mVertices.push_back(baseTri.mVertices[i] + height * triNorm);
-	
+
 	mesh->Preprocess();
 
@@ -217,5 +213,5 @@
 
 	std::merge(front.mPiercingRays.begin(), front.mPiercingRays.end(),
-			   back.mPiercingRays.begin(), back.mPiercingRays.end(), 
+			   back.mPiercingRays.begin(), back.mPiercingRays.end(),
 			   vc->mPiercingRays.begin());
 
@@ -321,5 +317,5 @@
 {
 	mViewCells.clear();
-	
+
 	CollectViewCells();
 	mViewCellsStats.Reset();
@@ -336,5 +332,5 @@
 
   ViewCellContainer viewcells;
-		
+
   ray.mPvsContribution = 0;
   ray.mRelativePvsContribution = 0.0f;
@@ -343,16 +339,16 @@
   Ray hray(ray);
   float tmin = 0, tmax = 1.0;
-  
+
   //hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT);
   if (!GetSceneBbox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
 	return;
-  
+
   Vector3 origin = hray.Extrap(tmin);
   Vector3 termination = hray.Extrap(tmax);
-  
+
   CastLineSegment(origin,
 				  termination,
 				  viewcells);
-  
+
   // copy viewcells memory efficiently
   const bool storeViewcells = false;
@@ -361,5 +357,5 @@
 	ray.mViewCells = viewcells;
   }
-  
+
   ViewCellContainer::const_iterator it = viewcells.begin();
 
@@ -367,10 +363,10 @@
 
   if (addInPlace) {
-	for (; it != viewcells.end(); ++it) { 	
+	for (; it != viewcells.end(); ++it) {
 	  ViewCell *viewcell = *it;
-	  
+
 	  // if ray not outside of view space
 	  float contribution;
-	  bool added = 
+	  bool added =
 		viewcell->GetPvs().AddSample(ray.mTerminationObject,
 									 contribution
@@ -378,9 +374,9 @@
 	  if (added)
 		ray.mPvsContribution++;
-	  
+
 	  ray.mRelativePvsContribution += contribution;
 	}
   } else {
-    for (; it != viewcells.end(); ++it) { 	
+    for (; it != viewcells.end(); ++it) {
 	  ViewCell *viewcell = *it;
 	  // if ray not outside of view space
@@ -390,9 +386,9 @@
 												   ))
 		ray.mPvsContribution++;
-	  
+
 	  ray.mRelativePvsContribution += contribution;
 	}
 
-	for (it = viewcells.begin(); it != viewcells.end(); ++it) { 	
+	for (it = viewcells.begin(); it != viewcells.end(); ++it) {
 	  ViewCell *viewcell = *it;
 	  // if ray not outside of view space
@@ -405,5 +401,5 @@
 void ViewCellsManager::GetRaySets(const VssRayContainer &sourceRays,
 								  const int maxSize,
-								  VssRayContainer &usedRays, 
+								  VssRayContainer &usedRays,
 								  VssRayContainer *savedRays) const
 {
@@ -461,4 +457,16 @@
 
 
+
+void ViewCellsManager::CreateViewCellsMeshes()
+{
+	// convert to meshes
+	ViewCellContainer::const_iterator it, it_end = mViewCells.end();
+
+	for (it = mViewCells.begin(); it != it_end; ++ it)
+	{
+		CreateMesh(*it);
+	}
+}
+
 /**********************************************************************/
 /*                   BspViewCellsManager implementation               */
@@ -466,7 +474,7 @@
 
 
-BspViewCellsManager::BspViewCellsManager(BspTree *bspTree, 
+BspViewCellsManager::BspViewCellsManager(BspTree *bspTree,
 										 int constructionSamples):
-ViewCellsManager(constructionSamples), 
+ViewCellsManager(constructionSamples),
 mBspTree(bspTree)
 {
@@ -486,5 +494,5 @@
 
 
-int BspViewCellsManager::Construct(const ObjectContainer &objects, 
+int BspViewCellsManager::Construct(const ObjectContainer &objects,
 								   const VssRayContainer &rays)
 {
@@ -494,5 +502,5 @@
 
 	int sampleContributions = 0;
-	
+
 	// construct view cells using the collected samples
 	RayContainer constructionRays;
@@ -513,11 +521,11 @@
 	}
 
-    if (mViewCells.empty()) 
-	{ 
-		// no view cells loaded 
+    if (mViewCells.empty())
+	{
+		// no view cells loaded
 		mBspTree->Construct(objects, constructionRays);
 		// collect final view cells
 		mBspTree->CollectViewCells(mViewCells);
-	} 
+	}
 	else
 	{
@@ -529,6 +537,6 @@
 
 	Debug << mBspTree->GetStatistics() << endl;
-	
-	EvaluateViewCellsStats();
+
+	//EvaluateViewCellsStats();
 	Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
 
@@ -536,11 +544,14 @@
 	ComputeSampleContributions(savedRays);
 
+
 	return sampleContributions;
 }
 
+
 void BspViewCellsManager::CollectViewCells()
 {
 	mBspTree->CollectViewCells(mViewCells);
 }
+
 
 float BspViewCellsManager::GetProbability(ViewCell *viewCell)
@@ -553,5 +564,5 @@
 #endif
 }
-  
+
 
 float BspViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
@@ -575,5 +586,5 @@
 
 
-int BspViewCellsManager::PostProcess(const ObjectContainer &objects, 
+int BspViewCellsManager::PostProcess(const ObjectContainer &objects,
 									 const VssRayContainer &rays)
 {
@@ -601,5 +612,5 @@
 		cout << "exporting initial view cells (=leaves) ... ";
 		Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
-	
+
 		if (exporter)
 		{
@@ -607,5 +618,5 @@
 			exporter->SetFilled();
 			ExportViewCells(exporter);
-				
+
 			if (mExportGeometry)
 			{
@@ -624,5 +635,5 @@
 
 	cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
-		
+
 	long startTime = GetTime();
 
@@ -637,19 +648,19 @@
 	CLEAR_CONTAINER(mBspRays);
 	ConstructBspRays(rays, mPostProcessSamples);
-	
+
 	for (int i = 0; i < (int)mBspRays.size(); ++ i)
-	{  
+	{
 		BspRay *ray = mBspRays[i];
-	  
+
 		// traverse leaves stored in the rays and compare and merge consecutive
 		// leaves (i.e., the neighbors in the tree)
 		if (ray->intersections.size() < 2)
 			continue;
-	  
+
 		iit = ray->intersections.begin();
 
 		BspLeaf *previousLeaf = (*iit).mLeaf;
 		++ iit;
-		
+
 		for (; iit != ray->intersections.end(); ++ iit)
 		{
@@ -657,10 +668,10 @@
 
 			if (ShouldMerge(leaf, previousLeaf))
-			{			
+			{
 				MergeBspLeafViewCells(leaf, previousLeaf);
 
 				++ merged;
 			}
-		
+
 			previousLeaf = leaf;
 		}
@@ -673,7 +684,7 @@
 
 	Debug << "Postprocessing: Merged " << merged << " view cells in "
-		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" 
+		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs"
 		  << "using " << (int)mBspRays.size() << " samples" << endl << endl;
-	
+
 	CLEAR_CONTAINER(mBspRays);
 
@@ -704,5 +715,5 @@
 	CLEAR_CONTAINER(mBspRays);
 	ConstructBspRays(sampleRays, mVisualizationSamples);
-	
+
 	if (1) // export view cells
 	{
@@ -715,12 +726,12 @@
 			delete exporter;
 		}
-		
+
 		cout << "finished" << endl;
-	}	
+	}
 
 	//-- visualization of the BSP splits
 	bool exportSplits = false;
 	environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
-	
+
 	if (exportSplits)
 	{
@@ -734,6 +745,6 @@
 
 
-inline bool vc_gt(ViewCell *a, ViewCell *b) 
-{ 
+inline bool vc_gt(ViewCell *a, ViewCell *b)
+{
 	return a->GetPvs().GetSize() > b->GetPvs().GetSize();
 }
@@ -744,11 +755,11 @@
 	Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
 
-	if (exporter) 
-	{	
-		Material m; 
+	if (exporter)
+	{
+		Material m;
 		m.mDiffuseColor = RgbColor(1, 0, 0);
 		exporter->SetForcedMaterial(m);
 		exporter->SetWireframe();
-		
+
 		exporter->ExportBspSplits(*mBspTree, true);
 
@@ -759,10 +770,10 @@
 
 		exporter->SetFilled();
-				
+
 		// export rays
 		if (0)
 		{
 			VssRayContainer outRays;
-		
+
 			int raysSize = min((int)mBspRays.size(), mVisualizationSamples);
 
@@ -770,6 +781,6 @@
 				// only rays piercing geometry
 				outRays.push_back(mBspRays[i]->vssRay);
-						
-			// export rays 
+
+			// export rays
 			exporter->ExportRays(outRays, RgbColor(1, 1, 0));
 		}
@@ -786,19 +797,19 @@
 {
 	const int leafOut = 10;
-	
+
 	ViewCell::NewMail();
 
 	//-- some rays for output
 	const int raysOut = min((int)mBspRays.size(), mVisualizationSamples);
-	
+
 	cout << "visualization using " << mVisualizationSamples << " samples" << endl;
 	Debug << "\nOutput view cells: " << endl;
-	
+
 	// sort view cells to get largest view cells
 #if 0
 	stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
 #endif
-	int limit = min(leafOut, (int)mViewCells.size()); 
-		
+	int limit = min(leafOut, (int)mViewCells.size());
+
 	for (int i = 0; i < limit; ++ i)
 	{
@@ -815,5 +826,5 @@
 #if 0
 		// check whether we can add the current ray to the output rays
-		for (int k = 0; k < raysOut; ++ k) 
+		for (int k = 0; k < raysOut; ++ k)
 		{
 			BspRay *ray = mBspRays[k];
@@ -821,5 +832,5 @@
 			{
 				BspLeaf *leaf = ray->intersections[j].mLeaf;
-				if (vc == leaf->GetViewCell()) 
+				if (vc == leaf->GetViewCell())
 					vcRays.push_back(ray->vssRay);
 			}
@@ -830,5 +841,5 @@
 
 		Exporter *exporter = Exporter::GetExporter(s);
-			
+
 		exporter->SetWireframe();
 
@@ -841,17 +852,16 @@
 		else
 		{
-			PolygonContainer vcGeom;
-			
+			BspNodeGeometry vcGeom;
+
 			//-- export view cell
 			mBspTree->ConstructGeometry(vc, vcGeom);
-			exporter->ExportPolygons(vcGeom);
-			CLEAR_CONTAINER(vcGeom);
-		}
-			
-		Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
+			exporter->ExportPolygons(vcGeom.mPolys);
+		}
+
+		Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
 			  << ", piercing rays=" << (int)vcRays.size()
 			  << ", leaves=" << (int)vc->mLeaves.size() << endl;
 
-			
+
 		// export rays piercing this view cell
 #if 0
@@ -871,5 +881,5 @@
 
 		// output PVS of view cell
-		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
+		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
 		{
 			Intersectable *intersect = (*it).first;
@@ -882,7 +892,7 @@
 				exporter->ExportIntersectable(intersect);
 				intersect->Mail();
-			}			
-		}
-				
+			}
+		}
+
 		DEL_PTR(exporter);
 		cout << "finished" << endl;
@@ -895,8 +905,8 @@
 bool BspViewCellsManager::MergeBspLeafViewCells(BspLeaf *front, BspLeaf *back) const
 {
-	BspViewCell *viewCell = 
-		dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(), 
+	BspViewCell *viewCell =
+		dynamic_cast<BspViewCell *>(MergeViewCells(*front->GetViewCell(),
 												   *back->GetViewCell()));
-	
+
 	if (!viewCell)
 		return false;
@@ -910,5 +920,5 @@
 
 	vector<BspLeaf *>::const_iterator it;
-	
+
 	for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
 	{
@@ -921,5 +931,5 @@
 		viewCell->mLeaves.push_back(*it);
 	}
-	
+
 	DEL_PTR(fVc);
 	DEL_PTR(bVc);
@@ -940,5 +950,5 @@
 	if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
 	{
-		if ((fvc->GetPvs().GetSize() < mMinPvs) ||	
+		if ((fvc->GetPvs().GetSize() < mMinPvs) ||
 			(bvc->GetPvs().GetSize() < mMinPvs) ||
 			((fdiff < mMinPvsDif) && (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
@@ -947,5 +957,5 @@
 		}
 	}
-	
+
 	return false;
 }
@@ -979,5 +989,5 @@
 
 
-void BspViewCellsManager::ExportColor(Exporter *exporter, 
+void BspViewCellsManager::ExportColor(Exporter *exporter,
 									  ViewCell *vc) const
 {
@@ -994,5 +1004,5 @@
 	case 1: // pvs
 		{
-			importance = (float)vc->GetPvs().GetSize() / 
+			importance = (float)vc->GetPvs().GetSize() /
 				(float)mViewCellsStats.maxPvs;
 		}
@@ -1002,5 +1012,5 @@
 			BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
 
-			importance = (float)bspVc->mLeaves.size() / 
+			importance = (float)bspVc->mLeaves.size() /
 				(float)mViewCellsStats.maxLeaves;
 		}
@@ -1019,9 +1029,9 @@
 	m.mDiffuseColor.r = importance;
 	m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
-	
+
 	exporter->SetForcedMaterial(m);
 }
 
-void BspViewCellsManager::ExportVcGeometry(Exporter *exporter, 
+void BspViewCellsManager::ExportVcGeometry(Exporter *exporter,
 										 ViewCell *vc) const
 {
@@ -1030,9 +1040,14 @@
 	else
 	{
-		PolygonContainer cell;
+		BspNodeGeometry geom;
 		mBspTree->ConstructGeometry(
-			dynamic_cast<BspViewCell *>(vc), cell);
-		exporter->ExportPolygons(cell);
-	}
+			dynamic_cast<BspViewCell *>(vc), geom);
+		exporter->ExportPolygons(geom.mPolys);
+	}
+}
+
+
+void BspViewCellsManager::CreateMesh(ViewCell *vc)
+{
 }
 
@@ -1048,4 +1063,6 @@
 /*                   KdViewCellsManager implementation               */
 /**********************************************************************/
+
+
 
 KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
@@ -1085,5 +1102,5 @@
 }
 
-int KdViewCellsManager::Construct(const ObjectContainer &objects, 
+int KdViewCellsManager::Construct(const ObjectContainer &objects,
 								  const VssRayContainer &rays)
 {
@@ -1097,5 +1114,5 @@
 	// create the view cells
 	mKdTree->CreateAndCollectViewCells(mViewCells);
-	
+
 	// cast rays
 	ComputeSampleContributions(rays);
@@ -1112,5 +1129,5 @@
 }
 
-int KdViewCellsManager::PostProcess(const ObjectContainer &objects, 
+int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
 									const VssRayContainer &rays)
 {
@@ -1135,7 +1152,7 @@
 	{
 		const int leafOut = 10;
-		
+
 		ViewCell::NewMail();
-  
+
 		//-- some rays for output
 		const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
@@ -1144,25 +1161,25 @@
 		//-- some random view cells and rays for output
 		vector<KdLeaf *> kdLeaves;
-		
+
 		for (int i = 0; i < leafOut; ++ i)
 			kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf()));
-		
+
 		for (int i = 0; i < kdLeaves.size(); ++ i)
 		{
 			KdLeaf *leaf = kdLeaves[i];
 			RayContainer vcRays;
-			
+
 			cout << "creating output for view cell " << i << " ... ";
-#if 0			
+#if 0
 			// check whether we can add the current ray to the output rays
-			for (int k = 0; k < raysOut; ++ k) 
+			for (int k = 0; k < raysOut; ++ k)
 			{
 				Ray *ray = sampleRays[k];
-				
+
 				for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
 				{
 					BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
-					
-					if (leaf->GetViewCell() == leaf2->GetViewCell()) 
+
+					if (leaf->GetViewCell() == leaf2->GetViewCell())
 					{
 						vcRays.push_back(ray);
@@ -1170,12 +1187,12 @@
 				}
 			}
-#endif			
+#endif
 			Intersectable::NewMail();
-			
+
 			ViewCell *vc = leaf->mViewCell;
-			
+
 			//bspLeaves[j]->Mail();
 			char s[64]; sprintf(s, "kd-pvs%04d.x3d", i);
-			
+
 			Exporter *exporter = Exporter::GetExporter(s);
 			exporter->SetFilled();
@@ -1183,27 +1200,27 @@
 			exporter->SetWireframe();
 			//exporter->SetFilled();
-			
+
 			Material m;//= RandomMaterial();
 			m.mDiffuseColor = RgbColor(1, 1, 0);
 			exporter->SetForcedMaterial(m);
-			
+
 			AxisAlignedBox3 box = mKdTree->GetBox(leaf);
 			exporter->ExportBox(box);
 
-			Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
+			Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
 				<< ", piercing rays=" << (int)vcRays.size() << endl;
-			
+
 			// export rays piercing this view cell
-			exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));	
-			
+			exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
+
 			m.mDiffuseColor = RgbColor(1, 0, 0);
 			exporter->SetForcedMaterial(m);
-			
+
 			// exporter->SetWireframe();
 			exporter->SetFilled();
-			
+
 			ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
 			// output PVS of view cell
-			for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it) 
+			for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
 			{
 				Intersectable *intersect = (*it).first;
@@ -1212,7 +1229,7 @@
 					exporter->ExportIntersectable(intersect);
 					intersect->Mail();
-				}			
+				}
 			}
-			
+
 			DEL_PTR(exporter);
 			cout << "finished" << endl;
@@ -1226,7 +1243,7 @@
 		{
 			VssRay *ray = sampleRays[i];
-		
+
 			// check whether we can add this to the rays
-			for (int j = 0; j < pvsOut; j++) 
+			for (int j = 0; j < pvsOut; j++)
 			{
 				if (objects[j] == ray->mTerminationObject)
@@ -1237,5 +1254,5 @@
 		}
 
-		if (exportRays) 
+		if (exportRays)
 		{
 			Exporter *exporter = NULL;
@@ -1243,51 +1260,51 @@
 			exporter->SetWireframe();
 			exporter->ExportKdTree(*mKdTree);
-		
-			for (i=0; i < pvsOut; i++) 
+
+			for (i=0; i < pvsOut; i++)
 				exporter->ExportRays(rays[i], RgbColor(1, 0, 0));
 
 			exporter->SetFilled();
-		
+
 			delete exporter;
 		}
 
-		for (int k=0; k < pvsOut; k++) 
+		for (int k=0; k < pvsOut; k++)
 		{
 			Intersectable *object = objects[k];
-			char s[64];	
+			char s[64];
 			sprintf(s, "sample-pvs%04d.x3d", k);
 
 			Exporter *exporter = Exporter::GetExporter(s);
 			exporter->SetWireframe();
-		
+
 			KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
 			Intersectable::NewMail();
-			
+
 			// avoid adding the object to the list
 			object->Mail();
 			ObjectContainer visibleObjects;
-	    
-			for (; i != object->mKdPvs.mEntries.end(); i++) 
+
+			for (; i != object->mKdPvs.mEntries.end(); i++)
 			{
 				KdNode *node = (*i).first;
 				exporter->ExportBox(mKdTree->GetBox(node));
-		
+
 				mKdTree->CollectObjects(node, visibleObjects);
 			}
-		
+
 			exporter->ExportRays(rays[k],  RgbColor(0, 1, 0));
 			exporter->SetFilled();
-			
+
 			for (int j = 0; j < visibleObjects.size(); j++)
 				exporter->ExportIntersectable(visibleObjects[j]);
-			
+
 			Material m;
 			m.mDiffuseColor = RgbColor(1, 0, 0);
 			exporter->SetForcedMaterial(m);
 			exporter->ExportIntersectable(object);
-		
+
 			delete exporter;
 		}
-	}		
+	}
 }
 
@@ -1300,5 +1317,5 @@
 
 
-void KdViewCellsManager::ExportVcGeometry(Exporter *exporter, 
+void KdViewCellsManager::ExportVcGeometry(Exporter *exporter,
 										  ViewCell *vc) const
 {
@@ -1335,4 +1352,8 @@
 
 
+void KdViewCellsManager::CreateMesh(ViewCell *vc)
+{
+}
+
 /**********************************************************************/
 /*                   VspKdViewCellsManager implementation             */
@@ -1340,7 +1361,7 @@
 
 
-VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree, 
+VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree,
 											 int constructionSamples):
-ViewCellsManager(constructionSamples), 
+ViewCellsManager(constructionSamples),
 mVspKdTree(vspKdTree)
 {
@@ -1364,4 +1385,5 @@
 }
 
+
 void VspKdViewCellsManager::CollectViewCells()
 {
@@ -1369,5 +1391,5 @@
 }
 
-int VspKdViewCellsManager::Construct(const ObjectContainer &objects, 
+int VspKdViewCellsManager::Construct(const ObjectContainer &objects,
 									 const VssRayContainer &rays)
 {
@@ -1375,14 +1397,14 @@
 	if (ViewCellsConstructed())
 		return 0;
-		
+
 	VssRayContainer constructionRays;
 	VssRayContainer savedRays;
 
-	GetRaySets(rays, 
-			   mConstructionSamples, 
-			   constructionRays, 
+	GetRaySets(rays,
+			   mConstructionSamples,
+			   constructionRays,
 			   &savedRays);
-	
-	Debug << "constructing vsp kd tree using " 
+
+	Debug << "constructing vsp kd tree using "
 		  << (int)constructionRays.size() << " samples" << endl;
 
@@ -1397,8 +1419,8 @@
 
 	// collapse siblings belonging to the same view cell
+	mVspKdTree->RefineViewCells(rays);
+
+		// collapse siblings belonging to the same view cell
 	mVspKdTree->CollapseTree();
-
-	// collapse siblings belonging to the same view cell
-	mVspKdTree->RefineViewCells(rays);
 
 	// evaluale view cell stats
@@ -1410,6 +1432,6 @@
 	// recast rest of rays
 	ComputeSampleContributions(savedRays);
-	
-	Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 
+
+	Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
 		  << " secs" << endl;
 
@@ -1428,5 +1450,5 @@
 }
 
-int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects, 
+int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
 									   const VssRayContainer &rays)
 {
@@ -1454,5 +1476,5 @@
 
 	//-- export leaf building blocks
-	Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d"); 
+	Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
 	if (!exporter)
 		return;
@@ -1462,10 +1484,10 @@
 	exporter->ExportVspKdTree(*mVspKdTree);
 
-	if (mExportGeometry) 
+	if (mExportGeometry)
 		exporter->ExportGeometry(objects);
 
-	if (mExportRays) 
-	{
-		const float prob = (float)mVisualizationSamples 
+	if (mExportRays)
+	{
+		const float prob = (float)mVisualizationSamples
 			/ ((float)sampleRays.size() + Limits::Small);
 
@@ -1491,5 +1513,5 @@
 	if (!ViewCellsConstructed())
 		return;
-	
+
 	//-- export single view cells
 	for (int i = 0; i < 10; ++ i)
@@ -1498,8 +1520,8 @@
 		sprintf(s, "vsp_viewcell%04d.x3d", i);
 		Exporter *exporter = Exporter::GetExporter(s);
-		const int idx = 
+		const int idx =
 			(int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1));
 
-		VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]); 
+		VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]);
 
 		cout << "Output view cell " << i << " with pvs size " << vc->GetPvs().GetSize() << endl;
@@ -1508,5 +1530,5 @@
 		Material m;
 		m.mDiffuseColor = RgbColor(0, 1, 1);
-				
+
 		exporter->SetForcedMaterial(m);
 		exporter->SetWireframe();
@@ -1517,5 +1539,5 @@
 		if (mExportRays)
 		{
-			vector<VspKdLeaf *>::const_iterator it, 
+			vector<VspKdLeaf *>::const_iterator it,
 				it_end = vc->mLeaves.end();
 
@@ -1540,5 +1562,5 @@
 						if ((*it)->mTerminationObject == NULL)
 							castRays.push_back(*it);
-						else 
+						else
 							initRays.push_back(*it);
 				}
@@ -1560,5 +1582,5 @@
 		exporter->SetFilled();
 
-		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
+		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
 		{
 			Intersectable *intersect = (*it).first;
@@ -1571,5 +1593,5 @@
 				exporter->ExportIntersectable(intersect);
 				intersect->Mail();
-			}			
+			}
 		}
 
@@ -1578,6 +1600,6 @@
 
 	//-- export final view cells
-	Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d"); 
-	
+	Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");
+
 	//if (exportGeometry) exporter->SetWireframe();
 	//else exporter->SetFilled();
@@ -1585,5 +1607,5 @@
 	ExportViewCells(exporter);
 
-	if (mExportGeometry) 
+	if (mExportGeometry)
 	{
 		exporter->SetFilled();
@@ -1591,13 +1613,13 @@
 	}
 
-	if (mExportRays) 
-	{
-		const float prob = (float)mVisualizationSamples 
+	if (mExportRays)
+	{
+		const float prob = (float)mVisualizationSamples
 			/ ((float)sampleRays.size() + Limits::Small);
-		
+
 		exporter->SetWireframe();
-			
+
 		VssRayContainer rays;
-		
+
 		for (int i = 0; i < sampleRays.size(); ++ i)
 		{
@@ -1605,5 +1627,5 @@
 			rays.push_back(sampleRays[i]);
 		}
-		exporter->ExportRays(rays, RgbColor(1, 0, 0));	
+		exporter->ExportRays(rays, RgbColor(1, 0, 0));
 	}
 
@@ -1630,5 +1652,5 @@
 	if (mColorCode == 0) // Random color
 		return;
-	
+
 	float importance = 0;
 
@@ -1637,5 +1659,5 @@
 	case 1: // pvs
 		{
-			importance = (float)vc->GetPvs().GetSize() / 
+			importance = (float)vc->GetPvs().GetSize() /
 				(float)mViewCellsStats.maxPvs;
 		}
@@ -1645,5 +1667,5 @@
             VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(vc);
 
-			importance = (float)vspKdVc->mLeaves.size() / 
+			importance = (float)vspKdVc->mLeaves.size() /
 				(float)mViewCellsStats.maxLeaves;
 		}
@@ -1651,5 +1673,5 @@
 	case 3: // merged tree depth difference
 		{
-			//importance = (float)GetMaxTreeDiff(vc) / 
+			//importance = (float)GetMaxTreeDiff(vc) /
 			//	(float)(mVspBspTree->GetStatistics().maxDepth * 2);
 		}
@@ -1668,5 +1690,5 @@
 
 
-void VspKdViewCellsManager::ExportVcGeometry(Exporter *exporter, 
+void VspKdViewCellsManager::ExportVcGeometry(Exporter *exporter,
 										   ViewCell *vc) const
 {
@@ -1684,12 +1706,16 @@
 
 
-/************************************************************************/
-/*                 VspBspViewCellsManager implementation                */
-/************************************************************************/
-
-
-VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree, 
+void VspKdViewCellsManager::CreateMesh(ViewCell *vc)
+{
+}
+
+/**************************************************************************/
+/*                   VspBspViewCellsManager implementation                */
+/**************************************************************************/
+
+
+VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree,
 											   int constructionSamples):
-ViewCellsManager(constructionSamples), 
+ViewCellsManager(constructionSamples),
 mVspBspTree(vspBspTree)
 {
@@ -1719,5 +1745,5 @@
 
 
-float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell, 
+float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell,
 											float objRendercost) const
 {
@@ -1743,20 +1769,19 @@
 }
 
-int VspBspViewCellsManager::Construct(const ObjectContainer &objects, 
+int VspBspViewCellsManager::Construct(const ObjectContainer &objects,
 									  const VssRayContainer &rays)
 {
-  // if view cells were already constructed
-  if (ViewCellsConstructed())
-	return 0;
-  
-  Debug << "Constructing bsp view cells" << endl;
-  
-  int sampleContributions = 0;
-  
-  VssRayContainer sampleRays;
-  
-  int limit = min (mConstructionSamples, (int)rays.size());
-
-	
+	// if view cells were already constructed
+	if (ViewCellsConstructed())
+		return 0;
+
+	Debug << "Constructing bsp view cells" << endl;
+
+	int sampleContributions = 0;
+
+	VssRayContainer sampleRays;
+
+	int limit = min (mConstructionSamples, (int)rays.size());
+
 	VssRayContainer constructionRays;
 	VssRayContainer savedRays;
@@ -1768,5 +1793,5 @@
 
 	mVspBspTree->Construct(constructionRays, &mSceneBox);
-	
+
 	Debug << mVspBspTree->GetStatistics() << endl;
 
@@ -1774,12 +1799,12 @@
 	cout << "collapsing invalid tree regions ... ";
 	long startTime = GetTime();
-	int collapsedLeaves = mVspBspTree->CollapseTree(); 
+	int collapsedLeaves = mVspBspTree->CollapseTree();
 	Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3 << " seconds" << endl;
     cout << "finished" << endl;
-	
+
 	cout << "reseting view cell stats ... ";
 	ResetViewCells();
 	cout << "finished" << endl;
-	
+
 	Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
 
@@ -1788,5 +1813,5 @@
 		cout << "exporting initial view cells (=leaves) ... ";
 		Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
-	
+
 		if (exporter)
 		{
@@ -1797,8 +1822,8 @@
 			if (0 && mExportRays)
 				exporter->ExportRays(rays, RgbColor(1, 1, 1));
-			
+
 			if (mExportGeometry)
 				exporter->ExportGeometry(objects);
-			
+
 			delete exporter;
 		}
@@ -1807,4 +1832,15 @@
 
 	startTime = GetTime();
+
+	//-- merge the individual view cells: Should be done here because it makes
+	MergeViewCells(rays, objects);
+	//-- refines the merged view cells
+	RefineViewCells(rays);
+	// collapse sibling leaves that share the same view cell
+	mVspBspTree->CollapseTree();
+
+	// reset view cells and stats
+	ResetViewCells();
+
 	cout << "Computing remaining ray contributions ... ";
 	// recast rest of rays
@@ -1812,62 +1848,16 @@
 	cout << "finished" << endl;
 
-	Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3 
+	Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
 		  << " secs" << endl;
 
 	cout << "construction finished" << endl;
+
 	return sampleContributions;
 }
 
 
-// matt TODO: remove
-int VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays) const
-{
-	vector<BspIntersection>::const_iterator iit;
-	vector<BspRay *>bspRays;
-	int merged = 0;
-
-	mVspBspTree->ConstructBspRays(bspRays, rays);
-
-	for (int i = 0; i < (int)bspRays.size(); ++ i)
-	{
-		BspRay *ray = bspRays[i];
-	  
-		// traverse leaves stored in the rays and compare and merge consecutive
-		// leaves (i.e., the neighbors in the tree)
-		if (ray->intersections.size() < 2)
-			continue;
-	  
-		iit = ray->intersections.begin();
-
-		BspLeaf *previousLeaf = (*iit).mLeaf;
-		++ iit;
-		
-		for (; iit != ray->intersections.end(); ++ iit)
-		{
-			BspLeaf *leaf = (*iit).mLeaf;
-
-			if (ShouldMerge(leaf, previousLeaf))
-			{			
-				mVspBspTree->MergeViewCells(leaf, previousLeaf);
-				++ merged;
-			}
-			previousLeaf = leaf;
-		}
-	}
-	CLEAR_CONTAINER(bspRays);
-
-	return merged;
-}
-	
-
-int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects, 
-										const VssRayContainer &rays)
-{
-	if (!ViewCellsConstructed())
-	{
-		Debug << "view cells not constructed" << endl;
-		return 0;
-	}
-
+void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays,
+											const ObjectContainer &objects)
+{
 	//-- post processing of bsp view cells
     int vcSize = 0;
@@ -1888,8 +1878,9 @@
 	//-- merge or subdivide view cells
 	int merged = 0;
-	
+
 	cout << "starting merge using " << mPostProcessSamples << " samples ... ";
 	long startTime = GetTime();
 
+	// TODO: should be done BEFORE the ray casting
 	merged = mVspBspTree->MergeViewCells(postProcessRays);
 
@@ -1901,5 +1892,5 @@
 	Debug << "Postprocessing: Merged " << merged << " view cells in "
 		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
-	
+
 	cout << "reseting view cell stats ... ";
 	ResetViewCells();
@@ -1934,12 +1925,17 @@
 		cout << "finished" << endl;
 	}
-
+}
+
+
+void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays)
+{
 	Debug << "render time before refine:" << endl;
 	mRenderer->RenderScene();
+	SimulationStatistics ss;
 	dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
     Debug << ss << endl;
 
 	cout << "Refining the merged view cells ... ";
-	startTime = GetTime();
+	long startTime = GetTime();
 
 	// refining the merged view cells
@@ -1953,12 +1949,18 @@
 	Debug << "Postprocessing: refined " << refined << " view cells in "
 		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
-	
-	// collapse sibling leaves that share the same view cell
-	mVspBspTree->CollapseTree();
-
-	// reset view cells and stats
-	ResetViewCells();
-
-	return merged;
+}
+
+int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
+										const VssRayContainer &rays)
+{
+	if (!ViewCellsConstructed())
+	{
+		Debug << "view cells not constructed" << endl;
+		return 0;
+	}
+
+	CreateViewCellsMeshes();
+
+	return 0;
 }
 
@@ -1993,5 +1995,5 @@
 bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
 {
-	return mSceneBox.IsInside(viewPoint) && 
+	return mSceneBox.IsInside(viewPoint) &&
 		   mVspBspTree->ViewPointValid(viewPoint);
 }
@@ -2026,12 +2028,12 @@
 			delete exporter;
 		}
-		
+
 		cout << "finished" << endl;
-	}	
+	}
 
 	//-- visualization of the BSP splits
 	bool exportSplits = false;
 	environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits);
-	
+
 	if (exportSplits)
 	{
@@ -2044,5 +2046,5 @@
 	ExportBspPvs(objects, visRays);
 }
-	
+
 
 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
@@ -2051,11 +2053,11 @@
 	Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
 
-	if (exporter) 
-	{	
-		Material m; 
+	if (exporter)
+	{
+		Material m;
 		m.mDiffuseColor = RgbColor(1, 0, 0);
 		exporter->SetForcedMaterial(m);
 		exporter->SetWireframe();
-		
+
 		exporter->ExportBspSplits(*mVspBspTree, true);
 
@@ -2066,9 +2068,9 @@
 
 		exporter->ResetForcedMaterial();
-		
+
 		// export rays
 		if (mExportRays)
 			exporter->ExportRays(rays, RgbColor(1, 1, 0));
-	
+
 		if (mExportGeometry)
 			exporter->ExportGeometry(objects);
@@ -2078,19 +2080,20 @@
 }
 
+
 void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
 										  const VssRayContainer &rays)
 {
 	const int leafOut = 10;
-	
+
 	ViewCell::NewMail();
-	
+
 	cout << "visualization using " << mVisualizationSamples << " samples" << endl;
 	Debug << "\nOutput view cells: " << endl;
-	
+
 	// sort view cells to visualize the largest view cells
 #if 0
 	stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
 #endif
-	int limit = min(leafOut, (int)mViewCells.size()); 
+	int limit = min(leafOut, (int)mViewCells.size());
 
 #if 1
@@ -2105,5 +2108,5 @@
 	{
 		cout << "creating output for view cell " << i << " ... ";
-		
+
 		VssRayContainer vcRays;
 		Intersectable::NewMail();
@@ -2117,5 +2120,5 @@
 #if 1
 		// check whether we can add the current ray to the output rays
-		for (int k = 0; k < raysOut; ++ k) 
+		for (int k = 0; k < raysOut; ++ k)
 		{
 			BspRay *ray = bspRays[k];
@@ -2123,5 +2126,5 @@
 			{
 				BspLeaf *leaf = ray->intersections[j].mLeaf;
-				if (vc == leaf->GetViewCell()) 
+				if (vc == leaf->GetViewCell())
 					vcRays.push_back(ray->vssRay);
 			}
@@ -2137,11 +2140,11 @@
 		exporter->SetForcedMaterial(m);
 
-		ExportVcGeometry(exporter, vc);	
-			
-				
-		Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
+		ExportVcGeometry(exporter, vc);
+
+
+		Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize()
 			  << ", piercing rays=" << (int)vcRays.size()
 			  << ", leaves=" << (int)vc->mLeaves.size() << endl;
-		
+
 		//-- export rays piercing this view cell
 #if 1
@@ -2163,5 +2166,5 @@
 
 		// output PVS of view cell
-		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
+		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
 		{
 			Intersectable *intersect = (*it).first;
@@ -2174,7 +2177,7 @@
 				exporter->ExportIntersectable(intersect);
 				intersect->Mail();
-			}			
-		}
-				
+			}
+		}
+
 		DEL_PTR(exporter);
 		cout << "finished" << endl;
@@ -2188,29 +2191,4 @@
 
 
-bool VspBspViewCellsManager::ShouldMerge(BspLeaf *front, BspLeaf *back) const
-{
-	ViewCell *fvc = front->GetViewCell();
-	ViewCell *bvc = back->GetViewCell();
-
-	if (fvc == bvc)
-		return false;
-
-	const int fdiff = fvc->GetPvs().Diff(bvc->GetPvs());
-
-	if (fvc->GetPvs().GetSize() + fdiff < mMaxPvs)
-	{
-		if ((fvc->GetPvs().GetSize() < mMinPvs) ||	
-			(bvc->GetPvs().GetSize() < mMinPvs) ||
-			((fdiff < mMinPvsDif) && 
-			 (bvc->GetPvs().Diff(fvc->GetPvs()) < mMinPvsDif)))
-		{
-			return true;
-		}
-	}
-	
-	return false;
-}
-
-
 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,
 											const Vector3 &termination,
@@ -2221,10 +2199,10 @@
 
 
-void VspBspViewCellsManager::ExportColor(Exporter *exporter, 
+void VspBspViewCellsManager::ExportColor(Exporter *exporter,
 										 ViewCell *vc) const
 {
 	if (mColorCode == 0) // Random color
 		return;
-	
+
 	float importance = 0;
 
@@ -2233,5 +2211,5 @@
 	case 1: // pvs
 		{
-			importance = (float)vc->GetPvs().GetSize() / 
+			importance = (float)vc->GetPvs().GetSize() /
 				(float)mViewCellsStats.maxPvs;
 		}
@@ -2241,5 +2219,5 @@
             BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
 
-			importance = (float)bspVc->mLeaves.size() / 
+			importance = (float)bspVc->mLeaves.size() /
 				(float)mViewCellsStats.maxLeaves;
 		}
@@ -2247,5 +2225,5 @@
 	case 3: // merge tree differene
 		{
-			importance = (float)GetMaxTreeDiff(vc) / 
+			importance = (float)GetMaxTreeDiff(vc) /
 				(float)(mVspBspTree->GetStatistics().maxDepth * 2);
 		}
@@ -2264,14 +2242,20 @@
 
 
-void VspBspViewCellsManager::ExportVcGeometry(Exporter *exporter, 
+void VspBspViewCellsManager::ExportVcGeometry(Exporter *exporter,
 											  ViewCell *vc) const
 {
 #if 1
+    if (vc->GetMesh())
+	{
+		exporter->ExportMesh(vc->GetMesh());
+		return;
+	}
+
 	BspNodeGeometry geom;
 	mVspBspTree->
-		ConstructGeometry(dynamic_cast<BspViewCell *>(vc), geom.mPolys);
+		ConstructGeometry(dynamic_cast<BspViewCell *>(vc), geom);
 	exporter->ExportPolygons(geom.mPolys);
 #else
-	
+
 	Material m2;
 	m2.mDiffuseColor.b = 0.3f + Random(0.7f);
@@ -2324,8 +2308,5 @@
 
 
-
-
-ViewCell *
-VspBspViewCellsManager::GetViewCell(const Vector3 &point)
+ViewCell *VspBspViewCellsManager::GetViewCell(const Vector3 &point)
 {
   if (!mVspBspTree)
@@ -2333,2 +2314,15 @@
   return mVspBspTree->GetViewCell(point);
 }
+
+
+void VspBspViewCellsManager::CreateMesh(ViewCell *vc)
+{
+	BspNodeGeometry geom;
+	BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
+	mVspBspTree->ConstructGeometry(bspVc, geom);
+
+	Mesh *mesh = new Mesh();
+	geom.AddToMesh(*mesh);
+	vc->SetMesh(mesh);
+	mMeshContainer.push_back(mesh);
+}
