Index: /GTP/trunk/Lib/Vis/Preprocessing/src/X3dParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/X3dParser.cpp	(revision 1404)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/X3dParser.cpp	(revision 1415)
@@ -220,90 +220,93 @@
 void X3dParseHandlers::EndShape()
 {
-	 //-- if shape is merely a definition => don't create particular mesh instance
-	 if (!mCurrentMesh || mIsMeshDefinition) 
-	 { 
-		 return;
-	 }
-
-	 ////////////////////////////////////
-	 //-- each triangle is one single mesh
-
-	 if (!mLoadMeshes)
-	 {
-		 cout << "m";	
-		 Mesh tempMesh(*mCurrentMesh);
-		 ApplyTransformations(mTransformations, &tempMesh);
-
-		 FaceContainer::const_iterator fit, fit_end = tempMesh.mFaces.end();
-		
-		 for (fit = tempMesh.mFaces.begin(); fit != fit_end; ++ fit)
-		 {
-			 cout << "f";
-			 // triangulate the faces
-			 Face *face = *fit;
-			 vector<Triangle3> triangles;
-			 Polygon3 poly(face, &tempMesh);
-			 poly.Triangulate(triangles);
-
-			 vector<Triangle3>::const_iterator tit, tit_end = triangles.end();
-
-			 for (tit = triangles.begin(); tit != tit_end; ++ tit)
-			 {
-				 //cout << "triangle: " << *tit << endl;
-				 TriangleIntersectable *ti = new TriangleIntersectable(*tit);
-				 mCurrentNode->mGeometry.push_back(ti);
-			 }
+	//////////////
+	//-- shape is only a definition => 
+	//-- don't create particular mesh instance
+
+	if (!mCurrentMesh || mIsMeshDefinition) 
+	{ 
+		return;
+	}
+
+	if (!mLoadMeshes)
+	{
+		////////////////////////////////////
+		//-- load data as single triangles instead of whole meshes
+
+		//cout << "m";	
+		Mesh tempMesh(*mCurrentMesh);
+		ApplyTransformations(mTransformations, &tempMesh);
+
+		FaceContainer::const_iterator fit, fit_end = tempMesh.mFaces.end();
+
+		for (fit = tempMesh.mFaces.begin(); fit != fit_end; ++ fit)
+		{
+			//cout << "f";
+			// triangulate the faces
+			Face *face = *fit;
+			vector<Triangle3> triangles;
+			Polygon3 poly(face, &tempMesh);
+			poly.Triangulate(triangles);
+
+			vector<Triangle3>::const_iterator tit, tit_end = triangles.end();
+
+			for (tit = triangles.begin(); tit != tit_end; ++ tit)
+			{
+				//cout << "triangle: " << *tit << endl;
+				TriangleIntersectable *ti = new TriangleIntersectable(*tit);
+				mCurrentNode->mGeometry.push_back(ti);
+			}
 #if 0
-			 // we create a new mesh for each face from the current mesh
-			 Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
-			
-			 VertexIndexContainer::const_iterator vit, vit_end = face->mVertexIndices.end();
-		
-			 int i = 0;
-			 // dummy vertex indices container
-			 VertexIndexContainer vcIndices;
-
-			 for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit, ++ i)
-			 {
-				 cout << "i";
-				 const int index = (*vit);
-				 // add vertices
-				 mesh->mVertices.push_back(mCurrentMesh->mVertices[index]);
-				 // indices don't make much sense if mesh == face, but we need them anyway ...
-				 vcIndices.push_back(i);
-			 }
-
-			 mesh->mFaces.push_back(new Face(vcIndices));
-
-			 // write transformations directly into the mesh
-			 // note: could be transformed in parent mesh, save some transformations
-			 ApplyTransformations(mTransformations, mesh);
-
-			 mesh->Preprocess();
-				
-			 if (mesh->mFaces.empty())
-			 {
-				 cout << "error: empy mesh" << endl;
-			 }
-			 else
-			 {
-				 // make an instance of this mesh
-				 MeshInstance *mi = new MeshInstance(mesh);
-				 mCurrentNode->mGeometry.push_back(mi);
-
-				 if (mCurrentMaterial && !mCurrentMesh->mMaterial)
-				 {
-					 // HACK: add the material to the mesh directly if no material yet
-					 mCurrentMesh->mMaterial = mCurrentMaterial;
-				 }
-			 }
+			// we create a new mesh for each face from the current mesh
+			Mesh *mesh = MeshManager::GetSingleton()->CreateResource();
+
+			VertexIndexContainer::const_iterator vit, vit_end = face->mVertexIndices.end();
+
+			int i = 0;
+			// dummy vertex indices container
+			VertexIndexContainer vcIndices;
+
+			for (vit = face->mVertexIndices.begin(); vit != vit_end; ++ vit, ++ i)
+			{
+				cout << "i";
+				const int index = (*vit);
+				// add vertices
+				mesh->mVertices.push_back(mCurrentMesh->mVertices[index]);
+				// indices don't make much sense if mesh == face, but we need them anyway ...
+				vcIndices.push_back(i);
+			}
+
+			mesh->mFaces.push_back(new Face(vcIndices));
+
+			// write transformations directly into the mesh
+			// note: could be transformed in parent mesh, save some transformations
+			ApplyTransformations(mTransformations, mesh);
+
+			mesh->Preprocess();
+
+			if (mesh->mFaces.empty())
+			{
+				cout << "error: empy mesh" << endl;
+			}
+			else
+			{
+				// make an instance of this mesh
+				MeshInstance *mi = new MeshInstance(mesh);
+				mCurrentNode->mGeometry.push_back(mi);
+
+				if (mCurrentMaterial && !mCurrentMesh->mMaterial)
+				{
+					// HACK: add the material to the mesh directly if no material yet
+					mCurrentMesh->mMaterial = mCurrentMaterial;
+				}
+			}
 #endif
-		 }
-
-		 // this mesh is not needed, unless it is used as a definition
-		 if (!mUsingMeshDefinition)
-		 {
-		 	 MeshManager::GetSingleton()->DestroyEntry(mCurrentMesh->GetId());
-		 }
+		}
+
+		// this mesh is not needed, unless it is used as a definition
+		if (!mUsingMeshDefinition)
+		{
+			MeshManager::GetSingleton()->DestroyEntry(mCurrentMesh->GetId());
+		}
 	}
 	else // default usage: create a mesh instance from the current mesh
@@ -321,12 +324,12 @@
 		else
 		{
-			 // make an instance of this mesh
+			// make an instance of this mesh
 			TransformedMeshInstance *tmi = new TransformedMeshInstance(mCurrentMesh);
 
-			 // apply transformation on the instance of the mesh 
-			 ApplyTransformations(mTransformations, tmi);
-			 mi = tmi;
-		}
-			
+			// apply transformation on the instance of the mesh 
+			ApplyTransformations(mTransformations, tmi);
+			mi = tmi;
+		}
+
 		if (mCurrentMaterial)
 		{
@@ -341,5 +344,5 @@
 			}
 		}
-		
+
 		// create local mesh kd tree
 		mCurrentMesh->Preprocess();
@@ -368,5 +371,5 @@
 
 	VertexIndexContainer vertices;
-  
+
 	mIsMeshDefinition = false;
 	mUsingMeshDefinition = false;
@@ -579,5 +582,5 @@
  
   if (element == "Shape") {
-	  cout << "+"; 
+	  //cout << "+"; 
 
 	  // reset current shape values
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1415)
@@ -1748,9 +1748,13 @@
 					"false");
 
-
-
-	/************************************************************************************/
-	/*                   VSS Preprocessor cells related options                         */
-	/************************************************************************************/
+	RegisterOption("Preprocessor.kdTreeFilename", 
+					optString,
+					"preprocessor_kd_tree_filename=",
+					"vienna_kdtree.bin.gz");
+	
+
+	/*************************************************************************/
+	/*             VSS Preprocessor cells related options                    */
+	/*************************************************************************/
 
 	RegisterOption("VssTree.maxDepth", optInt, "kd_depth=", "12");
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1404)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1415)
@@ -73,11 +73,5 @@
 
   virtual bool
-  ExportOspTree(const OspTree &tree, const int maxPvs);// = 0;
-
-//    virtual bool
-//    ExportRays(const vector<Ray> &rays,
-//  	     const float length=1000,
-//  	     const RgbColor &color = RgbColor(1,1,1)
-//  	     ) = 0;
+  ExportOspTree(const OspTree &tree, const int maxPvs);
   
   virtual bool
@@ -123,5 +117,5 @@
 
   virtual void
-  ExportGeometry(const ObjectContainer &objects, const bool exportSingleMesh = false);
+  ExportGeometry(const ObjectContainer &objects, const bool exportSingleMesh = false, AxisAlignedBox3 *bbox = NULL);
 
   virtual void
@@ -153,5 +147,5 @@
 
   void ExportKdIntersectable(const KdIntersectable &kdObj);
-  bool ExportBvHierarchy(const BvHierarchy &bvHierarchy, const int maxPvs);
+  bool ExportBvHierarchy(const BvHierarchy &bvHierarchy, const int maxPvs, AxisAlignedBox3 *box = NULL);
 
   virtual void ExportMeshInstance(MeshInstance *mi);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1415)
@@ -154,4 +154,5 @@
 	char buffer[256];
 	Environment::GetSingleton()->GetStringValue("Preprocessor.visibilityFile",  buffer);
+    
 	mVisibilityFileName = buffer;
 	Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", mApplyVisibilityFilter );
@@ -372,13 +373,15 @@
   mSceneGraph->CollectObjects(&root->mObjects);
   
-  long startTime = GetTime();
+  const long startTime = GetTime();
   cout << "building kd tree ... " << endl;
 
   mKdTree->Construct();
 
-  cout << "construction finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs " << endl;
+  cout << "finished kd tree construction in " << TimeDiff(startTime, GetTime()) * 1e-3 
+	   << " secs " << endl;
 
   return true;
 }
+
 
 void
@@ -787,4 +790,59 @@
 bool Preprocessor::InitRayCast(const string externKdTree)
 {
+	bool loadKdTree, exportKdTree;
+
+	Environment::GetSingleton()->GetBoolValue("Preprocessor.loadKdTree", loadKdTree);
+	Environment::GetSingleton()->GetBoolValue("Preprocessor.exportKdTree", exportKdTree);
+
+	char kdtreename[100];
+	Environment::GetSingleton()->GetStringValue("Preprocessor.kdTreeFilename", kdtreename);
+
+	
+	if (!loadKdTree)
+	{
+		/////////////////
+		//-- build new kd tree from scene geometry
+
+		BuildKdTree();
+		KdTreeStatistics(cout);
+	}
+	else
+	{
+		const long startTime = GetTime();
+		cout << "loading kd tree file " << kdtreename << " ... ";
+
+		if (!LoadKdTree(kdtreename))
+		{
+			cout << "error loading kd tree with filename " << kdtreename << endl;
+			return false;
+		}
+		cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+
+		if (0)
+		{
+			Exporter *exporter = Exporter::GetExporter("dummykd.x3d");
+			
+			if (exporter)
+			{
+				exporter->ExportKdTree(*mKdTree, true);
+				delete exporter;
+			}
+		}
+	}
+
+	if (exportKdTree)
+	{
+		const long startTime = GetTime();
+		cout << "exporting kd tree ... ";
+		if (!ExportKdTree(kdtreename))
+		{
+			cout << " error exporting kd tree with filename " << kdtreename << endl;
+		}
+		else
+		{
+			cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+		}
+	}
+
 	switch (mRayCastMethod) // use intel ray tracing
 	{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1328)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1415)
@@ -88,5 +88,5 @@
 
 
-#if 0 //matt: this moved up to preprocessor
+#if 0 //matt: this moved up into preprocessor
 int
 RssPreprocessor::CastRay(
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1379)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1415)
@@ -251,5 +251,9 @@
 		
 	void ExportOspTree(Exporter *exporter, const ObjectContainer &objects) const;
-	void ExportBvHierarchy(Exporter *exporter, const ObjectContainer &objects) const;
+
+	void ExportBvHierarchy(
+		Exporter *exporter, 
+		const ObjectContainer &objects, 
+		AxisAlignedBox3 *box) const;
 
 	void PrepareBvHierarchy(
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1415)
@@ -280,5 +280,5 @@
   /////////////////////////
 
-	int mRayCastMethod;
+  int mRayCastMethod;
   /// samples used for construction of the BSP view cells tree.
   int mBspConstructionSamples;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1415)
@@ -608,7 +608,9 @@
 	}
 
+#if 0
 	cout << "depth: " << data.mDepth << " objects: " << (int)leaf->mObjects.size() 
 		 << " rays: " << data.mNumRays << " rays / objects " 
 		 << (float)data.mNumRays / (float)leaf->mObjects.size() << endl;
+#endif
 }
 
@@ -1423,10 +1425,9 @@
 	ViewCellContainer viewCells;
 	CollectViewCells(node->mObjects, viewCells);
+	if (0) cout << "collected " << (int)viewCells.size() << " dirty candidates" << endl;
 
 	// split candidates handling 
 	// these view cells  are thrown into dirty list
 	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
-
-	Debug << "collecting " << (int)viewCells.size() << " dirty candidates" << endl;
 
 	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1415)
@@ -1946,5 +1946,5 @@
 }
 
-
+// matt: todo
 void ViewCellsManager::ExportViewCellsForViz(Exporter *exporter) const
 {
@@ -2640,8 +2640,19 @@
 		mViewCellsTree->SetRoot(root);
 
-		// compute pvs
+		// recompute pvs in the whole hierarchy
 		ObjectPvs pvs;
 		UpdatePvsForEvaluation(root, pvs);
 	}
+
+	cout << "finished" << endl;
+	cout << "merged view cells in "
+		 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+
+	Debug << "Postprocessing: Merged view cells in "
+		<< TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl << endl;
+
+	
+	/////////////////////////////////////////
+	//-- visualization and statistics
 
 	// export statistics after merge
@@ -2653,16 +2664,5 @@
 	}
 
-	//-- stats and visualizations
-	cout << "finished" << endl;
-	cout << "merged view cells in "
-		 << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-
-	Debug << "Postprocessing: Merged view cells in "
-		<< TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl << endl;
-	
-
-	//-- visualization and statistics
-    // reset view cells and stats
-	ResetViewCells();
+	ResetViewCells(); // reset view cells
 	Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl;
 
@@ -2763,5 +2763,5 @@
 	{
 		mColorCode = 1; // hack color code
-		Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");
+		Exporter *exporter = Exporter::GetExporter("final_view_cells.wrl");
 	
 		cout << "exporting view cells after merge (pvs size) ... ";	
@@ -3815,5 +3815,5 @@
 	SimulationStatistics ss;
 	dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
-    Debug << "render time before refine\n" << ss << endl;
+    Debug << "render time before refine\n\n" << ss << endl;
 
 	const long startTime = GetTime();
@@ -3898,5 +3898,5 @@
 	//-- render simulation after merge + refine
 
-	cout << "\nview cells partition render time before compress";
+	cout << "\nview cells partition render time before compress" << endl << endl;;
 	dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene();
 	SimulationStatistics ss;
@@ -4449,4 +4449,5 @@
 	//    find view cells associated with the samples
 	//    store the sample pvs with the pvs associated with the view cell
+	//
 	// for each view cell:
 	//    compute difference point sampled pvs - view cell pvs
@@ -4490,20 +4491,18 @@
 		m.mDiffuseColor.b = 1.0f;
 		//exporter->SetForcedMaterial(m);
-
-//		ExportViewCellGeometry(exporter, vc, mClipPlane);
-
-/*	// counting the pvss
-	for (rit = samples.begin(); rit != rit_end; ++ rit)
-	{
-		RenderCostSample sample = *rit;
-
-		ViewCell *vc = GetViewCell(sample.mPosition);
-		
-		AxisAlignedBox3 box(sample.mPosition - Vector3(1, 1, 1), sample.mPosition + Vector3(1, 1, 1));
-		Mesh *hMesh = CreateMeshFromBox(box);
-		
-		DEL_PTR(hMesh);
-
-*/
+		//ExportViewCellGeometry(exporter, vc, mClipPlane);
+
+		/*	// counting the pvss
+		for (rit = samples.begin(); rit != rit_end; ++ rit)
+		{
+			RenderCostSample sample = *rit;
+			ViewCell *vc = GetViewCell(sample.mPosition);
+
+			AxisAlignedBox3 box(sample.mPosition - Vector3(1, 1, 1), sample.mPosition + Vector3(1, 1, 1));
+			Mesh *hMesh = CreateMeshFromBox(box);
+
+			DEL_PTR(hMesh);
+		}
+		*/
 	}
 }
@@ -4801,4 +4800,5 @@
 
 	// print subdivision statistics
+	Debug << endl << endl;
 	mHierarchyManager->PrintHierarchyStatistics(Debug);
 
@@ -4815,5 +4815,4 @@
 
 	const long startTime = GetTime();
-
 	cout << "Computing remaining ray contributions ... ";
 
@@ -4822,14 +4821,10 @@
 		ComputeSampleContributions(savedRays, true, false);
 
-	cout << "finished" << endl;
-
-	Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
+	Debug << "finished computing remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
 		  << " secs" << endl;
 
-	cout << "construction finished" << endl;
-
-	// real meshes are contructed at this stage
 	if (0)
 	{
+		// real meshes are constructed at this stage
 		cout << "finalizing view cells ... ";
 		FinalizeViewCells(true);
@@ -4908,5 +4903,5 @@
 	//-- render simulation after merge + refine
 
-	cout << "\nview cells partition render time before compress";
+	cout << "\nview cells partition render time before compress" << endl << endl;
 	dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene();
 	SimulationStatistics ss;
@@ -5028,5 +5023,10 @@
 	
 	if (clipPlane)
+	{
 		plane = clipPlane->GetPlane();
+	}
+
+	AxisAlignedBox3 bbox = GetViewSpaceBox();
+	bbox.Scale(Vector3(0.5, 1, 0.5));			
 
 	for (it = leaves.begin(); it != it_end; ++ it)
@@ -5037,4 +5037,7 @@
 		const AxisAlignedBox3 box = mHierarchyManager->GetVspTree()->GetBoundingBox(vspVc->mLeaf);
 		
+		if (!Overlap(box, bbox))
+			continue;
+
 		if (clipPlane)
 		{
@@ -5081,7 +5084,8 @@
 	if (1) 
 	{	
+		/////////////////////////////
 		//-- export final view cells
 
-		// hack pvs
+		// hack color code (show pvs size)
 		const int savedColorCode = mColorCode;
 		mColorCode = 0;
@@ -5091,5 +5095,6 @@
 		if (exporter)
 		{
-			cout << "exporting view cells after post process ... ";
+			const long starttime = GetTime();
+			cout << "exporting final view cells (after initial construction + post process) ... ";
 
 			if (mExportGeometry)
@@ -5113,5 +5118,5 @@
 			delete exporter;
 
-			cout << "finished" << endl;
+			cout << "finished in " << TimeDiff(starttime, GetTime()) * 1e-3f << " secs" << endl;
 		}
 
@@ -5126,9 +5131,11 @@
 		if (exporter)
 		{
+			const long starttime = GetTime();
+
 			cout << "exporting object space hierarchy ... ";
 			mHierarchyManager->ExportObjectSpaceHierarchy(exporter, objects);
 		
 			delete exporter;
-			cout << "finished" << endl;
+			cout << "finished in " << TimeDiff(starttime, GetTime()) * 1e-3f << " secs" << endl;
 		}
 	}
@@ -5153,16 +5160,15 @@
 	const bool sortViewCells = true;
 
-	// sort view cells to visualize the largest view cells
 	if (sortViewCells)
 	{
 		//stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs);
+		// sort view cells to visualize the view cells with highest render cost
 		stable_sort(mViewCells.begin(), mViewCells.end(), ViewCell::LargerRenderCost);
 	}
 
 	int limit = min(leafOut, (int)mViewCells.size());
-
 	int raysOut = 0;
 
-
+	///////////////////////////
 	//-- some rays for output
 	
@@ -5249,9 +5255,11 @@
 				}	
 				
-				//-- export rays piercing this view cell
+				// export rays piercing this view cell
 				exporter->ExportRays(vcRays, RgbColor(1, 1, 0));
 			}
 		}
 
+
+		/////////////////
 		//-- export view cell geometry
 
@@ -5267,4 +5275,5 @@
 
 #if 0	
+		//////////
 		//-- export pvs
 
@@ -5336,4 +5345,5 @@
 		return false;
 
+	const long starttime = GetTime();
 	cout << "exporting view cells to xml ... ";
 	
@@ -5349,4 +5359,6 @@
 	//////////////////////////////////////////////////////////////
 	//-- export bounding boxes
+	//-- The bounding boxes are used to identify 
+	//-- the objects in the rendering engine
 
 	stream << "<BoundingBoxes>" << endl;
@@ -5356,14 +5368,12 @@
 	{
 			const AxisAlignedBox3 box = (*oit)->GetBox();
-
-			//-- the bounding boxes
 			stream << "<BoundingBox" << " id=\"" << (*oit)->GetId() << "\""
 				   << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\""
 				   << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl;
 	}
-
 	stream << "</BoundingBoxes>" << endl;
 
-	////////////////////////////////////////////////////////////////
+
+	//////////////////////////
 	//-- export the view cells and the pvs
 
@@ -5374,5 +5384,5 @@
 	stream << "</ViewCells>" << endl;
 
-
+	//////////////////////
 	//-- export the view space hierarchy
 	
@@ -5384,5 +5394,5 @@
 	stream << "</ViewSpaceHierarchy>" << endl;
 
-	
+	//////////////////////	
 	//-- export the object space partition
 	
@@ -5392,6 +5402,5 @@
 	stream.close();
 	
-	cout << "finished" << endl;
-
+	cout << "finished in " << TimeDiff(starttime, GetTime()) * 1e-3 << " secs" << endl;
 	return true;
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.cpp	(revision 1405)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.cpp	(revision 1415)
@@ -33,9 +33,10 @@
 
 
-bool Exporter::ExportOspTree(const OspTree &ospTree, const int maxPvs)
+bool Exporter::ExportOspTree(const OspTree &ospTree, 
+							 const int maxPvs
+							 )
 {
 	vector<KdLeaf *> leaves;
 	ospTree.CollectLeaves(leaves);
-
 	mUseForcedMaterial = true;
 
@@ -69,5 +70,4 @@
 			SetForcedMaterial(RandomMaterial());
 		}
-
 		if (0) ExportGeometry(leaf->mObjects);	
 	}
@@ -80,5 +80,4 @@
 {
 	KdNode *node = kdObj.GetItem();
-	
 	Intersectable::NewMail();
 
@@ -106,5 +105,6 @@
 
 bool Exporter::ExportBvHierarchy(const BvHierarchy &bvHierarchy, 
-								 const int maxPvs)
+								 const int maxPvs,
+								 AxisAlignedBox3 *box)
 {
 	vector<BvhLeaf *> leaves;
@@ -112,5 +112,4 @@
 
 	mUseForcedMaterial = true;
-
 	vector<BvhLeaf *>::const_iterator it, it_end = leaves.end();
 
@@ -126,4 +125,7 @@
 			continue;
 
+		if (box && !Overlap(*box, leaf->GetBoundingBox()))
+			continue;
+
 		SetWireframe();
 		SetForcedMaterial(white);
@@ -223,5 +225,6 @@
 
 void Exporter::ExportGeometry(const ObjectContainer &objects, 
-							  const bool exportSingleMesh)
+							  const bool exportSingleMesh,
+							  AxisAlignedBox3 *bbox)
 {
 	ObjectContainer::const_iterator oit, oit_end = objects.end();
@@ -231,6 +234,9 @@
 		for (oit = objects.begin(); oit != oit_end; ++ oit)
 		{
-			if (0) SetForcedMaterial(RandomMaterial());
-			ExportIntersectable(*oit);
+			if (bbox && Overlap(*bbox, (*oit)->GetBox()))
+			{
+				if (0) SetForcedMaterial(RandomMaterial());
+				ExportIntersectable(*oit);
+			}
 		}
 
@@ -238,6 +244,9 @@
 	}
 
+	
+	///////////////////////////////////////////
 	//-- all objects exported as one mesh
 	//-- hack: currently works only for triangles
+
 	PolygonContainer polys;
 
@@ -245,4 +254,8 @@
 	{
 		Intersectable *obj = *oit;
+
+		if (bbox && !Overlap(*bbox, (*oit)->GetBox()))
+			continue;
+
 		switch (obj->Type())
 		{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1415)
@@ -72,5 +72,4 @@
     mMin -= v;
   }
-
 
   void SetMin(const Vector3 &v) {
@@ -167,24 +166,11 @@
   /** Scales the box with the factor.
   */
-  void Scale(const float scale) {
-	Vector3 newSize = Size()*(scale*0.5f);
-	Vector3 center = Center();
-	mMin = center - newSize;
-	mMax = center + newSize;
-  }
-
-  void Scale(const Vector3 &scale) {
-	Vector3 newSize = Size()*(scale*0.5f);
-	Vector3 center = Center();
-	mMin = center - newSize;
-	mMax = center + newSize;
-  }
-
+  void Scale(const float scale);
+
+  void Scale(const Vector3 &scale);
+	
   /** Translates the box with the factor.
   */
-  void Translate(const Vector3 &shift) {
-	mMin += shift;
-	mMax += shift;
-  }
+  void Translate(const Vector3 &shift);
 
   /** Returns the square of the minimal and maximal distance to 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1415)
@@ -1380,7 +1380,8 @@
 		{
 			EvaluateLeafStats(tData);
-			cout << "l";
-		}
-	}
+			//cout << "l";
+		}
+	}
+
 	Debug << mStat << endl;
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1379)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1415)
@@ -94,10 +94,9 @@
 	app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n";
 
-	app << "#AXIS_ALIGNED_SPLITS (number of axis aligned splits)\n" << splits[0] + splits[1] + splits[2] << endl;
-
 	app << "#N_SPLITS ( Number of splits in axes x y z)\n";
 
 	for (int i = 0; i < 3; ++ i)
 		app << splits[i] << " ";
+
 	app << endl;
 
@@ -529,11 +528,11 @@
 		|| (data.mPvs <= mTermMinPvs)
 		|| (data.mProbability <= mTermMinProbability)
-		|| (data.GetAvgRayContribution() > mTermMaxRayContribution)
+		//|| (data.GetAvgRayContribution() > mTermMaxRayContribution)
 		|| (data.mDepth >= mTermMaxDepth)
 		);
 
-	if (1 && localTerminationCriteriaMet)
-	{
-		Debug << "********local termination *********" << endl;
+	if (0 && localTerminationCriteriaMet)
+	{
+		Debug << "local termination criteria met:" << endl;
 		Debug << "rays: " << (int)data.mRays->size() << "  " << mTermMinRays << endl;
 		Debug << "pvs: " << data.mPvs << " " << mTermMinPvs << endl;
@@ -552,10 +551,10 @@
 		// || mOutOfMemory
 		|| (mVspStats.Leaves() >= mMaxViewCells)
-        //|| (mGlobalCostMisses >= mTermGlobalCostMissTolerance) 
+        || (mGlobalCostMisses >= mTermGlobalCostMissTolerance) 
 		);
 
 	if (0 && terminationCriteriaMet)
 	{
-		Debug << "********* terminationCriteriaMet *********" << endl;
+		Debug << "globlal termination criteria met:" << endl;
 		Debug << "cost misses: " << mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
 		Debug << "leaves: " << mVspStats.Leaves() << " " <<  mMaxViewCells << endl;
@@ -768,6 +767,6 @@
 	VspLeaf *leaf = dynamic_cast<VspLeaf *>(tData.mNode);
 	
-	///////////////////////////////////////////////////////////////////
-	//-- the front and back traversal data is filled with the new values
+	////////////////////////////////////////////////////////
+	//-- the front and back traversal data are filled with the new values
 
 	frontData.mDepth = tData.mDepth + 1;
@@ -807,5 +806,6 @@
 	// two more leaves
 	mVspStats.nodes += 2;
-
+	/// and a new split
+	++ mVspStats.splits[splitPlane.mAxis];
 
     ///////////////////////////////////////////
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1414)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1415)
@@ -149,5 +149,6 @@
 	}
 
-	////////////////////////////////////////
+
+	/////////////
 	//-- load scene 
 
@@ -175,58 +176,4 @@
 		exit(1);
 	}
-
-	bool loadKdTree, exportKdTree;
-
-	Environment::GetSingleton()->GetBoolValue("Preprocessor.loadKdTree", loadKdTree);
-
-	const string kdtreename("kd.bin.gz");
-
-	if (!loadKdTree)
-	{
-		//-- build new kd tree from scene geometry
-		preprocessor->BuildKdTree();
-		preprocessor->KdTreeStatistics(cout);
-	}
-	else
-	{
-		const long startTime = GetTime();
-		cout << "loading kd tree ... ";
-
-		if (!preprocessor->LoadKdTree(kdtreename))
-		{
-			cout << "error loading kd tree with filename " << kdtreename << endl;
-			Cleanup();
-			exit(1);
-		}
-		cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-
-		if (0)
-		{
-			Exporter *exporter = Exporter::GetExporter("dummykd.x3d");
-			
-			if (exporter)
-			{
-				exporter->ExportKdTree(*preprocessor->mKdTree, true);
-				delete exporter;
-			}
-		}
-	}
-
-	Environment::GetSingleton()->GetBoolValue("Preprocessor.exportKdTree", exportKdTree);
-
-	if (exportKdTree)
-	{
-		const long startTime = GetTime();
-		cout << "exporting kd tree ... ";
-		if (!preprocessor->ExportKdTree(kdtreename))
-		{
-			cout << " error exporting kd tree with filename " << kdtreename << endl;
-		}
-		else
-		{
-			cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-		}
-	}
-
 
 	// parse view cells related options
@@ -301,4 +248,5 @@
 	}
 	
+	// release memory
 	Cleanup();
 	
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1379)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1415)
@@ -309,5 +309,4 @@
 {
 	cout << "starting bv hierarchy construction ... " << endl;
-
 	mBvHierarchy->CreateRoot(objects);
 
@@ -317,5 +316,5 @@
 
 	mTotalCost = mBvHierarchy->mTotalCost;
-	Debug << "reseting cost, new total cost: " << mTotalCost << endl;
+	Debug << "\nreseting cost, new total cost: " << mTotalCost << endl;
 
     mTQueue.Push(sc);
@@ -373,4 +372,5 @@
 		}
 	}
+
 	return true;//!globalTerminationCriteriaMet;
 }
@@ -458,9 +458,11 @@
 		}
 		
-		///////////////////////////
+		///////////////////
 		//-- subdivide leaf node
+
 		if (ApplySubdivisionCandidate(mCurrentCandidate))
 		{
-			cout << "subdividing candidate " << ++ i << " of type " << mCurrentCandidate->Type() << endl;
+			cout << mCurrentCandidate->Type() << " ";
+			if (0) cout << "subdividing candidate " << ++ i << " of type " << mCurrentCandidate->Type() << endl;
 			mHierarchyStats.nodes += 2;
 
@@ -474,10 +476,10 @@
 
 		// we use objects for evaluating vsp tree construction until 
-		// a certain depth once a certain depth existiert ....
+		// a certain depth once a certain depth existiert ...
 		if (StartObjectSpaceSubdivision())
 		{
 			mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;
 
-			cout << "starting object space subdivision at depth " 
+			cout << "\nstarting object space subdivision at depth " 
 				 << mVspTree->mVspStats.maxDepth << " (" 
 				 << mMinDepthForObjectSpaceSubdivion << ") " << endl;
@@ -494,5 +496,5 @@
 			mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType;
 
-			cout << "starting view space subdivision at depth " 
+			cout << "\nstarting view space subdivision at depth " 
 				 << GetObjectSpaceSubdivisionDepth() << " (" 
 				 << mMinDepthForViewSpaceSubdivion << ") " << endl;
@@ -608,7 +610,9 @@
 	vector<SubdivisionCandidate *> dirtyList;
 	CollectDirtyCandidates(dirtyList);
-	cout << "repairing " << (int)dirtyList.size() << " candidates ... ";
-	
+	if (0) cout << "repairing " << (int)dirtyList.size() << " candidates ... ";
+	
+	/////////////////////////////////
 	//-- reevaluate the dirty list
+
 	SubdivisionCandidateContainer::const_iterator sit, sit_end = dirtyList.end();
 	
@@ -638,5 +642,5 @@
 	mHierarchyStats.repairTime += timeDiff;
 
-	cout << "finished in " << timeDiff * 1e-3f << " secs" << endl;
+	if (0) cout << "finished in " << timeDiff * 1e-3f << " secs" << endl;
 }
 
@@ -753,5 +757,8 @@
 	case BV_BASED_OBJ_SUBDIV:
 		{
-			ExportBvHierarchy(exporter, objects);
+			AxisAlignedBox3 bbox = mBvHierarchy->GetBoundingBox();
+			bbox.Scale(Vector3(0.5, 1, 0.5));
+			
+			ExportBvHierarchy(exporter, objects, &bbox);
 			break;
 		}
@@ -763,8 +770,9 @@
 
 void HierarchyManager::ExportBvHierarchy(Exporter *exporter, 
-										 const ObjectContainer &objects) const
+										 const ObjectContainer &objects,
+										 AxisAlignedBox3 *bbox) const
 {
 	exporter->SetWireframe();
-	exporter->ExportBvHierarchy(*mBvHierarchy, 0);
+	exporter->ExportBvHierarchy(*mBvHierarchy, 0, bbox);
 }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp	(revision 1315)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.cpp	(revision 1415)
@@ -155,5 +155,6 @@
 	}
 
-	// if not using kd tree root, delete tree (otherwise mKdTree has to do the job)
+	// delete hierarchy only if not using the hierarchy from 
+	// some other kd tree (otherwise the other kd tree has to do the job)
 	if (!mCopyFromKdTree)
 		DEL_PTR(mRoot);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1047)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1415)
@@ -2129,5 +2129,5 @@
 							AxisAlignedBox3 &back) const
 {
-	if ( (value >= mMin[axis]) && (value <= mMax[axis]) )
+	if ((value >= mMin[axis]) && (value <= mMax[axis]))
 	{
 		front.mMin = mMin; front.mMax = mMax;
@@ -2139,4 +2139,29 @@
 }
 
-
-}
+ 
+void AxisAlignedBox3::Scale(const float scale) 
+{
+	Vector3 newSize = Size()*(scale*0.5f);
+	Vector3 center = Center();
+	mMin = center - newSize;
+	mMax = center + newSize;
+}
+
+
+void AxisAlignedBox3::Scale(const Vector3 &scale) 
+{
+	Vector3 newSize = Size()*(scale*0.5f);
+	Vector3 center = Center();
+	mMin = center - newSize;
+	mMax = center + newSize;
+}
+
+
+void AxisAlignedBox3::Translate(const Vector3 &shift) 
+{
+	 mMin += shift;
+	 mMax += shift;
+}
+
+
+}
