Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1760)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1761)
@@ -42,5 +42,12 @@
 struct BspRay;
 
-
+  struct PvsFilterStatistics {
+	PvsFilterStatistics(): mAvgFilterRadius(0.0f), mLocalFilterCount(0), mGlobalFilterCount(0) {}
+	float mAvgFilterRadius;
+	int mLocalFilterCount;
+	int mGlobalFilterCount;
+	
+  };
+  
 /** Probably Visible Set 
 */
@@ -69,5 +76,8 @@
 	  float avgFilteredPvs;
 	  float avgFilterContribution;
+	  float avgFilterRadius;
+	  float avgFilterRatio;
 	  int viewcells;
+	  
 	};
 
@@ -466,10 +476,10 @@
 
 	// TODO: write own visibiltiy filter class
-	void ApplyFilter(KdTree *kdTree,
+  void ApplyFilter(KdTree *kdTree,
 					 const float viewSpaceFilterSize,
 					 const float spatialFilterSize);
 
   // new adaptive version of the filter
-  void
+  PvsFilterStatistics 
   ApplyFilter2(ViewCell *viewCell,
 			   const bool useViewSpaceFilter,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1757)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1761)
@@ -1464,5 +1464,5 @@
 	RegisterOption("ViewCells.processOnlyValidViewCells",
 					optBool,
-					"view_cells_process_only_valid_view_cells=",
+					"view_cells_process_only_valid_view_cells",
 					"false");
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1737)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1761)
@@ -525,6 +525,4 @@
 	}
 	
-	mVssRays.PrintStatistics(mStats);
-	mViewCellsManager->PrintPvsStatistics(mStats);
 	  
 	// viewcells->UpdatePVS(newVssRays);
@@ -534,5 +532,8 @@
 	mViewCellsManager->SetValidityPercentage(0, 1.0f); 
 	Debug<<"Valid viewcells after set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
-	
+
+	mVssRays.PrintStatistics(mStats);
+	mViewCellsManager->PrintPvsStatistics(mStats);
+
 	ComputeRenderError();
   }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1757)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1761)
@@ -81,5 +81,5 @@
 RssPreprocessor {
 	samplesPerPass 1000
-	initialSamples 2000000
+	initialSamples 3000000
 	vssSamples 50000000
 #	vssSamples 1000000
@@ -205,5 +205,5 @@
 	maxPvsRatio 1.0
 		
-	processOnlyValidViewCells false
+	processOnlyValidViewCells true
 
 	#stats viewCellStats.log
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1760)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1761)
@@ -27,6 +27,6 @@
 #define USE_VOLUMES_FOR_HEURISTICS 1
 
-int BvhNode::sMailId = 10000; //2147483647;
-int BvhNode::sReservedMailboxes = 1;
+//int BvhNode::sMailId = 10000; //2147483647;
+//int BvhNode::sReservedMailboxes = 1;
 
 BvHierarchy *BvHierarchy::BvhSubdivisionCandidate::sBvHierarchy = NULL;
@@ -1871,5 +1871,4 @@
 	if (!object) 
 		return NULL;
-	
 	return object->mBvhLeaf;
 	
@@ -2397,27 +2396,27 @@
 	nodeStack.pop();
 	
-	  if (node->IsLeaf()) 
-		{
-	  BvhLeaf *leaf = (BvhLeaf *)node;
-	  if (Overlap(box, leaf->GetBoundingBox())) {
-			Intersectable *object = leaf;
-		if (!object->Mailed()) {
-		  object->Mail();
-		  objects.push_back(object);
-		}
+	if (node->IsLeaf()) 
+	  {
+		BvhLeaf *leaf = (BvhLeaf *)node;
+		if (Overlap(box, leaf->GetBoundingBox())) {
+		  Intersectable *object = 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/SamplingPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1757)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1761)
@@ -144,5 +144,6 @@
 	  }
 	  
-	  
+	  CLEAR_CONTAINER(vssRays);
+
 	  if (samples > mTotalSamples)
 		break;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1760)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1761)
@@ -32,6 +32,6 @@
 
 // $$JB HACK
-#define USE_KD_PVS 0
-#define KD_PVS_AREA (5*1e-4f)
+#define USE_KD_PVS 1
+#define KD_PVS_AREA (1e-4f)
 
 
@@ -87,5 +87,5 @@
 {
 	// visualization stuff
-	Environment::GetSingleton()->GetBoolValue("ViewCells.Visualization.exportRays", mExportRays);
+ 	Environment::GetSingleton()->GetBoolValue("ViewCells.Visualization.exportRays", mExportRays);
 	Environment::GetSingleton()->GetBoolValue("ViewCells.Visualization.exportGeometry", mExportGeometry);
 	Environment::GetSingleton()->GetFloatValue("ViewCells.maxPvsRatio", mMaxPvsRatio);
@@ -317,5 +317,15 @@
 ViewCellsManager::GetIntersectable(const VssRay &ray, const bool isTermination) const
 {
+#if USE_KD_PVS
+  float area = GetPreprocessor()->mKdTree->GetBox().SurfaceArea()*KD_PVS_AREA;
+  KdNode *node = GetPreprocessor()->mKdTree->GetNode(isTermination ?
+													 ray.mTermination : ray.mOrigin,
+													 area);
+  return 
+	GetPreprocessor()->mKdTree->
+	GetOrCreateKdIntersectable(node);
+#else
   return isTermination ? ray.mTerminationObject : ray.mOriginObject;
+#endif
 }
 
@@ -794,21 +804,21 @@
 		stream << "<BoundingBoxes>" << endl;
 #if USE_KD_PVS 
-	KdIntersectableMap::const_iterator kit, kit_end = GetPreprocessor()->mKdTree->mKdIntersectables.end();
+		vector<KdIntersectable *>::iterator kit, kit_end = GetPreprocessor()->mKdTree->mKdIntersectables.end();
 
 		int id = 0;
 		for (kit = GetPreprocessor()->mKdTree->mKdIntersectables.begin(); kit != kit_end; ++ kit, ++ id)
 		{
-			Intersectable *obj = (*kit).second;
-			const AxisAlignedBox3 box = obj->GetBox();
-		
-			obj->SetId(id);
-
-			stream << "<BoundingBox" << " id=\"" << id << "\""
-				   << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\""
-				   << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl;
+		  Intersectable *obj = *kit;
+		  const AxisAlignedBox3 box = obj->GetBox();
+		  
+		  obj->SetId(id);
+		  
+		  stream << "<BoundingBox" << " id=\"" << id << "\""
+				 << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\""
+				 << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl;
 		}
 #else
-	ObjectContainer::const_iterator oit, oit_end = objects.end();
-
+		ObjectContainer::const_iterator oit, oit_end = objects.end();
+		
 		for (oit = objects.begin(); oit != oit_end; ++ oit)
 		{
@@ -955,6 +965,7 @@
 									  float &contribution) const
 {
-	if (!obj) return false;
-
+	if (!obj)
+	  return false;
+	
 	// potentially visible objects
 	return vc->AddPvsSample(obj, pdf, contribution);
@@ -1401,12 +1412,19 @@
 										)
 {
-	sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs);
-
-	int start = (int)(mViewCells.size() * minValid);
-	int end = (int)(mViewCells.size() * maxValid);
-
-	for (int i = 0; i < (int)mViewCells.size(); ++ i)
-	{
-		mViewCells[i]->SetValid(i >= start && i <= end);
+  ObjectPvs dummyPvs;
+  // update pvs sizes
+  for (int i = 0; i < (int)mViewCells.size(); ++ i) {
+	UpdatePvsForEvaluation(mViewCells[i], dummyPvs);
+  }
+  
+  sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs);
+  
+  int start = (int)(mViewCells.size() * minValid);
+  int end = (int)(mViewCells.size() * maxValid);
+  
+  for (int i = 0; i < (int)mViewCells.size(); ++ i)
+	{
+	  //	  cout<<"pvs:"<<mViewCells[i]->GetCachedPvsCost()<<endl;
+	  mViewCells[i]->SetValid(i >= start && i <= end);
 	}
 }
@@ -1821,32 +1839,41 @@
   stat.avgFilteredPvs = 0.0f;
   stat.avgFilterContribution = 0.0f;
+  stat.avgFilterRadius = 0;
+  stat.avgFilterRatio = 0;
   
   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;
-
-	  const bool evaluateFilter = true;
-	  
-	  if (evaluateFilter) {
-		ObjectPvs filteredPvs = viewcell->GetPvs();
-		ApplyFilter2(viewcell, false, 1.0f, filteredPvs);
-		float filteredCost = filteredPvs.EvalPvsCost();
-		stat.avgFilteredPvs += filteredCost;
-		stat.avgFilterContribution += filteredCost - pvsCost;
-	  } else {
-		stat.avgFilteredPvs += pvsCost;
-		stat.avgFilterContribution += 0;
+	  if (viewcell->GetValid()) {
+		const float pvsCost = mViewCellsTree->GetPvsCost(viewcell);
+		
+		if (pvsCost < stat.minPvs)
+		  stat.minPvs = pvsCost;
+		if (pvsCost > stat.maxPvs)
+		  stat.maxPvs = pvsCost;
+		
+		stat.avgPvs += pvsCost;
+		
+		const bool evaluateFilter = true;
+		
+		if (evaluateFilter) {
+		  ObjectPvs filteredPvs = viewcell->GetPvs();
+		  PvsFilterStatistics fstat = ApplyFilter2(viewcell, false, 1.0f, filteredPvs);
+		  
+		  float filteredCost = filteredPvs.EvalPvsCost();
+		  stat.avgFilteredPvs += filteredCost;
+		  stat.avgFilterContribution += filteredCost - pvsCost;
+
+		  stat.avgFilterRadius += fstat.mAvgFilterRadius;
+		  stat.avgFilterRatio += fstat.mLocalFilterCount / (float) fstat.mGlobalFilterCount;
+		  
+		  
+		} else {
+		  stat.avgFilteredPvs += pvsCost;
+		  stat.avgFilterContribution += 0;
+		}
+		
+		++ stat.viewcells;
 	  }
-	  
-	  ++ stat.viewcells;
 	}
   
@@ -1855,4 +1882,6 @@
 	stat.avgFilteredPvs/=stat.viewcells;
 	stat.avgFilterContribution/=stat.viewcells;
+	stat.avgFilterRadius/=stat.viewcells;
+	stat.avgFilterRatio/=stat.viewcells;
   }
 }
@@ -1867,4 +1896,6 @@
   s<<"#AVG_FILTERED_PVS\n"<<pvsStat.avgFilteredPvs<<endl;
   s<<"#AVG_FILTER_CONTRIBUTION\n"<<pvsStat.avgFilterContribution<<endl;
+  s<<"#AVG_FILTER_RADIUS\n"<<pvsStat.avgFilterRadius<<endl;
+  s<<"#AVG_FILTER_RATIO\n"<<pvsStat.avgFilterRatio<<endl;
   s<<"#MAX_PVS\n"<<pvsStat.maxPvs<<endl;
   s<<"#MIN_PVS\n"<<pvsStat.minPvs<<endl;
@@ -1985,13 +2016,5 @@
 	return;
   
-#if USE_KD_PVS
-  float area = GetPreprocessor()->mKdTree->GetBox().SurfaceArea()*KD_PVS_AREA;
-  KdNode *node = GetPreprocessor()->mKdTree->GetNode(ray.mTermination, area);
-  Intersectable *obj =
-	GetPreprocessor()->mKdTree->
-	GetOrCreateKdIntersectable(node);
-#else
-  Intersectable *obj = ray.mTerminationObject;
-#endif
+  Intersectable *obj = GetIntersectable(ray, true);
   
   for (it = viewcells->begin(); it != viewcells->end(); ++it) {
@@ -2037,14 +2060,6 @@
 		ray.mViewCells = viewcells;
 	}
-
-#if USE_KD_PVS
-	float area = GetPreprocessor()->mKdTree->GetBox().SurfaceArea()*KD_PVS_AREA;
-	KdNode *node = GetPreprocessor()->mKdTree->GetNode(ray.mTermination, area);
-	Intersectable *obj =
-	  GetPreprocessor()->mKdTree->
-	  GetOrCreateKdIntersectable(node);
-#else
-	Intersectable *obj = ray.mTerminationObject;
-#endif
+	
+	Intersectable *obj = GetIntersectable(ray, true);
 	
 	
@@ -2590,5 +2605,5 @@
 
 
-void
+PvsFilterStatistics
 ViewCellsManager::ApplyFilter2(ViewCell *viewCell,
 							   const bool useViewSpaceFilter,
@@ -2597,7 +2612,8 @@
 							   )
 {
+  PvsFilterStatistics stats;
+
   AxisAlignedBox3 vbox = GetViewCellBox(viewCell);
   Vector3 center = vbox.Center();
-  
   // COpy the PVS
   ObjectPvs basePvs = viewCell->GetPvs();
@@ -2606,4 +2622,5 @@
   ObjectPvsIterator pit = basePvs.GetIterator();
 
+#if !USE_KD_PVS
   // first mark all object from this pvs
   while (pit.HasMoreEntries()) {		
@@ -2613,12 +2630,11 @@
 	object->Mail();
   }
-
+#endif
 
   int pvsSize = 0;
   int nPvsSize = 0;
-  float samples = (float)pvs.GetSamples();
-
-  //  cout<<"#s"<<samples<<endl;
-  //  cout<<"pvs size = "<<pvs.GetSize() <<endl;
+  float samples = (float)basePvs.GetSamples();
+  
+  cout<<"f #s="<<samples<<"pvs size = "<<basePvs.GetSize();
   //  cout<<"Filter size = "<<filterSize<<endl;
   //  cout<<"vbox = "<<vbox<<endl;
@@ -2635,5 +2651,4 @@
 #define MIN_LOCAL_SAMPLES 5
 
-  float globalC = 2.0f*filterSize/sqrt(samples);
   float viewCellRadius = 0.5f*Magnitude(vbox.Diagonal());
   
@@ -2659,55 +2674,72 @@
 	// update samples and globalC
 	samples = (float)pvs.GetSamples();
-	globalC = 2.0f*filterSize/sqrt(samples);
 	//	cout<<"neighboring viewcells = "<<i-1<<endl;
 	//	cout<<"Samples' = "<<samples<<endl;
   }
+
+  // Minimal number of samples so that filtering takes place
+#define MIN_SAMPLES  100
+  if (samples > MIN_SAMPLES) {
+	float globalC = 2.0f*filterSize/sqrt(samples);
+	
+	pit = basePvs.GetIterator();
+	
+	ObjectContainer objects;
+	
+	while (pit.HasMoreEntries())
+	  {		
+		ObjectPvsEntry entry = pit.Next();
+		
+		Intersectable *object = entry.mObject;
+		// 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)entry.mData.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;
+
+		if (localRadius < globalRadius) {
+		  radius = localRadius;
+		  stats.mLocalFilterCount++;
+		} else {
+		  radius = globalRadius;
+		  stats.mGlobalFilterCount++;
+		}
+
+		stats.mAvgFilterRadius += radius;
+		
+		// cout<<"box = "<<box<<endl;
+		//	cout<<"distance = "<<distance<<endl;
+		//	cout<<"radiues = "<<radius<<endl;
+		
+		box.Enlarge(Vector3(radius));
+		
+		objects.clear();
+		// $$ warning collect objects takes only unmailed ones!
+		CollectObjects(box, objects);
+		//	cout<<"collected objects="<<objects.size()<<endl;
+		ObjectContainer::const_iterator noi = objects.begin();
+		for (; noi != objects.end(); ++ noi) {
+		  Intersectable *o = *noi;
+		  // $$ JB warning: pdfs are not correct at this point!	  
+		  pvs.AddSampleDirty(o, Limits::Small);
+		}
+	  }
+	stats.mAvgFilterRadius /= (stats.mLocalFilterCount + stats.mGlobalFilterCount);
+  }
   
-  pit = basePvs.GetIterator();
-
-  ObjectContainer objects;
-
-  while (pit.HasMoreEntries())
-  {		
-	ObjectPvsEntry entry = pit.Next();
-
-	Intersectable *object = entry.mObject;
-	// 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)entry.mData.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));
-	
-	objects.clear();
-	// $$ warning collect objects takes only unmailed ones!
-	CollectObjects(box, objects);
-	//	cout<<"collected objects="<<objects.size()<<endl;
-	ObjectContainer::const_iterator noi = objects.begin();
-	for (; noi != objects.end(); ++ noi) {
-	  Intersectable *o = *noi;
-	  // $$ JB warning: pdfs are not correct at this point!	  
-	  pvs.AddSampleDirty(o, Limits::Small);
-	}
-  }
-
-  //  cout<<"nPvs size = "<<pvs.GetSize()<<endl;
-
+  cout<<" nPvs size = "<<pvs.GetSize()<<endl;
+
+#if !USE_KD_PVS
   // copy the base pvs to the new pvs
   pit = basePvs.GetIterator();
@@ -2716,6 +2748,8 @@
 	pvs.AddSampleDirty(entry.mObject, entry.mData.mSumPdf);
   }
+#endif
   
   Intersectable::NewMail();
+  return stats;
 }
   
@@ -5096,5 +5130,9 @@
 VspOspViewCellsManager::GetIntersectable(const VssRay &ray, const bool isTermination) const
 {
+#if USE_KD_PVS
+  return ViewCellsManager::GetIntersectable(ray, isTermination);
+#else
   return mHierarchyManager->GetIntersectable(ray, isTermination);
+#endif
 }
 
@@ -5853,4 +5891,7 @@
 	ViewCellContainer::const_iterator it = viewcells.begin();
 
+	Intersectable *terminationObj = GetIntersectable(ray, true);
+	Intersectable *originObj = GetIntersectable(ray, false);
+	  
 	for (; it != viewcells.end(); ++ it) 
 	{
@@ -5861,19 +5902,18 @@
 			float contribution;
 
-			if (ray.mTerminationObject) 
+			if (terminationObj) 
 			{
 				// todo: maybe not correct for kd node pvs
-				Intersectable *obj = mHierarchyManager->GetIntersectable(ray, true);
-
-				if (viewcell->GetPvs().GetSampleContribution(obj,
-					ray.mPdf, 
-					contribution))
+			  
+			  if (viewcell->GetPvs().GetSampleContribution(terminationObj,
+														   ray.mPdf, 
+														   contribution))
 				{
-					++ ray.mPvsContribution;
+				  ++ ray.mPvsContribution;
 				}
-
-				ray.mRelativePvsContribution += contribution;
+			  
+			  ray.mRelativePvsContribution += contribution;
 			}
-
+			
 			////////////////
 			//-- for directional sampling it is important to count only contributions 
@@ -5881,12 +5921,12 @@
 			//-- the other contributions of this sample will be counted for the opposite ray!
 #if SAMPLE_ORIGIN_OBJECTS
-			if (ray.mOriginObject && 
-				viewcell->GetPvs().GetSampleContribution(ray.mOriginObject,
-				ray.mPdf,
-				contribution))
-			{
+			if (originObj && 
+				viewcell->GetPvs().GetSampleContribution(originObj,
+														 ray.mPdf,
+														 contribution))
+			  {
 				++ ray.mPvsContribution;
 				ray.mRelativePvsContribution += contribution;
-			}
+			  }
 #endif
 		}
@@ -5906,22 +5946,26 @@
 			break;
 
+		//$$JB hack
+#if !USE_KD_PVS
 		AddSampleToPvs(
-			ray.mTerminationObject, 
-			ray.mTermination, 
-			viewCell, 
-			ray.mPdf, 
-			ray.mRelativePvsContribution);
-
+					   terminationObj, 
+					   ray.mTermination, 
+					   viewCell, 
+					   ray.mPdf, 
+					   ray.mRelativePvsContribution);
+#else
+		viewCell->GetPvs().AddSample(terminationObj, ray.mPdf);
+#endif
+		
 #if SAMPLE_ORIGIN_OBJECTS
-
 		AddSampleToPvs(
-			ray.mOriginObject, 
-			ray.mOrigin, 
-			viewCell, 
-			ray.mPdf, 
-			ray.mRelativePvsContribution);
+					   originObj, 
+					   ray.mOrigin, 
+					   viewCell, 
+					   ray.mPdf, 
+					   ray.mRelativePvsContribution);
 #endif			
 	}
-
+	
 	
 
@@ -5937,6 +5981,6 @@
 											float &contribution) const
 {
-	// The hierarchy manager decides about the type of sample cast
-	return mHierarchyManager->AddSampleToPvs(obj, hitPoint, vc, pdf, contribution);
+  // The hierarchy manager decides about the type of sample cast
+  return mHierarchyManager->AddSampleToPvs(obj, hitPoint, vc, pdf, contribution);
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1758)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1761)
@@ -206,20 +206,20 @@
 	//-- mailing options
 	
-	static void NewMail(const int reserve = 1) {
-		sMailId += sReservedMailboxes;
-		sReservedMailboxes = reserve;
-	}
-	
-	void Mail() { mMailbox = sMailId; }
-	bool Mailed() const { return mMailbox == sMailId; }
-
-	void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
-	bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
-
-	int IncMail() { return ++ mMailbox - sMailId; }
-
-	static int sMailId;
-	//int mMailbox;
-	static int sReservedMailboxes;
+// 	static void NewMail(const int reserve = 1) {
+// 		sMailId += sReservedMailboxes;
+// 		sReservedMailboxes = reserve;
+// 	}
+	
+// 	void Mail() { mMailbox = sMailId; }
+// 	bool Mailed() const { return mMailbox == sMailId; }
+
+// 	void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
+// 	bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
+
+// 	int IncMail() { return ++ mMailbox - sMailId; }
+
+// 	static int sMailId;
+// 	//int mMailbox;
+// 	static int sReservedMailboxes;
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1757)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1761)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: Tue Nov 14 23:59:07 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: Thu Nov 16 14:37:00 2006
 # Project:  preprocessor.pro
 # Template: app
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1736)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1761)
@@ -21,5 +21,6 @@
 
 
-KdNode::KdNode(KdInterior *parent):mParent(parent), mMailbox(0)
+KdNode::KdNode(KdInterior *parent):mParent(parent), mMailbox(0), mIntersectable(NULL)
+
 {
   if (parent)
@@ -1405,19 +1406,12 @@
   if (node == NULL)
 	return NULL;
-  
-  // search nodes
-  std::map<KdNode *, KdIntersectable *>::
-	const_iterator it = mKdIntersectables.find(node);
-  
-  if (it != mKdIntersectables.end()) 
-	{
-	  return (*it).second;
-	}
-  
-  // not in map => create new entry
-  KdIntersectable *kdObj = new KdIntersectable(node, GetBox(node));
-  mKdIntersectables[node] = kdObj;
-  
-  return kdObj;
+
+  if (node->mIntersectable == NULL) {
+	// not in map => create new entry
+	node->mIntersectable = new KdIntersectable(node, GetBox(node));
+	mKdIntersectables.push_back(node->mIntersectable);
+  }
+
+  return node->mIntersectable;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1732)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1761)
@@ -245,4 +245,8 @@
 	}
 
+  static bool GreaterOrEqualPvs(const ViewCell *a, const ViewCell *b) {
+	return !SmallerPvs(a, b);
+  }
+
 	static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b) 
 	{
@@ -267,4 +271,8 @@
 	float GetMergeCost() const;
 
+
+  float GetCachedPvsCost() const {
+	return mPvsCost;
+  }
 
 	//////////
@@ -483,4 +491,5 @@
 	*/
 	float GetPvsCost(ViewCell *vc) const;
+  
 
 	/** Returns number of entries associated with this view cell. 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1633)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1761)
@@ -101,4 +101,6 @@
   static int sReservedMailboxes;
   int mMailbox;
+
+  KdIntersectable *mIntersectable;
   
   void Mail() { mMailbox = sMailId; }
@@ -596,6 +598,6 @@
 public:
   /// stores the kd node intersectables used for pvs
-  KdIntersectableMap mKdIntersectables;
-
+  vector<KdIntersectable *> mKdIntersectables;
+  
 };
 
