Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1771)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1932)
@@ -105,15 +105,28 @@
 	void EnlargeTriangle(VertexContainer &vertices,
 						 const Triangle3 &hitTriangle,
-						 const VssRay &ray);
+						 const VssRay &ray) const;
 
-	int SubdivideEdge(
-		const Triangle3 &hitTriangle,
-		const Vector3 &p1, 
-		const Vector3 &p2, 
-		const VssRay &x, 
-		const VssRay &y,
-		const VssRay &oldRay);
+	int SubdivideEdge(const Triangle3 &hitTriangle,
+					  const Vector3 &p1, 
+					  const Vector3 &p2, 
+					  const VssRay &ray1,
+                      const VssRay &ray2,
+					  const VssRay &oldRay);
 
 	void Visualize();
+
+	void CreateDisplacedVertices(VertexContainer &vertices,
+								 const Triangle3 &hitTriangle,
+								 const VssRay &ray, 
+								 const int index) const;
+
+	Vector3 CalcPredictedHitPoint(const VssRay &newRay, 
+								  const Triangle3 &hitTriangle,
+								  const VssRay &oldRay) const;
+
+
+	Vector3 GetPassingPoint(const VssRay &currentRay,
+							const Triangle3 &hitTriangle,
+							const VssRay &oldRay) const;
 
 	//////////////////////
@@ -134,4 +147,5 @@
 	///////////
 	// stats
+
 	int mSampleContriPerPass;
 	int mTotalSampleContri;
@@ -139,4 +153,6 @@
 	int mBorderSamples;
 	int mGvsPass;
+
+	ofstream mGvsStats;
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1920)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1932)
@@ -486,5 +486,6 @@
 			a mesh is created representing the geometry
 		@param bconverter a conversion routine working with the similarities of bounding
-		boxes: if there is a certain similarity of overlap between bounding boxes, two tested
+			boxes: if there is a certain similarity of overlap between 
+			bounding boxes, two tested
 		candidate objects are considered to be the same objects
 		@returns the view cells manager if loading was successful, false otherwise
@@ -501,15 +502,14 @@
 	// TODO: write own visibiltiy filter class
   void ApplyFilter(KdTree *kdTree,
-					 const float viewSpaceFilterSize,
-					 const float spatialFilterSize);
+				   const float viewSpaceFilterSize,
+				   const float spatialFilterSize);
 
   // new adaptive version of the filter
   PvsFilterStatistics 
   ApplyFilter2(ViewCell *viewCell,
-							 const bool useViewSpaceFilter,
-							 const float filterSize,
-							 ObjectPvs &pvs,
-							 vector<AxisAlignedBox3> *filteredBoxes = NULL
-							 );
+			   const bool useViewSpaceFilter,
+			   const float filterSize,
+			   ObjectPvs &pvs,
+			   vector<AxisAlignedBox3> *filteredBoxes = NULL);
 
 	void ApplySpatialFilter(KdTree *kdTree,
@@ -560,18 +560,24 @@
 									   VssRayContainer *visRays = NULL) = NULL;
 
-	
+
 	void ViewCellsManager::ResetPvs();
-  
-  Preprocessor *GetPreprocessor() const {
-	return mPreprocessor;
-  }
-
-  void SetPreprocessor(Preprocessor *p) {
-	mPreprocessor = p;
-  }
-
-  void UpdatePvsForEvaluation();
+
+	Preprocessor *GetPreprocessor() const {
+		return mPreprocessor;
+	}
+
+	void SetPreprocessor(Preprocessor *p) {
+		mPreprocessor = p;
+	}
+
+	void UpdatePvsForEvaluation();
 
 protected:
+
+	void ComputeViewCellContribution(ViewCell *viewCell,
+									 VssRay &ray, 
+									 Intersectable *obj,
+									 const Vector3 &pt,
+									 const bool addRays);
 
 	void MergeViewCellsRecursivly(ObjectPvs &pvs, 
@@ -581,5 +587,5 @@
 
 	/** Intersects box with the tree and returns the number of intersected boxes.
-		@returns number of view cells found
+	@returns number of view cells found
 	*/
 	virtual int ComputeBoxIntersections(const AxisAlignedBox3 &box, 
@@ -618,5 +624,5 @@
 	*/
 	void ResetViewCells();
-	
+
 	/** Sets this view cell to active.
 	*/
@@ -626,11 +632,11 @@
 	*/
 	virtual void CollectViewCells() = 0;
-	
+
 	/** Evaluates view cells statistics and stores it in
-		mViewCellsStatistics.
+	mViewCellsStatistics.
 	*/
 	void EvaluateViewCellsStats();
 
-	
+
 	///////////////////////
 	//-- helper functions for view cell visualization
@@ -641,6 +647,5 @@
 							   const AxisAlignedBox3 *box,
 							   const bool colorCode,
-							   const AxisAlignedPlane *clipPlane
-							   ) const;
+							   const AxisAlignedPlane *clipPlane) const;
 
 	/** Sets exporter color.
@@ -649,15 +654,15 @@
 							 ViewCell *vc, 
 							 const bool colorCode) const;
-	
+
 	/** Creates meshes from the view cells.
 	*/
 	void CreateViewCellMeshes();
 
-    /** Creates clip plane for visualization.
+	/** Creates clip plane for visualization.
 	*/
 	void CreateClipPlane();
 
 	AxisAlignedPlane *GetClipPlane();
-	
+
 	void ExportMergedViewCells(const ObjectContainer &objects);
 
@@ -673,8 +678,8 @@
 	*/
 	ViewCell *ConstructLocalMergeTree(ViewCell *currentViewCell, 
-									  const ViewCellContainer &viewCells);
+		const ViewCellContainer &viewCells);
 
 	/** Constructs local view cell merge hierarchy based solely on similarity with the
-		current viewcell
+	current viewcell
 	*/
   	ViewCell *ConstructLocalMergeTree2(ViewCell *currentViewCell, 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1932)
@@ -43,26 +43,22 @@
 		@returns ray or NULL if invalid
 	*/
-	VssRay *CastRay(
-		const SimpleRay &simpleRay,
-	    const AxisAlignedBox3 &box,
-		const bool castDoubleRay
-		);
+	VssRay *CastRay(const SimpleRay &simpleRay,
+					const AxisAlignedBox3 &box);
+					//const bool castDoubleRay);
 
-	virtual int CastRay(
-		const SimpleRay &simpleRay,
-        VssRayContainer &vssRays,
-		const AxisAlignedBox3 &box,
-		const bool castDoubleRay,
-		const bool pruneInvalidRays = true
-		) = 0;
+	virtual int CastRay(const SimpleRay &simpleRay,
+						VssRayContainer &vssRays,
+						const AxisAlignedBox3 &box,
+						const bool castDoubleRay,
+						const bool pruneInvalidRays = true
+						) = 0;
 
-	 virtual void CastRays16(
-		 const int i,
-		 SimpleRayContainer &rays, 
-		 VssRayContainer &vssRays,
-		 const AxisAlignedBox3 &sbox,
-		 const bool castDoubleRay,
-		 const bool pruneInvalidRays = true
-		 ) = 0;
+	 virtual void CastRays16(const int i,
+							 SimpleRayContainer &rays,
+							 VssRayContainer &vssRays,
+							 const AxisAlignedBox3 &sbox,
+							 const bool castDoubleRay,
+							 const bool pruneInvalidRays = true
+							 ) = 0;
 	
 
@@ -86,13 +82,11 @@
 
 
-	int ProcessRay(
-			 const SimpleRay &ray,
-			 Intersection &hitA,
-			 Intersection &hitB,
-			 VssRayContainer &vssRays,
-			 const AxisAlignedBox3 &box,
-			 const bool castDoubleRay,
-			 const bool pruneInvalidRays = true
-			 );
+	int ProcessRay(const SimpleRay &ray,
+				   Intersection &hitA,
+				   Intersection &hitB,
+				   VssRayContainer &vssRays,
+				   const AxisAlignedBox3 &box,
+				   const bool castDoubleRay,
+				   const bool pruneInvalidRays = true);
 
 	/** Checks if ray is valid.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer/QtGlRenderer.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer/QtGlRenderer.h	(revision 1926)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer/QtGlRenderer.h	(revision 1932)
@@ -100,6 +100,5 @@
 	void ComputeRays(Intersectable *sourceObj, VssRayContainer &rays);
 
-	float
-		GetPixelError(int &pvsSize);
+	float GetPixelError(int &pvsSize);
 
 	int ComputePvs(ObjectContainer &objects, ObjectContainer &pvs) const;
@@ -109,6 +108,6 @@
 
 	void SetupProjectionForViewPoint(const Vector3 &viewPoint, 
-		const Beam &beam, 
-		Intersectable *sourceObject);
+									 const Beam &beam, 
+									 Intersectable *sourceObject);
 
 
@@ -296,5 +295,5 @@
 	}
 
-	// matt: dummy file
+	// matt: dummy function, must be provided by bittner
 	void RenderRenderCost() {}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1931)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1932)
@@ -1133,5 +1133,5 @@
 					   )
 {
-  const long t1 = GetTime();
+	const long t1 = GetTime();
 
 	for (int i = 0; i < (int)rays.size();)
@@ -1149,5 +1149,5 @@
 		}
 		else 
-		  {
+		{
 			mRayCaster->CastRay(
 								rays[i],
@@ -1156,6 +1156,6 @@
 								castDoubleRays,
 								pruneInvalidRays);
-			i ++;
-		  }
+			++ i;
+		}
 
 		if (rays.size() > 10000 && i % 10000 == 0)
@@ -1163,5 +1163,6 @@
 	}
 
-	if (rays.size() > 10000) {
+	if (rays.size() > 10000) 
+	{
 	  cout<<endl;
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1931)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1932)
@@ -142,7 +142,7 @@
 
 	virtual void CastRays(SimpleRayContainer &rays,
-		VssRayContainer &vssRays,
-		const bool castDoubleRays,
-		const bool pruneInvalidRays = true);
+						  VssRayContainer &vssRays,
+						  const bool castDoubleRays,
+						  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/Triangle3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.h	(revision 1420)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.h	(revision 1932)
@@ -9,5 +9,5 @@
 class AxisAlignedBox3;
 class Ray;
-
+class Plane3;
 
 struct Triangle3 
@@ -32,14 +32,22 @@
 	int CastRay(const Ray &ray, float &t, const float nearestT, Vector3 &normal) const;
 
-	 friend ostream& operator<< (ostream &s, const Triangle3 &A);
-	 friend istream& operator>> (istream &s, Triangle3 &A);
+	friend ostream& operator<< (ostream &s, const Triangle3 &A);
+	friend istream& operator>> (istream &s, Triangle3 &A);
 
-	 /** Checks if this triangle is ill-defined.
-	 */
-	 bool CheckValidity() const;
+	/** Checks if this triangle is ill-defined.
+	*/
+	bool CheckValidity() const;
 
-	 //////////////////////////////
-	 /// the triangle vertices
-	 Vector3 mVertices[3];
+	/** Intersects triangle with plane, returns intersection points
+		if intersection is happening.
+
+		@returns true if triangle intersects plane
+	*/
+	bool IntersectPlane(const Plane3 &plane, Vector3 &intersectA, Vector3 &intersectB) const;
+
+	///////////////////
+
+	/// the triangle vertices
+	Vector3 mVertices[3];
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1931)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1932)
@@ -34,4 +34,5 @@
 #define AVG_RAY_CONTRIBUTIONS 1
 #define CONTRIBUTION_RELATIVE_TO_PVS_SIZE 1
+#define PVS_ADD_DIRTY 1
 
 namespace GtpVisibilityPreprocessor {
@@ -82,5 +83,6 @@
 
 
-int ViewCellsManager::CastPassSamples2(const int samplesPerPass, VssRayContainer &passSamples) const
+int ViewCellsManager::CastPassSamples2(const int samplesPerPass, 
+									   VssRayContainer &passSamples) const
 {
 	long startTime = GetTime();
@@ -2153,6 +2155,73 @@
 
 
-
-#define PVS_ADD_DIRTY 1
+inline static void AddSampleToPvs(ObjectPvs &pvs, 
+								  Intersectable *obj, 
+								  const float pdf)
+{
+#if PVS_ADD_DIRTY
+	pvs.AddSampleDirtyCheck(obj, pdf);
+
+	if (pvs.RequiresResort()) 
+	{
+		pvs.SimpleSort();
+	}
+#else
+	pvs.AddSample(obj, pdf);
+#endif
+}
+
+
+void ViewCellsManager::ComputeViewCellContribution(ViewCell *viewCell,
+												   VssRay &ray, 
+												   Intersectable *obj,
+												   const Vector3 &pt,
+												   const bool addRays)
+{
+	// check if we are outside of view space
+	if (!obj || !viewCell->GetValid())
+		return;
+
+	// if ray not outside of view space
+	float relContribution = 0.0f;
+	float absContribution = 0.0f;
+
+	// todo: maybe not correct for kd node pvs
+	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)
+	{
+		++ ray.mPvsContribution;
+		relContribution = 1.0f;
+
+		if (addRays) 
+		{
+			AddSampleToPvs(viewCell->GetPvs(), obj, ray.mPdf);
+		}
+
+#if DIST_WEIGHTED_CONTRIBUTION 
+		// recalculate the contribution - weight the 1.0f contribution by the sqr distance to the
+		// object-> a new contribution in the proximity of the viewcell has a larger weight!
+		relContribution /= SqrDistance(GetViewCellBox(viewcell).Center(), pt);
+				  
+#endif
+	}
+
+#if SUM_RAY_CONTRIBUTIONS || AVG_RAY_CONTRIBUTIONS
+	ray.mRelativePvsContribution += relContribution;
+#else
+	// recalculate relative contribution - use max of AbsContribution
+	if (ray.mRelativePvsContribution < absContribution)
+		ray.mRelativePvsContribution = absContribution;
+#endif
+}
+
 
 float
@@ -2164,8 +2233,8 @@
 	ray.mRelativePvsContribution = 0.0f;
 
-	if (ray.mTerminationObject==NULL)
+	if (!ray.mTerminationObject)
 		return 0.0f;
 
-	ViewCellContainer viewcells;
+	ViewCellContainer viewCells;
 
 	static Ray hray;
@@ -2183,93 +2252,41 @@
 
 	// traverse the view space subdivision
-	CastLineSegment(origin, termination, viewcells);
+	CastLineSegment(origin, termination, viewCells);
 
 	if (storeViewCells)
 	{	
 		// copy viewcells memory efficiently
-		ray.mViewCells.reserve(viewcells.size());
-		ray.mViewCells = viewcells;
-	}
-
-	ViewCellContainer::const_iterator it = viewcells.begin();
-
+		ray.mViewCells.reserve(viewCells.size());
+		ray.mViewCells = viewCells;
+	}
+
+	// optain pvs entry (can be different from hit object)
 	Intersectable *terminationObj = GetIntersectable(ray, true);
 
-	
-	for (; it != viewcells.end(); ++ it) 
-	{
-		ViewCell *viewcell = *it;
-
-		if (viewcell->GetValid())
-		{	
-			// if ray not outside of view space
-			float relContribution = 0.0f;
-			float absContribution = 0.0f;
-			
-			if (terminationObj) 
-			{
-				// todo: maybe not correct for kd node pvs
-			  if (viewcell->GetPvs().GetSampleContribution(
-														   terminationObj,
-														   ray.mPdf,
-														   relContribution))
-				absContribution = 1.0f;
-			  
-			  // $$ clear the relative contribution as it is currently not correct anyway
-			  relContribution = 0.0f;
-
-			  if (absContribution == 1.0f)
-				{
-				  ++ ray.mPvsContribution;
-				  relContribution = 1.0f;
-				  if (addRays) {
-#if PVS_ADD_DIRTY
-					viewcell->GetPvs().AddSampleDirtyCheck(terminationObj, ray.mPdf);
-					if (viewcell->GetPvs().RequiresResort()) {
-					  viewcell->GetPvs().SimpleSort();
-					}
-#else
-					viewcell->GetPvs().AddSample(terminationObj, ray.mPdf);
-#endif
-				  }
-
-#if CONTRIBUTION_RELATIVE_TO_PVS_SIZE
-				  relContribution /= viewcell->GetPvs().GetSize();
-#endif
-				  
-#if DIST_WEIGHTED_CONTRIBUTION 
-				  // recalculate the contribution - weight the 1.0f contribution by the sqr distance to the
-				  // object-> a new contribution in the proximity of the viewcell has a larger weight!
-				  relContribution /= SqrDistance(GetViewCellBox(viewcell).Center(),
-												 ray.mTermination);
-				  
-#endif
-				}
-#if SUM_RAY_CONTRIBUTIONS || AVG_RAY_CONTRIBUTIONS
-			  ray.mRelativePvsContribution += relContribution;
-#else
-			  // recalculate relative contribution - use max of AbsContribution
-			  if (ray.mRelativePvsContribution < absContribution)
-				ray.mRelativePvsContribution = absContribution;
-#endif
-			}
-		}
+	ViewCellContainer::const_iterator it = viewCells.begin();
+
+	for (; it != viewCells.end(); ++ it) 
+	{
+		ComputeViewCellContribution(*it, 
+									ray, 
+									terminationObj, 
+									ray.mTermination, 
+									addRays);
 	}
 
 #if AVG_RAY_CONTRIBUTIONS
-	ray.mRelativePvsContribution /= viewcells.size();
+	ray.mRelativePvsContribution /= (float)viewCells.size();
 #endif
 #if USE_RAY_LENGTH_AS_CONTRIBUTION
-  float c = 0.0f;
-  if (terminationObj) 
-	c = ray.Length();
-  ray.mRelativePvsContribution = ray.mPvsContribution = c;
-  return c;
+	float c = 0.0f;
+	if (obj) 
+		c = ray.Length();
+	ray.mRelativePvsContribution = ray.mPvsContribution = c;
+	return c;
 #else
-  return ABS_CONTRIBUTION_WEIGHT*ray.mPvsContribution +
-	(1.0f - ABS_CONTRIBUTION_WEIGHT)*ray.mRelativePvsContribution;
+	return ABS_CONTRIBUTION_WEIGHT * ray.mPvsContribution +
+		(1.0f - ABS_CONTRIBUTION_WEIGHT) * ray.mRelativePvsContribution;
 #endif
 }
-
 
 
@@ -3544,17 +3561,15 @@
 				if (p < raysOut)
 				{
-					if ((*rit)->mFlags & VssRay::BorderSample)
+					if (0 && (*rit)->mFlags & VssRay::BorderSample)
 					{
-						cout << "b";
 						vcRays.push_back(*rit);
 					}
 					else if ((*rit)->mFlags & VssRay::ReverseSample)
 					{
+						cout << "l";
 						vcRays2.push_back(*rit);
-						cout << "r";
 					}
-					else
+					else if(0)
 					{
-						cout << "n";
 						vcRays3.push_back(*rit);
 					}	
@@ -5448,7 +5463,8 @@
 
 	if (0)
-	{	// real meshes are constructed at this stage
+	{	
+		// real meshes are constructed at this stage
 		cout << "finalizing view cells ... ";
-		FinalizeViewCells(true);
+        FinalizeViewCells(true);
 		cout << "finished" << endl;
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h	(revision 1842)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h	(revision 1932)
@@ -21,5 +21,5 @@
 		 const Vector3 &b,
 		 const Vector3 &c
-	 );
+		 );
 
   Plane3(const Vector3 &normal,
@@ -33,6 +33,7 @@
   }
 
-  float Distance(const Vector3 &v) const {
-    return DotProd(v, mNormal) + mD;
+  float Distance(const Vector3 &v) const 
+  {
+	  return DotProd(v, mNormal) + mD;
   }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp	(revision 1867)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp	(revision 1932)
@@ -185,3 +185,68 @@
 }
 
-}
+
+bool Triangle3::IntersectPlane(const Plane3 &plane, 
+							   Vector3 &intersectA, 
+							   Vector3 &intersectB) const
+{
+	int side[3];
+
+	// compute distance from plane
+	for (int i = 0; i < 3; ++ i)
+	{
+		side[i] = plane.Side(mVertices[i], Limits::Small);
+	}
+
+	/////
+	// no intersection => early exit
+	if (((side[0] > 0) && (side[1] > 0) && (side[2] > 0)) ||
+		((side[0] < 0) && (side[1] < 0) && (side[2] < 0)))
+	{
+		return false;
+	}
+
+	/////////////
+	// at least 2 triangle vertices lie in plane => early exit
+
+	for (int i = 0; i < 3; ++ i)
+	{
+		if (!side[i] && !side[(i + 1) % 3])
+		{
+			intersectA = mVertices[i];
+			intersectB = mVertices[(i + 1) % 3];
+
+			return true;
+		}
+	}
+
+	bool foundA = false;
+
+	// compute intersection points
+	for (int i = 0; i < 3; ++ i)
+	{
+		const int i_2 = (i + 1) % 3;
+
+		// intersection found
+		if ((side[i] >= 0) && (side[i_2] <= 0))
+		{	
+			const float t = plane.FindT(mVertices[i], mVertices[i_2]);
+			
+			if (!foundA)
+			{
+				intersectA = mVertices[i] + t * (mVertices[i_2] - mVertices[i]);
+				foundA = true;
+			}
+			else
+			{
+				intersectB = mVertices[i] + t * (mVertices[i_2] - mVertices[i]);
+				return true;
+			}
+		}
+	}
+
+	cout << "warning! wrong triangle - plane intersection" << endl;
+	return false; // something went wrong!
+}
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1900)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1932)
@@ -24,14 +24,16 @@
 
 VssRay *RayCaster::CastRay(const SimpleRay &simpleRay,
-						   const AxisAlignedBox3 &box,
-						   const bool castDoubleRay)
+						   const AxisAlignedBox3 &box)
+						   //const bool castDoubleRay) 
 {
-  VssRayContainer rays;
-  CastRay(simpleRay, rays, box, castDoubleRay);
-  
-  if (!rays.empty())
-	return rays.back();
-  else
-	return NULL;
+	// note: make no sense otherwise
+	const bool castDoubleRay = false;
+	VssRayContainer rays;
+	CastRay(simpleRay, rays, box, castDoubleRay);
+    
+	if (!rays.empty())
+		return rays.back();
+	else
+		return NULL;
 }
 
@@ -45,35 +47,42 @@
 					   Intersection &hit)
 {
-  if (!hit.mObject)  {
-	// compute intersection with the scene bounding box
+	if (!hit.mObject)  
+	{
+		// compute intersection with the scene bounding box
 #if EXACT_BOX_CLIPPING
-	static Ray ray;
-	mPreprocessor.SetupRay(ray, origin, direction);
-	
-	float tmin, tmax;
-	if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)) {
-	  hit.mPoint = ray.Extrap(tmax);
+		static Ray ray;
+		mPreprocessor.SetupRay(ray, origin, direction);
+
+		float tmin, tmax;
+		if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)) 
+		{
+			hit.mPoint = ray.Extrap(tmax);
+		}
+		else 
+		{
+			// cout<<" invalid hp "<<tmin<<" "<<tmax<<endl;
+			// cout<<" box "<<box<<endl;
+			// cout<<" origin "<<origin<<endl;
+			// cout<<" direction "<<direction<<endl;
+			// cout<< "inv dir"<<ray.GetInvDir()<<endl;
+			return false;
+		}
+#else
+		hit.mPoint = origin + direction * Magnitude(box.Diagonal());
+#endif
 	}
-	else {
-	  // 		cout<<" invalid hp "<<tmin<<" "<<tmax<<endl;
-	  // 		cout<<" box "<<box<<endl;
-	  // 		cout<<" origin "<<origin<<endl;
-	  // 		cout<<" direction "<<direction<<endl;
-	  // 		cout<< "inv dir"<<ray.GetInvDir()<<endl;
-	  return false;
+	else
+	{
+		if (mPreprocessor.mDetectEmptyViewSpace) 
+		{
+			if (DotProd(hit.mNormal, direction) >= -Limits::Small) 
+			{	
+				hit.mObject = NULL;
+				return false;
+			}
+		}
 	}
-#else
-	hit.mPoint = origin + direction*Magnitude(box.Diagonal());
-#endif
-  }
-  else
-	if (mPreprocessor.mDetectEmptyViewSpace) {
-	  if (DotProd(hit.mNormal, direction) >= -Limits::Small) {	
-		hit.mObject = NULL;
-		return false;
-	  }
-	}
-  
-  return true;
+
+	return true;
 }
 
@@ -98,8 +107,10 @@
 	//	  return 0;
 	
-	if (pruneInvalidRays) {
-	  if (!hitA.mObject && !hitB.mObject) {
-		return 0;
-	  }
+	if (pruneInvalidRays) 
+	{
+		if (!hitA.mObject && !hitB.mObject) 
+		{
+			return 0;
+		}
 	}
 	
@@ -107,6 +118,7 @@
 	  ValidateRay(simpleRay.mOrigin, simpleRay.mDirection, box, hitA);
 	
-	const bool validB = castDoubleRay && 
-	  ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB);
+	// note: should we check for backward valitidy also for single rays?
+	const bool validB = //castDoubleRay && 
+		ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB);
 	
 #if DEBUG_RAYCAST
@@ -115,14 +127,14 @@
 	
 	// reset both contributions
-	if (!validA || !validB) {
-	  if (pruneInvalidRays)
-		return 0;
-	  // reset both contributions of this ray
-	  hitA.mObject = NULL;
-	  hitB.mObject = NULL;
+	if (!validA || !validB)
+	{
+		if (pruneInvalidRays)
+			return 0;
+		
+		// reset both contributions of this ray
+		hitA.mObject = NULL;
+		hitB.mObject = NULL;
 	}
 	  
-	
-	const bool validSample = true;
 	// 8.11. 2007 JB
 	// degenerate rays checked by geometrical constraint...
@@ -133,45 +145,42 @@
 #endif
 
-	if (validSample) {
-	  if (!pruneInvalidRays || hitA.mObject) {
-		VssRay *vssRay = new VssRay(
-									hitB.mPoint,
+	if (!pruneInvalidRays || hitA.mObject) 
+	{
+		VssRay *vssRay = new VssRay(hitB.mPoint,
 									hitA.mPoint,
 									hitB.mObject,
 									hitA.mObject,
 									mPreprocessor.mPass,
-									simpleRay.mPdf
-									);
-		
+									simpleRay.mPdf);
+
 		if (validA)
-		  vssRay->mFlags |= VssRay::Valid;
+			vssRay->mFlags |= VssRay::Valid;
+
 		vssRay->mDistribution = simpleRay.mDistribution;
 		vssRays.push_back(vssRay);
 		++ hits;
 		//cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl;
-	  }
-	  
+	}
+
 #if DEBUG_RAYCAST
-	  Debug<<"PR3"<<flush;
+	Debug<<"PR3"<<flush;
 #endif
 
-	  if (castDoubleRay && (!pruneInvalidRays || hitB.mObject))
-		{
-		  VssRay *vssRay = new VssRay(
-									  hitA.mPoint,
-									  hitB.mPoint,
-									  hitA.mObject,
-									  hitB.mObject,
-									  mPreprocessor.mPass,
-									  simpleRay.mPdf
-									  );
-		  if (validB)
+	if (castDoubleRay && (!pruneInvalidRays || hitB.mObject))
+	{
+		VssRay *vssRay = new VssRay(hitA.mPoint,
+									hitB.mPoint,
+									hitA.mObject,
+									hitB.mObject,
+									mPreprocessor.mPass,
+									simpleRay.mPdf);
+
+		if (validB)
 			vssRay->mFlags |= VssRay::Valid;
-		  
-		  vssRay->mDistribution = simpleRay.mDistribution;
-		  vssRays.push_back(vssRay);
-		  ++ hits;
-		  //cout << "vssray 2: " << *vssRay << endl;
-		}
+
+		vssRay->mDistribution = simpleRay.mDistribution;
+		vssRays.push_back(vssRay);
+		++ hits;
+		//cout << "vssray 2: " << *vssRay << endl;
 	}
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1932)
@@ -357,11 +357,16 @@
 {
   VssRayContainer::const_iterator it = begin();
-  //  ofstream s("contrib.log");
-  for (; it != end(); it++) {
-	VssRay *ray = *it;
-	//	s<<"(pass="<<ray->mPass<<", c="<<ray->mPvsContribution<<")"<<endl;
-	if (ray->mPass >= minPass && ray->mPvsContribution > 0)
-	  selected.push_back(ray);
-  }
+
+  // ofstream s("contrib.log");
+
+  for (; it != end(); it++) 
+  {
+	  VssRay *ray = *it;
+
+	  // s<<"(pass="<<ray->mPass<<", c="<<ray->mPvsContribution<<")"<<endl;
+	  if (ray->mPass >= minPass && ray->mPvsContribution > 0)
+		  selected.push_back(ray);
+  }
+
   return (int)selected.size();
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1928)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1932)
@@ -46,5 +46,5 @@
 	Debug << "eps: " << mEps << endl;
 
-	mStats.open("gvspreprocessor.log");
+	mGvsStats.open("gvspreprocessor.log");
 }
 
@@ -54,19 +54,20 @@
 										 const VssRay &oldRay)
 {
-	const float dist = Magnitude(oldRay.GetDir());
-	const float newDist = Magnitude(currentRay.GetDir());
- 
-#if 0
-	if ((dist - newDist) > mThresHold)
-#else 
-	// rather take relative distance
-	if ((dist / newDist) > mThreshold)
-#endif
-	{
+	// the predicted hitpoint: we expect to hit the same mesh again
+	const Vector3 predictedHit = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay);
+
+	const float predictedLen = Magnitude(predictedHit - currentRay.mOrigin);
+	const float len = Magnitude(currentRay.mTermination - currentRay.mOrigin);
+	
+	// distance large => this is likely to be a discontinuity
+	if ((predictedLen - len) > mThreshold)
+	{
+		cout << "d";
 		VssRay *newRay = ReverseSampling(currentRay, hitTriangle, oldRay);
+		
 		// set flag for visualization
 		newRay->mFlags |= VssRay::ReverseSample;
 		
-		// ray is not pushed into the queue => can delete ray
+		// if ray is not further processed => can delete ray
 		if (!HandleRay(newRay))
 			delete newRay;
@@ -81,7 +82,10 @@
 bool GvsPreprocessor::HandleRay(VssRay *vssRay)
 {
+	// compute the contribution to the view cells
 	const bool storeRaysForViz = true;
-	mViewCellsManager->ComputeSampleContribution(*vssRay, true, storeRaysForViz);
-		
+	mViewCellsManager->ComputeSampleContribution(*vssRay, 
+												 true, 
+												 storeRaysForViz);
+
 	// some pvs contribution for this ray?
 	if (vssRay->mPvsContribution > 0)
@@ -92,11 +96,15 @@
 		if (storeRaysForViz)
 		{
+			VssRay *nray = new VssRay(*vssRay);
+			nray->mFlags = vssRay->mFlags;
+
+			// store ray in contributing view cell
 			ViewCellContainer::const_iterator vit, vit_end = vssRay->mViewCells.end();
 			for (vit = vssRay->mViewCells.begin(); vit != vit_end; ++ vit)
-			{
-				VssRay *nray = new VssRay(*vssRay);
+			{			
 				(*vit)->GetOrCreateRays()->push_back(nray);				
 			}
 		}
+
 		//mVssRays.push_back(new VssRay(*vssRay));
         ++ mSampleContriPerPass;
@@ -111,9 +119,8 @@
 /** Creates 3 new vertices for triangle vertex with specified index.
 */
-static void CreateNewVertices(VertexContainer &vertices,
-							  const Triangle3 &hitTriangle,
-							  const VssRay &ray, 
-							  const int index,
-							  const float eps)
+void GvsPreprocessor::CreateDisplacedVertices(VertexContainer &vertices,
+											  const Triangle3 &hitTriangle,
+											  const VssRay &ray, 
+											  const int index) const
 {
 	const int indexU = (index + 1) % 3;
@@ -125,5 +132,5 @@
 	
 	const float len = Magnitude(a);
-
+	
 	const Vector3 dir1 = Normalize(CrossProd(a, b)); //N((pi-xp)×(pi+1- pi));
 	const Vector3 dir2 = Normalize(CrossProd(a, c)); // N((pi-xp)×(pi- pi-1))
@@ -133,9 +140,9 @@
 	// compute the new three hit points
 	// pi, i + 1:  pi+ e·|pi-xp|·di, j
-	const Vector3 pt1 = hitTriangle.mVertices[index] + eps * len * dir1;
+	const Vector3 pt1 = hitTriangle.mVertices[index] + mEps * len * dir1;
 	// pi, i - 1:  pi+ e·|pi-xp|·di, j
-    const Vector3 pt2 = hitTriangle.mVertices[index] + eps * len * dir2;
+    const Vector3 pt2 = hitTriangle.mVertices[index] + mEps * len * dir2;
 	// pi, i:  pi+ e·|pi-xp|·di, j
-	const Vector3 pt3 = hitTriangle.mVertices[index] + eps * len * dir3;
+	const Vector3 pt3 = hitTriangle.mVertices[index] + mEps * len * dir3;
 	
 	vertices.push_back(pt2);
@@ -147,16 +154,18 @@
 void GvsPreprocessor::EnlargeTriangle(VertexContainer &vertices,
 									  const Triangle3 &hitTriangle,
-									  const VssRay &ray)
-{
-	CreateNewVertices(vertices, hitTriangle, ray, 0, mEps);
-	CreateNewVertices(vertices, hitTriangle, ray, 1, mEps);
-	CreateNewVertices(vertices, hitTriangle, ray, 2, mEps);
-}
-
-
-static Vector3 CalcPredictedHitPoint(const VssRay &newRay, 
-									 const Triangle3 &hitTriangle,
-									 const VssRay &oldRay)
-{
+									  const VssRay &ray) const
+{
+	CreateDisplacedVertices(vertices, hitTriangle, ray, 0);
+	CreateDisplacedVertices(vertices, hitTriangle, ray, 1);
+	CreateDisplacedVertices(vertices, hitTriangle, ray, 2);
+}
+
+
+Vector3 GvsPreprocessor::CalcPredictedHitPoint(const VssRay &newRay, 
+											   const Triangle3 &hitTriangle,
+											   const VssRay &oldRay) const
+{
+	// find the intersection of the plane induced by the 
+	// hit triangle with the new ray
 	Plane3 plane(hitTriangle.GetNormal(), hitTriangle.mVertices[0]);
 
@@ -177,16 +186,12 @@
 								   const Vector3 &p1, 
 								   const Vector3 &p2, 
-								   const VssRay &x, 
-								   const VssRay &y,
+								   const VssRay &ray1, 
+								   const VssRay &ray2,
 								   const VssRay &oldRay)
 {
-	// the predicted hitpoint expects to hit the same mesh again
-	const Vector3 predictedHitX = CalcPredictedHitPoint(x, hitTriangle, oldRay);
-	const Vector3 predictedHitY = CalcPredictedHitPoint(y, hitTriangle, oldRay);
-
-	CheckDiscontinuity(x, hitTriangle, oldRay);
-	CheckDiscontinuity(y, hitTriangle, oldRay);
-
-	if (EqualVisibility(x, y))
+	CheckDiscontinuity(ray1, hitTriangle, oldRay);
+	CheckDiscontinuity(ray2, hitTriangle, oldRay);
+
+	if (EqualVisibility(ray1, ray2) || (Magnitude(p1 - p2) <= mEps))
 	{
 		return 0;
@@ -194,11 +199,15 @@
 	else
 	{
-		cout << "s";
+		// 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);
 	
-		// cast ray into the new subdivision point
-		VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox(), false);
-		
+		VssRay *newRay = mRayCaster->CastRay(sray, mViewCellsManager->GetViewSpaceBox());
+
 		if (!newRay) return 0;
 
@@ -209,11 +218,12 @@
 		
 		// subdivide further
-		const int s1 = SubdivideEdge(hitTriangle, p1, p, x, *newRay, oldRay);
-		const int s2 = SubdivideEdge(hitTriangle, p, p2, *newRay, y, oldRay);
-				
+		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 s1 + s2 + 1;
+		return samples1 + samples2 + 1;
 	}
 }
@@ -222,5 +232,4 @@
 int GvsPreprocessor::AdaptiveBorderSampling(const VssRay &currentRay)
 {
-	cout << "a";
 	Intersectable *tObj = currentRay.mTerminationObject;
 	Triangle3 hitTriangle;
@@ -245,4 +254,6 @@
 	simpleRays.reserve(9);
 
+	//cout << "currentRay: " << currentRay.mOrigin << " dir: " << currentRay.GetDir() << endl;
+
 	VertexContainer::const_iterator vit, vit_end = enlargedTriangle.end();
 
@@ -252,13 +263,14 @@
 		SimpleRay sr(currentRay.GetOrigin(), rayDir, SamplingStrategy::GVS, 1.0f);
 		simpleRays.AddRay(sr);
-	}
-
-	// visualize enlarged triangles
+
+		//cout << "new: " << sr.mOrigin << " dist: " << sr.mDirection << endl;
+	}
+
 	if (0)
 	{
+		// visualize enlarged triangles
 		VizStruct dummy;
 		dummy.enlargedTriangle = new Polygon3(enlargedTriangle);
 		dummy.originalTriangle = hitTriangle;
-		//dummy.ray = new VssRay(currentRay);
 		vizContainer.push_back(dummy);
 	}
@@ -266,5 +278,12 @@
 	// cast rays to triangle vertices and determine visibility
 	VssRayContainer vssRays;
-	CastRays(simpleRays, vssRays, false, false);
+
+	// 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.
+	const bool pruneInvalidRays = false;
+
+	CastRays(simpleRays, vssRays, castDoubleRays, pruneInvalidRays);
 
 	// set flags
@@ -275,5 +294,5 @@
 	}
 
-	// add to ray queue
+	// handle rays
 	EnqueueRays(vssRays);
 	
@@ -282,25 +301,25 @@
 
     // recursivly subdivide each edge
-	for (int i = 0; 1 && (i < n); ++ i)
-	{
-		castRays += SubdivideEdge(
-			hitTriangle,
-			enlargedTriangle[i], 
-			enlargedTriangle[(i + 1) % n], 
-			*vssRays[i], 
-			*vssRays[(i + 1) % n],
-			currentRay);
+	for (int i = 0; i < n; ++ i)
+	{
+		castRays += SubdivideEdge(hitTriangle,
+								  enlargedTriangle[i], 
+								  enlargedTriangle[(i + 1) % n], 
+								  *vssRays[i], 
+								  *vssRays[(i + 1) % n],
+								  currentRay);
 	}
 
 	mBorderSamples += castRays;
+
 	return castRays;
 }
 
 
-static Vector3 GetPassingPoint(const VssRay &currentRay,
-							   const Triangle3 &hitTriangle,
-							   const VssRay &oldRay)
-{
-	// intersect triangle plane with plane spanned by current samples
+Vector3 GvsPreprocessor::GetPassingPoint(const VssRay &currentRay,
+										 const Triangle3 &hitTriangle,
+										 const VssRay &oldRay) const
+{
+	//-- intersect triangle plane with plane spanned by current samples
 	Plane3 plane(currentRay.GetOrigin(), currentRay.GetTermination(), oldRay.GetTermination());
 	Plane3 triPlane(hitTriangle.GetNormal(), hitTriangle.mVertices[0]);
@@ -310,5 +329,5 @@
 	// Evaluate new hitpoint just outside the triangle
 	const float factor = 0.95f;
-	float t = triPlane.FindT(intersectLine);
+	const float t = triPlane.FindT(intersectLine);
 	const Vector3 newPoint = intersectLine.mOrigin + t * factor * intersectLine.mDirection;
 
@@ -329,7 +348,8 @@
 	const Vector3 predicted = CalcPredictedHitPoint(currentRay, hitTriangle, oldRay);
 
-	//-- Construct the mutated ray with xnew,dir = predicted(x)- pnew 
-	//-- as direction vector
+	//-- Construct the mutated ray with xnew,
+	//-- dir = predicted(x)- pnew as direction vector
 	const Vector3 newDir = predicted - newPoint ;
+
 	// take xnew,p = intersect(viewcell, line(pnew, predicted(x)) as origin ?
 	// difficult to say!!
@@ -438,5 +458,4 @@
 	else if (0)
 	{	
-		//-- load view cells from file
 		//-- test successful view cells loading by exporting them again
 		VssRayContainer dummies;
@@ -451,8 +470,8 @@
 		////////
 		//-- stats
+
 		cout << "\nPass " << mPass << " #samples: " << castSamples << " of " << mTotalSamples << endl;
-
-		//mVssRays.PrintStatistics(mStats);
-		mStats 
+		//mVssRays.PrintStatistics(mGvsStats);
+		mGvsStats 
 			<< "#Pass\n" << mPass << endl
 			<< "#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl
@@ -464,5 +483,5 @@
 			<< "#GvsRuns\n" << mGvsPass << endl;
 
-		mViewCellsManager->PrintPvsStatistics(mStats);
+		mViewCellsManager->PrintPvsStatistics(mGvsStats);
 
 		char str[64]; sprintf(str, "tmp/pass%04d-", mPass);
@@ -489,5 +508,5 @@
 	}
 
-	cout << 2 * castSamples / (1e3f * TimeDiff(startTime, GetTime())) << "M rays/s" << endl;
+	cout << "cast " << 2 * castSamples / (1e3f * TimeDiff(startTime, GetTime())) << "M rays/s" << endl;
 	Visualize();
 
