Index: GTP/trunk/Lib/Vis/Preprocessing/scripts/vsposp_typical.sh
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/scripts/vsposp_typical.sh	(revision 1727)
+++ GTP/trunk/Lib/Vis/Preprocessing/scripts/vsposp_typical.sh	(revision 1768)
@@ -78,5 +78,5 @@
 
 ############################################################################
-OBJ_SPLITS=700
+OBJ_SPLITS=100
 
   METHOD=sequential-$OBJ_SPLITS
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1764)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1768)
@@ -567,5 +567,5 @@
 	*/
 	int CastPassSamples(const int samplesPerPass, 
-						const int sampleType, 
+						const vector<int> &strategies,
 						VssRayContainer &vssRays) const;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1765)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1768)
@@ -689,4 +689,5 @@
 	////////
 	//-- evaluation of render cost heuristics
+
 	float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1767)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1768)
@@ -93,8 +93,10 @@
 	mBoundingBox.GetEdge(idx, &a, &b);
 	
-	const float factor = RandomValue(0.0f, 1.0f);
-
-	point = a * factor + b * (1 - factor);
-	//normal = mBoundingBox.GetNormal();
+	const float w = RandomValue(0.0f, 1.0f);
+
+	point = a * w + b * (1.0f - w);
+
+	// TODO
+	normal = Vector3(0);
 
 	return idx;
@@ -564,6 +566,8 @@
 	float priority;
 
-	// surface area heuristics is used when there is no view space subdivision available. 
-	// In order to have some prioritized traversal, use this formula instead
+	// surface area heuristics is used when there is 
+	// no view space subdivision available. 
+	// In order to have some prioritized traversal, 
+	// we use this formula instead
 	if (mHierarchyManager->GetViewSpaceSubdivisionType() == 
 		HierarchyManager::NO_VIEWSPACE_SUBDIV)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1765)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1768)
@@ -309,6 +309,7 @@
 
 int ViewCellsManager::CastPassSamples(const int samplesPerPass, 
-									  const int sampleType, 
-									  VssRayContainer &passSamples) const
+									  const vector<int> &strategies,
+									  VssRayContainer &passSamples
+									  ) const
 {
 	SimpleRayContainer simpleRays;
@@ -318,10 +319,4 @@
 	int castRays = 0;
 	
-	vector<int> strategies;
-	 
-	strategies.push_back(SamplingStrategy::OBJECT_BASED_DISTRIBUTION);
-	strategies.push_back(SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION);
-	strategies.push_back(SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION);
-
 	const int numRaysPerPass = samplesPerPass / (int)strategies.size();
 
@@ -397,6 +392,12 @@
 	cout << "view cell construction: casting " << mInitialSamples << " initial samples ... " << endl;
 
+	// mix of sampling strategies
+	vector<int> strategies;
+	strategies.push_back(SamplingStrategy::OBJECT_BASED_DISTRIBUTION);
+	strategies.push_back(SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION);
+	strategies.push_back(SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION);
+
 	// cast initial samples
-	CastPassSamples(mInitialSamples, mSamplingType,	initialSamples);
+	CastPassSamples(mInitialSamples, strategies, initialSamples);
 
 	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
@@ -460,6 +461,4 @@
 	startTime = GetTime();
 	const int n = mConstructionSamples; //+initialSamples;
-	// should we use directional samples?
-	bool dirSamples = (mSamplingType == SamplingStrategy::DIRECTION_BASED_DISTRIBUTION);
 
 	while (numSamples < n)
@@ -470,12 +469,7 @@
 		VssRayContainer constructionSamples;
 
-		const int samplingType = mSamplingType;
-			//dirSamples ? Preprocessor::DIRECTION_BASED_DISTRIBUTION :	Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION;
-
-		if (0) dirSamples = !dirSamples; // toggle sampling method
-
 		// cast new samples
 		numSamples += CastPassSamples(mSamplesPerPass, 
-									  samplingType,
+									  strategies,
 									  constructionSamples);
 
@@ -519,5 +513,5 @@
 	cout << "casting " << mPostProcessSamples << " post processing samples ... ";
 	
-	CastPassSamples(mPostProcessSamples, mSamplingType, postProcessSamples);
+	CastPassSamples(mPostProcessSamples, strategies, postProcessSamples);
 
 	cout << "finished" << endl;
@@ -566,5 +560,5 @@
 		VssRayContainer visSamples;
 		int numSamples = CastPassSamples(mVisualizationSamples,
-										 mSamplingType, 
+										 strategies, 
 										 visSamples);
 
@@ -948,8 +942,4 @@
 	Debug << "view cell stats prefix: " << statsPrefix << endl;
 
-	// should directional sampling be used?
-	bool dirSamples = 
-		(mEvaluationSamplingType == SamplingStrategy::DIRECTION_BASED_DISTRIBUTION);
-
 	cout << "reseting pvs ... ";
 		
@@ -972,4 +962,10 @@
 	}
 
+	// mix of sampling strategies
+	vector<int> strategies;
+	strategies.push_back(SamplingStrategy::OBJECT_BASED_DISTRIBUTION);
+	strategies.push_back(SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION);
+	strategies.push_back(SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION);
+
 	cout << "finished" << endl;
     cout << "Evaluating view cell partition ... " << endl;
@@ -988,5 +984,5 @@
 		Debug << "casting " << samplesPerPass << " samples ... ";
 
-		CastPassSamples(samplesPerPass, samplingType, evaluationSamples);
+		CastPassSamples(samplesPerPass, strategies, evaluationSamples);
 		
 		castSamples += samplesPerPass;
@@ -1632,5 +1628,6 @@
 	ViewCellContainer::const_iterator it, it_end = mViewCells.end();
 
-	// volume and area of the view cells are recomputed and a view cell mesh is created
+	// volume and area of the view cells are recomputed 
+	// a view cell mesh is created
 	for (it = mViewCells.begin(); it != it_end; ++ it)
 	{
@@ -4134,4 +4131,5 @@
 	{	////////
 		//-- real meshes are contructed at this stage
+
 		cout << "finalizing view cells ... ";
 		FinalizeViewCells(true);
@@ -4334,10 +4332,6 @@
 	Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl;
 
-	// should maybe be done here to allow merge working 
-	// with area or volume and to correct the rendering statistics
-	if (0) FinalizeViewCells(false);
-		
 	//////////
-	//-- merge the individual view cells
+	//-- merge neighbouring view cells
 	MergeViewCells(postProcessRays, objects);
 	
@@ -4358,5 +4352,5 @@
 	////////////
 	//-- compression
-//#if HAS_TO_BE_REDONE
+
 	if (ViewCellsTreeConstructed() && mCompressViewCells)
 	{
@@ -4369,5 +4363,4 @@
 		Debug << "number of entries after compress: " << pvsEntries << endl;
 	}
-//#endif
 
 	// collapse sibling leaves that share the same view cell
@@ -5934,5 +5927,4 @@
 	int splitsStepSize;
 
-
 	Environment::GetSingleton()->GetIntValue("ViewCells.Evaluation.samplesPerPass", samplesPerPass);
 	Environment::GetSingleton()->GetIntValue("ViewCells.Evaluation.samplesForStats", samplesForStats);
@@ -5946,7 +5938,9 @@
 	Debug << "view cell stats prefix: " << statsPrefix << endl;
 
-	// should directional sampling be used?
-	bool dirSamples = 
-		(mEvaluationSamplingType == SamplingStrategy::DIRECTION_BASED_DISTRIBUTION);
+    // mix of sampling strategies
+	vector<int> strategies;
+	strategies.push_back(SamplingStrategy::OBJECT_BASED_DISTRIBUTION);
+	strategies.push_back(SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION);
+	strategies.push_back(SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION);
 
 	cout << "reseting pvs ... ";
@@ -5971,5 +5965,5 @@
 		Debug << "casting " << samplesPerPass << " samples ... ";
 
-		CastPassSamples(samplesPerPass, samplingType, evaluationSamples);
+		CastPassSamples(samplesPerPass, strategies, evaluationSamples);
 		
 		castSamples += samplesPerPass;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1768)
@@ -356,5 +356,8 @@
   /** Splits the box into two separate boxes with respect to the split plane
   */
-  void Split(const int axis, const float value, AxisAlignedBox3 &left, AxisAlignedBox3 &right) const;
+  void Split(const int axis, 
+			 const float value, 
+			 AxisAlignedBox3 &left, 
+			 AxisAlignedBox3 &right) const;
 
 #define __EXTENT_HACK
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1768)
@@ -1719,5 +1719,8 @@
 	
 	Vector3 vtx;
+	
+	//////////////
 	//-- compute classification of vertices
+
 	for (int i = 0; i < 8; ++i)
 	{
@@ -1732,5 +1735,7 @@
 	}
 
+	///////////
 	//-- find intersections
+
 	if (onFrontSide && onBackSide)
 	{
@@ -1756,4 +1761,5 @@
 	{
 		Vector3 centerOfMass(0);
+
 		int i;
 		// compute center of mass
@@ -1764,15 +1770,14 @@
 
 		vector<VertexData> vertexData;
-		
 		Vector3 refVec = Normalize(centerOfMass - planePoly->mVertices[0]);
 
 		// compute angle to reference point
 		for (i = 1; i < (int)planePoly->mVertices.size(); ++ i)
-		  {
+		{
 		    float angle = 
 		      Angle(refVec, centerOfMass - planePoly->mVertices[i], plane.mNormal);
 		    
 		    vertexData.push_back(VertexData(planePoly->mVertices[i], angle));
-		  }
+		}
 		
 		std::stable_sort(vertexData.begin(), vertexData.end());
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1763)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1768)
@@ -63,4 +63,6 @@
 	
 	int GetRandomEdgePoint(Vector3 &point, Vector3 &normal);
+
+
 protected:
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1763)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1768)
@@ -797,6 +797,26 @@
 int MeshInstance::GetRandomEdgePoint(Vector3 &point, Vector3 &normal)
 {
-	// TODO
-	return mMesh->GetRandomSurfacePoint(point, normal);
+	// get random face
+	const int faceIdx = (int)RandomValue(0.0f, (float)mMesh->mFaces.size() - 0.5f);
+	Face *face = mMesh->mFaces[faceIdx];
+
+	// get random edge of face (hack: this is not uniform in the edges!
+	const int edgeIdx = (int)RandomValue(0.0f, face->mVertexIndices.size() - 0.5f);
+
+	const int vertexIdxA = face->mVertexIndices[edgeIdx];
+	const int vertexIdxB = face->mVertexIndices[(edgeIdx + 1) % (int)face->mVertexIndices.size()];
+
+	const Vector3 a = mMesh->mVertices[vertexIdxA];
+	const Vector3 b = mMesh->mVertices[vertexIdxB];
+
+	const float w = RandomValue(0.0f, 1.0f);
+
+	// get random point on edge
+	point = a * w + b * (1.0f - w);
+
+	// hack: set normal of face as normal
+	normal = mMesh->GetFacePlane(faceIdx).mNormal;
+
+    return 1;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1765)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1768)
@@ -214,6 +214,8 @@
 	const float c = Magnitude(direction);
 
-	if (c <= Limits::Small) 
-		return false;
+	if ((c <= Limits::Small) || (DotProd(direction, normal) < 0))
+	{
+		return false;
+	}
 
 	// $$ jb the pdf is yet not correct for all sampling methods!
