Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 490)
@@ -19,4 +19,6 @@
 
 Preprocessor {
+	# stored sample rays
+	samplesFilename rays.out
 #	type sampling
 	type vss
@@ -26,8 +28,10 @@
 VssPreprocessor {
 	samplesPerPass  100000
-	initialSamples 500000
+	initialSamples 5000000
 	vssSamples 200000
 	vssSamplesPerPass 100000
 	useImportanceSampling true
+	loadInitialSamples  false
+	storeInitialSamples true
 }
 
@@ -68,4 +72,6 @@
 	vssSamplesPerPass 100000
 	useImportanceSampling true
+	loadInitialSamples true
+	storeInitialSamples false
 }
 
@@ -143,5 +149,4 @@
 }
 
-
 ViewCells {
 	loadFromFile false
@@ -155,5 +160,5 @@
 	height 5.0
 	maxViewCells 100
-	maxPvs 130
+	maxPvs 90
 	
 	
@@ -167,6 +172,6 @@
 
 	Visualization {
-		# how much samples are be used for visualization
-		samples 1000
+		# how much samples we use for visualization
+		samples 5000
 		#colorCode PVS
 		#colorCode MergedLeaves
@@ -233,5 +238,5 @@
 		samples 300000
 		epsilon 0.005
-		randomize true
+		randomize false
 	}
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 469)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 490)
@@ -66,4 +66,5 @@
   , mCharacterCount(0)
   , mSpaceCount(0)
+ // , mCurrentObjectId(0)
 {
   mCurrentNode = root;
@@ -94,4 +95,6 @@
     MeshInstance *mi = new MeshInstance(mCurrentMesh);
     mCurrentNode->mGeometry.push_back(mi);
+	// set the object id to a unique value
+	//mi->SetId(mCurrentObjectId ++);
   } else {
     cout<<"X";
@@ -386,11 +389,11 @@
 // ---------------------------------------------------------------------------
 X3dViewCellsParseHandlers::X3dViewCellsParseHandlers(ViewCellsManager *viewCellsManager, 
-													 float viewCellHeight) :
-  mElementCount(0)
-  , mAttrCount(0)
-  , mCharacterCount(0)
-  , mSpaceCount(0)
-  , mViewCellsManager(viewCellsManager)
-  , mViewCellHeight(viewCellHeight)
+													 float viewCellHeight):
+mElementCount(0), 
+mAttrCount(0), 
+mCharacterCount(0), 
+mSpaceCount(0), 
+mViewCellsManager(viewCellsManager), 
+mViewCellHeight(viewCellHeight)
 {
 }
@@ -512,5 +515,7 @@
 
 		// create view cell from base triangle
-		mViewCellsManager->AddViewCell(mViewCellsManager->ExtrudeViewCell(baseTri, mViewCellHeight));
+		mViewCellsManager->AddViewCell(
+			mViewCellsManager->ExtrudeViewCell(baseTri, 
+			mViewCellHeight));
 	}
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 487)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 490)
@@ -127,4 +127,6 @@
 	/// largest pvs
 	int maxPvs;
+	/// number of invalid leaves
+	int invalidLeaves;
 
 	// Constructor
@@ -162,4 +164,5 @@
 
 		maxPvs = 0;
+		invalidLeaves = 0;
 	}
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 490)
@@ -221,4 +221,8 @@
 	virtual bool GetViewPoint(Vector3 &viewPoint) const;
 
+	/** Returns true if this view point is in the valid view space.
+	*/
+	virtual bool ViewPointValid(const Vector3 &viewPoint) const;
+
 	/** Sets a view space boundary.
 	*/
@@ -517,4 +521,6 @@
 	bool GetViewPoint(Vector3 &viewPoint) const;
 
+	bool ViewPointValid(const Vector3 &viewPoint) const;
+
 protected:
 	/** DEPRECATED
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 490)
@@ -420,4 +420,5 @@
 			// view cell for invalid view space
 			viewCell = GetOrCreateOutOfBoundsCell();
+			++ mStat.invalidLeaves;
 		}
 		else
@@ -1225,12 +1226,12 @@
 		nodeStack.pop();
 		
-		// this subtree is not valid view space
-		if (!node->TreeValid())
-			continue;
-
 		if (node->IsLeaf())
 		{
-			BspLeaf *leaf = (BspLeaf *)node;
-			leaves.push_back(leaf);
+			// test if this leaf is in valid view space
+			if (node->TreeValid())
+			{
+				BspLeaf *leaf = (BspLeaf *)node;
+				leaves.push_back(leaf);
+			}
 		}
 		else
@@ -1428,13 +1429,9 @@
 		BspNode *node = nodeStack.top();
 		nodeStack.pop();
-		// this subtree is not valid view space
-		if (!node->TreeValid())
-			continue;
 
 		if (node->IsLeaf())
 		{
 			ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell();
-
-			if (!viewCell->Mailed())
+			if (node->TreeValid() && !viewCell->Mailed())
 			{
 				viewCell->Mail();
@@ -1667,11 +1664,9 @@
 		nodeStack.pop();
 
-		// view space not valid
-		if (!node->TreeValid())
-			continue;
-
 		if (node->IsLeaf())
-		{
-            if (node != n && (!onlyUnmailed || !node->Mailed()))
+		{	// test if this leaf is in valid view space
+            if (node->TreeValid() &&
+				node != n && 
+				(!onlyUnmailed || !node->Mailed()))
 			{
 				// test all planes of current node if candidate really
@@ -2344,7 +2339,6 @@
 	startTime = GetTime();
 
-	int nViewCells = /*mergeStats.nodes*/ mStat.Leaves();
-
-	
+	int nViewCells = /*mergeStats.nodes*/ mStat.Leaves() - mStat.invalidLeaves;
+
 	//-- use priority queue to merge leaf pairs
 	while (!mMergeQueue.empty() && (nViewCells > mMergeMinViewCells) &&
@@ -2569,7 +2563,6 @@
 			
 		BspInterior *in = dynamic_cast<BspInterior *>(node);
-		Plane3 splitPlane = in->GetPlane();
-			
-		if (splitPlane.Side(viewPoint) <= 0) 
+					
+		if (in->GetPlane().Side(viewPoint) <= 0) 
 		{
 			node = in->GetBack();
@@ -2594,5 +2587,5 @@
 void VspBspTree::PropagateUpValidity(BspNode *node)
 {
-	while (!node->IsRoot() && node->TreeValid())
+	while (!node->IsRoot() && node->GetParent()->TreeValid())
 	{
 		node = node->GetParent();
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 490)
@@ -1176,4 +1176,14 @@
 	  "true");
 
+   RegisterOption("VssPreprocessor.loadInitialSamples",
+	  optBool,
+	  "-vss_load_loadInitialSamples=",
+	  "false");
+
+   RegisterOption("VssPreprocessor.storeInitialSamples",
+	  optBool,
+	  "-vss_store_storedInitialSamples=",
+	  "false");
+   
 
   /************************************************************************************/
@@ -1411,4 +1421,8 @@
 				 "sampling");
 
+   RegisterOption("Preprocessor.samplesFilename",
+				  optString,
+				  "-preprocessor_samples_filename=",
+				  "rays.out");
 
    /**************************************************************************************/
@@ -1628,4 +1642,13 @@
 	RegisterOption("RssPreprocessor.updateSubdivision", optBool, "rss_update_subdivision", "false");
 
+	RegisterOption("RssPreprocessor.loadInitialSamples",
+	  optBool,
+	  "-vss_load_loadInitialSamples=",
+	  "false");
+
+	RegisterOption("RssPreprocessor.storeInitialSamples",
+	  optBool,
+	  "-vss_store_storeInitialSamples=",
+	  "false");
 
 	/************************************************************************************/
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h	(revision 486)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h	(revision 490)
@@ -134,5 +134,4 @@
 
   virtual void ExportViewpoint(const Vector3 &point, const Vector3 &direction) = 0;
-
 };
  
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 490)
@@ -413,5 +413,7 @@
 	app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl;
 
-	app << "#N_INPUT_POLYGONS (number of input polygons )\n" <<	polys << endl;
+	app << "#N_INPUTPOLYGONS (number of input polygons )\n" << polys << endl;
+
+	app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl;
 
 	//app << "#N_PVS: " << pvs << endl;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp	(revision 387)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp	(revision 490)
@@ -29,4 +29,5 @@
 SceneGraph::CollectObjects(ObjectContainer *instances)
 {
+	instances->clear();
   int number = 0;
   stack<SceneGraphNode *> nodeStack;
@@ -40,6 +41,6 @@
     ObjectContainer::const_iterator mi = node->mGeometry.begin();
     for (; mi != node->mGeometry.end(); mi++)
-      instances->push_back(*mi);
-    
+	  instances->push_back(*mi);
+	
     SceneGraphNodeContainer::iterator ni = node->mChildren.begin();
     for (; ni != node->mChildren.end(); ni++) {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 480)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 490)
@@ -238,8 +238,5 @@
 	mViewCellsManager->SetRenderer(mRenderSimulator);
 
-	//Debug << "Visualization samples: " << mViewCellsManager->GetVisualizationSamples() << endl;
-
 	//-- parse view cells construction method
-
 	bool loadViewCells = false;
 	environment->GetBoolValue("ViewCells.loadFromFile", loadViewCells);
@@ -256,2 +253,74 @@
 	return true;
 }
+
+
+inline bool ilt(Intersectable *obj1, Intersectable *obj2)
+{
+	return obj1->mId < obj2->mId;
+}
+
+
+bool Preprocessor::LoadSamples(VssRayContainer &samples, 
+							   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
+	MeshInstance object(NULL);
+	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", 
+			   &origin.x, &origin.y, &origin.z,
+			   &termination.x, &termination.y, &termination.z, &(object.mId));
+		
+		if (1)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &object, ilt);
+
+			samples.push_back(new VssRay(origin, termination, NULL, *oit));
+		}
+		else
+		{
+			samples.push_back(new VssRay(origin, termination, NULL, objects[object.mId]));
+		}
+	}
+	
+	samplesIn.close();
+
+	return true;
+}
+
+bool Preprocessor::WriteSamples(const VssRayContainer &samples) const
+{
+	char buf[100];
+	environment->GetStringValue("Preprocessor.samplesFilename", buf);
+	ofstream samplesOut(buf);
+
+	VssRayContainer::const_iterator it, it_end = samples.end();
+	
+	if (!samplesOut.is_open())
+		return false;
+
+	for (it = samples.begin(); it != it_end; ++ it)
+	{
+		VssRay *ray = *it;
+	
+		samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " " 
+				   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " " 
+				   << ray->mTerminationObject->mId << "\n";
+	}
+	samplesOut.close();
+
+	return true;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp	(revision 487)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp	(revision 490)
@@ -27,5 +27,4 @@
   environment->GetIntValue("RssPreprocessor.vssSamplesPerPass", mRssSamplesPerPass);
   environment->GetBoolValue("RssPreprocessor.useImportanceSampling", mUseImportanceSampling);
-  environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
 
   environment->GetBoolValue("RssPreprocessor.Export.pvs", mExportPvs);
@@ -34,6 +33,8 @@
   environment->GetIntValue("RssPreprocessor.Export.numRays", mExportNumRays);
   environment->GetBoolValue("RssPreprocessor.useViewcells", mUseViewcells);
-
-  environment->GetBoolValue("RssPreprocessor.updateSubdivision", mUpdateSubdivision);
+  environment->GetBoolValue("RssPreprocessor.useViewcells", mUseViewcells);
+
+  environment->GetBoolValue("RssPreprocessor.loadInitialSamples", mLoadInitialSamples);
+  environment->GetBoolValue("RssPreprocessor.storeInitialSamples", mStoreInitialSamples);
   
   mStats.open("stats.log");
@@ -443,55 +444,65 @@
   RssTree *rssTree = NULL;
 
-  while (totalSamples < mInitialSamples) {
-	int passContributingSamples = 0;
-	int passSampleContributions = 0;
-	int passSamples = 0;
-	int index = 0;
-		
-	int sampleContributions;
-		
-	int s = Min(mSamplesPerPass, mInitialSamples);
-	for (int k=0; k < s; k++) {
+  if (mLoadInitialSamples)
+  {
+	  cout << "Loading samples from file ... ";
+	  LoadSamples(mVssRays, mObjects);
+	  cout << "finished\n" << endl;
+  }
+  else
+  {
+	while (totalSamples < mInitialSamples) {
+		int passContributingSamples = 0;
+		int passSampleContributions = 0;
+		int passSamples = 0;
+		int index = 0;
 			
-	  //Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
-	  Vector3 viewpoint; 
-	  mViewCellsManager->GetViewPoint(viewpoint);
-	  Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
+		int sampleContributions;
 			
-	  sampleContributions = CastRay(viewpoint, direction, mVssRays);
+		int s = Min(mSamplesPerPass, mInitialSamples);
+		for (int k=0; k < s; k++) {
+				
+		//Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
+		Vector3 viewpoint; 
+		mViewCellsManager->GetViewPoint(viewpoint);
+		Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
+				
+		sampleContributions = CastRay(viewpoint, direction, mVssRays);
+				
+				
+		//-- CORR matt: put block inside loop
+		if (sampleContributions) {
+			passContributingSamples ++;
+			passSampleContributions += sampleContributions;
+		}
+		passSamples++;
+		totalSamples++;
+		}
+	    
 			
+		float avgRayContrib = (passContributingSamples > 0) ? 
+		passSampleContributions/(float)passContributingSamples : 0;
 			
-	  //-- CORR matt: put block inside loop
-	  if (sampleContributions) {
-		passContributingSamples ++;
-		passSampleContributions += sampleContributions;
-	  }
-	  passSamples++;
-	  totalSamples++;
-	}
-    
-		
-	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<<"%)" 
-		 << "avgcontrib=" << avgRayContrib << endl;
-		
-	mStats <<
-	  "#Pass\n" <<mPass<<endl<<
-	  "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
-	  "#TotalSamples\n" << totalSamples<< endl<<
-	  "#SampleContributions\n" << passSampleContributions << endl << 
-	  "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
-	  "#AvgRayContrib\n" << avgRayContrib << endl;
-	
-	mPass++;
-
-  }
-  
-  cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
+		cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+		cout << "#TotalSamples=" << totalSamples/1000 
+			<< "k   #SampleContributions=" << passSampleContributions << " (" 
+			<< 100*passContributingSamples/(float)passSamples<<"%)" 
+			<< "avgcontrib=" << avgRayContrib << endl;
+			
+		mStats <<
+		"#Pass\n" <<mPass<<endl<<
+		"#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
+		"#TotalSamples\n" << totalSamples<< endl<<
+		"#SampleContributions\n" << passSampleContributions << endl << 
+		"#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
+		"#AvgRayContrib\n" << avgRayContrib << endl;
+		
+		mPass++;
+
+	}
+  
+	cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
+  }
+
   cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl <<flush;
   
@@ -503,4 +514,11 @@
   }
   
+  if (mStoreInitialSamples)
+  {
+	  cout << "Writing samples to file ... ";
+	  WriteSamples(mVssRays);
+	  cout << "finished\n" << endl;
+  }
+
   if (mUseViewcells) {
 	// construct view cells
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 490)
@@ -26,5 +26,7 @@
   environment->GetIntValue("VssPreprocessor.vssSamplesPerPass", mVssSamplesPerPass);
   environment->GetBoolValue("VssPreprocessor.useImportanceSampling", mUseImportanceSampling);
-  environment->GetIntValue("BspTree.Construction.samples", mBspConstructionSamples);
+
+  environment->GetBoolValue("VssPreprocessor.loadInitialSamples", mLoadInitialSamples);
+  environment->GetBoolValue("VssPreprocessor.storeInitialSamples", mStoreInitialSamples);
 
   mStats.open("stats.log");
@@ -91,5 +93,4 @@
 	SetupRay(ray, viewPoint, -direction);
 
-
   if (mKdTree->CastRay(ray)) {
 
@@ -389,61 +390,83 @@
   VssTree *vssTree = NULL;
 
-  while (totalSamples < mInitialSamples) {
-	int passContributingSamples = 0;
-	int passSampleContributions = 0;
-	int passSamples = 0;
-	int index = 0;
-
-	int sampleContributions;
-
-	int s = Min(mSamplesPerPass, mInitialSamples);
-	for (int k=0; k < s; k++) {
-      // changed by matt
-	  //Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
-	  Vector3 viewpoint; 
-	  mViewCellsManager->GetViewPoint(viewpoint);
-	  Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
-
-	  sampleContributions = CastRay(viewpoint, direction, mVssRays);
-
-
-	  //-- CORR matt: put block inside loop
-	  if (sampleContributions) {
-		passContributingSamples ++;
-		passSampleContributions += sampleContributions;
+  mSceneGraph->CollectObjects(&mObjects);
+
+  long initialTime = GetTime();
+
+  if (mLoadInitialSamples)
+  {
+	  cout << "Loading samples from file ... ";
+	  LoadSamples(mVssRays, mObjects);
+	  cout << "finished\n" << endl;
+	  totalSamples = (int)mVssRays.size();
+  }
+  else
+  {
+	  while (totalSamples < mInitialSamples) {
+		int passContributingSamples = 0;
+		int passSampleContributions = 0;
+		int passSamples = 0;
+
+		int index = 0;
+
+		int sampleContributions;
+
+		int s = Min(mSamplesPerPass, mInitialSamples);
+		for (int k=0; k < s; k++) {
+			// changed by matt
+			//Vector3 viewpoint = GetViewpoint(mViewSpaceBox);
+			Vector3 viewpoint; 
+			mViewCellsManager->GetViewPoint(viewpoint);
+			Vector3 direction = GetDirection(viewpoint, mViewSpaceBox);
+	        
+			sampleContributions = CastRay(viewpoint, direction, mVssRays);
+
+			if (sampleContributions) {
+				passContributingSamples ++;
+				passSampleContributions += sampleContributions;
+			}
+			passSamples++;
+			totalSamples++;
+		}
+
+		mPass++;
+		int pvsSize = 0;
+		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)mObjects.size() << endl
+			<< "avg ray contrib=" << avgRayContrib << endl;
+
+		mStats <<
+			"#Pass\n" <<mPass<<endl<<
+			"#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
+			"#TotalSamples\n" << totalSamples<< endl<<
+			"#SampleContributions\n" << passSampleContributions << endl <<
+			"#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
+			"#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
+			"#AvgRayContrib\n" << avgRayContrib << endl;
 	  }
-	  passSamples++;
-	  totalSamples++;
-	}
-
-	mPass++;
-
-	int pvsSize = 0;
-	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)mObjects.size() << endl
-		 << "avg ray contrib=" << avgRayContrib << endl;
-
-	mStats <<
-	  "#Pass\n" <<mPass<<endl<<
-	  "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
-	  "#TotalSamples\n" << totalSamples<< endl<<
-	  "#SampleContributions\n" << passSampleContributions << endl <<
-	  "#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
-	  "#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
-	  "#AvgRayContrib\n" << avgRayContrib << endl;
-
-
-
-
-  }
-
-  cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
-  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl <<flush;
+ 
+	  cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
+  }
+  
+  cout << "#totalRayStackSize=" << (int)mVssRays.size() << endl << flush;
+  Debug << (int)mVssRays.size() << " rays generated in " 
+	    << TimeDiff(initialTime, GetTime()) * 1e-3 << " seconds" << endl;
+
+  if (mStoreInitialSamples)
+  {
+	  cout << "Writing " << (int)mVssRays.size() << " samples to file ... ";
+	  WriteSamples(mVssRays);
+	  cout << "finished\n" << endl;
+  }
+
+  //VssRayContainer dummyRays;
+  //LoadSamples(dummyRays, mObjects);
+  //Debug << "rays " << (int)mVssRays.size() << " " << dummyRays.size() << endl;
 
   //int numExportRays = 10000;
@@ -455,6 +478,4 @@
 	ExportRays(filename, mVssRays, numExportRays);
   }
-
-  mSceneGraph->CollectObjects(&mObjects);
 
   // construct view cells
@@ -563,5 +584,5 @@
 										 mViewCellsManager->GetVisualizationSamples()));
 
-	//-- post process view cells
+    //-- post process view cells
 	mViewCellsManager->PostProcess(mObjects, storedRays);
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 468)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 490)
@@ -16,4 +16,6 @@
 class VspBspTree;
 class RenderSimulator;
+struct VssRayContainer;
+
 
 /** Namespace for the external visibility preprocessor
@@ -78,4 +80,16 @@
   virtual void BspTreeStatistics(ostream &s);
 
+  /** Loads samples from file.
+	  @param samples returns the stored sample rays
+	  @param objects needed to associate the objects ids
+	  @returns true if samples were loaded successfully
+  */
+  bool LoadSamples(VssRayContainer &samples,
+				   ObjectContainer &objects) const;
+
+  /** Exports samples to file.
+	  @returns true if samples were written successfully
+  */
+  bool WriteSamples(const VssRayContainer &samples) const;
   /// scene graph loaded from file
   SceneGraph *mSceneGraph;
@@ -104,13 +118,4 @@
   */
   RenderSimulator *mRenderSimulator;
-
-protected:
-
-  /////////////////////////
-
-  /// samples used for construction of the BSP view cells tree.
-  int mBspConstructionSamples;
-   /// samples used for construction of the VSP KD tree.
-  int mVspKdConstructionSamples;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h	(revision 439)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h	(revision 490)
@@ -14,5 +14,6 @@
   bool ParseFile(const string filename, SceneGraphNode **root);
   bool ParseFile(const string filename, ViewCellsManager &viewCells);
-
+  
+  /// height of a loaded view cell
   float mViewCellHeight;
 };
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.h	(revision 487)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.h	(revision 490)
@@ -39,4 +39,9 @@
   VssRayContainer mVssRays;
 	
+   /// if initial samples should be loaded from file
+  bool mLoadInitialSamples;
+  /// if initial samples should be stored in file
+  bool mStoreInitialSamples;
+
   RssPreprocessor();
   ~RssPreprocessor();
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h	(revision 487)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.h	(revision 490)
@@ -27,4 +27,9 @@
 	
   ObjectContainer mObjects;
+
+  /// if initial samples should be loaded from file
+  bool mLoadInitialSamples;
+  /// if initial samples should be stored in file
+  bool mStoreInitialSamples;
 
   // rays cast during the processing
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 489)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 490)
@@ -45,6 +45,4 @@
 	environment->GetBoolValue("ViewCells.Visualization.exportGeometry", mExportGeometry);
 
-	//Debug << "export rays: " << mExportRays << endl;
-	//Debug << "export geometry: " << mExportGeometry << endl;
 	char buf[50];
 	
@@ -92,4 +90,9 @@
 }
 
+
+bool ViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
+{
+	return mSceneBox.IsInside(viewPoint);
+}
 
 void ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays)
@@ -1717,8 +1720,10 @@
 
 	mVspBspTree->Construct(constructionRays, &mSceneBox);
-
+	
 	Debug << mVspBspTree->GetStatistics() << endl;
+	// collapse invalid regions
+	mVspBspTree->CollapseTree(mVspBspTree->GetRoot()); 
 	ResetViewCells();
-
+	
 	Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
 	
@@ -1812,4 +1817,9 @@
 			ExportViewCells(exporter);
 
+			if (mExportRays)
+			{
+				exporter->ExportRays(postProcessRays, RgbColor(1, 1, 0));
+			}
+
 			if (mExportGeometry)
 			{
@@ -1900,7 +1910,36 @@
 }
 
+
 int VspBspViewCellsManager::GetType() const
 {
 	return VSP_BSP;
+}
+
+
+bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
+{
+	if (!ViewCellsConstructed())
+		return ViewCellsManager::GetViewPoint(viewPoint);
+
+	// TODO: set reasonable limit
+	const int limit = 20;
+
+	for (int i = 0; i < limit; ++ i)
+	{
+		viewPoint = mSceneBox.GetRandomPoint();
+		if (mVspBspTree->ViewPointValid(viewPoint))
+		{
+			return true;
+		}
+	}
+	Debug << "failed to find valid view point, taking " << viewPoint << endl;
+	return false;
+}
+
+
+bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
+{
+	return mSceneBox.IsInside(viewPoint) && 
+		   mVspBspTree->ViewPointValid(viewPoint);
 }
 
@@ -1913,5 +1952,4 @@
 
 	VssRayContainer visRays;
-	
 	GetRaySets(sampleRays, mVisualizationSamples, visRays);
 
@@ -1927,10 +1965,9 @@
 
 			// export rays
-			/*if (mExportRays)
+			if (mExportRays)
 			{
-				exporter->SetWireframe();
-				exporter->ExportRays(visRays, RgbColor(1, 1, 0));
-				exporter->SetFilled();
-			}*/
+				exporter->ExportRays(visRays, RgbColor(0, 1, 0));
+			}
+
 			ExportViewCells(exporter);
 			delete exporter;
@@ -1943,6 +1980,5 @@
 	bool exportSplits = false;
 	environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits);
-	Debug << "export splits: " << exportSplits << endl;
-
+	
 	if (exportSplits)
 	{
@@ -1956,23 +1992,4 @@
 }
 	
-
-bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
-{
-	if (!ViewCellsConstructed())
-		return ViewCellsManager::GetViewPoint(viewPoint);
-
-	// TODO: set reasonable limit
-	const int limit = 10;
-cout << "===" << endl;
-	for (int i = 0; i < limit; ++ i)
-	{
-		cout << i << " " << endl;
-		viewPoint = mSceneBox.GetRandomPoint();
-		if (mVspBspTree->ViewPointValid(viewPoint))
-			return true;
-	}
-
-	return false;
-}
 
 void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParserXerces.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParserXerces.h	(revision 439)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParserXerces.h	(revision 490)
@@ -64,5 +64,6 @@
   Mesh *mCurrentMesh;
   Material *mCurrentMaterial;
-  
+  //int mCurrentObjectId;
+
   // Handlers for X3D
   void
