Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1740)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1743)
@@ -178,4 +178,8 @@
 	ViewCell *ExtrudeViewCell(const Triangle3 &baseTri, const float height) const;
 
+
+  virtual Intersectable *
+  GetIntersectable(const VssRay &ray, const bool isTermination) const;
+
 	/** Sets maximal number of samples used for the 
 		construction of the view cells.
@@ -1067,4 +1071,7 @@
 	ViewCell *GenerateViewCell(Mesh *mesh = NULL) const;
 
+  virtual Intersectable *
+  GetIntersectable(const VssRay &ray, const bool isTermination) const;
+
 	bool ViewCellsConstructed() const;
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1737)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1743)
@@ -286,10 +286,11 @@
 	
 	// Render PVS
-	ObjectPvsMap::const_iterator it = viewcell->GetPvs().mEntries.begin();
-
-	pvsSize = viewcell->GetPvs().mEntries.size();
-	
-	for (; it != viewcell->GetPvs().mEntries.end(); ++ it) {
-	  Intersectable *object = (*it).first;
+	ObjectPvsIterator it = viewcell->GetPvs().GetIterator();
+
+	pvsSize = viewcell->GetPvs().GetSize();
+	
+	for (; it.HasMoreEntries(); ) {
+	  ObjectPvsEntry entry = it.Next();
+	  Intersectable *object = entry.mObject;
 	  RenderIntersectable(object);
 	}
@@ -348,8 +349,8 @@
 	  
 	  // Render PVS
-	  ObjectPvsMap::const_iterator it = viewcell->GetPvs().mEntries.begin();
-	  
-	  for (; it != viewcell->GetPvs().mEntries.end(); ++ it) {
-		Intersectable *object = (*it).first;
+	  ObjectPvsIterator it = viewcell->GetPvs().GetIterator();
+	  for (; it.HasMoreEntries(); ) {
+		ObjectPvsEntry entry = it.Next();
+		Intersectable *object = entry.mObject;
 		RenderIntersectable(object);
 	  }
@@ -958,5 +959,5 @@
   PrVs prvs;
   
-  if (!mUseFilter) {
+  if (1 || !mUseFilter) {
 	viewcell = mViewCellsManager->GetViewCell(mViewPoint, true);
   } else {
@@ -968,32 +969,41 @@
   if (viewcell) {
 	// copy the pvs so that it can be filtered...
-	ObjectPvs pvs = viewcell->GetPvs();
-
-	if (mUseSpatialFilter) {
-	  // 9.11. 2006 -> experiment with new spatial filter
+	
+	ObjectPvs &pvs = mPvsCache.mPvs;
+	
+	if (mPvsCache.mViewCell != viewcell) {
+	  mPvsCache.Reset();
+	  mPvsCache.mViewCell = viewcell;
+	  
+	  if (mUseSpatialFilter) {
+		// 9.11. 2006 -> experiment with new spatial filter
 #if 0
-	  mViewCellsManager->ApplySpatialFilter(mKdTree,
-											mSpatialFilterSize*
-											Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
-											pvs);
+		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);
+		// mSpatialFilter size is in range 0.001 - 0.1
+		mViewCellsManager->ApplyFilter2(viewcell,
+										mUseFilter,
+										100*mSpatialFilterSize,
+										pvs);
 #endif
-	}
-	
-	
-	ObjectPvsMap::const_iterator it = pvs.mEntries.begin();
-	
-	mPvsSize = pvs.mEntries.size();
-	  
-	for (; it != pvs.mEntries.end(); ++ it) {
-	  Intersectable *object = (*it).first;
+	  } else
+		pvs = viewcell->GetPvs();
+	}
+
+	// Render PVS
+	ObjectPvsIterator it = pvs.GetIterator();
+	
+	mPvsSize = pvs.GetSize();
+	
+	for (; it.HasMoreEntries(); ) {
+	  ObjectPvsEntry entry = it.Next();
+	  Intersectable *object = entry.mObject;
 	  
 	  if (mRenderVisibilityEstimates) {
-		float visibility = mTransferFunction*log10((*it).second.mSumPdf + 1); // /5.0f
+		
+		float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f
 		glColor3f(visibility, 0.0f, 0.0f);
 		mUseForcedColors = true;
@@ -1021,6 +1031,7 @@
 	}
 	
-	if (mUseFilter)
+	if (0 && mUseFilter)
 	  mViewCellsManager->DeleteLocalMergeTree(viewcell);
+
   } else {
 	ObjectContainer::const_iterator oi = mObjects.begin();
@@ -1741,5 +1752,5 @@
 
 	//const int p = vc->GetPvs().CountObjectsInPvs();
-	const int p = vc->GetPvs().Size();
+	const int p = vc->GetPvs().GetSize();
 	if (p > maxPvs)
 	  maxPvs = p;
@@ -1759,5 +1770,5 @@
 	} else {
 	  //	  const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().CountObjectsInPvs() / (float)maxPvs);
-	  const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().Size() / (float)maxPvs);
+	  const float importance = 5.0f*mTransferFunction * ((float)vc->GetPvs().GetSize() / (float)maxPvs);
 	  c = RgbColor(importance, 1.0f - importance, 0.0f);
 	}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1740)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1743)
@@ -1084,8 +1084,11 @@
 			i ++;
 		  }
-		if (i % 10000 == 0)
+
+		if (rays.size() > 10000 && i % 10000 == 0)
 		  cout<<"\r"<<i<<"/"<<(int)rays.size()<<"\r";
 	}
-	cout<<endl;
+
+	if (rays.size() > 10000) {
+	  cout<<endl;
 	
 	long t2 = GetTime();
@@ -1096,5 +1099,6 @@
 	else
 		cout << rays.size() / (1e3f * TimeDiff(t1, t2)) << "M rays/s" << endl;
-#endif	
+#endif
+	}
 }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1743)
@@ -169,5 +169,12 @@
   void SetCutScene(bool);
 
-  
+};
+
+
+struct PvsCache {
+  PvsCache():mViewCell(NULL) {}
+  Reset() { mViewCell = NULL; mPvs.Clear(); }
+  ViewCell *mViewCell;
+  ObjectPvs mPvs;
 };
 
@@ -205,4 +212,5 @@
   float mManipulatorLastQuat[4];
   float mManipulatorScale;
+  PvsCache mPvsCache;
   
   QtRendererControlWidget *mControlWidget;
@@ -300,4 +308,5 @@
   void SetUseFilter(bool b) {
    mUseFilter = b;
+   mPvsCache.Reset();
    updateGL();
  }
@@ -305,4 +314,5 @@
   void SetUseSpatialFilter(bool b) {
 	mUseSpatialFilter = b;
+	mPvsCache.Reset();
 	updateGL();
   }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1736)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1743)
@@ -269,5 +269,8 @@
 	*/
 	Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
-
+  
+  Intersectable *GetIntersectable(Intersectable *obj,
+								  const Vector3 &point) const;
+  
 	/** Export object space partition bounding boxes.
 	*/
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp	(revision 1723)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp	(revision 1743)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1737)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1743)
@@ -51,6 +51,6 @@
 #	type render
 	detectEmptyViewSpace true
-#	pvsRenderErrorSamples 0
-	pvsRenderErrorSamples 1000
+	pvsRenderErrorSamples 0
+#	pvsRenderErrorSamples 1000
 	quitOnFinish true
 	computeVisibility true
@@ -75,5 +75,5 @@
 
 SamplingPreprocessor {
-	totalSamples 10000000
+	totalSamples 100000000
 	samplesPerPass 1000000
 }
@@ -82,5 +82,5 @@
 	samplesPerPass 1000
 	initialSamples 2000000
-	vssSamples 50000000
+	vssSamples 100000000
 #	vssSamples 1000000
 	vssSamplesPerPass 3000000
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Trackball.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Trackball.cpp	(revision 1581)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Trackball.cpp	(revision 1743)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1715)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1743)
@@ -9,4 +9,5 @@
 #include "ViewCellsManager.h"
 #include "RenderSimulator.h"
+#include "VssRay.h"
 
 
@@ -30,49 +31,5 @@
 }
 
-Intersectable *
-SamplingPreprocessor::CastRay(
-							  const Vector3 &origin,
-							  const Vector3 &direction
-							  )
-{
-  AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
-  
-  AxisAlignedBox3 sbox = box;
-  sbox.Enlarge(Vector3(-Limits::Small));
-  if (!sbox.IsInside(origin))
-	return 0;
-  
-  Vector3 point, normal;
-  Intersectable *object;
 
-  // cast ray to KD tree to find intersection with other objects
-#if 0
-  object = CastSimpleRay(origin,
-						 direction,
-						 mKdTree->GetBox(),
-						 point,
-						 normal
-						 );
-#endif
-
-  if (mDetectEmptyViewSpace && DotProd(normal, direction) >= 0) {
-	object = NULL;
-  }
-  
-  return object;
-}
-
-void
-SamplingPreprocessor::HoleSamplingPass()
-{
-  vector<KdLeaf *> leaves;
-  mKdTree->CollectLeaves(leaves);
-  
-  // go through all the leaves and evaluate their passing contribution
-  for (int i=0 ; i < leaves.size(); i++) {
-    KdLeaf *leaf = leaves[i];
-    cout<<leaf->mPassingRays<<endl;
-  }
-}
 
 
@@ -127,48 +84,72 @@
 	ConstructViewCells();
   }
-    
+
+  int intersectables, faces;
+  mSceneGraph->GetStatistics(intersectables, faces);
+  
   int samples = 0;
   int i=0;
   while (samples < mTotalSamples) {
-	for (i=0; i < mSamplesPerPass; i++, samples++) {
+	for (i=0; i < mSamplesPerPass;) {
+	  SimpleRayContainer rays;
+	  VssRayContainer vssRays;
+	  vector<ViewCell *> viewcells;
+	  for (; rays.size() < 16; ) {
+		if (i%10000 == 0)
+		  cout<<"+";
+
+		Vector3 origin, direction;
+		mViewCellsManager->GetViewPoint( origin );
+		
+		direction = UniformRandomVector();
+		ViewCell *viewcell = mViewCellsManager->GetViewCell(origin);
+		
+		if (viewcell && viewcell->GetValid()) {
+		  viewcells.push_back(viewcell);
+		  // cast rays in both directions to make the number of samples comparable
+		  // with the global sampling method which also casts a "double" ray per sample
+		  rays.push_back(SimpleRay(origin, direction));
+		  i++;
+		  samples++;
+		}
+	  }
 	  
-	  if (i%10000 == 0)
-		cout<<"+";
-	  
-	  Vector3 origin, direction;
-	  mViewCellsManager->GetViewPoint(origin);
-	  direction = UniformRandomVector();
+	  CastRays(rays,
+			   vssRays,
+			   true,
+			   false);
 
-	  
-	  ViewCell *viewcell = mViewCellsManager->GetViewCell(origin);
-	  
-	  if (viewcell && viewcell->GetValid()) {
-		// cast rays in both directions to make the number of samples comparable
-		// with the global sampling method which also casts a "double" ray per sample
-		for (int j=0; j < 2; j++) {
-		  Intersectable *object = CastRay(origin, direction);
-		  if (object) {
-			// if ray not outside of view space
+	  if (vssRays.size()!=32) {
+		cerr<<"wrong number of rays "<<vssRays.size()<<endl;
+		exit(1);
+	  }
+		
+	  for (int j=0; j < vssRays.size(); j++) {
+		Intersectable *obj = mViewCellsManager->GetIntersectable(*(vssRays[j]), true);
+		if (obj) {
+		  // if ray not outside of view space
 			float contribution;
 			int pvsContribution = 0;
 			float relativePvsContribution = 0;
-			if (object) {
-			  float pdf = 1.0f;
-			  if (viewcell->GetPvs().GetSampleContribution(object,
-														   pdf,
-														   contribution))
-				++pvsContribution;
-			  relativePvsContribution += contribution;
-			  viewcell->GetPvs().AddSample(object, pdf);
-			}
-		  }
-		  direction = -direction;
+			float pdf = 1.0f;
+			ViewCell *viewcell = viewcells[j/2];
+			if (viewcell->GetPvs().GetSampleContribution(obj,
+														 pdf,
+														 contribution)) 
+			  ++pvsContribution;
+			relativePvsContribution += contribution;
+			viewcell->GetPvs().AddSample(obj, pdf);
 		}
 	  }
+	  
 	  
 	  if (samples > mTotalSamples)
 		break;
 	}
-	
+
+	Debug<<"Valid viewcells before set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
+	mViewCellsManager->SetValidity(0, intersectables/2);
+	Debug<<"Valid viewcells after set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
+
 	//	mVssRays.PrintStatistics(mStats);
 	mStats <<
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1742)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1743)
@@ -314,4 +314,9 @@
 }
 
+Intersectable *
+ViewCellsManager::GetIntersectable(const VssRay &ray, const bool isTermination) const
+{
+  return isTermination ? ray.mTerminationObject : ray.mOriginObject;
+}
 
 void
@@ -2591,6 +2596,7 @@
   // first determine the average size of the filter
 
+  pvs = viewCell->GetPvs();
   Intersectable::NewMail();
-
+  
   ObjectPvsIterator pit = pvs.GetIterator();
 
@@ -2712,8 +2718,8 @@
 	  ObjectContainer::const_iterator noi = objects.begin();
 	  for (; noi != objects.end(); ++ noi) {
-		  Intersectable *o = *noi;
-		  // $$ JB warning: pdfs are not correct at this point!	  
-		  nPvs.AddSample(o, Limits::Small);
-		  nPvsSize ++;
+		Intersectable *o = *noi;
+		// $$ JB warning: pdfs are not correct at this point!	  
+		nPvs.AddSample(o, Limits::Small);
+		nPvsSize ++;
 	  }
   }
@@ -2721,5 +2727,5 @@
   
   pvs.MergeInPlace(nPvs);
-
+  
   Intersectable::NewMail();
 }
@@ -5093,4 +5099,9 @@
 }
 
+Intersectable *
+VspOspViewCellsManager::GetIntersectable(const VssRay &ray, const bool isTermination) const
+{
+  return mHierarchyManager->GetIntersectable(ray, isTermination);
+}
 
 HierarchyManager *VspOspViewCellsManager::CreateHierarchyManager(const string &hierarchyType)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1737)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1743)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: ?t 9. XI 13:27:58 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: po 13. XI 15:12:57 2006
 # Project:  preprocessor.pro
 # Template: app
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.h	(revision 1221)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.h	(revision 1743)
@@ -34,15 +34,6 @@
 		   const Ray::Intersection &source);
   
-  /** Refined sampling for finding "holes", i.e., difficult visibility.
-   */
-  void
-  HoleSamplingPass();
   
   
-  Intersectable *
-  CastRay(
-		  const Vector3 &origin,
-		  const Vector3 &direction
-		  );
   
   /** Verify if the exact visibility for this object was established.
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1736)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1743)
@@ -102,5 +102,5 @@
   ////////////////////////////////////////////////////
   virtual AxisAlignedBox3 GetBox() const = 0;
-  virtual int CastRay(GtpVisibilityPreprocessor::Ray &ray) = 0;
+  virtual int CastRay(Ray &ray) = 0;
   
   virtual bool IsConvex() const = 0;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1742)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1743)
@@ -1517,9 +1517,32 @@
 
 
+Intersectable *HierarchyManager::GetIntersectable(Intersectable *obj,
+												  const Vector3 &point) const
+{
+  
+  if (!obj)
+	return NULL;
+  
+  switch (mObjectSpaceSubdivisionType)
+	{
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+	  {
+		KdLeaf *leaf = mOspTree->GetLeaf(point, NULL);
+		return mOspTree->GetOrCreateKdIntersectable(leaf);
+	  }
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+	  {
+		BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+		return mBvHierarchy->GetOrCreateBvhIntersectable(leaf);
+	  }
+	default:
+	  return obj;
+	}
+}
+
 Intersectable *HierarchyManager::GetIntersectable(const VssRay &ray, 
 												  const bool isTermination) const
 {
-
-	Intersectable *obj;
+  Intersectable *obj = NULL;
 	Vector3 pt;
 	KdNode *node;
@@ -1527,5 +1550,6 @@
 	ray.GetSampleData(isTermination, pt, &obj, &node);
 	
-	if (!obj) return NULL;
+	if (!obj)
+	  return NULL;
 
 	switch (mObjectSpaceSubdivisionType)
@@ -1533,5 +1557,5 @@
 	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
 		{
-			KdLeaf *leaf = mOspTree->GetLeaf(pt, node);
+		  KdLeaf *leaf = mOspTree->GetLeaf(pt, node);
 			return mOspTree->GetOrCreateKdIntersectable(leaf);
 		}
@@ -1542,6 +1566,7 @@
 		}
 	default:
-		return obj;
-	}
+	  break;
+	}
+	return obj;
 }
 
