Index: /GTP/trunk/Lib/Vis/Preprocessing/scripts/run_gvs_vps.sh
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/scripts/run_gvs_vps.sh	(revision 2690)
+++ /GTP/trunk/Lib/Vis/Preprocessing/scripts/run_gvs_vps.sh	(revision 2691)
@@ -36,5 +36,5 @@
 -gvs_initial_samples=16 \
 -gvs_max_viewcells=1 \
--gvs_min_contribution=1500 \
+-gvs_min_contribution=3000 \
 -gvs_per_viewcell=true \
 -gvs_stats=$LOG_PREFIX-gvsStats.log \
Index: /GTP/trunk/Lib/Vis/Preprocessing/scripts/run_demo_vienna
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/scripts/run_demo_vienna	(revision 2689)
+++ /GTP/trunk/Lib/Vis/Preprocessing/scripts/run_demo_vienna	(revision 2691)
@@ -25,5 +25,6 @@
 #PREFIX=../work/plots/atlanta2-rss9
 
-DISTRIBUTIONS=mutation+object_direction+spatial
+#DISTRIBUTIONS=mutation+object_direction+spatial
+DISTRIBUTIONS=object_direction
 #DISTRIBUTIONS=spatial
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 2690)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 2691)
@@ -13,5 +13,5 @@
 class TriangleIntersectable;
 class KdIntersectable;
-
+class ViewCellBasedDistribution;
 
 /** View space partition statistics.
@@ -128,5 +128,5 @@
 	/** Generates the rays starting the adaptive visibility sampling process.
 	*/
-	int CastInitialSamples(const int numSamples, const int sampleType);
+	int CastInitialSamples(int numSamples);
 
 	/** Uses the information gained from the ray for doing adaptive border sampling.
@@ -256,5 +256,5 @@
 
 	RayQueue mRayQueue; 
-	int mSamplingType;
+	ViewCellBasedDistribution *mDistribution;
 
 	//AxisAlignedBox3 mViewSpaceBox;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 2687)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 2691)
@@ -1016,8 +1016,6 @@
 	case SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION:
 		return new ReverseObjectBasedDistribution(*this);
-	case SamplingStrategy::VIEWCELL_BORDER_BASED_DISTRIBUTION:
-		return new ViewCellBorderBasedDistribution(*this);
-	case SamplingStrategy::VIEWSPACE_BORDER_BASED_DISTRIBUTION:
-		return new ViewSpaceBorderBasedDistribution(*this);
+	//case SamplingStrategy::VIEWCELL_BORDER_BASED_DISTRIBUTION:
+	//	return new ViewCellBorderBasedDistribution(*this);
 	case SamplingStrategy::REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION:
 		return new ReverseViewSpaceBorderBasedDistribution(*this);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 2678)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 2691)
@@ -273,6 +273,5 @@
 	RayCaster *mRayCaster;
 
-	int mGenericStats;
-	int mGenericStats2;
+	int mGenericStats[2];
 
 	void ScheduleUpdateDynamicObjects();
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 2575)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 2691)
@@ -194,5 +194,6 @@
  public:
 	 ViewSpaceBorderBasedDistribution(Preprocessor &preprocessor):
-	   SamplingStrategy(preprocessor){
+	   SamplingStrategy(preprocessor)
+	   {
 	   mType = VIEWSPACE_BORDER_BASED_DISTRIBUTION;
 	 }
@@ -220,12 +221,14 @@
 {
  public:
-  ViewCellBorderBasedDistribution(Preprocessor &preprocessor):
-	SamplingStrategy(preprocessor) {
-	mType = VIEWCELL_BORDER_BASED_DISTRIBUTION;
-
-  }
+	 ViewCellBorderBasedDistribution(Preprocessor &preprocessor, ViewCell *viewCell)
+		 : SamplingStrategy(preprocessor), mViewCell(viewCell)
+	 {
+		 mType = VIEWCELL_BORDER_BASED_DISTRIBUTION;
+	 }
 
 private:
   virtual bool GenerateSample(SimpleRay &ray);
+
+  ViewCell *mViewCell;
 };
 
@@ -268,7 +271,9 @@
 	}
 
-private:
-
-  virtual bool GenerateSample(SimpleRay &ray);
+	void SetViewCell(ViewCell *vc) { mViewCell = vc; }
+
+private:
+
+	virtual bool GenerateSample(SimpleRay &ray);
 
 	ViewCell *mViewCell;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 2686)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 2691)
@@ -200,4 +200,6 @@
   Vector3 GetRandomSurfacePoint() const;
   Vector3 GetUniformRandomSurfacePoint() const;
+
+  void GetRandomEdgePoint(Vector3 &point, Vector3 &normal);
 
   Vector3 GetPoint(const Vector3 &p) const {
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.h	(revision 2614)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.h	(revision 2691)
@@ -241,7 +241,7 @@
 
 	virtual int CastRay(Ray &ray);
-        virtual int CastSimpleRay(const SimpleRay &ray) { return 0;}
-        virtual int CastSimpleRay(const SimpleRay &ray, int IndexRay)
-        { return 0; }
+	virtual int CastSimpleRay(const SimpleRay &ray) { return 0;}
+	virtual int CastSimpleRay(const SimpleRay &ray, int IndexRay)
+	{ return 0; }
 
 	virtual bool IsConvex() const { return mMesh->mIsConvex; }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 2690)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 2691)
@@ -1077,8 +1077,8 @@
       KdInterior *interior = (KdInterior *)node;
 	  
-      if ( box.Max()[interior->mAxis] > interior->mPosition )
+      if ( box.Max()[interior->mAxis] >= interior->mPosition )
 	nodeStack.push(interior->mFront);
       
-      if (box.Min()[interior->mAxis] < interior->mPosition)
+      if (box.Min()[interior->mAxis] <= interior->mPosition)
 	nodeStack.push(interior->mBack);
     }
@@ -1155,5 +1155,5 @@
 
 
-void KdTree::CollectObjectsWithDublicates(KdNode *n, ObjectContainer &objects)
+void KdTree::CollectObjectsWithDublicates(KdNode *n, ObjectContainer &objects) const
 {
 	stack<KdNode *> nodeStack;
@@ -1778,4 +1778,35 @@
 }
 
+
+KdNode *
+KdTree::GetPvsNodeCheck(const Vector3 &point, Intersectable *obj) const
+{
+  KdNode *node = mRoot;
+  
+  while (node->mPvsTermination == 0 ) {
+    KdInterior *inter = (KdInterior *)node;
+    if (point[inter->mAxis] < inter->mPosition)
+      node = inter->mBack;
+    else
+      node = inter->mFront;
+  }
+  
+  ObjectContainer objects;
+  CollectObjectsWithDublicates(node, objects);
+
+  ObjectContainer::const_iterator oit, oit_end = objects.end();
+
+  bool found = false;
+  for (oit = objects.begin(); oit != oit_end; ++ oit)
+  {
+	  if ((*oit)->GetId() == obj->GetId())
+		  found = true;
+  }
+
+  if (!found) return NULL;
+
+  return node;
+}
+
 KdNode *
 KdTree::GetNode(const Vector3 &point,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 2690)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 2691)
@@ -386,4 +386,6 @@
   GetPvsNode(const Vector3 &point) const;
   
+ KdNode *
+  GetPvsNodeCheck(const Vector3 &point, Intersectable *obj) const;
 
   void
@@ -406,5 +408,5 @@
   /** Collects objects with dublicates (no mailing going on)
   */
-  void CollectObjectsWithDublicates(KdNode *n, ObjectContainer &objects);
+  void CollectObjectsWithDublicates(KdNode *n, ObjectContainer &objects) const;
   void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp	(revision 2672)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ObjParser.cpp	(revision 2691)
@@ -296,10 +296,11 @@
 					for (tit = triangles.begin(); tit != tit_end; ++ tit)
 					{
-					  // test if the triangle is valid (i.e., not degenerated)
-					  if (!TriangleValid(*tit))
-						  continue;
-
-					  TriangleIntersectable *obj = new TriangleIntersectable(*tit);	
-					  root->mGeometry.push_back(obj);
+						// test if the triangle is valid (i.e., not degenerated)
+						// matt: removed this option so tris can be mapped to intel
+						if (0 && !TriangleValid(*tit))
+							continue;
+						
+						TriangleIntersectable *obj = new TriangleIntersectable(*tit);
+						root->mGeometry.push_back(obj);
 					}
 				}
@@ -311,5 +312,5 @@
 	}
 
-	//cout << "\n**** " << root->mGeometry.size() << " " << " lines: " << line << endl;
+	cout << "\n*********\n***** " << root->mGeometry.size() << " " << " lines: " << line << endl;
 	if (loadMeshes)
 	{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 2690)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 2691)
@@ -45,8 +45,9 @@
 GvsPreprocessor::GvsPreprocessor(): 
 Preprocessor(), 
-mSamplingType(SamplingStrategy::VIEWCELL_BASED_DISTRIBUTION),
 mProcessedViewCells(0),
 mCurrentViewCell(NULL),
-mCurrentViewPoint(Vector3(0.0f, 0.0f, 0.0f))
+mCurrentViewPoint(Vector3(0.0f, 0.0f, 0.0f)),
+mOnlyRandomSampling(false)
+//mOnlyRandomSampling(true)
 {
 	Environment::GetSingleton()->GetIntValue("GvsPreprocessor.totalSamples", mTotalSamples);
@@ -70,4 +71,5 @@
 	cout << "number of gvs samples per pass: " << mGvsSamplesPerPass << endl;
 	cout << "number of samples per pass: " << mSamplesPerPass << endl;
+	cout << "only random sampling: " << mOnlyRandomSampling << endl;
 
 	Debug << "Gvs preprocessor options" << endl;
@@ -81,8 +83,5 @@
 	Debug << "min contribution: " << mMinContribution << endl;
 
-	if (1)
-		mOnlyRandomSampling = false;		
-	else
-		mOnlyRandomSampling = true;
+	mDistribution = new ViewCellBasedDistribution(*this, NULL);
 
 	mGvsStats.Reset();
@@ -90,6 +89,6 @@
 	// hack: some generic statistical values that can be read
 	// by an application using the preprocessor
-	mGenericStats = 0;
-	mGenericStats2 = 0;
+	for (int i = 0; i < 2; ++ i)
+		mGenericStats[i] = 0;
 }
 
@@ -97,4 +96,5 @@
 GvsPreprocessor::~GvsPreprocessor()
 {
+	delete mDistribution;
 	ClearRayQueue();
 }
@@ -177,5 +177,5 @@
 	{
 		++ triObj->mCounter;
-		++ mGenericStats2;
+		++ mGenericStats[1];
 	}
 }
@@ -221,28 +221,24 @@
 
 		// counter < 2 => not accounted for yet
-			// test of triangle was accounted for yet
-		if (result = AddTriangleObject(obj))
+		// test of triangle was accounted for yet
+		result = AddTriangleObject(obj);
+		
+		if (mUseKdPvs && (1 || result))
 		{
 			// exchange the triangle with the node in the pvs for kd pvs
-			if (mUseKdPvs)
+			KdNode *node = mKdTree->GetPvsNode(ray.mTermination);
+
+			//KdNode *node = mKdTree->GetPvsNodeCheck(ray.mTermination, obj);
+			//if (!node) cerr << "e: " << obj->GetBox() << " " << ray.mTermination << endl;	else 
+			if (!node->Mailed())
 			{
-				KdNode *node = mKdTree->GetPvsNode(ray.mTermination);
-
-				if (!node->Mailed())
-				{
-					// add to pvs
-					node->Mail();
-					KdIntersectable *kdInt = mKdTree->GetOrCreateKdIntersectable(node);
-					mCurrentViewCell->GetPvs().AddSampleDirty(kdInt, 1.0f);
-				
-					if (SHOW_QT_VISUALIZATION) UpdateStatsForVisualization(kdInt);	
-				}
+				//cout<<"o";
+				// add to pvs
+				node->Mail();
+				KdIntersectable *kdInt = mKdTree->GetOrCreateKdIntersectable(node);
+				mCurrentViewCell->GetPvs().AddSampleDirty(kdInt, 1.0f);
+
+				if (SHOW_QT_VISUALIZATION) UpdateStatsForVisualization(kdInt);	
 			}
-
-			result = true;
-		}
-		else
-		{
-			result = false;
 		}
 	}
@@ -257,5 +253,4 @@
 		return false;
 
-//	cout << "t";
 	if (0 && GVS_DEBUG)
 		mVssRays.push_back(new VssRay(*vssRay));
@@ -441,7 +436,6 @@
 	//const int numRandomRays = 0;
 	const int numRandomRays = 16 - (int)simpleRays.size();
-	ViewCellBasedDistribution vcStrat(*this, mCurrentViewCell);
-
-	GenerateRays(numRandomRays, vcStrat, simpleRays);
+
+	GenerateRays(numRandomRays, *mDistribution, simpleRays);
 
 
@@ -607,6 +601,5 @@
 
 
-int GvsPreprocessor::CastInitialSamples(const int numSamples, 
-										const int sampleType)
+int GvsPreprocessor::CastInitialSamples(int numSamples)
 {	
 	const long startTime = GetTime();
@@ -615,6 +608,6 @@
 	SimpleRayContainer simpleRays;
 	
-	ViewCellBasedDistribution vcStrat(*this, mCurrentViewCell);
-    GenerateRays(numSamples, vcStrat, simpleRays);
+	ViewCellBorderBasedDistribution vcStrat(*this, mCurrentViewCell);
+    GenerateRays(numSamples, *mDistribution, simpleRays);
 
 	//cout << "sr: " << simpleRays.size() << endl;
@@ -880,27 +873,32 @@
 }
 
-#if 1
+
 void GvsPreprocessor::IntersectWithViewCell()
 {
-	mCurrentViewCell->GetMesh()->ComputeBoundingBox();
-	AxisAlignedBox3 box = mCurrentViewCell->GetMesh()->mBox;
-	
+	AxisAlignedBox3 box = mCurrentViewCell->GetBox();
+
+	int oldTrianglePvs = (int)mTrianglePvs.size();
+	int newKdObj = 0;
+
+	// compute pvs kd nodes that intersect view cell
 	ObjectContainer kdobjects;
+
+	// find intersecting objects not in pvs (i.e., only unmailed)
 	mKdTree->CollectKdObjects(box, kdobjects);
 
+	ObjectContainer pvsKdObjects;
+
 	ObjectContainer::const_iterator oit, oit_end = kdobjects.end();
 
 	for (oit = kdobjects.begin(); oit != oit_end; ++ oit)
 	{
-       	// add to kdnode pvs
-		KdIntersectable *kdInt = static_cast<KdIntersectable *>(*oit);
-		
-		mCurrentViewCell->GetPvs().AddSampleDirtyCheck(kdInt, 1.0f);
-		//if (SHOW_QT_VISUALIZATION) mViewCellsManager->UpdateStatsForViewCell(mCurrentViewCell, kdInt);
-
+       	KdIntersectable *kdInt = static_cast<KdIntersectable *>(*oit);
+	
 		myobjects.clear();
-		mKdTree->CollectObjects(kdInt->GetItem(), myobjects);
+		mKdTree->CollectObjectsWithDublicates(kdInt->GetItem(), myobjects);
 
 		// account for kd object pvs
+		bool addkdobj = false;
+
 		ObjectContainer::const_iterator oit, oit_end = myobjects.end();
 
@@ -908,94 +906,23 @@
 		{
 			TriangleIntersectable *triObj = static_cast<TriangleIntersectable *>(*oit);
-            
-			CountObject(triObj);
-            
-			// the triangle itself intersects
+             
+			// test if the triangle itself intersects
 			if (box.Intersects(triObj->GetItem()))
-			{
-				if ((triObj->mCounter < ACCOUNTED_OBJECT))
-				{
-					triObj->mCounter += ACCOUNTED_OBJECT;
-
-					mTrianglePvs.push_back(triObj);
-					mGenericStats = (int)mTrianglePvs.size();
-				}
-			}			
-		}
-	}
-	cout << "added " << mTrianglePvs.size() << " triangles (" << mCurrentViewCell->GetPvs().GetSize() << " objects) by intersection" << endl;
-
-}
-
-#else
-
-void GvsPreprocessor::IntersectWithViewCell()
-{
-	//Intersectable::NewMail();
-	mCurrentViewCell->GetMesh()->ComputeBoundingBox();
-	AxisAlignedBox3 box = mCurrentViewCell->GetMesh()->mBox;
-
-	// compute pvs kd nodes that intersect view cell
-	ObjectContainer kdobjects;
-	mKdTree->CollectKdObjects(box, kdobjects);
-
-	ObjectContainer pvsKdObjects;
-
-	ObjectContainer::const_iterator oit, oit_end = kdobjects.end();
-
-	for (oit = kdobjects.begin(); oit != oit_end; ++ oit)
-	{
-       	KdIntersectable *kdInt = static_cast<KdIntersectable *>(*oit);
-	
-		myobjects.clear();
-		mKdTree->CollectObjects(kdInt->GetItem(), myobjects);
-
-		// account for kd object pvs
-		bool addkdobj = false;
-
-		ObjectContainer::const_iterator oit, oit_end = myobjects.end();
-
-		for (oit = myobjects.begin(); oit != oit_end; ++ oit)
-		{
-			TriangleIntersectable *triObj = static_cast<TriangleIntersectable *>(*oit);
-			// the triangle itself intersects => add object
-			if (box.Intersects(triObj->GetItem()))
-			{
-				if ((triObj->mCounter < ACCOUNTED_OBJECT))
-				{
-					triObj->mCounter += ACCOUNTED_OBJECT;
-
-					mTrianglePvs.push_back(triObj);
-					mGenericStats = (int)mTrianglePvs.size();
-
-					addkdobj = true;
-				}
-			}
+				addkdobj = AddTriangleObject(triObj);
 		}
 		
-		// add node to object pvs
-		if (addkdobj)
-			pvsKdObjects.push_back(kdInt);
-	}
-
-	// new mail because objects were mailed for kd tree search
-	KdNode::NewMail();
-
-	// now actually ADD new objects to object pvs
-	oit_end = pvsKdObjects.end();
-
-	for (oit = pvsKdObjects.begin(); oit != oit_end; ++ oit)
-	{
-       	KdIntersectable *kdInt = static_cast<KdIntersectable *>(*oit);
-	
-		kdInt->Mail();
-
-		mCurrentViewCell->GetPvs().AddSampleDirty(kdInt, 1.0f);
-		if (SHOW_QT_VISUALIZATION) UpdateStatsForVisualization(kdInt);	
-	}
-
-	cout << "added " << mTrianglePvs.size() << " triangles (" << (int)pvsKdObjects.size() << " objects) by intersection" << endl;
-}
-#endif
+		// add node to kd pvs
+		if (1 && addkdobj)
+		{
+			++ newKdObj;
+			mCurrentViewCell->GetPvs().AddSampleDirty(kdInt, 1.0f);
+			//mCurrentViewCell->GetPvs().AddSampleDirtyCheck(kdInt, 1.0f);
+			if (SHOW_QT_VISUALIZATION) UpdateStatsForVisualization(kdInt);
+		}
+	}
+
+	cout << "added " << (int)mTrianglePvs.size() - oldTrianglePvs << " triangles (" << newKdObj << " objects) by intersection" << endl;
+}
+
 
 void GvsPreprocessor::PerViewCellComputation()
@@ -1009,4 +936,5 @@
 			(*oit)->mCounter = NOT_ACCOUNTED_OBJECT;
 
+		mDistribution->SetViewCell(mCurrentViewCell);
         ComputeViewCell();
 	}
@@ -1114,7 +1042,8 @@
 	{
 		mRayCaster->InitPass();
+
 		// Ray queue empty => 
 		// cast a number of uniform samples to fill ray queue
-		int newSamples = CastInitialSamples(mInitialSamples, mSamplingType);
+		int newSamples = CastInitialSamples(mInitialSamples);
 
 		if (!mOnlyRandomSampling)
@@ -1286,4 +1215,6 @@
 void GvsPreprocessor::ComputeViewCell()
 {
+	mCurrentViewCell->GetMesh()->ComputeBoundingBox();
+
 	KdNode::NewMail();
 
@@ -1293,8 +1224,5 @@
 		<< "computing view cell " << mProcessedViewCells 
 		<< " (id: " << mCurrentViewCell->GetId() << ")" << endl;
-
-	// compute the pvs of the current view cell
-	// compute object that directly intersect view cell
-	//IntersectWithViewCell();
+	cout << "bb: " << mCurrentViewCell->GetBox() << endl;
 
 	mGvsStats.mPerViewCellSamples = 0;
@@ -1303,10 +1231,10 @@
 	int passSamples = 0;
 
-	mGenericStats = 0;
-	mGenericStats2 = 0;
+	for (int i = 0; i < 0; ++ i)
+		mGenericStats[i] = 0;
 
 	while (1)
 	{
-		int oldPvsSize = 0;//mCurrentViewCell->GetPvs().GetSize();
+		int oldPvsSize = mCurrentViewCell->GetPvs().GetSize();
 
 		mRayCaster->InitPass();
@@ -1314,5 +1242,5 @@
 		// Ray queue empty => 
 		// cast a number of uniform samples to fill ray queue
-		int newSamples = CastInitialSamples(mInitialSamples, mSamplingType);
+		int newSamples = CastInitialSamples(mInitialSamples);
 
 		if (!mOnlyRandomSampling)
@@ -1330,4 +1258,5 @@
 			if (GVS_DEBUG) VisualizeViewCell(mTrianglePvs);
 
+			//const bool convertPerPass = true;
 			const bool convertPerPass = false;
 
@@ -1364,6 +1293,6 @@
 	}
 	
-	// finally add objects that directly intersect the view cell
-	//IntersectWithViewCell();
+	// at last compute objects that directly intersect view cell
+	IntersectWithViewCell();
 
 		
@@ -1407,6 +1336,31 @@
 		mGvsStats.mPvsCost = 0; // todo objectPvs.EvalPvsCost();
 	}
-	else
-	{
+	else if (0)
+	{
+		//KdNode::NewMail();
+
+		// compute pvs kd nodes that intersect view cell
+		ObjectContainer mykdobjects;
+
+		// extract kd pvs
+		ObjectContainer::const_iterator it, it_end = mTrianglePvs.end();
+
+		for (it = mTrianglePvs.begin(); it != it_end; ++ it)
+		{
+			Intersectable *obj = *it;
+			// find intersecting objects not yet in pvs (i.e., only unmailed)
+			mKdTree->CollectKdObjects(obj->GetBox(), mykdobjects);
+		}
+
+		// add pvs
+		it_end = mykdobjects.end();
+
+		for (it = mykdobjects.begin(); it != it_end; ++ it)
+		{
+			mCurrentViewCell->GetPvs().AddSampleDirty(*it, 1.0f);
+		}
+
+		cout << "added " << (int)mykdobjects.size() << " new objects " << endl;
+
 		mGvsStats.mPerViewCellPvs = mCurrentViewCell->GetPvs().GetSize();
 		mGvsStats.mPvsCost = mCurrentViewCell->GetPvs().EvalPvsCost();
@@ -1471,5 +1425,5 @@
 
 		mTrianglePvs.push_back(triObj);
-		mGenericStats = (int)mTrianglePvs.size();
+		mGenericStats[0] = (int)mTrianglePvs.size();
 		return true;
 	}
@@ -1478,3 +1432,5 @@
 }
 
-}
+
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 2686)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 2691)
@@ -2372,4 +2372,22 @@
 }
 
+
+void AxisAlignedBox3::GetRandomEdgePoint(Vector3 &point,
+										 Vector3 &normal)
+{
+	// get random edge
+	const int idx = Random(12); 
+	Vector3 a, b;
+	GetEdge(idx, &a, &b);
+	
+	const float w = RandomValue(0.0f, 1.0f);
+
+	point = a * w + b * (1.0f - w);
+
+	// TODO
+	normal = Vector3(0);
+}
+
+
 Vector3
 AxisAlignedBox3::GetUniformRandomSurfacePoint() const
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 2614)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 2691)
@@ -296,14 +296,14 @@
 	Vector3 origin, direction; 
 
-	ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells();
+	//ViewCellContainer &viewCells = mPreprocessor.mViewCellsManager->GetViewCells();
 
 	Vector3 point;
 	Vector3 normal, normal2;
 	
-	const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f);
+	//const int vcIdx = (int)RandomValue(0, (float)viewCells.size() - 0.5f);
 	const int objIdx = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
 
 	Intersectable *object = mPreprocessor.mObjects[objIdx];
-	ViewCell *viewCell = viewCells[vcIdx];
+	ViewCell *viewCell = mViewCell;//viewCells[vcIdx];
 
 	object->GetRandomSurfacePoint(point, normal);
@@ -843,19 +843,11 @@
 	Vector3 origin, direction; 
 
-	ViewCellContainer &viewCells = 
-		mPreprocessor.mViewCellsManager->GetViewCells();
-
 	Vector3 point;
 	Vector3 normal;
 		
-	//Vector normalObj;
-	// float r[1];
-	// sHalton.GetNext(1, r);
-	// const int objIdx = (int)(r[0] * (float)mPreprocessor.mObjects.size() - 1.0f);
-	// Intersectable *object = mPreprocessor.mObjects[objIdx];
-	// object->GetRandomSurfacePoint(point, normal);
-	// cout << "obj: " << objIdx << endl;
-
 	float r[2];
+	//for (int i=0; i < 2; i++)
+	// r[i] = RandomValue(0, 1);
+
 	sHalton.GetNext(2, r);
 
@@ -869,11 +861,17 @@
 
 	// get point on view cell surface
-	mViewCell->GetRandomSurfacePoint(origin, normal);
+	if (0)
+	{
+		//mViewCell->GetRandomEdgePoint(origin, normal);
+		mViewCell->GetRandomSurfacePoint(origin, normal);
+
+		// move a little bit back to avoid piercing through walls
+		// that bound the view cell
+		if (0) origin -= 0.01f * normal;
+	}
+	else
+		origin = mViewCell->GetBox().GetUniformRandomSurfacePoint();
 
 	//direction = point - origin;
-
-	// move a little bit back to avoid piercing through walls
-	// that bound the view cell
-	origin -= 0.01f * normal;
 
 	// $$ jb the pdf is yet not correct for all sampling methods!
