Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.h	(revision 1972)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.h	(revision 1990)
@@ -42,5 +42,6 @@
 						const AxisAlignedBox3 &box,
 						const bool castDoubleRay,
-						const bool pruneInvalidRays = true);
+						const bool pruneInvalidRays = true,
+						const bool keepOrigin = false);
 
 	virtual void CastRays16(
@@ -49,5 +50,6 @@
 							const AxisAlignedBox3 &sbox,
 							const bool castDoubleRay,
-							const bool pruneInvalidRays = true);
+							const bool pruneInvalidRays = true,
+							const bool keepOrigin = false);
 
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h	(revision 1972)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h	(revision 1990)
@@ -40,5 +40,6 @@
 						const AxisAlignedBox3 &box,
 						const bool castDoubleRay,
-						const bool pruneInvalidRays = true
+						const bool pruneInvalidRays = true,
+						const bool keepOrigin = false
 						);
 
@@ -47,5 +48,6 @@
 							 const AxisAlignedBox3 &sbox,
 							 const bool castDoubleRay,
-							 const bool pruneInvalidRays = true
+							 const bool pruneInvalidRays = true,
+							 const bool keepOrigin = false
 							 );
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1982)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1990)
@@ -34,4 +34,8 @@
 		mBorderSamples = 0;
 		mGvsPass = 0;
+
+		mTotalPvs = 0;
+		mViewCells = 0;
+		mPerViewCellSamples = 0;
 	}
 
@@ -46,4 +50,8 @@
 	int mBorderSamples;
 	int mGvsPass;
+	
+	int mTotalPvs;
+	int mViewCells;
+	int mPerViewCellSamples;
 		
 	void Print(ostream &app) const;
@@ -65,5 +73,5 @@
 
 	GvsPreprocessor();
-	~GvsPreprocessor() {}
+	~GvsPreprocessor();
 
 	virtual bool ComputeVisibility();
@@ -94,10 +102,4 @@
 	*/
 	int ProcessQueue();
-
-	/** One pass of the sampling preprocessor. 
-		Continues as long as at least passSample rays have been cast.
-		@returns the number of samples cast.
-	*/
-	int Pass();
 
 	/** Generates the rays starting the adaptive visibility sampling process.
@@ -180,4 +182,11 @@
 	void VisualizeViewCells();
 
+	void VisualizeViewCell(ViewCell *vc);
+
+	/** Exchanges view cell triangle pvs with bvh leaf pvs.
+	*/
+	void UpdatePvs(ViewCell *currentViewCell);
+
+	void ProcessViewCell();
 
 	//////////////////////
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1983)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1990)
@@ -152,5 +152,6 @@
 	float ComputeSampleContributions(const VssRayContainer &rays,
 									 const bool addContributions,
-									 const bool storeViewCells);
+									 const bool storeViewCells,
+									 const bool useHitObject = false);
 
 	/** Computes sample contribution of a simgle ray to the view cells PVS.
@@ -162,5 +163,6 @@
 	virtual float ComputeSampleContribution(VssRay &ray, 
 											const bool addContributions,
-											const bool storeViewCells);
+											const bool storeViewCells,
+											const bool useHitObject = false);
 
 	/** Compute sample contribution only for current view cell.
@@ -168,5 +170,6 @@
 	virtual float ComputeSampleContribution(VssRay &ray, 
 											const bool addContributions,
-											ViewCell *currentViewCell);
+											ViewCell *currentViewCell,
+											const bool useHitObject = false);
 
 	/** Prints out statistics of the view cells.
@@ -1036,5 +1039,4 @@
 
 	bool ViewCellsConstructed() const;
-
 	
 	int CastLineSegment(const Vector3 &origin,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1984)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1990)
@@ -44,5 +44,6 @@
 	*/
 	VssRay *CastRay(const SimpleRay &simpleRay,
-					const AxisAlignedBox3 &box);
+					const AxisAlignedBox3 &box,
+					const bool keepOrigin);
 
 	virtual int CastRay(const SimpleRay &simpleRay,
@@ -50,13 +51,15 @@
 						const AxisAlignedBox3 &box,
 						const bool castDoubleRay,
-						const bool pruneInvalidRays = true
+						const bool pruneInvalidRays = true,
+						const bool keepOrigin = false
 						) = 0;
 
-	 virtual void CastRays16(
+	virtual void CastRays16(
 							 SimpleRayContainer &rays,
 							 VssRayContainer &vssRays,
 							 const AxisAlignedBox3 &sbox,
 							 const bool castDoubleRay,
-							 const bool pruneInvalidRays = true
+							 const bool pruneInvalidRays = true,
+							 const bool keepOrigin = false
 							 ) = 0;
 
@@ -98,5 +101,6 @@
 				   const AxisAlignedBox3 &box,
 				   const bool castDoubleRay,
-				   const bool pruneInvalidRays = true);
+				   const bool pruneInvalidRays = true,
+				   const bool keepOrigin = false);
 
 	/** Checks if ray is valid.
@@ -109,9 +113,9 @@
 					 Intersection &hit);
 
-  bool
-  ClipToViewSpaceBox(const Vector3 &origin,
-					 const Vector3 &termination,
-					 Vector3 &clippedOrigin,
-					 Vector3 &clippedTermination);
+	bool
+		ClipToViewSpaceBox(const Vector3 &origin,
+						   const Vector3 &termination,
+						   Vector3 &clippedOrigin,
+						   Vector3 &clippedTermination);
 	
   	const Preprocessor &mPreprocessor;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1976)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1990)
@@ -1320,5 +1320,4 @@
 					"gvs_stats=",
 					"gvsStats.log");
-
 	
   /**********************************************************************/
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1984)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1990)
@@ -211,6 +211,7 @@
 	DEL_PTR(renderer);
 	DEL_PTR(mRayCaster);
-
+#ifdef USE_CG
 	DEL_PTR(mGlobalLinesRenderer);
+#endif
 }
 
@@ -1012,4 +1013,5 @@
   return strategy.GenerateSamples(number, rays);
 }
+
 
 int
@@ -1145,5 +1147,6 @@
 					   VssRayContainer &vssRays,
 					   const bool castDoubleRays,
-					   const bool pruneInvalidRays
+					   const bool pruneInvalidRays,
+					   const bool keepOrigin
 					   )
 {
@@ -1178,4 +1181,5 @@
 	{
 		SimpleRay ray = *rit;
+#ifdef USE_CG
 		// HACK: global lines must be treated special
 		if (ray.mDistribution == SamplingStrategy::HW_GLOBAL_LINES_DISTRIBUTION)
@@ -1184,5 +1188,5 @@
 			continue;
 		}
-
+#endif
 		rayBucket.push_back(ray);
 
@@ -1195,5 +1199,6 @@
 								   mViewCellsManager->GetViewSpaceBox(),
 								   castDoubleRays,
-								   pruneInvalidRays);
+								   pruneInvalidRays,
+								   keepOrigin);
 
 			rayBucket.clear();
@@ -1210,18 +1215,21 @@
 	{
 		SimpleRay ray = *sit;
+
+#ifdef USE_CG
 		// HACK: global lines must be treated special
 		if (ray.mDistribution == SamplingStrategy::HW_GLOBAL_LINES_DISTRIBUTION)
 		{
 			mGlobalLinesRenderer->CastGlobalLines(ray, vssRays);
-		}
-		else
-		{
-			mRayCaster->CastRay(
-								ray,
-								vssRays,
-								mViewCellsManager->GetViewSpaceBox(),
-								castDoubleRays,
-								pruneInvalidRays);
-		}
+			continue;
+		}
+#endif
+		mRayCaster->CastRay(
+							ray,
+							vssRays,
+							mViewCellsManager->GetViewSpaceBox(),
+							castDoubleRays,
+							pruneInvalidRays,
+							keepOrigin);
+		
 	}
 
@@ -1403,4 +1411,5 @@
 	Debug << endl;
 
+#ifdef USE_CG
 	globalLinesRenderer = mGlobalLinesRenderer = 
 		new GlobalLinesRenderer(this,
@@ -1410,7 +1419,9 @@
 								maxDepth,
 								sampleReverse);
-								
+
 	mGlobalLinesRenderer->InitGl();
-}
-
-}
+
+#endif
+}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1968)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1990)
@@ -145,5 +145,6 @@
 						  VssRayContainer &vssRays,
 						  const bool castDoubleRays,
-						  const bool pruneInvalidRays = true);
+						  const bool pruneInvalidRays = true,
+						  const bool keepOrigin = false);
 
 	/** Compute pixel error of the current PVS solution by sampling given number of viewpoints */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1989)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1990)
@@ -15,4 +15,5 @@
 struct SimpleRay;
 class SimpleRayContainer;
+class ViewCell;
 
 struct VssRayContainer;
@@ -45,5 +46,6 @@
 		GVS,
 		MUTATION_BASED_DISTRIBUTION,
-		HW_GLOBAL_LINES_DISTRIBUTION
+		HW_GLOBAL_LINES_DISTRIBUTION,
+		VIEWCELL_BASED_DISTRIBUTION
 	};
 
@@ -257,16 +259,21 @@
 };
 
-/** This strategy generates samples inside of the objects, e.g.,
-	for sampling the inside of a colon.
-*/
-/*class ObjectsInteriorDistribution: public SamplingStrategy
-{
- public:
-	 ObjectsInteriorDistribution(Preprocessor &preprocessor):
-	 SamplingStrategy(preprocessor) {}
-	 
-	 virtual bool GenerateSample(SimpleRay &ray);
-};
-*/
+class ViewCellBasedDistribution: public SamplingStrategy
+{
+public:
+	ViewCellBasedDistribution(Preprocessor &preprocessor, ViewCell *viewCell)
+	: SamplingStrategy(preprocessor), mViewCell(viewCell)
+	{
+		mType = VIEWCELL_BASED_DISTRIBUTION;
+	}
+
+private:
+
+	virtual bool GenerateSample(SimpleRay &ray);
+
+	ViewCell *mViewCell;
+	static HaltonSequence sHalton;
+};
+
 
 class MixtureDistribution: public SamplingStrategy 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.cpp	(revision 1980)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.cpp	(revision 1990)
@@ -9,5 +9,4 @@
 #include "SamplingStrategy.h"
 
-
 // the devil library
 #include <IL/il.h>
@@ -15,8 +14,9 @@
 #include <IL/ilut.h>
 
+#ifdef USE_CG
+
 #include <Cg/cg.h>
 #include <Cg/cgGL.h>
 
-//#include <QtOpenGL>
 
 namespace GtpVisibilityPreprocessor {
@@ -659,8 +659,5 @@
 	
 	const float leftDist = -0.5f * mWidth + mWidth * ((float)x + 0.5f) / mTexWidth;
-	//const float leftDist = 0.5f * mWidth - mWidth * ((float)x + 0.5f) / mTexWidth;
-	
-	const float upDist = -0.5f * mWidth + mWidth * ((float)y + 0.5f) / mTexHeight;
-	//const float upDist = 0.5f * mWidth - mWidth * ((float)y + 0.5f) / mTexHeight;
+	const float upDist   = -0.5f * mWidth + mWidth * ((float)y + 0.5f) / mTexHeight;
 
 	hitPoint = mViewPoint + 
@@ -693,8 +690,8 @@
 
 
-void GlobalLinesRenderer::ComputeBoundingQuad(float &xMin, 
-											  float &yMin, 
-											  float &xMax,
-											  float &yMax)
+void GlobalLinesRenderer::ComputeBoundingQuad(int &xMin, 
+											  int &yMin, 
+											  int &xMax,
+											  int &yMax)
 {
 	const AxisAlignedBox3 bbox = mPreprocessor->mKdTree->GetBox();
@@ -704,30 +701,45 @@
 	m.Invert();
 
-	Vector3 eye(m.x[0][0], m.x[0][1], m.x[0][2]);
-	Vector3 up(m.x[1][0], m.x[1][1], m.x[1][2]);
-	Vector3 left(m.x[2][0], m.x[2][1], m.x[2][2]);
+	Vector3 eye(m.x[0][0], m.x[1][0], m.x[2][0]);
+	Vector3 up(m.x[0][0], m.x[1][1], m.x[2][1]);
+	Vector3 left(m.x[0][2], m.x[1][2], m.x[2][2]);
 
 	Vector3 boxMin(1e20f);
 	Vector3 boxMax(-1e20f);
 	
-/*	for (int i = 0; i < 6; ++ i)
-	{
-		Vector3 pt;
+	for (int i = 0; i < 8; ++ i)
+	{
+        Vector3 vtx;
+
+		bbox.GetVertex(i, vtx);
+
+		Vector3 pt = vtx.x * eye + vtx.y * up + vtx.z * left;
+
 		// TODO
-		if (boxMin.x < pt[i].x)
-			boxMin.x = pt[i].x;
+		if (boxMin.x > pt.x)
+			boxMin.x = pt.x;
 		
-		if (boxMin.y < pt[i].y)
-			boxMin.y = pt[i].y;
-
-		if (boxMin.z < pt[i].z)
-			boxMin.z = pt[i].z;
-	}
-*/
-	xMin = boxMin.x;
-	yMin = boxMin.y;
-
-	xMax = boxMax.x;
-	yMax = boxMax.y;
+		if (boxMin.y > pt.y)
+			boxMin.y = pt.y;
+
+		if (boxMin.z > pt.z)
+			boxMin.z = pt.z;
+
+		if (boxMax.x < pt.x)
+			boxMax.x = pt.x;
+		
+		if (boxMax.y < pt.y)
+			boxMax.y = pt.y;
+
+		if (boxMax.z < pt.z)
+			boxMax.z = pt.z;
+	}
+
+	cout << "xmin: " << boxMin.x << " ymin " << boxMin.y << " xmax: " << boxMax.x << " ymax: " << boxMax.y << endl;
+
+	xMin = (int)(-0.5f * mWidth + mWidth * (boxMin.x + 0.5f) / mTexWidth);
+	yMin = (int)(-0.5f * mWidth + mWidth * (boxMin.y + 0.5f) / mTexHeight);
+	xMax = (int)(-0.5f * mWidth + mWidth * (boxMax.x + 0.5f) / mTexWidth);
+	yMax = (int)(-0.5f * mWidth + mWidth * (boxMax.y + 0.5f) / mTexHeight);
 }
 
@@ -757,4 +769,9 @@
 		}
 	}
+
+	int xMin, yMin, xMax, yMax;
+	ComputeBoundingQuad(xMin, yMin, xMax, yMax);
+	
+	cout << "xmin2: " << xMin << " ymin " << yMin << " xmax: " << xMax << " ymax: " << yMax << endl;
 
 	/////////////////
@@ -1081,4 +1098,5 @@
 }
 
-
-}
+}
+
+#endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1989)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1990)
@@ -1679,5 +1679,6 @@
 ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays,
 											 const bool addRays,
-   											 const bool storeViewCells)
+   											 const bool storeViewCells,
+											 const bool useHitObjects)
 {
   float sum = 0.0f;
@@ -1693,5 +1694,5 @@
 		  sum += (*it)->Length();
 	  } else {
-		sum += ComputeSampleContribution(*(*it), addRays, storeViewCells);
+		sum += ComputeSampleContribution(*(*it), addRays, storeViewCells, useHitObjects);
 	  }
 	}
@@ -2242,22 +2243,31 @@
 	  {
 		// todo: maybe not correct for kd node pvs
-		if (addRays) {
-		  float pdf = viewCell->GetPvs().AddSampleDirtyCheck(obj, ray.mPdf);
-		  if (pdf == ray.mPdf) {
-			absContribution = 1.0f;
-			if (viewCell->GetPvs().RequiresResort()) 
-			  viewCell->GetPvs().SimpleSort();
-		  }
-			  } else {
-				if (viewCell->GetPvs().GetSampleContribution(
-															 obj,
-															 ray.mPdf,
-															 relContribution))
-				  absContribution = 1.0f;
-			  }
+		if (addRays) 
+		{
+			float pdf = viewCell->GetPvs().AddSampleDirtyCheck(obj, ray.mPdf);
+			
+			if (pdf == ray.mPdf) 
+			{
+				absContribution = 1.0f;
+				if (viewCell->GetPvs().RequiresResort()) 
+					viewCell->GetPvs().SimpleSort();
+			}
+		} 
+		else 
+		{
+			if (viewCell->GetPvs().GetSampleContribution(
+														 obj,
+														 ray.mPdf,
+														 relContribution))
+			{
+				absContribution = 1.0f;
+			}
+		}
+
 		// $$ clear the relative contribution as it is currently not correct anyway
 		relContribution = 0.0f;
 		
-		if (absContribution == 1.0f) {
+		if (absContribution == 1.0f) 
+		{
 		  ++ ray.mPvsContribution;
 		  relContribution = 1.0f;
@@ -2297,5 +2307,6 @@
 float ViewCellsManager::ComputeSampleContribution(VssRay &ray,
 												  const bool addRays,
-												  ViewCell *currentViewCell)
+												  ViewCell *currentViewCell,
+												  const bool useHitObjects)
 {
 	ray.mPvsContribution = 0;
@@ -2306,5 +2317,10 @@
 
 	// optain pvs entry (can be different from hit object)
-	Intersectable *terminationObj = GetIntersectable(ray, true);
+	Intersectable *terminationObj;
+
+	if (!useHitObjects)
+		terminationObj = GetIntersectable(ray, true);
+	else
+		terminationObj = ray.mTerminationObject;
 
 	ComputeViewCellContribution(currentViewCell, 
@@ -2331,5 +2347,6 @@
 ViewCellsManager::ComputeSampleContribution(VssRay &ray,
 											const bool addRays,
-											const bool storeViewCells)
+											const bool storeViewCells,
+											const bool useHitObjects)
 {
 	ray.mPvsContribution = 0;
@@ -2361,5 +2378,5 @@
 	CastLineSegment(origin, termination, viewCells);
 
-	mSamplesStat.mViewCells+=viewCells.size();
+	mSamplesStat.mViewCells += (int)viewCells.size();
 
 	if (storeViewCells)
@@ -2375,6 +2392,11 @@
 	}
 
-	// optain pvs entry (can be different from hit object)
-	Intersectable *terminationObj = GetIntersectable(ray, true);
+	Intersectable *terminationObj;
+
+	// obtain pvs entry (can be different from hit object)
+	if (!useHitObjects)
+		terminationObj = GetIntersectable(ray, true);
+	else
+		terminationObj = ray.mTerminationObject;
 
 	ViewCellContainer::const_iterator it = viewCells.begin();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1983)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1990)
@@ -15,7 +15,10 @@
 #include "KdTree.h"
 
-//#include <Cg/cg.h>
-//#include <Cg/cgGL.h>
-
+#ifdef USE_CG
+
+#include <Cg/cg.h>
+#include <Cg/cgGL.h>
+
+#endif
 
 namespace GtpVisibilityPreprocessor {
@@ -814,9 +817,11 @@
 GlRendererBuffer::~GlRendererBuffer()
 {
-#if USE_CG
-  if (sCgFragmentProgram)
+#if 0
+#ifdef USE_CG
+	if (sCgFragmentProgram)
 		cgDestroyProgram(sCgFragmentProgram);
 	if (sCgContext)
 		cgDestroyContext(sCgContext);
+#endif
 #endif
 }
@@ -1040,10 +1045,11 @@
 	glEnable(GL_TEXTURE_2D);
 	
-#if USE_CG
+#if 0
+#ifdef USE_CG
 	// bind pixel shader implementing the front depth buffer functionality
 	cgGLBindProgram(sCgFragmentProgram);
 	cgGLEnableProfile(sCgFragmentProfile);
 #endif
-
+#endif
 	// 5. render all objects inside the beam 
 	//    we can use id based false color to read them back for gaining the pvs
@@ -1173,4 +1179,5 @@
 #endif
 
+	////////
 	//-- cleanup
 
@@ -1181,7 +1188,10 @@
 	glDisable(GL_STENCIL_TEST);
 
-#if USE_CG
+#if 0
+#ifdef USE_CG
 	cgGLDisableProfile(sCgFragmentProfile);
 #endif
+#endif
+
 	glDisable(GL_TEXTURE_2D);
 
@@ -1227,8 +1237,7 @@
 void GlRendererBuffer::InitGL()
 {
-  MakeCurrent(); 
-  GlRenderer::InitGL();
-
-#if 1
+	MakeCurrent(); 
+	GlRenderer::InitGL();
+
 	// initialise dual depth buffer textures
 	glGenTextures(1, &frontDepthMap);
@@ -1253,6 +1262,7 @@
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
-	
-#if USE_CG
+#if 0
+#ifdef USE_CG
+
 	// cg initialization
 	cgSetErrorCallback(handleCgError);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.cpp	(revision 1883)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.cpp	(revision 1990)
@@ -106,6 +106,7 @@
 								 bool *coplanar) const 
 {
-    const Vector3 v = b - a; // line from A to B
-    float dv = DotProd(v, mNormal);
+	//cout << "a: " << a << " b: " << b << endl;
+	const Vector3 v = b - a; // line from A to B
+	float dv = DotProd(v, mNormal);
     
     if (signum(dv) == 0)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.h	(revision 1980)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlobalLinesRenderer.h	(revision 1990)
@@ -50,8 +50,8 @@
 
 
-	void ComputeBoundingQuad(float &xMin, 
-							 float &yMin, 
-							 float &xMax,
-							 float &yMax);
+	void ComputeBoundingQuad(int &xMin, 
+							 int &yMin, 
+							 int &xMax,
+							 int &yMax);
 
 	void InitGl();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1984)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1990)
@@ -38,5 +38,6 @@
 							const AxisAlignedBox3 &box,
 							const bool castDoubleRay,
-							const bool pruneInvalidRays
+							const bool pruneInvalidRays,
+							const bool keepOrigin
 							)
 {
@@ -102,5 +103,6 @@
 					  box,
 					  castDoubleRay,
-					  pruneInvalidRays
+					  pruneInvalidRays,
+					  keepOrigin
 					  );
 }
@@ -112,5 +114,6 @@
 								const AxisAlignedBox3 &sbox,
 								const bool castDoubleRay,
-								const bool pruneInvalidRays)
+								const bool pruneInvalidRays,
+								const bool keepOrigin)
 {
 	int i;
@@ -227,5 +230,6 @@
 				   sbox,
 				   castDoubleRay,
-				   pruneInvalidRays
+				   pruneInvalidRays,
+				   keepOrigin
 				   );
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1977)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1990)
@@ -468,13 +468,13 @@
 	//mMemoryConst = (float)(sizeof(VspLeaf) + sizeof(VspViewCell));
 	//mMemoryConst = 50;//(float)(sizeof(VspViewCell));
-
 	//mMemoryConst = (float)(sizeof(VspLeaf) + sizeof(ObjectPvs));
+
 	mMemoryConst = 16;//(float)sizeof(ObjectPvs);
-	cout << "vsp memcost: " << mMemoryConst << endl;
+	
 
 	//////////////
 	//-- debug output
 
-	Debug << "******* VSP options ******** " << endl;
+	Debug << "******* VSP options ********" << endl;
 
     Debug << "max depth: " << mTermMaxDepth << endl;
@@ -501,6 +501,4 @@
 
 	Debug << "vsp mem const: " << mMemoryConst << endl;
-
-	cout << "use cost heuristics: " << mUseCostHeuristics << endl;
 
 	Debug << endl;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1989)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1990)
@@ -25,11 +25,12 @@
 
 VssRay *RayCaster::CastRay(const SimpleRay &simpleRay,
-						   const AxisAlignedBox3 &box)
-						   //const bool castDoubleRay) 
+						   const AxisAlignedBox3 &box,
+						   const bool keepOrigin) 
 {
 	// note: make no sense otherwise
 	const bool castDoubleRay = false;
+	
 	VssRayContainer rays;
-	CastRay(simpleRay, rays, box, castDoubleRay);
+	CastRay(simpleRay, rays, box, castDoubleRay, true, keepOrigin);
     
 	if (!rays.empty())
@@ -38,4 +39,5 @@
 		return NULL;
 }
+
 
 bool
@@ -143,5 +145,5 @@
   _SortRays(rays,
 			0,
-			rays.size()-1,
+			(int)rays.size()-1,
 			0,
 			b
@@ -162,9 +164,10 @@
   // get the largest axis
   int offset = 0;
+  int i;
 
   if (depth%5==0)
   	offset = 3;
   
-  for (int i=offset; i < offset+3; i++) {
+  for (i=offset; i < offset+3; i++) {
 	float diff = box[i+6] - box[i];
 	if (diff > maxDiff) {
@@ -176,5 +179,7 @@
   //  cout<<depth<<" "<<axis<<endl;
   
-  int i=l,j=r;
+  i=l;
+  int j=r;
+
   float x = (box[axis] + box[axis+6])*0.5f;
   //  float x = rays[(l+r)/2].GetParam(axis);
@@ -216,5 +221,6 @@
 					  const AxisAlignedBox3 &box,
 					  const bool castDoubleRay,
-					  const bool pruneInvalidRays)
+					  const bool pruneInvalidRays,
+					  const bool keepOrigin)
 {
   int hits = 0;
@@ -235,5 +241,5 @@
 	// regardless of the pruneInvalidRays setting reject rays whic degenerate to a point
 	if (EpsilonEqualV3(hitA.mPoint, hitB.mPoint, Limits::Small)) {
-	  return 0;
+		return 0;
 	}
 	
@@ -277,5 +283,5 @@
 	  if (!pruneInvalidRays || hitA.mObject) {
 		VssRay *vssRay = new VssRay(
-									clipB,
+									keepOrigin ? simpleRay.mOrigin : clipB,
 									hitA.mPoint,
 									hitB.mObject,
@@ -303,5 +309,5 @@
 		{
 		  VssRay *vssRay = new VssRay(
-									  clipA,
+									  keepOrigin ? simpleRay.mOrigin : clipA,
 									  hitB.mPoint,
 									  hitA.mObject,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1877)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1990)
@@ -129,4 +129,7 @@
                                            const int maxTries) = 0;
 
+ // virtual int GetRandomPoint(Vector3 &point,
+//							 Vector3 &normal) = 0;
+
   virtual ostream &Describe(ostream &s) = 0;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1984)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1990)
@@ -25,5 +25,6 @@
 							   const AxisAlignedBox3 &box,
 							   const bool castDoubleRay,
-							   const bool pruneInvalidRays
+							   const bool pruneInvalidRays,
+							   const bool keepOrigin
 							   )
 {
@@ -74,5 +75,6 @@
 					box,
 					castDoubleRay,
-					pruneInvalidRays
+					pruneInvalidRays,
+					keepOrigin
 					);
 }
@@ -196,5 +198,6 @@
 								   const AxisAlignedBox3 &sbox,
 								   const bool castDoubleRays,
-								   const bool pruneInvalidRays)
+								   const bool pruneInvalidRays,
+								   const bool keepOrigin)
 {
 #if DEBUG_RAYCAST
@@ -207,5 +210,5 @@
 	for (sit = rays.begin(); sit != sit_end; ++ sit) 
 	{
-		CastRay(*sit, vssRays, sbox, castDoubleRays, pruneInvalidRays);
+		CastRay(*sit, vssRays, sbox, castDoubleRays, pruneInvalidRays, keepOrigin);
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1982)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1990)
@@ -10,4 +10,5 @@
 #include "Exporter.h"
 #include "SamplingStrategy.h"
+#include "BvHierarchy.h"
 
 
@@ -24,9 +25,12 @@
 };
 
+static const float MIN_DIST = 0.01f;
+
 static vector<VizStruct> vizContainer;
 
 GvsPreprocessor::GvsPreprocessor(): 
 Preprocessor(), 
-mSamplingType(SamplingStrategy::DIRECTION_BOX_BASED_DISTRIBUTION),
+mSamplingType(SamplingStrategy::VIEWCELL_BASED_DISTRIBUTION),
+//mSamplingType(SamplingStrategy::DIRECTION_BASED_DISTRIBUTION),
 mNumViewCells(0),
 mCurrentViewCell(NULL)
@@ -37,5 +41,5 @@
 	Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.epsilon", mEps);
 	Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.threshold", mThreshold);	
-	Environment::GetSingleton()->GetBoolValue("GvsPreprocessor.UsePerViewCellSampling", mPerViewCell);
+	Environment::GetSingleton()->GetBoolValue("GvsPreprocessor.perViewCell", mPerViewCell);
 
 	char gvsStatsLog[100];
@@ -51,10 +55,24 @@
 	Debug << "stats: " << gvsStatsLog << endl;
 
-	if (0)
+	if (1)
+		mOnlyRandomSampling = false;		
+	else
 		mOnlyRandomSampling = true;
-	else
-		mOnlyRandomSampling = false;
 
 	mGvsStats.Reset();
+}
+
+
+GvsPreprocessor::~GvsPreprocessor()
+{
+	// clean ray queue
+	while (!mRayQueue.empty())
+	{
+		// handle next ray
+		VssRay *ray = mRayQueue.top();
+		mRayQueue.pop();
+
+		delete ray;
+	}
 }
 
@@ -65,6 +83,15 @@
 		return false; // no more view cells
 
-	mCurrentViewCell = mViewCellsManager->GetViewCell(mNumViewCells);
-	mViewCellsManager->CreateMesh(mCurrentViewCell);
+    if (1)
+		mCurrentViewCell = mViewCellsManager->GetViewCell(mNumViewCells);
+	else
+	{
+		// HACK
+		int idx = (int)RandomValue(0.0f, (float)mViewCellsManager->GetNumViewCells() - 0.5f);
+		mCurrentViewCell = mViewCellsManager->GetViewCell(idx);
+	}
+
+	if (!mCurrentViewCell->GetMesh())
+		mViewCellsManager->CreateMesh(mCurrentViewCell);
 
 	++ mNumViewCells;
@@ -106,5 +133,5 @@
 			delete newRay;
 		}
-		else if (GVS_DEBUG && (mVssRays.size() < 9))
+		else if (0 && GVS_DEBUG && (mVssRays.size() < 9))
 		{
 			mVssRays.push_back(new VssRay(oldRay));
@@ -122,6 +149,6 @@
 bool GvsPreprocessor::HandleRay(VssRay *vssRay)
 {
-	// compute the contribution to the view cells
-	const bool storeRaysForViz = GVS_DEBUG;
+	// store the rays + the intersected view cells
+	const bool storeRaysForViz = false; //GVS_DEBUG;
 
 	if (!mPerViewCell)
@@ -129,5 +156,6 @@
 		mViewCellsManager->ComputeSampleContribution(*vssRay, 
 													 true, 
-													 storeRaysForViz);
+													 storeRaysForViz,
+													 true);
 	}
 	else
@@ -135,5 +163,6 @@
 		mViewCellsManager->ComputeSampleContribution(*vssRay, 
 													 true, 
-													 mCurrentViewCell);
+													 mCurrentViewCell,
+													 true);
 	}
 
@@ -141,4 +170,7 @@
 	if (!vssRay->mPvsContribution)
 		return false;
+
+	if (GVS_DEBUG)
+		mVssRays.push_back(new VssRay(*vssRay));
 
 	// add new ray to ray queue
@@ -158,5 +190,5 @@
 	}
 
-	++ mGvsStats.mPassContribution;
+	++ mGvsStats.mTotalContribution;
 
 	return true;
@@ -237,41 +269,37 @@
 								   const VssRay &oldRay)
 {
+	// cast reverse rays if necessary
 	CheckDiscontinuity(ray1, hitTriangle, oldRay);
 	CheckDiscontinuity(ray2, hitTriangle, oldRay);
 
-	if (EqualVisibility(ray1, ray2) || (Magnitude(p1 - p2) <= mEps))
+	if (EqualVisibility(ray1, ray2) || (Magnitude(p1 - p2) <= MIN_DIST))
 	{
 		return 0;
 	}
-	else
-	{
-		// the new subdivision point
-		const Vector3 p = (p1 + p2) * 0.5f;
-	
-		//cout << "tobj " << ray1.mTerminationObject << " " << ray2.mTerminationObject << " " << p1 << " " << p2 << endl;
-		//cout << "term " << ray1.mTermination << " " << ray2.mTermination << endl;
-
-		// cast ray into the new point
-		SimpleRay sray(oldRay.mOrigin, p - oldRay.mOrigin, SamplingStrategy::GVS, 1.0f);
-	
-		VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox());
-
-		if (!newRay) return 0;
-
-		newRay->mFlags |= VssRay::BorderSample;
-
-		// add new ray to queue
-		const bool enqueued = HandleRay(newRay);
-		
-		// subdivide further
-		const int samples1 = SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay);
-		const int samples2 = SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay);
-			
-		// this ray will not be further processed
-		if (!enqueued)
-			delete newRay;
-		
-		return samples1 + samples2 + 1;
-	}
+	
+	// the new subdivision point
+	const Vector3 p = (p1 + p2) * 0.5f;
+
+	// cast ray into the new point
+	SimpleRay sray(oldRay.mOrigin, p - oldRay.mOrigin, SamplingStrategy::GVS, 1.0f);
+
+	VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox(), mPerViewCell);
+
+	if (!newRay) return 0;
+
+	newRay->mFlags |= VssRay::BorderSample;
+
+	// add new ray to queue
+	const bool enqueued = HandleRay(newRay);
+
+	// subdivide further
+	const int samples1 = SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay);
+	const int samples2 = SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay);
+
+	// this ray will not be further processed
+	if (!enqueued)
+		delete newRay;
+
+	return samples1 + samples2 + 1;
 }
 
@@ -301,6 +329,4 @@
 	simpleRays.reserve(9);
 
-	//cout << "currentRay: " << currentRay.mOrigin << " dir: " << currentRay.GetDir() << endl;
-
 	VertexContainer::const_iterator vit, vit_end = enlargedTriangle.end();
 
@@ -308,8 +334,7 @@
 	{
 		const Vector3 rayDir = (*vit) - currentRay.GetOrigin();
+
 		SimpleRay sr(currentRay.GetOrigin(), rayDir, SamplingStrategy::GVS, 1.0f);
-		simpleRays.AddRay(sr);
-
-		//cout << "new: " << sr.mOrigin << " dist: " << sr.mDirection << endl;
+		simpleRays.AddRay(sr);	
 	}
 
@@ -328,9 +353,9 @@
 	// don't cast double rays as we need only the forward rays
 	const bool castDoubleRays = false;
-	// cannot prune invalid rays because we have to 
-	// compare adjacent  rays.
+	// cannot prune invalid rays because we have to compare adjacent  rays.
 	const bool pruneInvalidRays = false;
 
-	CastRays(simpleRays, vssRays, castDoubleRays, pruneInvalidRays);
+	// keep origin for per view cell sampling
+	CastRays(simpleRays, vssRays, castDoubleRays, pruneInvalidRays, mPerViewCell);
 
 	// set flags
@@ -344,7 +369,7 @@
 	EnqueueRays(vssRays);
 	
-	const int n = (int)enlargedTriangle.size();
-	int castRays = (int)vssRays.size();
-
+	const int n = (int)vssRays.size();
+	int castRays = n;
+	
     // recursivly subdivide each edge
 	for (int i = 0; i < n; ++ i)
@@ -395,4 +420,5 @@
 
 	const float eps = mEps;
+
 	// the point is chosen to be on the side closer to the original ray
 	if (Distance(pt1, pt3) < Distance(pt2, pt3))
@@ -432,24 +458,43 @@
 	const Vector3 predicted = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay);
 
+	Vector3 newDir, newOrigin;
+
 	//-- Construct the mutated ray with xnew,
 	//-- dir = predicted(x)- pnew as direction vector
-	const Vector3 newDir = predicted - newPoint;
+	newDir = predicted - newPoint;
 
 	// take xnew, p = intersect(viewcell, line(pnew, predicted(x)) as origin ?
 	// difficult to say!!
 	const float offset = 0.5f;
-	const Vector3 newOrigin = newPoint - newDir * offset;
-
-	static Ray ray(newOrigin, newDir, Ray::LOCAL_RAY);
-	ray.Precompute();
-
-	// check if ray intersects view cell
-	if (mPerViewCell && !mCurrentViewCell->CastRay(ray))
-		return NULL;
+	newOrigin = newPoint - newDir * offset;
+	
+	//////////////
+	//-- for per view cell sampling, we must check for intersection
+	//-- with the current view cell
+
+    if (mPerViewCell)
+	{
+		// send ray to view cell
+		static Ray ray;
+		ray.Clear();
+		ray.Init(newOrigin, -newDir, Ray::LOCAL_RAY);
+		//ray.Init(newOrigin, -newDir, Ray::LINE_SEGMENT);
+		
+		//cout << "z";
+		// check if ray intersects view cell
+		if (!mCurrentViewCell->CastRay(ray))
+			return NULL;
+
+		Ray::Intersection &hit = ray.intersections[0];
+	
+		//cout << "q";
+		// the ray starts from the view cell
+		newOrigin = ray.Extrap(hit.mT);
+	}
 
 	const SimpleRay simpleRay(newOrigin, newDir, SamplingStrategy::GVS, 1.0f);
 
 	VssRay *reverseRay = 
-		mRayCaster->CastRay(simpleRay, mViewCellsManager->GetViewSpaceBox());
+		mRayCaster->CastRay(simpleRay, mViewCellsManager->GetViewSpaceBox(), mPerViewCell);
 
     ++ mGvsStats.mReverseSamples;
@@ -466,14 +511,24 @@
 	// generate simple rays
 	SimpleRayContainer simpleRays;
-	GenerateRays(numSamples, sampleType, simpleRays);
-
+	
+	ViewCellBasedDistribution vcStrat(*this, mCurrentViewCell);
+
+    GenerateRays(numSamples, vcStrat, simpleRays);
+
+	//cout << "sr: " << simpleRays.size() << endl;
 	// generate vss rays
 	VssRayContainer samples;
-	CastRays(simpleRays, samples, true);
+	
+	const bool castDoubleRays = false;
+	const bool pruneInvalidRays = true;
+	const bool keepOrigin = mPerViewCell;
+
+	CastRays(simpleRays, samples, castDoubleRays, pruneInvalidRays, keepOrigin);
+	
 	// add to ray queue
 	EnqueueRays(samples);
 
 	//Debug << "generated " <<  numSamples << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-	return (int)samples.size();
+	return (int)simpleRays.size();
 }
 
@@ -490,25 +545,4 @@
 
 
-int GvsPreprocessor::Pass()
-{
-	// reset samples
-	int castSamples = 0;
-	mGvsStats.mPassContribution = 0;
-
-	while (castSamples < mSamplesPerPass) 
-	{	
-		// Ray queue empty => 
-		// cast a number of uniform samples to fill ray queue
-		castSamples += CastInitialSamples(mInitialSamples, mSamplingType);
-
-		if (!mOnlyRandomSampling)
-			castSamples += ProcessQueue();
-	}
-
-	mGvsStats.mTotalContribution += mGvsStats.mPassContribution;
-	return castSamples;
-}
-
-
 int GvsPreprocessor::ProcessQueue()
 {
@@ -516,187 +550,34 @@
 	++ mGvsStats.mGvsPass;
 
-	while (!mRayQueue.empty()) 
+	while (!mRayQueue.empty() 
+		)//&& (mGvsStats.mTotalSamples + castSamples < mTotalSamples) )
 	{
 		// handle next ray
 		VssRay *ray = mRayQueue.top();
 		mRayQueue.pop();
-
-		castSamples += AdaptiveBorderSampling(*ray);
+		if (!ray) cout << "Error!!!!!" << endl;
+		const int newSamples = AdaptiveBorderSampling(*ray);
+
+		castSamples += newSamples;
+
+		//cout << newSamples << " ";	
 		delete ray;
 	}
-	
+
 	return castSamples;
 }
 
 
-void GvsPreprocessor::VisualizeViewCells()
-{
-	char str[64]; sprintf(str, "tmp/pass%06d_%04d-", mNumViewCells, mPass);
-			
-	// visualization
-	if (mGvsStats.mPassContribution > 0)
-	{
-		const bool exportRays = true;
-		const bool exportPvs = true;
-
-		mViewCellsManager->ExportSingleViewCells(mObjects, 
-												 10, 
-												 false, 
-												 exportPvs, 
-												 exportRays, 
-												 1000, 
-												 str);
-	}
-
-	// remove pass samples
-	ViewCellContainer::const_iterator vit, vit_end = mViewCellsManager->GetViewCells().end();
-
-	for (vit = mViewCellsManager->GetViewCells().begin(); vit != vit_end; ++ vit)
-	{
-		(*vit)->DelRayRefs();
-	}
-}
-
-
-void GvsPreprocessor::PerViewCellComputation()
-{
-	const int maxViewCells = 5;
-
-	while (NextViewCell() && mNumViewCells < maxViewCells)
-	{
-		cout << "processing view cell " << mNumViewCells << endl;
-
-		while (mGvsStats.mTotalSamples < mTotalSamples) 
-		{
-			++ mPass;
-
-			mGvsStats.mTotalSamples += Pass();
-				
-			////////
-			//-- stats
-
-			cout << "\nPass " << mPass << " #samples: " << mGvsStats.mTotalSamples 
-				 << " of " << mTotalSamples << endl;
-
-			mGvsStats.mPass = mPass;
-			mGvsStats.Stop();
-			mGvsStats.Print(mGvsStatsStream);
-			//mViewCellsManager->PrintPvsStatistics(mGvsStats);
-
-			if (GVS_DEBUG)
-				VisualizeViewCells();
-		}
-
-		// ComputeRenderError();
-	}
-}
-
-
-void GvsPreprocessor::GlobalComputation()
-{
-	while (mGvsStats.mTotalSamples < mTotalSamples) 
-	{
-		++ mPass;
-
-		mGvsStats.mTotalSamples += Pass();
-				
-		////////
-		//-- stats
-
-		cout << "\nPass " << mPass << " #samples: " << mGvsStats.mTotalSamples 
-			 << " of " << mTotalSamples << endl;
-
-		mGvsStats.mPass = mPass;
-		mGvsStats.Stop();
-		mGvsStats.Print(mGvsStatsStream);
-		//mViewCellsManager->PrintPvsStatistics(mGvsStats);
-
-		if (GVS_DEBUG)
-			VisualizeViewCells();
-	}
-}
-
-
-bool GvsPreprocessor::ComputeVisibility()
-{
-	cout << "Gvs Preprocessor started\n" << flush;
-	const long startTime = GetTime();
-
-	Randomize(0);
-	
-	mGvsStats.Reset();
-	mGvsStats.Start();
-
-	if (!mLoadViewCells)
-	{	
-		/// construct the view cells from the scratch
-		ConstructViewCells();
-		// reset pvs already gathered during view cells construction
-		mViewCellsManager->ResetPvs();
-		cout << "finished view cell construction" << endl;
-	}
-	else if (0)
-	{	
-		//-- test successful view cells loading by exporting them again
-		VssRayContainer dummies;
-		mViewCellsManager->Visualize(mObjects, dummies);
-		mViewCellsManager->ExportViewCells("test.xml.gz", mViewCellsManager->GetExportPvs(), mObjects);
-	}
-
-	mGvsStats.Stop();
-	mGvsStats.Print(mGvsStatsStream);
-
-	if (mPerViewCell)
-	{
-		PerViewCellComputation();
-	}
-	else
-	{
-		GlobalComputation();
-	}
-
-	cout << "cast " << 2 * mGvsStats.mTotalSamples / (1e3f * TimeDiff(startTime, GetTime())) << "M rays/s" << endl;
-
-	if (GVS_DEBUG)
-	{
-		Visualize();
-		CLEAR_CONTAINER(mVssRays);
-	}
-
-	return true;
-}
-
-
-void GvsPreprocessor::Visualize()
-{
-	Exporter *exporter = Exporter::GetExporter("gvs.wrl");
-
-	if (!exporter)
-		return;
-	
-	vector<VizStruct>::const_iterator vit, vit_end = vizContainer.end();
-	for (vit = vizContainer.begin(); vit != vit_end; ++ vit)
-	{
-		exporter->SetWireframe();
-		exporter->ExportPolygon((*vit).enlargedTriangle);
-		//Material m;
-		exporter->SetFilled();
-		Polygon3 poly = Polygon3((*vit).originalTriangle);
-		exporter->ExportPolygon(&poly);
-	}
-
-	VssRayContainer::const_iterator rit, rit_end = mVssRays.end();
-	for (rit = mVssRays.begin(); rit != rit_end; ++ rit)
-	{
-		Intersectable *obj = (*rit)->mTerminationObject;
-		exporter->ExportIntersectable(obj);
-	}
-
+void ExportVssRays(Exporter *exporter, const VssRayContainer &vssRays)
+{
 	VssRayContainer vcRays, vcRays2, vcRays3;
 
+	VssRayContainer::const_iterator rit, rit_end = vssRays.end();
+
 	// prepare some rays for output
-	for (rit = mVssRays.begin(); rit != rit_end; ++ rit)
-	{
-		const float p = RandomValue(0.0f, (float)mVssRays.size());
+	for (rit = vssRays.begin(); rit != rit_end; ++ rit)
+	{
+		//const float p = RandomValue(0.0f, (float)vssRays.size());
+
 		if (1)//(p < raysOut)
 		{
@@ -716,9 +597,316 @@
 	}
 
-	exporter->ExportRays(vcRays, RgbColor(1, 0, 0));
+	//exporter->ExportRays(vcRays, RgbColor(1, 0, 0));
 	exporter->ExportRays(vcRays2, RgbColor(0, 1, 0));
-	exporter->ExportRays(vcRays3, RgbColor(1, 1, 1));
-
-	//exporter->ExportRays(mVssRays);
+	//exporter->ExportRays(vcRays3, RgbColor(1, 1, 1));
+}
+
+
+void GvsPreprocessor::VisualizeViewCell(ViewCell *vc)
+{
+    Intersectable::NewMail();
+
+	Material m;
+	
+	char str[64]; sprintf(str, "pass%06d.wrl", mNumViewCells);
+
+	Exporter *exporter = Exporter::GetExporter(str);
+	if (!exporter)
+		return;
+
+	ObjectPvsIterator pit = vc->GetPvs().GetIterator();
+
+	// output PVS of view cell
+	while (pit.HasMoreEntries())
+	{		
+		ObjectPvsEntry entry = pit.Next();
+
+		Intersectable *intersect = entry.mObject;
+		
+		if (intersect->Mailed())
+			continue;
+		
+		intersect->Mail();
+		//m.mDiffuseColor = RgbColor(1, 0, 0);
+		m = RandomMaterial();
+		exporter->SetForcedMaterial(m);
+
+		exporter->ExportIntersectable(intersect);
+	}
+
+	cout << "vssrays: " << (int)mVssRays.size() << endl;
+	ExportVssRays(exporter, mVssRays);
+
+	/////////////////
+	//-- export view cell geometry
+
+	exporter->SetWireframe();
+
+	m.mDiffuseColor = RgbColor(0, 1, 0);
+	exporter->SetForcedMaterial(m);
+
+	mViewCellsManager->ExportViewCellGeometry(exporter, vc, NULL, NULL);
+	//exporter->SetFilled();
+
+	DEL_PTR(exporter);
+}
+
+
+void GvsPreprocessor::VisualizeViewCells()
+{
+	char str[64]; sprintf(str, "tmp/pass%06d_%04d-", mNumViewCells, mPass);
+			
+	// visualization
+	if (mGvsStats.mPassContribution > 0)
+	{
+		const bool exportRays = true;
+		const bool exportPvs = true;
+
+		mViewCellsManager->ExportSingleViewCells(mObjects, 
+												 10, 
+												 false, 
+												 exportPvs, 
+												 exportRays, 
+												 1000, 
+												 str);
+	}
+
+	// remove pass samples
+	ViewCellContainer::const_iterator vit, vit_end = mViewCellsManager->GetViewCells().end();
+
+	for (vit = mViewCellsManager->GetViewCells().begin(); vit != vit_end; ++ vit)
+	{
+		(*vit)->DelRayRefs();
+	}
+}
+
+
+void GvsPreprocessor::ProcessViewCell()
+{
+	mGvsStats.mPerViewCellSamples = 0;
+	int oldContribution = 0;
+	int passSamples = 0;
+
+	while (mGvsStats.mPerViewCellSamples < mTotalSamples) 
+	{
+		// Ray queue empty => 
+		// cast a number of uniform samples to fill ray queue
+		int newSamples = CastInitialSamples(mInitialSamples, mSamplingType);
+
+		if (!mOnlyRandomSampling)
+			newSamples += ProcessQueue();
+
+		passSamples += newSamples;
+		mGvsStats.mPerViewCellSamples += newSamples;
+	
+		if (0 &&
+			passSamples % (mSamplesPerPass + 1) == mSamplesPerPass)
+		{
+			++ mPass;
+
+			mGvsStats.mPassContribution = mGvsStats.mTotalContribution - oldContribution;
+
+			////////
+			//-- stats
+
+			mGvsStats.mPass = mPass;
+			mGvsStats.Stop();
+			mGvsStats.Print(mGvsStatsStream);
+
+			//cout << "\nPass " << mPass << " #samples: " << mGvsStats.mTotalSamples << " of " << mTotalSamples << endl;
+
+			// reset
+			oldContribution = mGvsStats.mTotalContribution;
+			mGvsStats.mPassContribution = 0;
+			passSamples = 0;
+		}
+	}
+}
+
+
+void GvsPreprocessor::PerViewCellComputation()
+{
+	const int maxViewCells = 25;
+	
+	while (mNumViewCells < maxViewCells && NextViewCell())
+	{
+		cout << "processing view cell " << mNumViewCells << endl;
+
+		// compute the pvs of the current view cell
+		ProcessViewCell();
+
+		// exchange triangle pvs with objects
+		UpdatePvs(mCurrentViewCell);
+
+		if (GVS_DEBUG)
+		{
+			VisualizeViewCell(mCurrentViewCell);
+			CLEAR_CONTAINER(mVssRays);
+		}
+
+		////////
+		//-- stats
+		
+		mGvsStats.mViewCells = mNumViewCells;//mPass;
+		mGvsStats.mTotalPvs += mCurrentViewCell->GetPvs().GetSize();
+		mGvsStats.mTotalSamples += mGvsStats.mPerViewCellSamples;
+
+		mGvsStats.Stop();
+		mGvsStats.Print(mGvsStatsStream);
+	}
+}
+
+
+void GvsPreprocessor::UpdatePvs(ViewCell *currentViewCell)
+{
+	ObjectPvs newPvs;
+	BvhLeaf::NewMail();
+
+	ObjectPvsIterator pit = currentViewCell->GetPvs().GetIterator();
+
+	// output PVS of view cell
+	while (pit.HasMoreEntries())
+	{		
+		ObjectPvsEntry entry = pit.Next();
+
+		Intersectable *intersect = entry.mObject;
+	
+		BvhLeaf *bv = intersect->mBvhLeaf;
+
+		if (!bv || bv->Mailed())
+			continue;
+		
+		bv->Mail();
+
+		//m.mDiffuseColor = RgbColor(1, 0, 0);
+		newPvs.AddSampleDirty(bv, 1.0f);
+	}
+
+	newPvs.SimpleSort();
+
+	currentViewCell->SetPvs(newPvs);
+}
+
+
+void GvsPreprocessor::GlobalComputation()
+{
+	int passSamples = 0;
+	int oldContribution = 0;
+
+	while (mGvsStats.mTotalSamples < mTotalSamples) 
+	{
+		// Ray queue empty => 
+		// cast a number of uniform samples to fill ray queue
+		int newSamples = CastInitialSamples(mInitialSamples, mSamplingType);
+
+		if (!mOnlyRandomSampling)
+			newSamples += ProcessQueue();
+
+		passSamples += newSamples;
+		mGvsStats.mTotalSamples += newSamples;
+
+		if (passSamples % (mSamplesPerPass + 1) == mSamplesPerPass)
+		{
+			++ mPass;
+
+			mGvsStats.mPassContribution = mGvsStats.mTotalContribution - oldContribution;
+
+			////////
+			//-- stats
+
+			//cout << "\nPass " << mPass << " #samples: " << mGvsStats.mTotalSamples << " of " << mTotalSamples << endl;
+			mGvsStats.mPass = mPass;
+			mGvsStats.Stop();
+			mGvsStats.Print(mGvsStatsStream);
+
+			// reset
+			oldContribution = mGvsStats.mTotalContribution;
+			mGvsStats.mPassContribution = 0;
+			passSamples = 0;
+
+			if (GVS_DEBUG)
+				VisualizeViewCells();
+		}
+	}
+}
+
+
+bool GvsPreprocessor::ComputeVisibility()
+{
+	cout << "Gvs Preprocessor started\n" << flush;
+	const long startTime = GetTime();
+
+	//Randomize(0);
+	
+	mGvsStats.Reset();
+	mGvsStats.Start();
+
+	if (!mLoadViewCells)
+	{	
+		/// construct the view cells from the scratch
+		ConstructViewCells();
+		// reset pvs already gathered during view cells construction
+		mViewCellsManager->ResetPvs();
+		cout << "finished view cell construction" << endl;
+	}
+	else if (0)
+	{	
+		//-- test successful view cells loading by exporting them again
+		VssRayContainer dummies;
+		mViewCellsManager->Visualize(mObjects, dummies);
+		mViewCellsManager->ExportViewCells("test.xml.gz", mViewCellsManager->GetExportPvs(), mObjects);
+	}
+
+	mGvsStats.Stop();
+	mGvsStats.Print(mGvsStatsStream);
+
+	if (mPerViewCell)
+	{
+		PerViewCellComputation();
+	}
+	else
+	{
+		GlobalComputation();
+	}
+
+	cout << "cast " << 2 * mGvsStats.mTotalSamples / (1e3f * TimeDiff(startTime, GetTime())) << "M rays/s" << endl;
+
+	if (GVS_DEBUG)
+	{
+		Visualize();
+		CLEAR_CONTAINER(mVssRays);
+	}
+
+	return true;
+}
+
+
+void GvsPreprocessor::Visualize()
+{
+	Exporter *exporter = Exporter::GetExporter("gvs.wrl");
+
+	if (!exporter)
+		return;
+	
+	vector<VizStruct>::const_iterator vit, vit_end = vizContainer.end();
+	for (vit = vizContainer.begin(); vit != vit_end; ++ vit)
+	{
+		exporter->SetWireframe();
+		exporter->ExportPolygon((*vit).enlargedTriangle);
+		//Material m;
+		exporter->SetFilled();
+		Polygon3 poly = Polygon3((*vit).originalTriangle);
+		exporter->ExportPolygon(&poly);
+	}
+
+	VssRayContainer::const_iterator rit, rit_end = mVssRays.end();
+	for (rit = mVssRays.begin(); rit != rit_end; ++ rit)
+	{
+		Intersectable *obj = (*rit)->mTerminationObject;
+		exporter->ExportIntersectable(obj);
+	}
+
+	ExportVssRays(exporter, mVssRays);
+	
 	delete exporter;
 }
@@ -735,6 +923,9 @@
 	app << "#BorderSamples\n" << mBorderSamples << endl;		
 	app << "#GvsRuns\n" << mGvsPass << endl;
-}
-
-
-}
+	app << "#ViewCells\n" << mViewCells << endl;
+	app << "#TotalPvs\n" << mTotalPvs << endl;
+	app << "#PerViewCellSamples\n" << mPerViewCellSamples << endl << endl;
+}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1981)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1990)
@@ -212,5 +212,5 @@
   int nearestFace = -1;
   
-  if (ray.GetType() == Ray::LOCAL_RAY && ray.intersections.size())
+  if (ray.GetType() == Ray::LOCAL_RAY && !ray.intersections.empty())
     nearestT = ray.intersections[0].mT;
 
@@ -230,14 +230,14 @@
   
   if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
-    if (ray.intersections.size())
+    if (!ray.intersections.empty())
       ray.intersections[0] = Ray::Intersection(nearestT,
-																							 nearestNormal,
-																							 instance,
-																							 nearestFace);
+											   nearestNormal,
+											   instance,
+											   nearestFace);
     else
       ray.intersections.push_back(Ray::Intersection(nearestT,
-																										nearestNormal,
-																										instance,
-																										nearestFace));
+													nearestNormal,
+													instance,
+													nearestFace));
   }
   
@@ -758,4 +758,5 @@
 {
   int res = mMesh->CastRay(ray, this);
+
   return res;
 }
