Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1737)
@@ -64,8 +64,10 @@
 	struct PvsStatistics 
 	{
-		float minPvs;
-		float maxPvs;
-		float avgPvs;
-		int viewcells;
+	  float minPvs;
+	  float maxPvs;
+	  float avgPvs;
+	  float avgFilteredPvs;
+	  float avgFilterContribution;
+	  int viewcells;
 	};
 
@@ -136,4 +138,7 @@
 	virtual void Visualize(const ObjectContainer &objects,
 						   const VssRayContainer &sampleRays) = 0;
+
+  /** collect objects intersecting a given spatial box */
+  virtual void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
 
 	/** type of the view cell container.
@@ -464,5 +469,5 @@
   void
   ApplyFilter2(ViewCell *viewCell,
-			   KdTree *kdTree,
+			   const bool useViewSpaceFilter,
 			   const float filterSize,
 			   ObjectPvs &pvs
@@ -1147,4 +1152,7 @@
 	/////////////////////////////////////////
 
+    /** collect objects intersecting a given spatial box */
+  virtual void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
+
 	HierarchyManager *mHierarchyManager;
 };
Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1737)
@@ -947,4 +947,5 @@
 }
 
+
 void
 QtGlRendererWidget::RenderPvs()
@@ -970,8 +971,17 @@
 
 	if (mUseSpatialFilter) {
+	  // 9.11. 2006 -> experiment with new spatial filter
+#if 0
 	  mViewCellsManager->ApplySpatialFilter(mKdTree,
 											mSpatialFilterSize*
 											Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
 											pvs);
+#else
+	  // mSpatialFilter size is in range 0.001 - 0.1
+	  mViewCellsManager->ApplyFilter2(viewcell,
+									  mUseFilter,
+									  100*mSpatialFilterSize,
+									  pvs);
+#endif
 	}
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1723)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1737)
@@ -366,15 +366,15 @@
 
 void
-NormalizeRatios(float ratios[3])
+NormalizeRatios(float ratios[4])
 {
   int i;
   float sumRatios;
-  sumRatios = ratios[0] + ratios[1] + ratios[2];
+  sumRatios = ratios[0] + ratios[1] + ratios[2] + ratios[3];
   if (sumRatios == 0.0f) {
 	ratios[0] = ratios[1] = ratios[2] = 1.0f;
-	sumRatios = 3.0f;
-  }
-  
-  for (i=0 ; i < 3; i++)
+	sumRatios = 4.0f;
+  }
+  
+  for (i=0 ; i < 4; i++)
 	ratios[i]/=sumRatios;
 
@@ -387,10 +387,10 @@
 #endif
   
-  for (; i < 3; i++)
+  for (; i < 4; i++)
 	if (ratios[i] < MIN_RATIO)
 	  ratios[i] = MIN_RATIO;
 
-  sumRatios = ratios[0] + ratios[1] + ratios[2];
-  for (i=0 ; i < 3; i++)
+  sumRatios = ratios[0] + ratios[1] + ratios[2] + ratios[3];
+  for (i=0 ; i < 4; i++)
 	ratios[i]/=sumRatios;
   
@@ -432,4 +432,9 @@
   int rssPass = 0;
   int rssSamples = 0;
+
+  mDistributions.push_back(SamplingDistribution(SamplingStrategy::RSS_BASED_DISTRIBUTION));
+  mDistributions.push_back(SamplingDistribution(SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION));
+  mDistributions.push_back(SamplingDistribution(SamplingStrategy::DIRECTION_BASED_DISTRIBUTION));
+  mDistributions.push_back(SamplingDistribution(SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION));
   
   if (mLoadInitialSamples) {
@@ -439,14 +444,17 @@
   } else {
 	SimpleRayContainer rays;
-
+	
 	cout<<"Generating initial rays..."<<endl<<flush;
-
+	
 	if (mUseImportanceSampling) {
-	  GenerateRays(mInitialSamples/2, SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION, rays);
+	  GenerateRays(mInitialSamples/3, SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION, rays);
 	  //	  GenerateRays(mInitialSamples/3, SamplingStrategy::OBJECT_BASED_DISTRIBUTION, rays);
-	  GenerateRays(mInitialSamples/2, SamplingStrategy::DIRECTION_BASED_DISTRIBUTION, rays);
+	  GenerateRays(mInitialSamples/3, SamplingStrategy::DIRECTION_BASED_DISTRIBUTION, rays);
+	  GenerateRays(mInitialSamples/3, SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION, rays);
 	  //	GenerateRays(mInitialSamples/4, OBJECT_DIRECTION_BASED_DISTRIBUTION, rays);
+	  
+
 	} else {
-		int rayType = SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION;
+	  int rayType = SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION;
 	  if (mObjectBasedSampling)
 		rayType = SamplingStrategy::OBJECT_BASED_DISTRIBUTION;
@@ -578,17 +586,17 @@
 
 #if USE_RSS_TREE	
-	  static float ratios[] = {0.9f,0.05f,0.05f};
+	  static float ratios[] = {0.9f,0.05f,0.05f,0.05f};
 #else
-	  static float ratios[] = {0.0f,0.05f,0.05f};
+	  static float ratios[] = {0.0f,0.05f,0.05f,0.05f};
 #endif
 	  NormalizeRatios(ratios);
 	  	  
-	  cout<<"New ratios: "<<ratios[0]<<" "<<ratios[1]<<" "<<ratios[2]<<endl;
+	  cout<<"New ratios: "<<ratios[0]<<" "<<ratios[1]<<" "<<ratios[2]<<" "<<ratios[3]<<endl;
 
 	  //float ratios[] = {1.0f,0.0f,0.0f};
 	  
-	  int nrays[3];
-	  float contributions[3];
-	  float times[3];
+	  int nrays[4];
+	  float contributions[4];
+	  float times[4];
 	  
 	  long t1;
@@ -660,4 +668,26 @@
 	  }
 	  
+	  if (ratios[3]!=0.0f) {
+		t1 = GetTime();
+		GenerateRays(int(mRssSamplesPerPass*ratios[3]),
+					 SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION, rays);
+		CastRays(rays, tmpVssRays, true);
+		castRays += (int)rays.size();
+#if ADD_RAYS_IN_PLACE 
+		contributions[3] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
+#else
+		contributions[3] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
+#endif
+		times[3] = TimeDiff(t1, GetTime());
+		nrays[3] = (int)rays.size();
+		
+		mStats<<"#DirectionalRelContrib"<<endl<<contributions[3]/nrays[3]<<endl;
+		
+		vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
+		
+		rays.clear();
+		tmpVssRays.clear();
+	  }
+
 	  
 	  // now evaluate the ratios for the next pass
@@ -668,8 +698,11 @@
 	  ratios[1] = sqr(contributions[1]/(TIME_WEIGHT*times[1] + (1 - TIME_WEIGHT)*nrays[1]));
 	  ratios[2] = sqr(contributions[2]/(TIME_WEIGHT*times[2] + (1 - TIME_WEIGHT)*nrays[2]));
+	  ratios[3] = sqr(contributions[3]/(TIME_WEIGHT*times[3] + (1 - TIME_WEIGHT)*nrays[3]));
 #else
 	  ratios[0] = contributions[0]/(TIME_WEIGHT*times[0] + (1 - TIME_WEIGHT)*nrays[0]);
 	  ratios[1] = contributions[1]/(TIME_WEIGHT*times[1] + (1 - TIME_WEIGHT)*nrays[1]);
 	  ratios[2] = contributions[2]/(TIME_WEIGHT*times[2] + (1 - TIME_WEIGHT)*nrays[2]);
+	  ratios[3] = contributions[3]/(TIME_WEIGHT*times[3] + (1 - TIME_WEIGHT)*nrays[3]);
+	  
 #endif	  
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1737)
@@ -19,5 +19,5 @@
 #filename ../data/vienna/vienna.obj
 
-filename ../data/vienna/vienna-buildings_vienna-roofs_vienna-roads_vienna-plane_cropped.obj
+filename ../data/vienna/vienna_cropped.obj
 
 # filename ../data/vienna/viewcells-25-sel.x3d
@@ -51,6 +51,6 @@
 #	type render
 	detectEmptyViewSpace true
-	pvsRenderErrorSamples 0
-#	pvsRenderErrorSamples 5000
+#	pvsRenderErrorSamples 0
+	pvsRenderErrorSamples 1000
 	quitOnFinish true
 	computeVisibility true
@@ -84,5 +84,5 @@
 	vssSamples 50000000
 #	vssSamples 1000000
-	vssSamplesPerPass 2000000
+	vssSamplesPerPass 3000000
 	useImportanceSampling true
 
@@ -196,6 +196,6 @@
 	#type vspKdTree
 	#type bspTree
-	type vspBspTree
-	#type vspOspTree
+	#type vspBspTree
+	type vspOspTree
 	#type sceneDependent
 	
@@ -289,5 +289,7 @@
 #	filename ../data/vienna/vsposp-seq-viewCells.xml.gz
 
-	filename ../data/vienna/vienna_cropped-2-sequential-30000-viewcells.xml.gz
+	filename ../data/vienna/vienna_cropped-gradient-2-viewcells.xml.gz
+
+#	filename ../data/vienna/vienna_cropped-2-sequential-30000-viewcells.xml.gz
 #	filename ../data/vienna/vienna_cropped-sequential-400000-viewcells.xml.gz
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1736)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1737)
@@ -2421,42 +2421,37 @@
 void BvHierarchy::CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects)
 {
-	stack<BvhNode *> nodeStack;
-
-	nodeStack.push(mRoot);
-
-	while (!nodeStack.empty()) 
-	{
-		BvhNode *node = nodeStack.top();
-
-		nodeStack.pop();
-
-		if (node->IsLeaf()) 
-		{
-			BvhLeaf *leaf = (BvhLeaf *)node;
-
-			ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
-
-			for (oit = leaf->mObjects.begin(); oit != oit_end; ++oit) 
-			{
-				Intersectable *object = *oit;
-				if (Overlap(box, object->GetBox())) 
-				{
-					object->Mail();
-					objects.push_back(object);
-				}
+  stack<BvhNode *> nodeStack;
+
+  nodeStack.push(mRoot);
+
+  while (!nodeStack.empty()) 
+	{
+	  BvhNode *node = nodeStack.top();
+	  
+	  nodeStack.pop();
+	  
+	  if (node->IsLeaf()) 
+		{
+		  BvhLeaf *leaf = (BvhLeaf *)node;
+		  if (Overlap(box, leaf->GetBoundingBox())) {
+			Intersectable *object = GetOrCreateBvhIntersectable(leaf);
+			if (!object->Mailed()) {
+			  object->Mail();
+			  objects.push_back(object);
 			}
+		  }
 		} 
-		else 
-		{
-			BvhInterior *interior = (BvhInterior *)node;
-
-			if (Overlap(box, interior->GetBoundingBox()))
-				nodeStack.push(interior->GetFront());
-
-			if (Overlap(box, interior->GetBoundingBox()))
-				nodeStack.push(interior->GetBack());
-		}
-	}
-}
-
-}
+	  else 
+		{
+		  BvhInterior *interior = (BvhInterior *)node;
+		  
+		  if (Overlap(box, interior->GetBoundingBox()))
+			nodeStack.push(interior->GetFront());
+		  
+		  if (Overlap(box, interior->GetBoundingBox()))
+			nodeStack.push(interior->GetBack());
+		}
+	}
+}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h	(revision 1563)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h	(revision 1737)
@@ -14,5 +14,14 @@
 class RssTreeLeaf;
 
-
+  class SamplingDistribution {
+  public:
+	SamplingDistribution() {}
+	SamplingDistribution(const int t):mType(t) {}
+	int mType;
+	int mRays;
+	float mContribution;
+	float mTime;
+  };
+  
 /** Sampling based visibility preprocessing. The implementation is 
 	based on heuristical sampling of view space 
@@ -21,4 +30,5 @@
   
 public:
+  vector<SamplingDistribution> mDistributions;
   int mSamplesPerPass;
   int mRssSamplesPerPass;
@@ -40,4 +50,5 @@
   //AxisAlignedBox3 *mViewSpaceBox;
 
+  
   ofstream mStats;
   RssTree *mRssTree;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1736)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1737)
@@ -261,4 +261,9 @@
 
 
+void
+ViewCellsManager::CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects)
+{
+  GetPreprocessor()->mKdTree->CollectObjects(box, objects);
+}
 
 AxisAlignedBox3 ViewCellsManager::GetViewCellBox(ViewCell *vc)
@@ -1731,17 +1736,17 @@
 void ViewCellsManager::UpdatePvs()
 {
-	if (mViewCellPvsIsUpdated || !ViewCellsTreeConstructed())
-		return;
-
-	mViewCellPvsIsUpdated = true;
-
-	ViewCellContainer leaves;
-	mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
-
-	ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		mViewCellsTree->PropagatePvs(*it);
+  if (mViewCellPvsIsUpdated || !ViewCellsTreeConstructed())
+	return;
+  
+  mViewCellPvsIsUpdated = true;
+  
+  ViewCellContainer leaves;
+  mViewCellsTree->CollectLeaves(mViewCellsTree->GetRoot(), leaves);
+  
+  ViewCellContainer::const_iterator it, it_end = leaves.end();
+  
+  for (it = leaves.begin(); it != it_end; ++ it)
+	{
+	  mViewCellsTree->PropagatePvs(*it);
 	}
 }
@@ -1750,32 +1755,45 @@
 void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
 {
-	// update pvs of view cells tree if necessary
-	UpdatePvs();
-
-	ViewCellContainer::const_iterator it = mViewCells.begin();
-
-	stat.viewcells = 0;
-	stat.minPvs = 100000000;
-	stat.maxPvs = 0;
-	stat.avgPvs = 0.0f;
-
-	for (; it != mViewCells.end(); ++ it) 
-	{
-		ViewCell *viewcell = *it;
-
-		const float pvsCost = mViewCellsTree->GetPvsCost(viewcell);
-
-		if (pvsCost < stat.minPvs)
-			stat.minPvs = pvsCost;
-		if (pvsCost > stat.maxPvs)
-			stat.maxPvs = pvsCost;
-
-		stat.avgPvs += pvsCost;
-
-		++ stat.viewcells;
-	}
-
-	if (stat.viewcells)
-		stat.avgPvs/=stat.viewcells;
+  // update pvs of view cells tree if necessary
+  UpdatePvs();
+  
+  ViewCellContainer::const_iterator it = mViewCells.begin();
+  
+  stat.viewcells = 0;
+  stat.minPvs = 100000000;
+  stat.maxPvs = 0;
+  stat.avgPvs = 0.0f;
+  stat.avgFilteredPvs = 0.0f;
+  stat.avgFilterContribution = 0.0f;
+  
+  for (; it != mViewCells.end(); ++ it) 
+	{
+	  ViewCell *viewcell = *it;
+	  
+	  const float pvsCost = mViewCellsTree->GetPvsCost(viewcell);
+	  
+	  if (pvsCost < stat.minPvs)
+		stat.minPvs = pvsCost;
+	  if (pvsCost > stat.maxPvs)
+		stat.maxPvs = pvsCost;
+	  
+	  stat.avgPvs += pvsCost;
+
+	  if (0) {
+		ObjectPvs filteredPvs = viewcell->GetPvs();
+		ApplyFilter2(viewcell, false, 1.0f, filteredPvs);
+		float filteredCost = filteredPvs.EvalPvsCost();
+		stat.avgFilteredPvs += filteredCost;
+		stat.avgFilterContribution += filteredCost - pvsCost;
+	  }
+	  
+	  ++ stat.viewcells;
+	}
+  
+  if (stat.viewcells) {
+	stat.avgPvs/=stat.viewcells;
+	stat.avgFilteredPvs/=stat.viewcells;
+	stat.avgFilterContribution/=stat.viewcells;
+  }
 }
 
@@ -1787,4 +1805,6 @@
   GetPvsStatistics(pvsStat);
   s<<"#AVG_PVS\n"<<pvsStat.avgPvs<<endl;
+  s<<"#AVG_FILTERED_PVS\n"<<pvsStat.avgFilteredPvs<<endl;
+  s<<"#AVG_FILTER_CONTRIBUTION\n"<<pvsStat.avgFilterContribution<<endl;
   s<<"#MAX_PVS\n"<<pvsStat.maxPvs<<endl;
   s<<"#MIN_PVS\n"<<pvsStat.minPvs<<endl;
@@ -2497,13 +2517,12 @@
 void
 ViewCellsManager::ApplyFilter2(ViewCell *viewCell,
-							   KdTree *kdTree,
+							   const bool useViewSpaceFilter,
 							   const float filterSize,
 							   ObjectPvs &pvs
 							   )
 {
-  Vector3 center = viewCell->GetBox().Center();
+  AxisAlignedBox3 vbox = GetViewCellBox(viewCell);
+  Vector3 center = vbox.Center();
   // first determine the average size of the filter
-
-
 
   Intersectable::NewMail();
@@ -2518,21 +2537,96 @@
   int pvsSize = 0;
   int nPvsSize = 0;
-  int samples = pvs.mSamples;
-
-  
+  float samples = pvs.mSamples;
+  cout<<"Samples = "<<samples<<endl;
+  //  cout<<"Filter size = "<<filterSize<<endl;
+  //  cout<<"vbox = "<<vbox<<endl;
+  //  cout<<"center = "<<center<<endl;
+
+
+#define MIN_LOCAL_SAMPLES 5
+
+  // compute the average filter radius
+  float globalC = 2.0f*filterSize/sqrt(samples);
+
+  float sumRadius = 0.0f;
   for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi, pvsSize++) {
 	Intersectable *object = (*oi).first;
 	// compute filter size based on the distance and the numebr of samples
-	float distance = Distance(center, object->GetBox().Center());
-
+	AxisAlignedBox3 box = object->GetBox();
+
+	float distance = Distance(center, box.Center());
+	float globalRadius = distance*globalC;
+
+	int objectSamples = (int)(*oi).second.mSumPdf;
+	float localRadius = MAX_FLOAT;
+	
+	if (objectSamples > MIN_LOCAL_SAMPLES)
+	  localRadius = 0.5f*Magnitude(box.Diagonal())/sqrt((float)objectSamples);
+	
 	// now compute the filter size
-	float radius = distance*(filterSize/(4*samples));
+	float radius = Min(localRadius, globalRadius);
+	
+	sumRadius +=radius;
+  }
+  
+  float avgRadius = sumRadius/pvsSize;
+  float viewCellRadius = 0.5f*Magnitude(vbox.Diagonal());
+  cout<<"radius ratio = "<<avgRadius/viewCellRadius<<endl;
+  
+  // now compute the filter box around the current viewCell
+
+  if (useViewSpaceFilter) {
+	//	float radius = Max(viewCellRadius/100.0f, avgRadius - viewCellRadius);
+	float radius = viewCellRadius/100.0f;
+	vbox.Enlarge(radius);
+	cout<<"vbox = "<<vbox<<endl;
+	ViewCellContainer viewCells;
+	ComputeBoxIntersections(vbox, viewCells);
+	
+	//  cout<<"box="<<box<<endl;
+	ViewCellContainer::const_iterator it = viewCells.begin(), it_end = viewCells.end();
+	
+	int i;
+	for (i=0; it != it_end; ++ it, ++ i)
+	  if ((*it) != viewCell) {
+		//cout<<"v"<<i<<" pvs="<<(*it)->GetPvs().mEntries.size()<<endl;
+		pvs.Merge((*it)->GetPvs());
+	  }
+
+	// update samples and globalC
+	samples = pvs.mSamples;
+	globalC = 2.0f*filterSize/sqrt(samples);
+	cout<<"neighboring viewcells = "<<i-1<<endl;
+	cout<<"Samples' = "<<samples<<endl;
+  }
+  
+  for (oi = pvs.mEntries.begin(); oi != pvs.mEntries.end(); ++oi) {
+	Intersectable *object = (*oi).first;
+	// compute filter size based on the distance and the numebr of samples
 	AxisAlignedBox3 box = object->GetBox();
+
+	float distance = Distance(center, box.Center());
+	float globalRadius = distance*globalC;
+
+	
+	int objectSamples = (int)(*oi).second.mSumPdf;
+	float localRadius = MAX_FLOAT;
+	if (objectSamples > MIN_LOCAL_SAMPLES)
+	  localRadius = filterSize*0.5f*Magnitude(box.Diagonal())/sqrt((float)objectSamples);
+	
+	//	cout<<"lr="<<localRadius<<" gr="<<globalRadius<<endl;
+	
+	// now compute the filter size
+	float radius = Min(localRadius, globalRadius);
+
+	// cout<<"box = "<<box<<endl;
+	//	cout<<"distance = "<<distance<<endl;
+	//	cout<<"radiues = "<<radius<<endl;
+	
 	box.Enlarge(Vector3(radius));
 
 	ObjectContainer objects;
 	// $$ warning collect objects takes only unmailed ones!
-	// should use VspOsp!!
-	kdTree->CollectObjects(box, objects);
+	CollectObjects(box, objects);
 	//	cout<<"collected objects="<<objects.size()<<endl;
 	ObjectContainer::const_iterator noi = objects.begin();
@@ -2544,6 +2638,7 @@
 	}
   }
-  //  cout<<"nPvs size = "<<nPvsSize<<endl;
+  cout<<"nPvs size = "<<nPvsSize<<endl;
   pvs.Merge(nPvs);
+  Intersectable::NewMail();
 }
   
@@ -5724,4 +5819,10 @@
 }
 
+void
+VspOspViewCellsManager::CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects)
+{
+  mHierarchyManager->CollectObjects(box, objects);
+}
+
 
 #if 1
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1608)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1737)
@@ -176,4 +176,6 @@
   glEnd();
 }
+
+
 
 void
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1736)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1737)
@@ -298,10 +298,13 @@
 template <typename T, typename S> void Pvs<T, S>::Merge(const Pvs<T, S> &a)
 {
-	std::map<T, S, LtSample<T> >::const_iterator it;
-
-	for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
-	{
-		AddSample((*it).first, (*it).second.mSumPdf);
-	}
+  
+  std::map<T, S, LtSample<T> >::const_iterator it;
+  int samples = mSamples + a.mSamples;
+
+  for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
+	{
+	  AddSample((*it).first, (*it).second.mSumPdf);
+	}
+  mSamples = samples;
 }
 
@@ -446,5 +449,5 @@
 int Pvs<T, S>::AddPvs(const Pvs<T, S> &pvs)
 {
-  mSamples += pvs.mSamples;
+  int samples = mSamples + pvs.mSamples;
   std::map<T, S, LtSample<T> >::
 	const_iterator it, it_end = pvs.mEntries.end();
@@ -456,5 +459,7 @@
 	  AddSample((*it).first, (*it).second.mSumPdf, contri);
   }
-  
+
+  mSamples = samples;
+
   return GetSize();
 }
@@ -463,5 +468,6 @@
 int Pvs<T, S>::SubtractPvs(const Pvs<T, S> &pvs)
 {
-  mSamples -= pvs.mSamples;
+  
+  int samples = mSamples - pvs.mSamples;
   std::map<T, S, LtSample<T> >::
 	const_iterator it, it_end = pvs.mEntries.end();
@@ -470,5 +476,6 @@
   for (it = pvs.mEntries.begin(); it != it_end; ++ it) 
 	RemoveSample((*it).first, (*it).second.mSumPdf);
-  
+
+  mSamples = samples;
   return GetSize();
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp	(revision 1694)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp	(revision 1737)
@@ -3,4 +3,5 @@
 #include "Triangle3.h"
 #include "KdTree.h"
+#include "BvHierarchy.h"
 
 
@@ -97,3 +98,8 @@
 }
 
+AxisAlignedBox3 BvhIntersectable::GetBox() const
+{
+  return mItem->GetBoundingBox();
 }
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1737)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: st 1. XI 14:21:30 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: ?t 9. XI 13:27:58 2006
 # Project:  preprocessor.pro
 # Template: app
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1733)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1737)
@@ -2769,4 +2769,6 @@
 	ViewCell::NewMail();
 
+	nodeStack.push(mRoot);
+	
 	while (!nodeStack.empty()) 
 	{
@@ -2776,32 +2778,26 @@
 		const AxisAlignedBox3 bbox = GetBoundingBox(node);
 
-		if (bbox.Includes(box))
-		{
-			// node geometry is contained in box
-			CollectViewCells(node, true, viewCells, true);
-		}
-		else if (Overlap(bbox, box))
-		{
-			if (node->IsLeaf())
-			{
-				BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
-			
-				if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid())
+		if (Overlap(bbox, box)) {
+		  if (node->IsLeaf())
+			{
+			  VspLeaf *leaf = dynamic_cast<VspLeaf *>(node);
+			  
+			  if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid())
 				{
-					leaf->GetViewCell()->Mail();
-					viewCells.push_back(leaf->GetViewCell());
+				  leaf->GetViewCell()->Mail();
+				  viewCells.push_back(leaf->GetViewCell());
 				}
 			}
-			else 
-			{
-				VspInterior *interior = dynamic_cast<VspInterior *>(node);
-			
-				VspNode *first = interior->GetFront();
-				VspNode *second = interior->GetBack();
-            
-				nodeStack.push(first);
-				nodeStack.push(second);
-			}
-		}	
+		  else 
+			{
+			  VspInterior *interior = dynamic_cast<VspInterior *>(node);
+			  
+			  VspNode *first = interior->GetFront();
+			  VspNode *second = interior->GetBack();
+			  
+			  nodeStack.push(first);
+			  nodeStack.push(second);
+			}
+		}
 		// default: cull
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1707)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1737)
@@ -179,4 +179,7 @@
 		return Intersectable::BVH_INTERSECTABLE;
 	}
+
+	AxisAlignedBox3 GetBox() const;
+
 };
 
