Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1585)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1594)
@@ -870,5 +870,5 @@
 
 int QtGlRendererBuffer::ComputePvs(ObjectContainer &objects, 
-								 ObjectContainer &pvs) const
+								   ObjectContainer &pvs) const
 {
 	int pvsSize = 0;
@@ -950,5 +950,6 @@
 {
   
-  
+  Intersectable::NewMail();
+
   ViewCell *viewcell = NULL;
 
@@ -975,16 +976,21 @@
 	
 	
-	// read back the texture
 	ObjectPvsMap::const_iterator it = pvs.mEntries.begin();
-
+	
 	mPvsSize = pvs.mEntries.size();
 	  
 	for (; it != pvs.mEntries.end(); ++ it) {
 	  Intersectable *object = (*it).first;
-	  float visibility = log10((*it).second.mSumPdf + 1)/5.0f;
-	  glColor3f(visibility, 0.0f, 0.0f);
-	  mUseForcedColors = true;
-	  RenderIntersectable(object);
-	  mUseForcedColors = false;
+	  
+	  if (mRenderVisibilityEstimates) {
+		float visibility = log10((*it).second.mSumPdf + 1)/5.0f;
+		glColor3f(visibility, 0.0f, 0.0f);
+		mUseForcedColors = true;
+		RenderIntersectable(object);
+		mUseForcedColors = false;
+	  } else {
+		mUseForcedColors = false;
+		RenderIntersectable(object);
+	  }
 	}
 
@@ -1360,5 +1366,8 @@
   mCutScene = false;
   mRenderErrors = false;
+  mRenderBoxes = false;
   mRenderFilter = true;
+  mRenderVisibilityEstimates = false;
+
   mManipulatorScale = 1.0f;
   trackball(mManipulatorLastQuat, 0.0f, 0.0f, 0.0f, 0.0f);
@@ -1370,5 +1379,4 @@
   Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
 							tmp );
-
   mUseSpatialFilter = tmp;
 
@@ -1396,5 +1404,8 @@
   connect(mControlWidget, SIGNAL(SetCutScene(bool)), this, SLOT(SetCutScene(bool)));
   connect(mControlWidget, SIGNAL(SetRenderErrors(bool)), this, SLOT(SetRenderErrors(bool)));
+  connect(mControlWidget, SIGNAL(SetRenderBoxes(bool)), this, SLOT(SetRenderBoxes(bool)));
   connect(mControlWidget, SIGNAL(SetRenderFilter(bool)), this, SLOT(SetRenderFilter(bool)));
+  connect(mControlWidget, SIGNAL(SetRenderVisibilityEstimates(bool)),
+		  this, SLOT(SetRenderVisibilityEstimates(bool)));
   connect(mControlWidget, SIGNAL(SetUseFilter(bool)), this, SLOT(SetUseFilter(bool)));
   connect(mControlWidget, SIGNAL(SetUseSpatialFilter(bool)),
@@ -1825,4 +1836,16 @@
   connect(slider, SIGNAL(valueChanged(int)), SIGNAL(SetSceneCut(int)));
 
+
+  cb = new QCheckBox("Render boxes", vbox);
+  vbox->layout()->addWidget(cb);
+  cb->setChecked(false);
+  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderBoxes(bool)));
+
+  cb = new QCheckBox("Render visibility estimates", vbox);
+  vbox->layout()->addWidget(cb);
+  cb->setChecked(false);
+  connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderVisibilityEstimates(bool)));
+
+  
   cb = new QCheckBox("Render errors", vbox);
   vbox->layout()->addWidget(cb);
@@ -1830,12 +1853,19 @@
   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetRenderErrors(bool)));
 
+  
+  bool tmp;
+
   cb = new QCheckBox("Use filter", vbox);
   vbox->layout()->addWidget(cb);
-  cb->setChecked(true);
+  Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", tmp );
+  cb->setChecked(tmp);
   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseFilter(bool)));
 
+  
   cb = new QCheckBox("Use spatial filter", vbox);
   vbox->layout()->addWidget(cb);
-  cb->setChecked(true);
+  Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
+											tmp );
+  cb->setChecked(tmp);
   connect(cb, SIGNAL(toggled(bool)), SIGNAL(SetUseSpatialFilter(bool)));
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1584)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1594)
@@ -46,5 +46,5 @@
 	  Intersectable *mObject;
 
-	  /// the face of the intersectable
+	/// the face of the intersectable
 	  int mFace;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1584)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1594)
@@ -152,7 +152,9 @@
   void SetShowRays(bool);
   void SetRenderFilter(bool);
+  void SetRenderVisibilityEstimates(bool);
   void SetUseFilter(bool);
   void SetUseSpatialFilter(bool);
   void SetRenderErrors(bool);
+  void SetRenderBoxes(bool);
   void SetShowViewCells(bool);
   void SetShowRenderCost(bool);
@@ -179,4 +181,5 @@
   bool mRenderErrors;
   bool mRenderFilter;
+  bool mRenderVisibilityEstimates;
   bool mUseFilter;
   bool mUseSpatialFilter;
@@ -266,6 +269,16 @@
  }
 
+  void SetRenderBoxes(bool b) {
+	mRenderBoxes = b;
+	updateGL();
+  }
+
  void SetRenderFilter(bool b) {
    mRenderFilter = b;
+   updateGL();
+ }
+
+  void SetRenderVisibilityEstimates(bool b) {
+	mRenderVisibilityEstimates = b;
    updateGL();
  }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h	(revision 1449)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h	(revision 1594)
@@ -11,4 +11,5 @@
 #include "gzstream.h"
 #include "SubdivisionCandidate.h"
+#include "IntersectableWrapper.h"
 
 
@@ -135,5 +136,4 @@
 
 
-typedef map<KdNode *, KdIntersectable *> KdIntersectableMap;
 
 
@@ -826,5 +826,5 @@
 
     /// stores the kd node intersectables used for pvs
-	KdIntersectableMap mKdIntersectables;
+  KdIntersectableMap mKdIntersectables;
 	
 private:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1585)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1594)
@@ -11,5 +11,5 @@
 # filename ../data/glasgow/glasgow1.x3d
 #	filename vienna.x3d
-filename ../data/vienna/vienna-simple.x3d
+# filename ../data/vienna/vienna-simple.x3d
 # filename ../data/vienna/vienna-buildings.x3d
 # filename ../data/vienna/city1500_flat_1.x3d
@@ -143,9 +143,9 @@
 	sahUseFaces false
 	Termination {
-		minCost 0.95
+		minCost 4
 		maxDepth 30
-		maxCostRatio 0.98
+		maxCostRatio 0.99
 		ct_div_ci 0.5
-		maxNodes 100000
+		maxNodes 300000
 #500000	
 	}
@@ -170,9 +170,4 @@
 }
 
-
-
-
-
-
 ViewCells {
 	# samples used for view cell construction
@@ -189,11 +184,11 @@
 
 	exportToFile true
-	loadFromFile false
+	loadFromFile true
 
 	#type kdTree
 	#type vspKdTree
 	#type bspTree
-#	type vspBspTree
-	type vspOspTree
+	type vspBspTree
+	#type vspOspTree
 	#type sceneDependent
 	
@@ -243,5 +238,5 @@
 	Evaluation {
 		samplesPerPass 1000000
-		samples 1000000
+		samples 5000000
 		statsPrefix ../scripts/viewCells
 		#samplingType directional
@@ -269,5 +264,5 @@
 
 
-	filename ../data/vienna/vsposp-seq-viewCells.xml.gz
+#	filename ../data/vienna/vsposp-seq-viewCells.xml.gz
 
 #	filename ../data/atlanta/viewcells_atlanta3.xml
@@ -277,6 +272,6 @@
 #	filename ../data/vienna/vienna_simple-21-04-avs2-viewCells.xml
 #	filename ../data/vienna/vienna-viewcells-5000.xml
-#	filename ../data/vienna/vienna-viewcells-1000.xml.zip
-	filename ../data/vienna/vsposp-seq-viewCells.xml.gz
+	filename ../data/vienna/vienna-viewcells-1000.xml.zip
+#	filename ../data/vienna/vsposp-seq-viewCells.xml.gz
 
 #	filename ../data/PowerPlant/power_plant_viewcells1.xml
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1589)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1594)
@@ -29,4 +29,7 @@
 #define SAMPLE_ORIGIN_OBJECTS 0
 
+// $$JB HACK
+#define USE_KD_PVS 1
+#define KD_PVS_AREA 1e-3f
 
 namespace GtpVisibilityPreprocessor {
@@ -1183,26 +1186,26 @@
 							   const float filterWidth)
 {
-	ViewCell *currentViewCell = GetViewCell(viewPoint);
-
-	if (mMaxFilterSize < 1) {
-		prvs.mViewCell = currentViewCell;
-		return;
-	}
-
-	const AxisAlignedBox3 box = GetFilterBBox(viewPoint, filterWidth);
-
-	if (currentViewCell) 
-	{
-		ViewCellContainer viewCells;
-		ComputeBoxIntersections(box, viewCells);
-
-		ViewCell *root = ConstructLocalMergeTree2(currentViewCell, viewCells);
-		prvs.mViewCell = root;
-
+  ViewCell *currentViewCell = GetViewCell(viewPoint);
+
+  if (mMaxFilterSize < 1) {
+	prvs.mViewCell = currentViewCell;
+	return;
+  }
+  
+  const AxisAlignedBox3 box = GetFilterBBox(viewPoint, filterWidth);
+  
+  if (currentViewCell) 
+	{
+	  ViewCellContainer viewCells;
+	  ComputeBoxIntersections(box, viewCells);
+	  
+	  ViewCell *root = ConstructLocalMergeTree2(currentViewCell, viewCells);
+	  prvs.mViewCell = root;
+	  
 	} 
-	else
-	{
-		prvs.mViewCell = NULL;
-		//prvs.mPvs = root->GetPvs();
+  else
+	{
+	  prvs.mViewCell = NULL;
+	  //prvs.mPvs = root->GetPvs();
 	}
 }
@@ -1808,9 +1811,23 @@
   ViewCellContainer *viewcells = &ray.mViewCells;
   ViewCellContainer::const_iterator it;
+
+  if (!ray.mTerminationObject)
+	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
+  
   for (it = viewcells->begin(); it != viewcells->end(); ++it) {
 	ViewCell *viewcell = *it;
 	if (viewcell->GetValid()) {
 	  // if ray not outside of view space
-	  viewcell->GetPvs().AddSample(ray.mTerminationObject, ray.mPdf);
+	  viewcell->GetPvs().AddSample(obj, ray.mPdf);
 	}
   }
@@ -1851,6 +1868,17 @@
 	}
 
+#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
+	
+	
 	ViewCellContainer::const_iterator it = viewcells.begin();
-
+	
 	for (; it != viewcells.end(); ++ it) 
 	{
@@ -1862,12 +1890,13 @@
 
 			if (ray.mTerminationObject) 
-			{			
-				if (viewcell->GetPvs().GetSampleContribution(
-							ray.mTerminationObject,
-							ray.mPdf,
-							contribution))
+			  {			
+				
+
+			  if (viewcell->GetPvs().GetSampleContribution(obj,
+														   ray.mPdf,
+														   contribution))
 				{
-					++ ray.mPvsContribution;
-					ray.mRelativePvsContribution += contribution;
+				  ++ ray.mPvsContribution;
+				  ray.mRelativePvsContribution += contribution;
 				}
 			}
@@ -1903,5 +1932,5 @@
 				if (ray.mTerminationObject)
 				{
-					viewcell->GetPvs().AddSample(ray.mTerminationObject, ray.mPdf);
+					viewcell->GetPvs().AddSample(obj, ray.mPdf);
 				}				
 #if SAMPLE_ORIGIN_OBJECTS
@@ -2330,5 +2359,4 @@
   // now compute a new Pvs by including also objects intersecting the 
   // extended boxes of visible objects
-
   Intersectable::NewMail();
   
@@ -5510,16 +5538,17 @@
 			if (ray.mTerminationObject) 
 			{
-				// todo: maybe not correct for kd node pvs
-				Intersectable *obj = mHierarchyManager->GetIntersectable(ray, true);
-				if (viewcell->GetPvs().GetSampleContribution(obj,
-															 ray.mPdf, 
-															 contribution))
+			  // todo: maybe not correct for kd node pvs
+			  Intersectable *obj = mHierarchyManager->GetIntersectable(ray, true);
+			  
+			  if (viewcell->GetPvs().GetSampleContribution(obj,
+														   ray.mPdf, 
+														   contribution))
 				{
-					++ ray.mPvsContribution;
+				  ++ ray.mPvsContribution;
 				}
-
-				ray.mRelativePvsContribution += contribution;
+			  
+			  ray.mRelativePvsContribution += contribution;
 			}
-
+			
 			// for directional sampling it is important to count only contributions
 			// made in one direction!
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1589)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1594)
@@ -13,4 +13,5 @@
 #include "IntersectableWrapper.h"
 #include "BvHierarchy.h"
+#include "KdTree.h"
 
 //#include <Cg/cg.h>
@@ -78,5 +79,5 @@
   mSnapPrefix = "snap/";
   mUseForcedColors = false;
-
+  mRenderBoxes = false;
   mUseGlLists = true;
   //mUseGlLists = false;
@@ -108,5 +109,8 @@
 GlRenderer::RenderIntersectable(Intersectable *object)
 {
-
+  if (object->Mailed())
+	return;
+  object->Mail();
+  
   glPushAttrib(GL_CURRENT_BIT);
   if (mUseFalseColors)
@@ -129,7 +133,20 @@
   case Intersectable::BVH_INTERSECTABLE: {
 
+	
 	BvhNode *node = (dynamic_cast<BvhIntersectable *>(object))->GetItem();
-	//	RenderBvhNode(node);
-	RenderBox(node->GetBoundingBox());
+
+	if (mRenderBoxes)
+	  RenderBox(node->GetBoundingBox());
+	else
+	  RenderBvhNode(node);
+	break;
+  }
+  case Intersectable::KD_INTERSECTABLE: {
+	KdNode *node = (dynamic_cast<KdIntersectable *>(object))->GetItem();
+
+	if (mRenderBoxes)
+	  RenderBox(mKdTree->GetBox(node));
+	else
+	  RenderKdNode(node);
 	break;
   }
@@ -628,6 +645,5 @@
 	BvhLeaf *leaf = (BvhLeaf *) node;
 	for (int i=0; i < leaf->mObjects.size(); i++)
-		cout << "leaf obj " << i << endl;
-	  //RenderIntersectable(mObjects[i]);
+	  RenderIntersectable(leaf->mObjects[i]);
   } else {
 	BvhInterior *in = (BvhInterior *)node;
@@ -635,6 +651,24 @@
 	RenderBvhNode(in->GetFront());
   }
-  
-}
-
-}
+
+  //cout << "leaf obj " << i << endl;
+
+}
+
+void
+GlRenderer::RenderKdNode(KdNode *node)
+{
+  if (node->IsLeaf()) {
+	KdLeaf *leaf = (KdLeaf *) node;
+	for (int i=0; i < leaf->mObjects.size(); i++) {
+	  RenderIntersectable(leaf->mObjects[i]);
+	}
+  } else {
+	KdInterior *in = (KdInterior *)node;
+	RenderKdNode(in->mBack);
+	RenderKdNode(in->mFront);
+  }
+  
+}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1585)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1594)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: ne 8. X 23:47:35 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: po 9. X 21:25:05 2006
 # Project:  preprocessor.pro
 # Template: app
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1584)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1594)
@@ -1392,4 +1392,44 @@
 }
 
-
-}
+KdIntersectable *
+KdTree::GetOrCreateKdIntersectable(KdNode *node)
+{
+
+  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);
+  mKdIntersectables[node] = kdObj;
+  
+  return kdObj;
+}
+
+KdNode *
+KdTree::GetNode(const Vector3 &point,
+				const float maxArea) const
+{
+  KdNode *node = mRoot;
+  
+  while (!node->IsLeaf() && (GetSurfaceArea(node) > maxArea) ) {
+	KdInterior *inter = (KdInterior *)node;
+	if (point[inter->mAxis] < inter->mPosition)
+	  node = inter->mBack;
+	else
+	  node = inter->mFront;
+  }
+  
+  return node;
+}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1286)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1594)
@@ -11,4 +11,5 @@
 #include "Viewcell.h"
 #include "VssRay.h"
+#include "IntersectableWrapper.h"
 
 
@@ -336,4 +337,9 @@
   }
 
+  /** Returns or creates a new intersectable for use in a kd based pvs.
+	  The OspTree is responsible for destruction of the intersectable.
+  */
+  KdIntersectable *GetOrCreateKdIntersectable(KdNode *node);
+
   void
   CollectObjects(KdNode *n, ObjectContainer &objects);
@@ -368,5 +374,10 @@
     return box;
   }
-	
+
+  float GetSurfaceArea(const KdNode *node) const {
+	return GetBox(node).SurfaceArea();
+  }
+
+  
   KdNode *
   FindRandomNeighbor(KdNode *n,
@@ -379,5 +390,9 @@
   KdNode *
   GetRandomLeaf(const bool onlyUnmailed = false);
-  
+
+
+  KdNode *
+  GetNode(const Vector3 &point, const float maxArea) const;
+
   int
   FindNeighbors(KdNode *n,
@@ -574,5 +589,8 @@
   AxisAlignedBox3 mBox;
   KdTreeStatistics mStat;
-  
+
+  /// stores the kd node intersectables used for pvs
+  KdIntersectableMap mKdIntersectables;
+
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1585)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1594)
@@ -113,5 +113,8 @@
   void
   RenderBvhNode(BvhNode *node);
-	
+
+  void
+  RenderKdNode(KdNode *node);
+
   bool
   RenderScene();
@@ -161,4 +164,6 @@
   bool mDetectEmptyViewSpace;
   bool mSnapErrorFrames;
+
+  bool mRenderBoxes;
 
   bool mUseGlLists;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1587)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1594)
@@ -157,4 +157,6 @@
 
 
+typedef map<KdNode *, KdIntersectable *> KdIntersectableMap;
+
 class BvhIntersectable: public IntersectableWrapper<BvhNode *>
 {
