Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 330)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 331)
@@ -9,7 +9,7 @@
 #	filename vienna.x3d
 #	filename ../data/vienna/vienna-simple.x3d
-	filename ../data/vienna/vienna-buildings.x3d
+#	filename ../data/vienna/vienna-buildings.x3d
 #	filename ../data/vienna/viewcells-25-sel.x3d
-#	filename ../data/atlanta/atlanta2.x3d
+	filename ../data/atlanta/atlanta2.x3d
 #	filename ../data/soda/soda.dat
 #	filename ../data/soda/soda5.dat
@@ -56,5 +56,5 @@
 
 Sampling {
-	totalSamples	5000
+	totalSamples	1000000
 	samplesPerPass  20
 }
@@ -76,8 +76,8 @@
 BspTree {
 	Construction {
-	        input fromRays
+		input fromRays
 	#	input fromViewCells
 	#	input fromSceneGeometry
-		samples 3000
+		samples 200000
 		sideTolerance 0.002
 	}
@@ -114,5 +114,5 @@
 	Termination {
 		maxPolysForAxisAligned 100
-		maxPolygons 20
+		maxPolygons 2
 		maxDepth 100
 	}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 329)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 331)
@@ -229,4 +229,9 @@
 	void SetViewCell(ViewCell *viewCell);
 
+	/** Generates new view cell and stores it back in the container.
+		@returns the number of sample contributions from the rays
+	*/
+	int GenerateViewCell(const RayContainer &rays, ViewCellContainer &viewCells);
+
 protected:
 
@@ -295,5 +300,5 @@
 		Many leafs can point to the same viewcell.
 	*/
-	void Construct(const ViewCellContainer &viewCells);
+	int Construct(const ViewCellContainer &viewCells);
 
 	/** Constructs tree using the given list of objects. 
@@ -304,13 +309,13 @@
 		@returns list of view cells.
 	*/
-	void Construct(const ObjectContainer &objects, ViewCellContainer *viewCells);
-
-	/** Constructs the tree from  a given bundle of rays.
-		@param rays the bundle of sample rays
+	int Construct(const ObjectContainer &objects, ViewCellContainer *viewCells);
+
+	/** Constructs the tree from a given set of rays.
+		@param sampleRays the set of sample rays the construction is based on
 		@param viewCells if not NULL, new view cells are 
 		created in the leafs and stored in the conatainer
 	*/
-	void Construct(RayContainer *rays, 
-				   ViewCellContainer *viewCells = NULL);
+	int Construct(const RayContainer &sampleRays, 
+	 		      ViewCellContainer *viewCells = NULL);
 
 	/** Returns list of BSP leaves.
@@ -380,5 +385,7 @@
 		created in the leafs and stored in the conatainer
 	*/
-	void Construct(PolygonContainer *polys, RayContainer *rays, ViewCellContainer *viewCells = NULL);
+	int Construct(PolygonContainer *polys, 
+		          RayContainer *rays, 
+				  ViewCellContainer *viewCells = NULL);
 
 	/** Selects the best possible splitting plane. 
@@ -526,9 +533,4 @@
 							 vector<SortableEntry> &splitCandidates) const;
 
-
-	/** Generates new view cell for a leaf and stores it back in the container.
-	*/
-	void BspTree::GenerateViewCell(BspLeaf *leaf, ViewCellContainer &viewCells) const;
-
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 330)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 331)
@@ -174,5 +174,5 @@
 		// bound ray
 		if ((ray->GetType() == Ray::LOCAL_RAY) && 
-			(ray->intersections.empty())      &&
+			(!ray->intersections.empty())      &&
 			(ray->intersections[0].mT <= maxT))
 		{
@@ -327,4 +327,5 @@
 {
 }
+
 ViewCell *BspLeaf::GetViewCell()
 {
@@ -341,4 +342,25 @@
 	return true; 
 }
+
+int BspLeaf::GenerateViewCell(const RayContainer &rays, 
+							   ViewCellContainer &viewCells)
+{
+	int sampleContri = 0;
+	ViewCell *viewCell = new ViewCell();
+	viewCells.push_back(viewCell);
+				
+    mViewCell = viewCell;
+
+    RayContainer::const_iterator it, it_end = rays.end();
+
+	// add contributions from samples to the PVS
+	for (it = rays.begin(); it != it_end; ++ it)
+	{
+		for (int i = 0; i < (int)(*it)->intersections.size(); ++ i)
+			sampleContri = viewCell->GetPvs().AddSample((*it)->intersections[i].mObject);
+	}
+	return sampleContri;
+}
+
 
 /****************************************************************/
@@ -501,17 +523,14 @@
 			BspNode *subRoot = Subdivide(tStack, tData);		
 
+			int sampleContri = 0;
+
 			// generate new view cell for each leaf
 			if (viewCells && subRoot->IsLeaf())
-				GenerateViewCell(dynamic_cast<BspLeaf *>(subRoot), *viewCells);
-		}
-	}
-}
-
-void BspTree::GenerateViewCell(BspLeaf *leaf, ViewCellContainer &viewCells) const
-{
-	ViewCell *viewCell = new ViewCell();
-	viewCells.push_back(viewCell);
-				
-	leaf->SetViewCell(viewCell);
+				sampleContri += dynamic_cast<BspLeaf *>(subRoot)->
+					GenerateViewCell(*tData.mRays, *viewCells);
+
+			DEL_PTR(tData.mRays);
+		}
+	}
 }
 
@@ -585,5 +604,5 @@
 }
 
-void BspTree::Construct(const ViewCellContainer &viewCells)
+int BspTree::Construct(const ViewCellContainer &viewCells)
 {
 	mStat.nodes = 1;
@@ -595,9 +614,9 @@
 
 	// construct tree from the view cell polygons
-	Construct(polys, new RayContainer());
-}
-
-
-void BspTree::Construct(const ObjectContainer &objects, ViewCellContainer *viewCells)
+	return Construct(polys, new RayContainer());
+}
+
+
+int BspTree::Construct(const ObjectContainer &objects, ViewCellContainer *viewCells)
 {
 	mStat.nodes = 1;
@@ -610,13 +629,17 @@
 
 	// construct tree from polygon soup
-	Construct(polys, new RayContainer(), viewCells);
-}
-
-void BspTree::Construct(RayContainer *rays, 
+	return Construct(polys, new RayContainer(), viewCells);
+}
+
+int BspTree::Construct(const RayContainer &sampleRays, 
 						ViewCellContainer *viewCells)
 {
+	mStat.nodes = 1;
+	mBox.Initialize(); 	// initialise bsp tree bounding box
+	
 	PolygonContainer *polys = new PolygonContainer();
-	
-	RayContainer::const_iterator rit, rit_end = rays->end();
+	RayContainer *rays = new RayContainer();
+
+	RayContainer::const_iterator rit, rit_end = sampleRays.end();
 
 	long startTime = GetTime();
@@ -626,47 +649,51 @@
 
 	//-- extract polygons from faces stored in the rays
-	for (rit = rays->begin(); rit != rit_end; ++ rit)
+	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
 	{
 		Ray *ray = *rit;
-	
 		ray->SetId(-1); // reset id
+		rays->push_back(ray);
 
 		for (int i = 0; i < (int)ray->intersections.size(); ++ i)
 		{
 			MeshInstance *obj = dynamic_cast<MeshInstance *>(ray->intersections[i].mObject);
-			Face *face = obj->GetMesh()->mFaces[i];
-			
-			 std::map<Face *, Polygon3 *>::iterator it= facePolyMap.find(face);
-
-			 if (it != facePolyMap.end()) 
-			 {
-				 (*it).second->AddPiercingRay(ray);
-			 } 
-			 else
-			 {
-				 Polygon3 *poly = new Polygon3(face, obj->GetMesh());
-				 polys->push_back(poly);
-				 poly->AddPiercingRay(ray);
-
-				 facePolyMap[face] = poly;
-			 }
-		}
-	}
-
-	
+			Face *face = obj->GetMesh()->mFaces[ray->intersections[i].mFace];
+
+			// store rays piercing a face with the polygon representing the face
+			std::map<Face *, Polygon3 *>::iterator it= facePolyMap.find(face);
+
+			if (it != facePolyMap.end()) 
+			{
+				(*it).second->AddPiercingRay(ray);
+			} 
+			else
+			{
+				Polygon3 *poly = new Polygon3(face, obj->GetMesh());
+				polys->push_back(poly);
+				Debug << "poly: " << *poly << endl;
+				poly->AddPiercingRay(ray);
+
+				facePolyMap[face] = poly;
+			}
+		}
+	}
+	
+	Polygon3::IncludeInBox(*polys, mBox);
 	mStat.polys = (int)polys->size();
 
-	Debug << "**** Finished polygon extraction ****\n";
-	Debug << "ray casting time: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
-
-	Construct(polys, rays, viewCells);
-}
-
-void BspTree::Construct(PolygonContainer *polys, RayContainer *rays, ViewCellContainer *viewCells)
+	Debug << "**** Finished polygon extraction ****" << endl;
+	Debug << polys->size() << " polys extracted from " << rays->size() << " rays" << endl;
+	Debug << "extraction time: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+
+	return Construct(polys, rays, viewCells);
+}
+
+int BspTree::Construct(PolygonContainer *polys, 
+					   RayContainer *rays, 
+					   ViewCellContainer *viewCells)
 {
 	std::stack<BspTraversalData> tStack;
 
 	BspTraversalData tData(new BspLeaf(), polys, 0, mRootCell, rays);
-
 	tStack.push(tData);
 
@@ -674,4 +701,6 @@
 	cout << "**** Contructing bsp tree ****\n";
 
+	int sampleContri = 0;
+
 	while (!tStack.empty()) 
 	{
@@ -683,9 +712,12 @@
 
 		if (viewCells && subRoot->IsLeaf())
-			GenerateViewCell(dynamic_cast<BspLeaf *>(subRoot), *viewCells);
+			sampleContri += dynamic_cast<BspLeaf *>(subRoot)->
+					GenerateViewCell(*tData.mRays, *viewCells);
+		DEL_PTR(tData.mRays);
 	}
 
 	cout << "**** Finished tree construction ****\n";
 	Debug << "BSP tree contruction time: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+	return sampleContri;
 }
 
@@ -696,8 +728,8 @@
 	if ((tData.mPolygons->size() <= sTermMaxPolygons) || (tData.mDepth >= sTermMaxDepth))
 	{
-#ifdef _DEBUG
+//#ifdef _DEBUG
 		Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " 
 			  << (int)tData.mPolygons->size() << endl;
-#endif
+//#endif
 		EvaluateLeafStats(tData);
 		BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
@@ -711,6 +743,5 @@
 		leaf->ProcessPolygons(tData.mPolygons, sStoreSplitPolys);
 		DEL_PTR(tData.mPolygons);
-		DEL_PTR(tData.mRays);
-
+	
 		return leaf;
 	}
@@ -726,5 +757,4 @@
 	RayContainer *backRays = new RayContainer();
 	
-
 	// create new interior node and two leaf nodes
 	BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode), 
@@ -736,5 +766,4 @@
 										   *frontRays,
 										   *backRays);
-
 	ViewCell *frontViewCell = mRootCell;
 	ViewCell *backViewCell = mRootCell;
@@ -775,6 +804,5 @@
 	DEL_PTR(tData.mNode);
 	DEL_PTR(tData.mPolygons);
-	DEL_PTR(tData.mRays);
-
+	
 	return interior;
 }
@@ -820,5 +848,5 @@
 {
 	mStat.nodes += 2;
-
+	
 	// select subdivision plane
 	BspInterior *interior = 
@@ -838,4 +866,5 @@
 							               coincident, 
 							               sStoreSplitPolys);
+
 	BspInterior *parent = leaf->GetParent();
 
@@ -1063,5 +1092,5 @@
 {
 	float val = 0;
-	
+
 	if (sSplitPlaneStrategy & VERTICAL_AXIS)
 	{
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 329)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 331)
@@ -53,13 +53,7 @@
   
 	if (strcmp(viewCellsStr, "bspTree") == 0)
-	{
-		Debug << "here bsp" << endl;
-    	mViewCellsType = BSP_VIEW_CELLS;
-	}
+	   	mViewCellsType = BSP_VIEW_CELLS;
 	else if (strcmp(viewCellsStr, "kdTree") == 0)
-		{
-		Debug << "here kd" << endl;
-    	mViewCellsType = KD_VIEW_CELLS;
-	}
+	   	mViewCellsType = KD_VIEW_CELLS;
 	else if (strcmp(viewCellsStr, "sceneDependent") == 0)
 	{
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 330)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 331)
@@ -39,8 +39,10 @@
   p->ParseViewCellsOptions();
 
+  // construct tree immediately for "from view cells" or "from scene geometry"
+  // construction method. For "from rays" construction, wait until there is
+  // a certain number of rays collected
   if (p->mViewCellsType == Preprocessor::BSP_VIEW_CELLS &&
-	  !(BspTree::sConstructionMethod == BspTree::FROM_RAYS)) // construct tree later
+	  !(BspTree::sConstructionMethod == BspTree::FROM_RAYS)) 
   {
-	  Debug << "do1" << endl;
 	  if (BspTree::sConstructionMethod == BspTree::FROM_INPUT_VIEW_CELLS)
 	  {
@@ -61,42 +63,4 @@
 	  p->BspTreeStatistics(Debug);
 
-	  bool exportSplits = false;
-	  environment->GetBoolValue("BspTree.exportSplits", exportSplits);
-
-	  // export the bsp splits
-	  if (exportSplits)
-	  {
-		  Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
-
-		  if (exporter) 
-		  {	
-			  Material m; 
-			  m.mDiffuseColor = RgbColor(1, 0, 0);
-			  exporter->SetForcedMaterial(m);
-			  exporter->SetWireframe();
-			  exporter->ExportBspSplits(*p->mBspTree);
-
-			  // take forced material because does not load for big scenes otherwise
-			  m.mDiffuseColor = RgbColor(0, 1, 0);
-			  exporter->SetForcedMaterial(m);
-			  exporter->SetFilled();
-
-			  exporter->ResetForcedMaterial();
-
-			  if (1)
-			  {
-				  ObjectContainer objects;
-				  p->mSceneGraph->CollectObjects(&objects);
-                  Material m;//= RandomMaterial();
-				  m.mDiffuseColor = RgbColor(0, 0, 1);
-				  exporter->SetForcedMaterial(m);
-                 
-				  for (int j = 0; j < objects.size(); ++ j)
-					   exporter->ExportIntersectable(objects[j]);
-			
-				  delete exporter;
-			  }
-		  }
-	  }
 #if 0
 	  //-- export the complementary view cells
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 329)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 331)
@@ -23,5 +23,5 @@
   ofstream mStats;
   ObjectContainer mObjects;
-  RayContainer *mSampleRays;
+  RayContainer mSampleRays;
   int mBspConstructionSamples;
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 330)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 331)
@@ -8,5 +8,5 @@
 #include "ViewCell.h"
 
-SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
+SamplingPreprocessor::SamplingPreprocessor(): mPass(0), mSampleRays(NULL)
 {
   // this should increase coherence of the samples
@@ -22,10 +22,5 @@
 SamplingPreprocessor::~SamplingPreprocessor()
 {
-	// clean up
-	if (mSampleRays)
-	{
-		CLEAR_CONTAINER (*mSampleRays);
-		DEL_PTR (mSampleRays);
-	}
+	CLEAR_CONTAINER(mSampleRays);
 }
 
@@ -66,13 +61,10 @@
 		break;
 	case BspTree::FROM_SCENE_GEOMETRY:
-		
 		DeleteViewCells(); // we generate new view cells
 		mSceneGraph->CollectObjects(&objects);
-		mBspTree->Construct(objects, &mViewCells);
-		
+		mBspTree->Construct(objects, &mViewCells);	
 		break;
 	case BspTree::FROM_RAYS:
 		DeleteViewCells(); // we generate new view cells
-		mSceneGraph->CollectObjects(&objects);
 		mBspTree->Construct(mSampleRays, &mViewCells);
 		break;
@@ -81,4 +73,5 @@
 		break;
 	}
+	
 	
 	return true;
@@ -278,23 +271,10 @@
 
   int pvsOut = Min((int)objects.size(), 10);
-  int vcPvsOut = Min((int)mViewCells.size(), 5);
-
+
+  vector<Ray> rays[10];
+
+  vector<Ray> vcRays[5];
   ViewCellContainer pvsViewCells;
-
-  // some random view cells for output
-  for (int j = 0; j < vcPvsOut; ++ j)
-  {
-	  int idx = Random((int)mViewCells.size());
-	  Debug << "output view cell=" << idx << endl;
-	  pvsViewCells.push_back(mViewCells[Random((int)mViewCells.size())]);
-  }
-
-  vector<Ray> rays[10];
-  vector<Ray> vcRays[5];
-
   vector<Ray> viewCellRays; // used for BSP tree construction
- 
-  mSampleRays = new RayContainer();
-  //mSampleRays->reserve(mBspConstructionSamples);
 
   while (totalSamples < mTotalSamples) {
@@ -303,10 +283,11 @@
 		int passSamples = 0;
 		int index = 0;
-			
-		cout << "totalSamples: "  << totalSamples;
+		Real maxTime = 0;
+		int maxTimeIdx = 0;
+
+		cout << "totalSamples: "  << totalSamples << endl;
+
 		for (i = 0; i < objects.size(); i++) {
-			
-			Debug << "\nsampling object " << i << " of " << (int)objects.size() << " sample " << passSamples << endl;
-
+						
 			KdNode *nodeToSample = NULL;
 			Intersectable *object = objects[i];
@@ -369,8 +350,9 @@
 			
 			object->GetRandomSurfacePoint(point, normal);
+			
+			long samplesPerObjStart = GetTime();
+
 			bool viewcellSample = true;
 			int sampleContributions;
-			
-			long startTime = GetTime();
 
 			if (viewcellSample) {
@@ -400,5 +382,10 @@
 					sampleContributions = CastRay(object, ray);
 
-					// CORR matt: put inside loop
+					//-- CORR matt: put block inside loop
+					if (sampleContributions) {
+						passContributingSamples++;
+						passSampleContributions += sampleContributions;
+					}
+
 					if ( i < pvsOut )
 						rays[i].push_back(ray);
@@ -412,24 +399,24 @@
 						}
 					}
+					//-------------------
 
 					if (mViewCellsType == BSP_VIEW_CELLS) 
 					{
-						// save rays for bsp tree construction
+                        // save rays for bsp tree construction
 						if ((BspTree::sConstructionMethod = BspTree::FROM_RAYS) &&
 							(totalSamples < mBspConstructionSamples))
 						{
-							//cout << "pushing back sampling ray << " << mSampleRays->size() << endl;
-							mSampleRays->push_back(new Ray(ray));
+							//cout << "pushing back sampling ray << " << mSampleRays.size() << endl;
+							mSampleRays.push_back(new Ray(ray));
 						}
 						else
 						{
-							// construct BSP tree using the samples
+                            // construct BSP tree using the samples
 							if (!mBspTree)
 							{
-								Debug << "Building bsp tree" << endl;
 								BuildBspTree();
 
-								CLEAR_CONTAINER (*mSampleRays);
-								DEL_PTR (mSampleRays);
+								BspTreeStatistics(Debug);	
+								Export("vc_bsptree.x3d", false, false, true);
 							}
 							// check whether we can add this to the rays
@@ -440,4 +427,16 @@
 										vcRays[j].push_back(ray);
 									}
+							// some random view cells for output
+							if (pvsViewCells.empty())
+							{
+								int vcPvsOut = Min((int)mViewCells.size(), 5);
+							
+								for (int j = 0; j < vcPvsOut; ++ j)
+								{
+									int idx = Random((int)mViewCells.size());
+									Debug << "output view cell=" << idx << endl;
+									pvsViewCells.push_back(mViewCells[Random((int)mViewCells.size())]);
+								}
+							}
 						}				
 					}
@@ -449,22 +448,23 @@
 				//				object->GetRandomVisibleMesh(Plane3(normal, point));
 			}
-			long t = TimeDiff(startTime, GetTime());
-			Debug << "pass time: " << t << endl;
-		
+				
+			// measure maximal time for samples per object
+			Real t = TimeDiff(samplesPerObjStart, GetTime());
+
+			if (t > maxTime)
+			{
+				maxTime = t;
+				maxTimeIdx = i;
+			}
+	
+			// CORR matt: must add all samples
 			passSamples += mSamplesPerPass;
-		
-			if (sampleContributions) {
-				passContributingSamples++;
-				passSampleContributions += sampleContributions;
-			}
 		}
 	
-		// CORR matt: must add pass samples
-		totalSamples += passSamples; // totalSamples ++;
+		totalSamples += passSamples; 
 		
 		//    if (pass>10)
 		//      HoleSamplingPass();
     
-		
 		mPass++;
 
@@ -483,13 +483,15 @@
 		}
 
-		cout << "#Pass " << mPass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+		Debug << "maximal time needed for pass: " << maxTime << " (object " << maxTimeIdx << ")" << endl;
+
+		float avgRayContrib = (passContributingSamples > 0) ? 
+			passSampleContributions/(float)passContributingSamples : 0;
+
+		cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
 		cout << "#TotalSamples=" << totalSamples/1000 
 				 << "k   #SampleContributions=" << passSampleContributions << " (" 
 				 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
 				 << pvsSize/(float)objects.size() << endl 
-				 << "avg ray contrib=" << 
-				 ((passContributingSamples > 0) ? passSampleContributions/(float)passContributingSamples : 0)
-				 << endl;
-		
+				 << "avg ray contrib=" << avgRayContrib << endl;
 		
 		mStats <<
@@ -500,7 +502,5 @@
 			"#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
 			"#AvgPVS\n"<< pvsSize/(float)objects.size() << endl <<
-			"#AvgRayContrib\n" << 
-			((passContributingSamples > 0) ? passSampleContributions/(float)passContributingSamples : 0)
-			<< endl;
+			"#AvgRayContrib\n" << avgRayContrib << endl;
 	}
 
@@ -509,5 +509,5 @@
   
   //  HoleSamplingPass();
-  if (1) {
+  if (0) {
     Exporter *exporter = Exporter::GetExporter("ray-density.x3d");
     exporter->SetExportRayDensity(true);
@@ -534,70 +534,108 @@
     delete exporter;
   }
+  
   if (1) {
   if (mViewCellsType == BSP_VIEW_CELLS)
   {
+	  bool exportSplits = false;
+	  environment->GetBoolValue("BspTree.exportSplits", exportSplits);
+
+	  // export the bsp splits
+	  if (exportSplits)
+	  {
+		  Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
+
+		  if (exporter) 
+		  {	
+			  Material m; 
+			  m.mDiffuseColor = RgbColor(1, 0, 0);
+			  exporter->SetForcedMaterial(m);
+			  exporter->SetWireframe();
+			  exporter->ExportBspSplits(*mBspTree);
+
+			  // take forced material, else big scenes cannot be viewed
+			  m.mDiffuseColor = RgbColor(0, 1, 0);
+			  exporter->SetForcedMaterial(m);
+			  exporter->SetFilled();
+
+			  exporter->ResetForcedMaterial();
+
+			  if (1)
+			  {
+				  Material m;//= RandomMaterial();
+				  m.mDiffuseColor = RgbColor(0, 0, 1);
+				  exporter->SetForcedMaterial(m);
+                 
+				  for (int j = 0; j < objects.size(); ++ j)
+					   exporter->ExportIntersectable(objects[j]);
+			
+				  delete exporter;
+			  }
+		  }
+	  }
+
 	  for (int j = 0; j < pvsViewCells.size(); ++ j)
-		{
-			ViewCell *vc = pvsViewCells[j];
-
-			Intersectable::NewMail();
-
-			char s[64]; sprintf(s, "bsp-pvs%04d.x3d", j);
-			Exporter *exporter = Exporter::GetExporter(s);
-			exporter->SetFilled();
-
-			ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
-
-			Material m;//= RandomMaterial();
-			m.mDiffuseColor = RgbColor(0, 1, 0);
-			exporter->SetForcedMaterial(m);
-
-			exporter->ExportViewCell(vc);
-
-			Debug << "pvs size: " << (int)vc->GetPvs().GetSize() << " of " << (int)objects.size();
-			Debug << " exporting rays: " << (int)vcRays[j].size() << endl;
-
-			exporter->SetWireframe();
-
-			// export view cells
-			m.mDiffuseColor = RgbColor(1, 0, 1);
-			exporter->SetForcedMaterial(m);
-			exporter->ExportViewCells(mViewCells);
+	  {
+		  ViewCell *vc = pvsViewCells[j];
+
+		  Intersectable::NewMail();
+		  char s[64]; sprintf(s, "bsp-pvs%04d.x3d", j);
+
+		  Exporter *exporter = Exporter::GetExporter(s);
+		  exporter->SetFilled();
+
+		  ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
+
+		  Material m;//= RandomMaterial();
+		  m.mDiffuseColor = RgbColor(0, 1, 0);
+		  exporter->SetForcedMaterial(m);
+
+		  exporter->ExportViewCell(vc);
+
+		  Debug << j << ": pvs size=" << (int)vc->GetPvs().GetSize() 
+			    << ", piercing rays=" << (int)vcRays[j].size() << endl;
+
+		  exporter->SetWireframe();
+
+		  // export view cells
+		  m.mDiffuseColor = RgbColor(1, 0, 1);
+		  exporter->SetForcedMaterial(m);
+		  exporter->ExportViewCells(mViewCells);
 			
-			// export rays piercing this view cell
-			exporter->ExportRays(vcRays[j], 1000, RgbColor(0, 1, 0));
-
-			m.mDiffuseColor = RgbColor(1, 0, 0);
-			exporter->SetForcedMaterial(m);
-
-			// output pvs of view cell
-			for (; it != vc->GetPvs().mEntries.end(); ++ it) 
-			{
-				Intersectable *intersect = (*it).first;
-				if (!intersect->Mailed())
-				{
-					exporter->ExportIntersectable(intersect);
-					intersect->Mail();
-				}			
-			}
-
-			// output rest of the objects
-			if (1)
-			{
-				Material m;//= RandomMaterial();
-				m.mDiffuseColor = RgbColor(0, 0, 1);
-				exporter->SetForcedMaterial(m);
-                
-				for (int j = 0; j < objects.size(); ++ j)
-					if (!objects[j]->Mailed())
-					{
-						//if (j == 2198)m.mDiffuseColor = RgbColor(1, 0, 1);
-						//else m.mDiffuseColor = RgbColor(1, 1, 0);
-						exporter->SetForcedMaterial(m);
-						exporter->ExportIntersectable(objects[j]);
-						objects[j]->Mail();
-					}
-			}
-			DEL_PTR(exporter);
+		  // export rays piercing this view cell
+		  exporter->ExportRays(vcRays[j], 1000, RgbColor(0, 1, 0));
+
+		  m.mDiffuseColor = RgbColor(1, 0, 0);
+		  exporter->SetForcedMaterial(m);
+
+		  // output pvs of view cell
+		  for (; it != vc->GetPvs().mEntries.end(); ++ it) 
+		  {
+			  Intersectable *intersect = (*it).first;
+			  if (!intersect->Mailed())
+			  {
+				  exporter->ExportIntersectable(intersect);
+				  intersect->Mail();
+			  }			
+		  }
+		
+		  // output rest of the objects
+		  if (1)
+		  {
+			  Material m;//= RandomMaterial();
+			  m.mDiffuseColor = RgbColor(0, 0, 1);
+			  exporter->SetForcedMaterial(m);
+
+			  for (int j = 0; j < objects.size(); ++ j)
+				  if (!objects[j]->Mailed())
+				  {
+					  //if (j == 2198)m.mDiffuseColor = RgbColor(1, 0, 1);
+					  //else m.mDiffuseColor = RgbColor(1, 1, 0);
+					  exporter->SetForcedMaterial(m);
+					  exporter->ExportIntersectable(objects[j]);
+					  objects[j]->Mail();
+				  }
+		  }
+		  DEL_PTR(exporter);
 		}
   }  
