Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.h	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.h	(revision 1996)
@@ -42,6 +42,5 @@
 						const AxisAlignedBox3 &box,
 						const bool castDoubleRay,
-						const bool pruneInvalidRays = true,
-						const bool keepOrigin = false);
+						const bool pruneInvalidRays = true);
 
 	virtual void CastRays16(
@@ -50,6 +49,5 @@
 							const AxisAlignedBox3 &sbox,
 							const bool castDoubleRay,
-							const bool pruneInvalidRays = true,
-							const bool keepOrigin = false);
+							const bool pruneInvalidRays = true);
 
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h	(revision 1996)
@@ -40,6 +40,5 @@
 						const AxisAlignedBox3 &box,
 						const bool castDoubleRay,
-						const bool pruneInvalidRays = true,
-						const bool keepOrigin = false
+						const bool pruneInvalidRays = true
 						);
 
@@ -48,6 +47,5 @@
 							 const AxisAlignedBox3 &sbox,
 							 const bool castDoubleRay,
-							 const bool pruneInvalidRays = true,
-							 const bool keepOrigin = false
+							 const bool pruneInvalidRays = true
 							 );
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1996)
@@ -38,4 +38,7 @@
 		mViewCells = 0;
 		mPerViewCellSamples = 0;
+		mPerViewCellPvs = 0;
+		mTrianglePvs = 0;
+		mViewCellId = 0;
 	}
 
@@ -54,5 +57,10 @@
 	int mViewCells;
 	int mPerViewCellSamples;
-		
+	int mPerViewCellPvs;
+	int mTrianglePvs;
+	int mViewCellId;
+	
+	float RaysPerSec() const { if (!Time()) return 0; return (float)mTotalSamples / Time() * 1e-6f; }
+
 	void Print(ostream &app) const;
 
@@ -135,7 +143,7 @@
 		Does reverse sampling if gap found.
 	*/
-	bool CheckDiscontinuity(const VssRay &currentRay, 
-							const Triangle3 &hitTriangle,
-							const VssRay &oldRay);
+	int CheckDiscontinuity(const VssRay &currentRay, 
+						   const Triangle3 &hitTriangle,
+						   const VssRay &oldRay);
 
 	/** Adds new samples to the ray queue and classifies them
@@ -169,8 +177,8 @@
 								  const VssRay &oldRay) const;
 
-
-	Vector3 GetPassingPoint(const VssRay &currentRay,
-							const Triangle3 &hitTriangle,
-							const VssRay &oldRay) const;
+	bool GetPassingPoint(const VssRay &currentRay,
+						 const Triangle3 &occluder,
+						 const VssRay &oldRay,
+						 Vector3 &newPoint) const;
 
 	bool NextViewCell();
@@ -189,4 +197,8 @@
 
 	void ProcessViewCell();
+	void ClearRayQueue();
+
+	void CompileViewCellsList();
+
 
 	//////////////////////
@@ -222,5 +234,11 @@
 	ViewCell *mCurrentViewCell;
 
-	int mNumViewCells;
+	int mProcessedViewCells;
+
+	int mMinContribution;
+
+	ViewCellContainer mViewCells;
+
+	int mMaxViewCells;
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1996)
@@ -45,5 +45,5 @@
 	VssRay *CastRay(const SimpleRay &simpleRay,
 					const AxisAlignedBox3 &box,
-					const bool keepOrigin);
+					const bool castDoubleRay);
 
 	virtual int CastRay(const SimpleRay &simpleRay,
@@ -51,7 +51,5 @@
 						const AxisAlignedBox3 &box,
 						const bool castDoubleRay,
-						const bool pruneInvalidRays = true,
-						const bool keepOrigin = false
-						) = 0;
+						const bool pruneInvalidRays = true) = 0;
 
 	virtual void CastRays16(
@@ -60,7 +58,5 @@
 							 const AxisAlignedBox3 &sbox,
 							 const bool castDoubleRay,
-							 const bool pruneInvalidRays = true,
-							 const bool keepOrigin = false
-							 ) = 0;
+							 const bool pruneInvalidRays = true) = 0;
 
 
@@ -101,6 +97,5 @@
 				   const AxisAlignedBox3 &box,
 				   const bool castDoubleRay,
-				   const bool pruneInvalidRays = true,
-				   const bool keepOrigin = false);
+				   const bool pruneInvalidRays = true);
 
 	/** Checks if ray is valid.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1996)
@@ -1317,8 +1317,19 @@
 
 	RegisterOption("GvsPreprocessor.stats",
-					optString,
-					"gvs_stats=",
-					"gvsStats.log");
-	
+		optString,
+		"gvs_stats=",
+		"gvsStats.log");
+
+	RegisterOption("GvsPreprocessor.minContribution",
+		 optInt,
+		 "gvs_min_contribution=",
+		 "50");
+
+	 RegisterOption("GvsPreprocessor.maxViewCells",
+		 optInt,
+		 "gvs_max_viewcells=",
+		 "5");
+
+
   /**********************************************************************/
   /*                     View cells related options                     */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1996)
@@ -1147,6 +1147,5 @@
 					   VssRayContainer &vssRays,
 					   const bool castDoubleRays,
-					   const bool pruneInvalidRays,
-					   const bool keepOrigin
+					   const bool pruneInvalidRays
 					   )
 {
@@ -1199,6 +1198,5 @@
 								   mViewCellsManager->GetViewSpaceBox(),
 								   castDoubleRays,
-								   pruneInvalidRays,
-								   keepOrigin);
+								   pruneInvalidRays);
 
 			rayBucket.clear();
@@ -1229,6 +1227,5 @@
 							mViewCellsManager->GetViewSpaceBox(),
 							castDoubleRays,
-							pruneInvalidRays,
-							keepOrigin);
+							pruneInvalidRays);
 		
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1996)
@@ -145,6 +145,5 @@
 						  VssRayContainer &vssRays,
 						  const bool castDoubleRays,
-						  const bool pruneInvalidRays = true,
-						  const bool keepOrigin = false);
+						  const bool pruneInvalidRays = true);
 
 	/** Compute pixel error of the current PVS solution by sampling given number of viewpoints */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1996)
@@ -38,6 +38,5 @@
 							const AxisAlignedBox3 &box,
 							const bool castDoubleRay,
-							const bool pruneInvalidRays,
-							const bool keepOrigin
+							const bool pruneInvalidRays
 							)
 {
@@ -103,6 +102,5 @@
 					  box,
 					  castDoubleRay,
-					  pruneInvalidRays,
-					  keepOrigin
+					  pruneInvalidRays
 					  );
 }
@@ -114,6 +112,5 @@
 								const AxisAlignedBox3 &sbox,
 								const bool castDoubleRay,
-								const bool pruneInvalidRays,
-								const bool keepOrigin)
+								const bool pruneInvalidRays)
 {
 	int i;
@@ -230,6 +227,5 @@
 				   sbox,
 				   castDoubleRay,
-				   pruneInvalidRays,
-				   keepOrigin
+				   pruneInvalidRays
 				   );
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1996)
@@ -26,11 +26,8 @@
 VssRay *RayCaster::CastRay(const SimpleRay &simpleRay,
 						   const AxisAlignedBox3 &box,
-						   const bool keepOrigin) 
-{
-	// note: make no sense otherwise
-	const bool castDoubleRay = false;
-	
+						   const bool castDoubleRay) 
+{
 	VssRayContainer rays;
-	CastRay(simpleRay, rays, box, castDoubleRay, true, keepOrigin);
+	CastRay(simpleRay, rays, box, castDoubleRay, true);
     
 	if (!rays.empty())
@@ -221,6 +218,5 @@
 					  const AxisAlignedBox3 &box,
 					  const bool castDoubleRay,
-					  const bool pruneInvalidRays,
-					  const bool keepOrigin)
+					  const bool pruneInvalidRays)
 {
   int hits = 0;
@@ -283,5 +279,5 @@
 	  if (!pruneInvalidRays || hitA.mObject) {
 		VssRay *vssRay = new VssRay(
-									keepOrigin ? simpleRay.mOrigin : clipB,
+									!castDoubleRay ? simpleRay.mOrigin : clipB,
 									hitA.mPoint,
 									hitB.mObject,
@@ -309,5 +305,5 @@
 		{
 		  VssRay *vssRay = new VssRay(
-									  keepOrigin ? simpleRay.mOrigin : clipA,
+									  clipA,
 									  hitB.mPoint,
 									  hitA.mObject,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1996)
@@ -25,7 +25,5 @@
 							   const AxisAlignedBox3 &box,
 							   const bool castDoubleRay,
-							   const bool pruneInvalidRays,
-							   const bool keepOrigin
-							   )
+							   const bool pruneInvalidRays)
 {
   if (simpleRay.mType == Ray::GLOBAL_RAY)
@@ -75,6 +73,5 @@
 					box,
 					castDoubleRay,
-					pruneInvalidRays,
-					keepOrigin
+					pruneInvalidRays
 					);
 }
@@ -198,6 +195,5 @@
 								   const AxisAlignedBox3 &sbox,
 								   const bool castDoubleRays,
-								   const bool pruneInvalidRays,
-								   const bool keepOrigin)
+								   const bool pruneInvalidRays)
 {
 #if DEBUG_RAYCAST
@@ -210,5 +206,5 @@
 	for (sit = rays.begin(); sit != sit_end; ++ sit) 
 	{
-		CastRay(*sit, vssRays, sbox, castDoubleRays, pruneInvalidRays, keepOrigin);
+		CastRay(*sit, vssRays, sbox, castDoubleRays, pruneInvalidRays);
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1990)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1996)
@@ -16,5 +16,5 @@
 {
   
-#define GVS_DEBUG 1
+#define GVS_DEBUG 0
 
 struct VizStruct
@@ -33,5 +33,5 @@
 mSamplingType(SamplingStrategy::VIEWCELL_BASED_DISTRIBUTION),
 //mSamplingType(SamplingStrategy::DIRECTION_BASED_DISTRIBUTION),
-mNumViewCells(0),
+mProcessedViewCells(0),
 mCurrentViewCell(NULL)
 {
@@ -39,7 +39,9 @@
 	Environment::GetSingleton()->GetIntValue("GvsPreprocessor.initialSamples", mInitialSamples);
 	Environment::GetSingleton()->GetIntValue("GvsPreprocessor.samplesPerPass", mSamplesPerPass);
+	Environment::GetSingleton()->GetIntValue("GvsPreprocessor.minContribution", mMinContribution);
 	Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.epsilon", mEps);
 	Environment::GetSingleton()->GetFloatValue("GvsPreprocessor.threshold", mThreshold);	
 	Environment::GetSingleton()->GetBoolValue("GvsPreprocessor.perViewCell", mPerViewCell);
+	Environment::GetSingleton()->GetIntValue("GvsPreprocessor.maxViewCells", mMaxViewCells);
 
 	char gvsStatsLog[100];
@@ -54,4 +56,7 @@
 	Debug << "epsilon: " << mEps << endl;
 	Debug << "stats: " << gvsStatsLog << endl;
+	Debug << "per view cell: " << mPerViewCell << endl;
+	Debug << "max view cells: " << mMaxViewCells << endl;
+	Debug << "min contribution: " << mMinContribution << endl;
 
 	if (1)
@@ -66,4 +71,10 @@
 GvsPreprocessor::~GvsPreprocessor()
 {
+	ClearRayQueue();
+}
+
+
+void GvsPreprocessor::ClearRayQueue()
+{
 	// clean ray queue
 	while (!mRayQueue.empty())
@@ -80,20 +91,20 @@
 bool GvsPreprocessor::NextViewCell()
 {
-	if (mViewCellsManager->GetNumViewCells() == mNumViewCells)
+	//if (mViewCellsManager->GetNumViewCells() == mProcessedViewCells)
+	//	return false; // no more view cells
+
+	if (mProcessedViewCells == (int)mViewCells.size())
 		return false; // no more view cells
 
-    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())
+	mCurrentViewCell = mViewCells[mProcessedViewCells];
+
+   if (!mCurrentViewCell->GetMesh())
 		mViewCellsManager->CreateMesh(mCurrentViewCell);
 
-	++ mNumViewCells;
+	mGvsStats.mViewCellId = mCurrentViewCell->GetId();
+
+	Debug << "vc: " << mCurrentViewCell->GetId() << endl;
+
+	++ mProcessedViewCells;
     
 	return true;
@@ -101,7 +112,7 @@
 
 
-bool GvsPreprocessor::CheckDiscontinuity(const VssRay &currentRay,
-										 const Triangle3 &hitTriangle,
-										 const VssRay &oldRay)
+int GvsPreprocessor::CheckDiscontinuity(const VssRay &currentRay,
+										const Triangle3 &hitTriangle,
+										const VssRay &oldRay)
 {
 	// the predicted hitpoint: we expect to hit the same mesh again
@@ -123,5 +134,5 @@
 
 		if (!newRay)
-			return false;
+			return 1;
 
 		// set flag for visualization
@@ -140,8 +151,8 @@
 		}
 
-		return true;
-	}
-
-	return false;
+		return 1;
+	}
+
+	return 0;
 }
 
@@ -269,11 +280,13 @@
 								   const VssRay &oldRay)
 {
+	int castRays = 0;
+
 	// cast reverse rays if necessary
-	CheckDiscontinuity(ray1, hitTriangle, oldRay);
-	CheckDiscontinuity(ray2, hitTriangle, oldRay);
+	castRays += CheckDiscontinuity(ray1, hitTriangle, oldRay);
+	castRays += CheckDiscontinuity(ray2, hitTriangle, oldRay);
 
 	if (EqualVisibility(ray1, ray2) || (Magnitude(p1 - p2) <= MIN_DIST))
 	{
-		return 0;
+		return castRays;
 	}
 	
@@ -284,7 +297,9 @@
 	SimpleRay sray(oldRay.mOrigin, p - oldRay.mOrigin, SamplingStrategy::GVS, 1.0f);
 
-	VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox(), mPerViewCell);
-
-	if (!newRay) return 0;
+	VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox(), !mPerViewCell);
+	
+	++ castRays;
+
+	if (!newRay) return castRays;
 
 	newRay->mFlags |= VssRay::BorderSample;
@@ -294,6 +309,6 @@
 
 	// subdivide further
-	const int samples1 = SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay);
-	const int samples2 = SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay);
+	castRays += SubdivideEdge(hitTriangle, p1, p, ray1, *newRay, oldRay);
+	castRays += SubdivideEdge(hitTriangle, p, p2, *newRay, ray2, oldRay);
 
 	// this ray will not be further processed
@@ -301,5 +316,5 @@
 		delete newRay;
 
-	return samples1 + samples2 + 1;
+	return castRays;
 }
 
@@ -352,16 +367,34 @@
 
 	// don't cast double rays as we need only the forward rays
-	const bool castDoubleRays = false;
+	const bool castDoubleRays = !mPerViewCell;
 	// cannot prune invalid rays because we have to compare adjacent  rays.
 	const bool pruneInvalidRays = false;
 
+
+	//////////
+	//-- fill up simple rays with random rays so we can cast 16
+
+	//const int numRandomRays = 0;
+	const int numRandomRays = 16 - (int)simpleRays.size();
+	ViewCellBasedDistribution vcStrat(*this, mCurrentViewCell);
+
+	GenerateRays(numRandomRays, vcStrat, simpleRays);
+
+	/////////////////////
+
+
 	// keep origin for per view cell sampling
-	CastRays(simpleRays, vssRays, castDoubleRays, pruneInvalidRays, mPerViewCell);
+	CastRays(simpleRays, vssRays, castDoubleRays, pruneInvalidRays);
+
+	const int numBorderSamples = (int)vssRays.size() - numRandomRays;
 
 	// set flags
 	VssRayContainer::const_iterator rit, rit_end = vssRays.end();
-	for (rit = vssRays.begin(); rit != rit_end; ++ rit)
-	{
-		(*rit)->mFlags |= VssRay::BorderSample;
+	int i = 0;
+  
+	for (rit = vssRays.begin(); rit != rit_end; ++ rit, ++ i)
+	{
+		if (i < numBorderSamples)
+			(*rit)->mFlags |= VssRay::BorderSample;
 	}
 
@@ -369,15 +402,14 @@
 	EnqueueRays(vssRays);
 	
-	const int n = (int)vssRays.size();
-	int castRays = n;
+	int castRays = simpleRays.size();
 	
     // recursivly subdivide each edge
-	for (int i = 0; i < n; ++ i)
+	for (int i = 0; i < numBorderSamples; ++ i)
 	{
 		castRays += SubdivideEdge(hitTriangle,
 								  enlargedTriangle[i], 
-								  enlargedTriangle[(i + 1) % n], 
+								  enlargedTriangle[(i + 1) % numBorderSamples], 
 								  *vssRays[i], 
-								  *vssRays[(i + 1) % n],
+								  *vssRays[(i + 1) % numBorderSamples],
 								  currentRay);
 	}
@@ -389,7 +421,8 @@
 
 
-Vector3 GvsPreprocessor::GetPassingPoint(const VssRay &currentRay,
-										 const Triangle3 &occluder,
-										 const VssRay &oldRay) const
+bool GvsPreprocessor::GetPassingPoint(const VssRay &currentRay,
+									  const Triangle3 &occluder,
+									  const VssRay &oldRay,
+									  Vector3 &newPoint) const
 {
 	//-- The plane p = (xp, hit(x), hit(xold)) is intersected
@@ -408,5 +441,8 @@
 
 	if (!intersects)
-		cerr << "big error!! no intersection" << endl;
+	{
+		cerr << "big error!! no intersection " << pt1 << " " << pt2 << endl;
+		return false;
+	}
 
 	// get the intersection point on the old ray
@@ -417,6 +453,4 @@
 
 	// Evaluate new hitpoint just outside the triangle
-	Vector3 newPoint;
-
 	const float eps = mEps;
 
@@ -432,5 +466,5 @@
 
 	//cout << "passing point: " << newPoint << endl << endl;
-	return newPoint;
+	return true;
 }
 
@@ -455,5 +489,10 @@
 	
 	// get a point which is passing just outside of the occluder
-    const Vector3 newPoint = GetPassingPoint(currentRay, occluder, oldRay);
+    Vector3 newPoint;
+
+	// why is there sometimes no intersecton found?
+	if (!GetPassingPoint(currentRay, occluder, oldRay, newPoint))
+		return NULL;
+
 	const Vector3 predicted = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay);
 
@@ -479,5 +518,4 @@
 		ray.Clear();
 		ray.Init(newOrigin, -newDir, Ray::LOCAL_RAY);
-		//ray.Init(newOrigin, -newDir, Ray::LINE_SEGMENT);
 		
 		//cout << "z";
@@ -496,5 +534,5 @@
 
 	VssRay *reverseRay = 
-		mRayCaster->CastRay(simpleRay, mViewCellsManager->GetViewSpaceBox(), mPerViewCell);
+		mRayCaster->CastRay(simpleRay, mViewCellsManager->GetViewSpaceBox(), !mPerViewCell);
 
     ++ mGvsStats.mReverseSamples;
@@ -513,5 +551,4 @@
 	
 	ViewCellBasedDistribution vcStrat(*this, mCurrentViewCell);
-
     GenerateRays(numSamples, vcStrat, simpleRays);
 
@@ -520,9 +557,8 @@
 	VssRayContainer samples;
 	
-	const bool castDoubleRays = false;
+	const bool castDoubleRays = !mPerViewCell;
 	const bool pruneInvalidRays = true;
-	const bool keepOrigin = mPerViewCell;
-
-	CastRays(simpleRays, samples, castDoubleRays, pruneInvalidRays, keepOrigin);
+	
+	CastRays(simpleRays, samples, castDoubleRays, pruneInvalidRays);
 	
 	// add to ray queue
@@ -556,5 +592,5 @@
 		VssRay *ray = mRayQueue.top();
 		mRayQueue.pop();
-		if (!ray) cout << "Error!!!!!" << endl;
+		
 		const int newSamples = AdaptiveBorderSampling(*ray);
 
@@ -598,5 +634,5 @@
 
 	//exporter->ExportRays(vcRays, RgbColor(1, 0, 0));
-	exporter->ExportRays(vcRays2, RgbColor(0, 1, 0));
+	//exporter->ExportRays(vcRays2, RgbColor(0, 1, 0));
 	//exporter->ExportRays(vcRays3, RgbColor(1, 1, 1));
 }
@@ -609,5 +645,5 @@
 	Material m;
 	
-	char str[64]; sprintf(str, "pass%06d.wrl", mNumViewCells);
+	char str[64]; sprintf(str, "pass%06d.wrl", mProcessedViewCells);
 
 	Exporter *exporter = Exporter::GetExporter(str);
@@ -655,5 +691,5 @@
 void GvsPreprocessor::VisualizeViewCells()
 {
-	char str[64]; sprintf(str, "tmp/pass%06d_%04d-", mNumViewCells, mPass);
+	char str[64]; sprintf(str, "tmp/pass%06d_%04d-", mProcessedViewCells, mPass);
 			
 	// visualization
@@ -685,8 +721,9 @@
 {
 	mGvsStats.mPerViewCellSamples = 0;
-	int oldContribution = 0;
+	int oldContribution = mGvsStats.mTotalContribution;
 	int passSamples = 0;
 
-	while (mGvsStats.mPerViewCellSamples < mTotalSamples) 
+	//while (mGvsStats.mPerViewCellSamples < mTotalSamples) 
+	while (1) 
 	{
 		// Ray queue empty => 
@@ -699,7 +736,7 @@
 		passSamples += newSamples;
 		mGvsStats.mPerViewCellSamples += newSamples;
-	
-		if (0 &&
-			passSamples % (mSamplesPerPass + 1) == mSamplesPerPass)
+		//cout << "here4 " << passSamples % (mSamplesPerPass + 1) << endl;
+
+		if (passSamples >= mSamplesPerPass)
 		{
 			++ mPass;
@@ -711,8 +748,13 @@
 
 			mGvsStats.mPass = mPass;
-			mGvsStats.Stop();
-			mGvsStats.Print(mGvsStatsStream);
-
-			//cout << "\nPass " << mPass << " #samples: " << mGvsStats.mTotalSamples << " of " << mTotalSamples << endl;
+
+			cout << "\nPass " << mPass << " #samples: " << mGvsStats.mPerViewCellSamples << endl;
+			cout << "contribution=" << mGvsStats.mPassContribution << " (of " << mMinContribution << ")" << endl;
+
+			// termination criterium
+			if (mGvsStats.mPassContribution < mMinContribution)
+			{
+				break;
+			}
 
 			// reset
@@ -725,14 +767,53 @@
 
 
+void GvsPreprocessor::CompileViewCellsList()
+{
+	while ((int)mViewCells.size() < mMaxViewCells)
+    {
+		if (0)
+		{
+			mViewCells.push_back(mViewCellsManager->GetViewCell((int)mViewCells.size()));
+		}
+		else
+		{
+			// HACK
+			const int tries = 10000;
+			int i = 0;
+
+			for (i = 0; i < tries; ++ i)
+			{
+				const int idx = (int)RandomValue(0.0f, (float)mViewCellsManager->GetNumViewCells() - 0.5f);
+	
+				ViewCell *viewCell = mViewCellsManager->GetViewCell(idx);
+
+				if (!viewCell->Mailed())
+				{
+					viewCell->Mail();
+					break;
+				}
+
+				mViewCells.push_back(viewCell);
+			}
+
+			if (i == tries)
+			{
+				cerr << "big error! no view cell found" << endl;
+				return;
+			}
+		}
+	}
+}
+
+
 void GvsPreprocessor::PerViewCellComputation()
 {
-	const int maxViewCells = 25;
-	
-	while (mNumViewCells < maxViewCells && NextViewCell())
-	{
-		cout << "processing view cell " << mNumViewCells << endl;
+	while (NextViewCell())
+	{
+		cout << "\n***********************\nprocessing view cell " << mProcessedViewCells << endl;
 
 		// compute the pvs of the current view cell
 		ProcessViewCell();
+
+		mGvsStats.mTrianglePvs = mCurrentViewCell->GetPvs().GetSize();
 
 		// exchange triangle pvs with objects
@@ -748,5 +829,6 @@
 		//-- stats
 		
-		mGvsStats.mViewCells = mNumViewCells;//mPass;
+		mGvsStats.mViewCells = mProcessedViewCells;//mPass;
+		mGvsStats.mPerViewCellPvs = mCurrentViewCell->GetPvs().GetSize();
 		mGvsStats.mTotalPvs += mCurrentViewCell->GetPvs().GetSize();
 		mGvsStats.mTotalSamples += mGvsStats.mPerViewCellSamples;
@@ -754,4 +836,7 @@
 		mGvsStats.Stop();
 		mGvsStats.Print(mGvsStatsStream);
+
+		// is this really necessary?
+		ClearRayQueue();
 	}
 }
@@ -863,4 +948,7 @@
 	if (mPerViewCell)
 	{
+		// list of view cells to compute
+		CompileViewCellsList();
+
 		PerViewCellComputation();
 	}
@@ -916,4 +1004,5 @@
 {
 	app << "#Pass\n" << mPass << endl;
+	app << "#ViewCellId\n" << mViewCellId << endl;
 	app << "#Time\n" << Time() << endl;
 	app << "#TotalSamples\n" << mTotalSamples << endl;
@@ -925,4 +1014,7 @@
 	app << "#ViewCells\n" << mViewCells << endl;
 	app << "#TotalPvs\n" << mTotalPvs << endl;
+	app << "#PerViewCellPvs\n" << mPerViewCellPvs << endl;
+	app << "#TrianglePvs\n" << mTrianglePvs << endl;
+	app << "#RaysPerSec\n" << RaysPerSec() << endl;
 	app << "#PerViewCellSamples\n" << mPerViewCellSamples << endl << endl;
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1994)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1996)
@@ -20,4 +20,5 @@
 HaltonSequence HwGlobalLinesDistribution::sHalton;
 
+HaltonSequence ViewCellBasedDistribution::sHalton;
 
 SamplingStrategy::SamplingStrategy(Preprocessor &preprocessor): 
@@ -651,5 +652,6 @@
 				  } else
 					if (strcmp(curr, "mutation")==0) {
-					  mDistributions.push_back(new MutationBasedDistribution(mPreprocessor));
+						// temp matt: still no mutationstrategy!
+					  //mDistributions.push_back(new MutationBasedDistribution(mPreprocessor));
 					} 
 	
@@ -738,5 +740,53 @@
 
 
-}
-
-
+bool ViewCellBasedDistribution::GenerateSample(SimpleRay &ray)
+{
+	Vector3 origin, direction; 
+
+	ViewCellContainer &viewCells = 
+		mPreprocessor.mViewCellsManager->GetViewCells();
+
+	Vector3 point;
+	Vector3 normal, normal2;
+	
+	float r[1];
+	sHalton.GetNext(1, r);
+
+	const int objIdx = (int)(r[0] * (float)mPreprocessor.mObjects.size() - 1.0f);
+				//	= (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
+	Intersectable *object = mPreprocessor.mObjects[objIdx];
+
+	//cout << "obj: " << objIdx << endl;
+
+	object->GetRandomSurfacePoint(point, normal);
+	mViewCell->GetRandomSurfacePoint(origin, normal2);
+
+	direction = point - origin;
+
+	// move a little bit back to avoid piercing through walls
+	// that bound the view cell
+	origin -= 0.01f * normal2;
+
+	// $$ jb the pdf is yet not correct for all sampling methods!
+	const float c = Magnitude(direction);
+
+	if ((c <= Limits::Small) /*|| (DotProd(direction, normal) < 0)*/)
+	{
+		return false;
+	}
+
+	// $$ jb the pdf is yet not correct for all sampling methods!
+	const float pdf = 1.0f;
+
+	direction *= 1.0f / c;
+	ray = SimpleRay(origin, direction, VIEWCELL_BASED_DISTRIBUTION, pdf);
+
+	//cout << "ray: " << ray.mOrigin << " " << ray.mDirection << endl;
+
+	return true;
+}
+
+
+}
+
+
