Index: GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp	(revision 704)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Beam.cpp	(revision 840)
@@ -202,5 +202,5 @@
 		if (poly)
 		{
-			poly->AddToMesh(*mMesh);
+			IncludePolyInMesh(*poly, *mMesh);
 		}
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 712)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 840)
@@ -1238,5 +1238,6 @@
 	for (pit = polys.begin(); pit != pit_end; ++ pit)
 	{
-		(*pit)->AddToMesh(dummyMesh);
+		Polygon3 *poly = (*pit);
+		IncludePolyInMesh(*poly, dummyMesh);
 	}
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 837)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 840)
@@ -1959,8 +1959,8 @@
 
 
-bool ViewCellsTree::Export(ofstream &stream, const int pvsType)
-{
-	// export recurvivly all view cells from the root
-	ExportViewCell(mRoot, stream, pvsType);
+bool ViewCellsTree::Export(ofstream &stream)
+{
+	// export recursivly all view cells from the root
+	ExportViewCell(mRoot, stream);
 
 	return true;
@@ -1996,5 +1996,5 @@
 
 
-void ViewCellsTree::ExportPvs(ViewCell *viewCell, ofstream &stream, const int pvsType)
+void ViewCellsTree::ExportPvs(ViewCell *viewCell, ofstream &stream)
 {
 	ObjectPvsMap::iterator it, it_end = viewCell->GetPvs().mEntries.end();
@@ -2002,30 +2002,10 @@
 	for (it = viewCell->GetPvs().mEntries.begin(); it != it_end; ++ it)
 	{
-		switch (pvsType)
-		{
-		case EXPORT_IDS:
-            {
-				stream << (*it).first->GetId() << " ";
-			}
-			break;
-		case EXPORT_BBOXES:
-			{
-				Debug << "here24 " << pvsType << endl;
-				MeshInstance *mi = dynamic_cast<MeshInstance *>((*it).first);
-				AxisAlignedBox3 box = mi->GetBox();
-				stream << "<BoundingBox" 
-					   << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\""
-					   << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl;
-			}
-			break;
-		case EXPORT_EMPTY_PVS:
-		default:
-			break;
-		}
-	}
-}
-
-
-void ViewCellsTree::ExportViewCell(ViewCell *viewCell, ofstream &stream, const int pvsType)
+		stream << (*it).first->GetId() << " ";
+	}
+}
+
+
+void ViewCellsTree::ExportViewCell(ViewCell *viewCell, ofstream &stream)
 {
 	if (viewCell->IsLeaf())
@@ -2038,6 +2018,6 @@
 		
 		//-- export pvs
-		Debug << "here66 " << pvsType << endl;
-		ExportPvs(viewCell, stream, pvsType);
+		if (0)
+			ExportPvs(viewCell, stream);
 	
 		stream << "\" />" << endl;
@@ -2058,5 +2038,5 @@
 		{
 			stream << "pvs=\"";
-			ExportPvs(viewCell, stream, pvsType);
+			ExportPvs(viewCell, stream);
 		}
 
@@ -2068,5 +2048,5 @@
 		for (it = interior->mChildren.begin(); it != it_end; ++ it)
 		{
-			ExportViewCell(*it, stream, pvsType);
+			ExportViewCell(*it, stream);
 		}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Polygon3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Polygon3.h	(revision 752)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Polygon3.h	(revision 840)
@@ -100,13 +100,10 @@
 	/** The polygon is converted to triangles.
 	*/
-	void Triangulate(vector<Triangle3> &triangles);
-	/**
-		Adds polygon to mesh description as a face
-	*/
-	void AddToMesh(Mesh &mesh);
+	void Triangulate(vector<Triangle3> &triangles) const;
+
 	/** 
 		Triangle strip indices are created from this polgon.
 	*/
-	void Triangulate(VertexIndexContainer &indices);
+	void Triangulate(VertexIndexContainer &indices) const;
 	
 	/** The piercing rays of the polygon are inherited by the child fragments
@@ -153,4 +150,9 @@
 	*/
 	static float GetArea(const PolygonContainer &cell);
+
+	/**
+		Adds polygon to mesh description as a face
+	*/
+	friend void IncludePolyInMesh(const Polygon3 &poly, Mesh &mesh);
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 748)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 840)
@@ -82,9 +82,4 @@
 	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);
-
 	/** Computes mass center of bsp node geometry.
 	*/
@@ -109,4 +104,9 @@
 	*/
 	void Add(Polygon3 *p, const Plane3 &plane);
+
+	/** Adds node geometry to mesh.
+		@note the mesh vertices will not be connected
+	*/
+	friend void IncludeNodeGeomInMesh(const BspNodeGeometry &geom, Mesh &mesh);
 
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 837)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 840)
@@ -392,12 +392,11 @@
 	void SetMaxFilterSize(const int size);
 
-  int GetMaxFilterSize() {
-	return mMaxFilterSize;
-  }
-
-  /** deletes interior nodes from the tree which have negative merge cost set (local merge) */
-  void
-  DeleteLocalMergeTree(ViewCell *vc
-					   ) const;
+	/** Returns maximal filter size.
+	*/
+	int GetMaxFilterSize() const;
+
+	/** Deletes interior nodes from the tree which have negative merge cost set (local merge).
+	*/  
+	void DeleteLocalMergeTree(ViewCell *vc) const;
   
 	/** Evaluautes histogram for a given number of view cells.
@@ -412,4 +411,9 @@
 	*/
 	float EvalRenderCost(Intersectable *obj) const;
+
+	/** Exports bounding boxes of objects to file.
+	*/
+	bool ExportBoundingBoxes(const string filename, const ObjectContainer &objects) const;
+
 
 protected:
@@ -499,5 +503,10 @@
 
 
-	int mPvsExportMode;
+
+
+
+	/// if bounding boxes should also be exported
+	bool mExportBboxesForPvs;
+		
 
 	Plane3 mClipPlane;
@@ -645,14 +654,8 @@
 
 
-	/** HACK
-	*/
-	void AddCurrentViewCellsToHierarchy();
-
 	void CollectViewCells();
 
 	void ExportColor(Exporter *exporter, ViewCell *vc) const;
 	
-
-
 	/// the BSP tree.
 	BspTree *mBspTree;
@@ -873,8 +876,4 @@
 	BspNode *GetSpatialNode(ViewCell *viewCell) const;
 
-	/** HACK
-	*/
-	void AddCurrentViewCellsToHierarchy();
-
 	/** Merges the view cells.
 	*/
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 837)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 840)
@@ -1319,8 +1319,15 @@
 					"false");
 
-	RegisterOption("ViewCells.pvsExportMode",
-					optInt,
-					"view_cells_export_bounding_boxes=",
-					"2");
+	RegisterOption("ViewCells.exportBboxesForPvs",
+					optBool,
+					"view_cells_export_bboxes=",
+					"true");
+
+	
+	RegisterOption("ViewCells.boxesFilename",
+					optString,
+					"view_cells_boxes_filename=",
+					"boxes.out");
+
 
 	RegisterOption("ViewCells.PostProcess.emptyViewCellsMerge",
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 744)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 840)
@@ -3075,12 +3075,13 @@
 }
 
-
-void BspNodeGeometry::AddToMesh(Mesh &mesh)
-{
-	PolygonContainer::const_iterator it, it_end = mPolys.end();
-	
-	for (it = mPolys.begin(); it != mPolys.end(); ++ it)
-	{
-		(*it)->AddToMesh(mesh);
+void IncludeNodeGeomInMesh(const BspNodeGeometry &geom, Mesh &mesh)
+{
+	// add single polygons to mesh
+	PolygonContainer::const_iterator it, it_end = geom.mPolys.end();
+	
+	for (it = geom.mPolys.begin(); it != geom.mPolys.end(); ++ it)
+	{
+		Polygon3 *poly = (*it);
+		IncludePolyInMesh(*poly, mesh);
 	}
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 837)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 840)
@@ -388,6 +388,5 @@
 	enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
 
-	enum {EXPORT_EMPTY_PVS, EXPORT_IDS, EXPORT_BBOXES};
-
+	
 	/** If view cells in this tree have compressed pvs.
 	*/
@@ -408,5 +407,5 @@
 	/** Exports view cells to file.
 	*/
-    bool Export(ofstream &stream, const int pvsType = EXPORT_EMPTY_PVS);
+    bool Export(ofstream &stream);
 
 	/** Export statistics of this view cell tree.
@@ -512,9 +511,9 @@
 		NOTE: should be in exporter!!
 	*/
-	void ExportViewCell(ViewCell *viewCell, ofstream &stream, const int pvsType);
+	void ExportViewCell(ViewCell *viewCell, ofstream &stream);
 
 	/** Exports pvs of a view cell.
 	*/
-	void ExportPvs(ViewCell *viewCell, ofstream &stream, const int pvsType);
+	void ExportPvs(ViewCell *viewCell, ofstream &stream);
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 837)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 840)
@@ -17,4 +17,5 @@
 
 
+// HACK
 static void AddGeometry(SceneGraph *scene)
 {
@@ -26,5 +27,5 @@
 
 	if (0){
-	// form grrid of meshes
+	// form grid of boxes
 	for (int i = 0; i < n; ++ i)
 	{
@@ -33,7 +34,7 @@
 			const Vector3 scale2((float)j * 0.8 / n + 0.1,  0.05, (float)i * 0.8  / (float)n + 0.1);
 		
-			Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
-		
-			Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
+			const Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
+		
+			const Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
 			AxisAlignedBox3 box(pt2, pt2 + boxSize);
 			Mesh *mesh = CreateBox(box);
@@ -84,24 +85,23 @@
 	scene->mRoot->UpdateBox();
 	}
-// plane separating areas
-if(1)
-{
-const Vector3 scale(1.0, 0.0, 0);
-
-    Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
-
-	Plane3 cuttingPlane(Vector3(1, 0, 0), pt);
-	
-	Mesh *planeMesh = new Mesh();
-	
-	Polygon3 *poly = sceneBox.CrossSection(cuttingPlane);
-
-	poly->AddToMesh(*planeMesh);
-
-	planeMesh->Preprocess();
-
-    MeshInstance *planeMi = new MeshInstance(planeMesh);
-    scene->mRoot->mGeometry.push_back(planeMi);
-}	
+	
+	// plane separating view space regions
+	if (1)
+	{
+		const Vector3 scale(1.0, 0.0, 0);
+
+		Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
+
+		Plane3 cuttingPlane(Vector3(1, 0, 0), pt);
+		Mesh *planeMesh = new Mesh();
+		
+		Polygon3 *poly = sceneBox.CrossSection(cuttingPlane);
+		IncludePolyInMesh(*poly, *planeMesh);
+		
+		planeMesh->Preprocess();
+		
+		MeshInstance *planeMi = new MeshInstance(planeMesh);
+		scene->mRoot->mGeometry.push_back(planeMi);
+	}	
 }
 
@@ -114,18 +114,17 @@
 mViewCellsManager(NULL)
 {
-  environment->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
+	environment->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
   
-  // renderer will be constructed when the scene graph and viewcell manager will be known
-  renderer = NULL;
+	// renderer will be constructed when the scene graph and viewcell manager will be known
+	renderer = NULL;
   
-  environment->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
-  environment->GetBoolValue("Preprocessor.loadPolygonsAsMeshes", mLoadPolygonsAsMeshes);
-  environment->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
-  environment->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
-  environment->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
-  
-  Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
-  Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
-
+	environment->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
+	environment->GetBoolValue("Preprocessor.loadPolygonsAsMeshes", mLoadPolygonsAsMeshes);
+	environment->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
+	environment->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
+	environment->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
+
+	Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
+	Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
 }
 
@@ -143,15 +142,15 @@
   cout << "done.\n";
 
-  cout<<"Deleting kd tree...\n";
+  cout << "Deleting kd tree...\n";
   DEL_PTR(mKdTree);
-  cout<<"done.\n";
+  cout << "done.\n";
   
-  cout<<"Deleting vspkd tree...\n";
+  cout << "Deleting vspkd tree...\n";
   DEL_PTR(mVspKdTree);
-  cout<<"done.\n";
-
-  cout<<"Deleting vspbsp tree...\n";
+  cout << "done.\n";
+
+  cout << "Deleting vspbsp tree...\n";
   DEL_PTR(mVspBspTree);
-  cout<<"done.\n";
+  cout << "done.\n";
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.cpp	(revision 822)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.cpp	(revision 840)
@@ -1954,8 +1954,7 @@
 
 #if 1
-	// take render cost of node into account
+	// also take render cost of node into account to avoid unsubdivided regions which
+	// could reduce the render cost after some subdivisions
 	const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume();
-	//Debug << "rendercostdecr: " << 0.99f * renderCostDecrease << " old render cost: " << 0.01f * normalizedOldRenderCost << endl;
-	//return 0.5f * renderCostDecrease + 0.5f * normalizedOldRenderCost;
 	return 0.99f * renderCostDecrease + 0.01f * normalizedOldRenderCost;
 #else
Index: GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 822)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 840)
@@ -136,6 +136,7 @@
   
   // clean up
-  //  DEL_PTR(p);
-  //  DEL_PTR(environment);
+  DEL_PTR(p);
+  DEL_PTR(environment);
+
   if (app)
 	return app->exec();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 726)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 840)
@@ -1167,5 +1167,6 @@
 	for (pit = polys.begin(); pit != pit_end; ++ pit)
 	{
-		(*pit)->AddToMesh(dummyMesh);
+		Polygon3 *poly = (*pit);
+		IncludePolyInMesh(*poly, dummyMesh);
 	}
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Polygon3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Polygon3.cpp	(revision 683)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Polygon3.cpp	(revision 840)
@@ -498,5 +498,5 @@
 
 
-void Polygon3::Triangulate(vector<Triangle3> &triangles)
+void Polygon3::Triangulate(vector<Triangle3> &triangles) const
 {
 	int i = 1;
@@ -517,5 +517,5 @@
 
 
-void Polygon3::Triangulate(VertexIndexContainer &indices)
+void Polygon3::Triangulate(VertexIndexContainer &indices) const
 {
 	int i = 1;
@@ -539,11 +539,11 @@
 
 
-void Polygon3::AddToMesh(Mesh &mesh)
+void IncludePolyInMesh(const Polygon3 &poly, Mesh &mesh)
 {
 	const int n = (int)mesh.mVertices.size();
 
     //-- add the vertices
-    VertexContainer::const_iterator vit, vit_end = mVertices.end();
-	for (vit = mVertices.begin(); vit != vit_end; ++ vit)
+    VertexContainer::const_iterator vit, vit_end = poly.mVertices.end();
+	for (vit = poly.mVertices.begin(); vit != vit_end; ++ vit)
 	{
 		mesh.mVertices.push_back(*vit);
@@ -551,21 +551,20 @@
 
 	// one quad => no triangulation necessary
-	if ((int)mVertices.size() == 4)
+	if (poly.mVertices.size() == 4)
 	{
 		mesh.AddFace(new Face(n, n + 1, n + 2, n + 3));
-	}
-	else
-	{
-		VertexIndexContainer indices;
-		Triangulate(indices);
-
-		// add indices of triangle strip
-		for (int i = 0; i < (int)indices.size(); i += 3)
-		{
-			Face *face = new Face(n + indices[i], 
-								  n + indices[i + 1], 
-								  n + indices[i + 2]);
-			mesh.AddFace(face);
-		}
-	}
-}
+		return;
+	}
+	
+	VertexIndexContainer indices;
+	poly.Triangulate(indices);
+
+	// add indices of triangle strip
+	for (int i = 0; i < (int)indices.size(); i += 3)
+	{
+		Face *face = new Face(n + indices[i], 
+							  n + indices[i + 1], 
+							  n + indices[i + 2]);
+		mesh.AddFace(face);
+	}
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 837)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 840)
@@ -93,5 +93,5 @@
 	environment->GetIntValue("ViewCells.renderCostEvaluationType", mRenderCostEvaluationType);
 
-	environment->GetIntValue("ViewCells.pvsExportMode", mPvsExportMode);
+	environment->GetBoolValue("ViewCells.exportBboxesForPvs", mExportBboxesForPvs);
 
 	char buf[100];
@@ -1677,15 +1677,4 @@
 		if (viewcell->GetValid())
 		{
-			// HACK
-#if TEST_EMPTY_VIEW_CELLS
-				for (int i = 0; i < mEmptyViewCells.size(); ++i)
-				{
-					if (viewcell == mEmptyViewCells[i])
-					{
-						viewcell->mPiercingRays.push_back(new Ray(ray));
-						Debug << "empty view cell ray found: " << ray.mOriginObject << ", " << ray.mTerminationObject << endl;
-					}
-				}
-#endif
 			// if ray not outside of view space
 			float contribution;
@@ -1699,5 +1688,5 @@
 			}
 
-			//for directional sampling it is important to count only contributions
+			// for directional sampling it is important to count only contributions
 			// made in one direction!!!
 			// the other contributions of this sample will be counted for the oposite ray!
@@ -1858,4 +1847,161 @@
 }
 
+
+int ViewCellsManager::GetMaxFilterSize() const
+{
+	return mMaxFilterSize;  
+}
+
+static const bool USE_ASCII = true;
+
+bool ViewCellsManager::ExportBoundingBoxes(const string filename, 
+										   const ObjectContainer &objects) const
+{
+	ObjectContainer::const_iterator it, it_end = objects.end();
+	
+	if (USE_ASCII)
+	{
+		ofstream boxesOut(filename.c_str());
+		if (!boxesOut.is_open())
+			return false;
+
+		for (it = objects.begin(); it != it_end; ++ it)
+		{
+			MeshInstance *mi = dynamic_cast<MeshInstance *>(*it);
+			const AxisAlignedBox3 box = mi->GetBox();
+
+			boxesOut << mi->GetId() << " " 
+					 << box.Min().x << " " 
+					 << box.Min().y << " " 
+					 << box.Min().z << " " 
+					 << box.Max().x << " " 
+					 << box.Max().y << " " 
+                     << box.Max().z << endl;	
+		}
+
+		boxesOut.close();
+	}
+	else
+	{
+		ofstream boxesOut(filename.c_str(), ios::binary);
+
+		if (!boxesOut.is_open())
+			return false;
+
+		for (it = objects.begin(); it != it_end; ++ it)
+		{	
+			MeshInstance *mi = dynamic_cast<MeshInstance *>(*it);
+			const AxisAlignedBox3 box = mi->GetBox();
+			Vector3 bmin = box.Min();
+			Vector3 bmax = box.Max();
+
+			boxesOut.write(reinterpret_cast<char *>(&bmin), sizeof(Vector3));
+			boxesOut.write(reinterpret_cast<char *>(&bmax), sizeof(Vector3));
+		}
+		
+		boxesOut.close();
+	}
+
+
+	return true;
+}
+
+
+// use ascii format to store rays
+#define USE_ASCII 0
+
+
+inline bool ilt(Intersectable *obj1, Intersectable *obj2)
+{
+	return obj1->mId < obj2->mId;
+}
+
+/*
+bool Preprocessor::LoadBoundingBoxes(const string filename, 
+									 const ObjectContainer &objects) const
+{
+	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);
+	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;
+}*/
+
 /**********************************************************************/
 /*                   BspViewCellsManager implementation               */
@@ -2117,10 +2263,17 @@
 	if (mExportViewCells)
 	{
-		char buff[100];
-		environment->GetStringValue("ViewCells.filename", buff);
-		string vcFilename(buff);
-
-		ExportViewCells(buff);
-	}
+		char filename[100];
+		environment->GetStringValue("ViewCells.filename", filename);
+		ExportViewCells(filename);
+	}
+	
+	// export bounding boxes
+	if (mExportBboxesForPvs)
+	{
+		char filename[100];
+		environment->GetStringValue("ViewCells.boxesFilename", filename);
+		ExportBoundingBoxes(filename, objects);
+	}
+
 
 	return 0;
@@ -2484,6 +2637,7 @@
 	Mesh *mesh = new Mesh();
 
-	geom.AddToMesh(*mesh);
+	IncludeNodeGeomInMesh(geom, *mesh);
 	vc->SetMesh(mesh);
+
 	// put mesh into mesh container so we can savely delete it
 	mMeshContainer.push_back(mesh);
@@ -2578,9 +2732,11 @@
 	//-- the type of the view cells hierarchy
 	//stream << "<Hierarchy name=\"bspTree\" />" << endl;
-	stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free
+	// NOTE: load in vsp bsp here because bsp and vsp bsp can use same tree and vsp bsp is bug free
+	stream << "<Hierarchy name=\"vspBspTree\" />" << endl; 
+	
 	//-- load the view cells itself, i.e., the ids and the pvs
 	stream << "<ViewCells>" << endl;
 
-	mViewCellsTree->Export(stream, mPvsExportMode);
+	mViewCellsTree->Export(stream);
 
 	stream << "</ViewCells>" << endl;
@@ -2597,24 +2753,4 @@
 
 	return true;
-}
-
-
-void BspViewCellsManager::AddCurrentViewCellsToHierarchy()
-{
-	ViewCellContainer::const_iterator it, it_end = mViewCells.end();
-	for (it = mViewCells.begin(); it != it_end; ++ it)
-	{
-		ViewCell *vc = *it;
-		ViewCellContainer leaves;
-		mViewCellsTree->CollectLeaves(vc, leaves);
-		
-		ViewCellContainer::const_iterator lit, lit_end = leaves.end();
-
-		for (lit = leaves.begin(); lit != lit_end; ++ lit)
-		{
-			BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit);
-			bspVc->mLeaf->SetViewCell(vc);
-		}
-	}
 }
 
@@ -3723,5 +3859,5 @@
 int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
 										const VssRayContainer &rays)
-{Debug << "here8773" << endl;
+{
 	if (!ViewCellsConstructed())
 	{
@@ -3812,6 +3948,5 @@
 
 	// collapse sibling leaves that share the same view cell
-	if (0)
-		mVspBspTree->CollapseTree();
+	if (0) mVspBspTree->CollapseTree();
 
 	// recompute view cell list and statistics
@@ -3821,15 +3956,19 @@
 	if (1) FinalizeViewCells(true);
 
-
-	Debug << "here3" << endl;
 	// write view cells to disc
 	if (mExportViewCells)
 	{
-	Debug << "here4" << endl;
-		char buff[100];
-		environment->GetStringValue("ViewCells.filename", buff);
-		string vcFilename(buff);
-
-		ExportViewCells(buff);
+		char filename[100];
+		environment->GetStringValue("ViewCells.filename", filename);
+		ExportViewCells(filename);
+	}
+
+	
+	// export bounding boxes
+	if (mExportBboxesForPvs)
+	{
+		char filename[100];
+		environment->GetStringValue("ViewCells.boxesFilename", filename);
+		ExportBoundingBoxes(filename, objects);
 	}
 
@@ -4506,5 +4645,6 @@
 	
 	Mesh *mesh = new Mesh();
-	geom.AddToMesh(*mesh);
+	IncludeNodeGeomInMesh(geom, *mesh);
+
 	vc->SetMesh(mesh);
 	// put mesh into mesh container so we can savely delete it
@@ -4543,9 +4683,4 @@
 }
 
-
-inline bool ilt(Intersectable *obj1, Intersectable *obj2)
-{
-	return obj1->mId < obj2->mId;
-}
 
 
@@ -4567,13 +4702,16 @@
 		   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;
 
+
+
 	//-- the type of the view cells hierarchy
 	stream << "<Hierarchy name=\"vspBspTree\" />" << endl;
 
-	//-- export the view cells itself, i.e., the ids and the pvs
+	//-- export the view cells and the pvs
 	stream << "<ViewCells>" << endl;
-	Debug << "**************************** mode: " << mPvsExportMode << endl;
-	mViewCellsTree->Export(stream, mPvsExportMode);
+	
+	mViewCellsTree->Export(stream);
 
 	stream << "</ViewCells>" << endl;
+
 
 	//-- export the hierarchy
@@ -4581,4 +4719,6 @@
 	mVspBspTree->Export(stream);
 	stream << endl << "</Hierarchy>" << endl;
+
+
 
 	stream << "</Visibility_Solution>" << endl;
@@ -4734,12 +4874,4 @@
 
 
-void VspBspViewCellsManager::AddCurrentViewCellsToHierarchy()
-{
-	ViewCellContainer::const_iterator it, it_end = mViewCells.end();
-	for (it = mViewCells.begin(); it != it_end; ++ it)
-	{
-	}
-}
-
 //////////////////////////////////
 ViewCellsManager *ViewCellsManagerFactory::Create(const string mName)
