Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1112)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1199)
@@ -39,4 +39,7 @@
     float mT;
 
+	// the normal of the intersection
+	Vector3 mNormal;
+	
     // can be either mesh or a viewcell
     Intersectable *mObject;
@@ -44,10 +47,13 @@
     // the face of the intersectable
     int mFace;
-
+	
     Intersection(const float t,
+				 const Vector3 &normal,
 				 Intersectable *object,
-				 const int face):mT(t), mObject(object), mFace(face) {}
+				 const int face):mT(t),
+								 mNormal(normal),
+								 mObject(object), mFace(face) {}
 		
-				 Intersection(): mT(0), mObject(NULL), mFace(0) {}
+				 Intersection(): mT(0), mNormal(0,0,0), mObject(NULL), mFace(0) {}
 		
     bool operator<(
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.cpp	(revision 1138)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.cpp	(revision 1199)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1174)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1199)
@@ -1816,4 +1816,5 @@
 					"false");
 
+	RegisterOption("RssTree.hybridDepth", optInt, "hybrid_depth=", "10");
 	RegisterOption("RssTree.maxDepth", optInt, "kd_depth=", "12");
 	RegisterOption("RssTree.minPvs", optInt, "kd_minpvs=", "1");
@@ -1825,5 +1826,5 @@
 	RegisterOption("RssTree.ct_div_ci", optFloat, "kd_ctdivci=", "1.0");
 	RegisterOption("RssTree.randomize", optBool, "randomize=", "false");
-	RegisterOption("RssTree.splitType", optString, "split=", "queries");
+	RegisterOption("RssTree.splitType", optString, "rss_split=", "queries");
 	RegisterOption("RssTree.splitUseOnlyDrivingAxis", optBool, "splitdriving=", "false");
 
@@ -2354,5 +2355,5 @@
   if (!GetParam(' ', 0, filename)) {
     // user didn't specified environment file explicitly, so
-    strcpy(filename, "default.Environment::GetSingleton()");
+    strcpy(filename, "default.env");
   }
   
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1197)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1199)
@@ -299,6 +299,6 @@
 	
 	if (!mViewCellsManager)
-		return false;
-
+	  return false;
+	
 	mViewCellsManager->ApplyFilter(mKdTree,
 								   mApplyVisibilityFilter ? mVisibilityFilterWidth : -1.0f,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/glInterface.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/glInterface.h	(revision 1001)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/glInterface.h	(revision 1199)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp	(revision 863)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp	(revision 1199)
@@ -227,5 +227,5 @@
 {
   loc = vssRay.mOrigin;
-  sourceObject = Intersection(0, vssRay.mOriginObject, 0);
+  sourceObject = Intersection(0, vssRay.GetDir(), vssRay.mOriginObject, 0);
   mType = LOCAL_RAY;
   
@@ -239,5 +239,5 @@
   intersections.clear();
   if (vssRay.mTerminationObject)
-	intersections.push_back(Intersection(len, vssRay.mTerminationObject, 0));
+	intersections.push_back(Intersection(len, -vssRay.GetDir(), vssRay.mTerminationObject, 0));
   
   Precompute();
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1151)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1199)
@@ -23,5 +23,5 @@
 static bool fromBoxVisibility = false;
 
-#define ADD_RAYS_IN_PLACE 0
+#define ADD_RAYS_IN_PLACE 1
   
 RssPreprocessor::RssPreprocessor():
@@ -122,6 +122,9 @@
   int hits = 0;
   static Ray ray;
+  Intersectable *objectA, *objectB;
+  Vector3 pointA, pointB;
+
   //  AxisAlignedBox3 box = Union(mKdTree->GetBox(), mViewCellsManager->GetViewSpaceBox());
-
+  
   AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
 
@@ -132,20 +135,19 @@
 	
   SetupRay(ray, viewPoint, direction);
-
-  if (!mDetectEmptyViewSpace)
-	ray.mFlags &= ~Ray::CULL_BACKFACES;
-  else
-	ray.mFlags |= Ray::CULL_BACKFACES;
-
+  ray.mFlags &= ~Ray::CULL_BACKFACES;
 
   // cast ray to KD tree to find intersection with other objects
-  Intersectable *objectA, *objectB;
-  Vector3 pointA, pointB;
   float bsize = Magnitude(box.Size());
-
+  
   
   if (mKdTree->CastRay(ray)) {
 	objectA = ray.intersections[0].mObject;
 	pointA = ray.Extrap(ray.intersections[0].mT);
+	if (mDetectEmptyViewSpace)
+	  if (DotProd(ray.intersections[0].mNormal, direction) >= 0) {
+		// discard the sample
+		return 0;
+	  }
+	
   } else {
 	objectA = NULL;
@@ -158,18 +160,16 @@
   }
 
-
-  if (mDetectEmptyViewSpace) {
-	SetupRay(ray, pointA, -direction);
-  } else
-	SetupRay(ray, viewPoint, -direction);
-	
-  if (!mDetectEmptyViewSpace)
-	ray.mFlags &= ~Ray::CULL_BACKFACES;
-  else
-	ray.mFlags |= Ray::CULL_BACKFACES;
-
+  
+  SetupRay(ray, viewPoint, -direction);
+  ray.mFlags &= ~Ray::CULL_BACKFACES;
+  
   if (mKdTree->CastRay(ray)) {
 	objectB = ray.intersections[0].mObject;
 	pointB = ray.Extrap(ray.intersections[0].mT);
+	if (mDetectEmptyViewSpace)
+	  if (DotProd(ray.intersections[0].mNormal, direction) <= 0) {
+		// discard the sample
+		return 0;
+	  }
   } else {
 	objectB = NULL;
@@ -180,19 +180,7 @@
 	  return 0;
   }
-
-  //  if (objectA == NULL && objectB != NULL) {
-  if (mDetectEmptyViewSpace) {
-	// cast again to ensure that there is no objectA
-	SetupRay(ray, pointB, direction);
-	ray.mFlags |= Ray::CULL_BACKFACES;
-	if (mKdTree->CastRay(ray)) {
-	  objectA = ray.intersections[0].mObject;
-	  pointA = ray.Extrap(ray.intersections[0].mT);
-	}
-  }
   
   
   VssRay *vssRay  = NULL;
-
   bool validSample = (objectA != objectB);
   if (validSample) {
@@ -207,5 +195,4 @@
 	  vssRays.push_back(vssRay);
 	  hits ++;
-
 	}
 	
@@ -587,9 +574,21 @@
 	cout<<"Generating initial rays..."<<endl<<flush;
 
-	GenerateRays(mInitialSamples/3, SPATIAL_BOX_BASED_DISTRIBUTION, rays);
-	GenerateRays(mInitialSamples/3, OBJECT_BASED_DISTRIBUTION, rays);
-	GenerateRays(mInitialSamples/3, DIRECTION_BASED_DISTRIBUTION, rays);
-	//	GenerateRays(mInitialSamples/4, OBJECT_DIRECTION_BASED_DISTRIBUTION, rays);
-
+	if (mUseImportanceSampling) {
+	  GenerateRays(mInitialSamples/3, SPATIAL_BOX_BASED_DISTRIBUTION, rays);
+	  GenerateRays(mInitialSamples/3, OBJECT_BASED_DISTRIBUTION, rays);
+	  GenerateRays(mInitialSamples/3, DIRECTION_BASED_DISTRIBUTION, rays);
+	  //	GenerateRays(mInitialSamples/4, OBJECT_DIRECTION_BASED_DISTRIBUTION, rays);
+	} else {
+	  int rayType = SPATIAL_BOX_BASED_DISTRIBUTION;
+	  if (mObjectBasedSampling)
+		rayType = OBJECT_BASED_DISTRIBUTION;
+	  else
+		if (mDirectionalSampling)
+		  rayType = DIRECTION_BASED_DISTRIBUTION;
+	  cout<<"Generating rays..."<<endl;
+	  GenerateRays(mRssSamplesPerPass, rayType, rays);
+	}
+	
+	
 	cout<<"Casting initial rays..."<<endl<<flush;
 	CastRays(rays, mVssRays);
@@ -904,5 +903,5 @@
 	
 	
-	if (!mUseImportanceSampling) 
+	if (!mUseImportanceSampling)
 	  CLEAR_CONTAINER(vssRays);
 	// otherwise the rays get deleted by the rss tree update according to RssTree.maxRays ....
@@ -919,27 +918,27 @@
   if (mUseViewcells) {
 
-	  if(0)
+	if(0)
 	  {
-		  VssRayContainer selectedRays;
-		  int desired = mViewCellsManager->GetVisualizationSamples();
-
-		  mVssRays.SelectRays(desired, selectedRays);
-
-		  mViewCellsManager->Visualize(mObjects, selectedRays);
-	  }
-	  
-	  // view cells after sampling
-	  mViewCellsManager->PrintStatistics(Debug);
-      
-	  //-- render simulation after merge
-	  cout << "\nevaluating bsp view cells render time after sampling ... ";
-	  
-	  mRenderSimulator->RenderScene();
-	  SimulationStatistics ss;
-	  mRenderSimulator->GetStatistics(ss);
-	  
-	  cout << " finished" << endl;
-	  cout << ss << endl;
-	  Debug << ss << endl;
+		VssRayContainer selectedRays;
+		int desired = mViewCellsManager->GetVisualizationSamples();
+		
+		mVssRays.SelectRays(desired, selectedRays);
+		
+		mViewCellsManager->Visualize(mObjects, selectedRays);
+	  }
+	
+	// view cells after sampling
+	mViewCellsManager->PrintStatistics(Debug);
+	
+	//-- render simulation after merge
+	cout << "\nevaluating bsp view cells render time after sampling ... ";
+	
+	mRenderSimulator->RenderScene();
+	SimulationStatistics ss;
+	mRenderSimulator->GetStatistics(ss);
+	
+	cout << " finished" << endl;
+	cout << ss << endl;
+	Debug << ss << endl;
 	
   }
@@ -959,5 +958,5 @@
 
 
-  // mViewCellsManager->ExportViewCells("visibility.xml",
+  //mViewCellsManager->ExportViewCells("visibility.xml",
   //									 true);
   
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1112)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1199)
@@ -11,8 +11,10 @@
 #filename ../data/vienna/vienna-buildings.x3d
 #filename ../data/vienna/city1500_flat_1.x3d
-#filename ../data/vienna/vienna-buildings.x3d;../data/vienna/vienna-roofs.x3d;../data/vienna/vienna-plane.x3d;../data/vienna/vienna-roads.x3d
+filename ../data/vienna/vienna-buildings.x3d;../data/vienna/vienna-roofs.x3d
+#;../data/vienna/vienna-plane.x3d;../data/vienna/vienna-roads.x3d
 # filename ../data/vienna/viewcells-25-sel.x3d
 #filename ../data/atlanta/atlanta2.x3d
-# filename ../data/soda/soda.dat
+#filename ../data/soda/soda.dat
+#filename ../data/test1/test2.x3d
 #filename ../data/soda/soda5.dat
 #filename ../data/PowerPlant/ppsection1/part_a/g0.ply
@@ -22,5 +24,5 @@
 #filename ../data/PowerPlant/selection3.plb
 #filename ../data/PowerPlant/section10.plb;../data/PowerPlant/section14.plb
-filename ../data/PowerPlant/selection.plb
+#filename ../data/PowerPlant/selection.plb
 #filename ../data/PowerPlant/comps/ppsection1/comps.plb
 }
@@ -29,5 +31,5 @@
 	# stored sample rays
 	samplesFilename rays.out
-	useGlRenderer true
+	useGlRenderer false
 	useGlDebugger false
 #	type sampling
@@ -55,5 +57,5 @@
 	samplesPerPass  100000
 	initialSamples 100000
-	vssSamples 1000000
+	vssSamples 500000
 	vssSamplesPerPass 100000
 	useImportanceSampling true
@@ -71,5 +73,5 @@
 	maxDepth 	40
 	minPvs		30
-	minRays		100
+	minRays		20
 	minSize		0.001
  	maxCostRatio	2.0
@@ -79,8 +81,8 @@
 	maxStaticMemory	100
 
-#	splitType regular
-	splitType heuristic
+	splitType regular
+#	splitType heuristic
 #	splitType hybrid
-	splitUseOnlyDrivingAxis true
+	splitUseOnlyDrivingAxis false
 
 	interleaveDirSplits	true
@@ -94,8 +96,13 @@
 }
 
+SamplingPreprocessor {
+	totalSamples 30000000
+	samplesPerPass 1000000
+}
+
 RssPreprocessor {
 	samplesPerPass 1000
-	initialSamples 1000000
-	vssSamples 500000000
+	initialSamples 2000000
+	vssSamples 30000000
 	vssSamplesPerPass 1000000
 	useImportanceSampling true
@@ -128,16 +135,18 @@
 #	splitType heuristic
 
-	minRays		200
+	minRays		100
 	minSize		0.001
- 	maxCostRatio 0.98
-	maxRayContribution 0.5
+ 	maxCostRatio 1.0
+	maxRayContribution 1.0
 	maxRays		4000000
 	maxTotalMemory	200
 	maxStaticMemory	100
 
-#	splitType regular
-	splitType heuristic
+	splitType regular
+#	splitType heuristic
 #	splitType hybrid
+	hybridDepth		10
 	splitUseOnlyDrivingAxis false
+#false
 	importanceBasedCost false
 
@@ -190,8 +199,4 @@
 
 
-SamplingPreprocessor {
-	totalSamples 10000000
-	samplesPerPass  3
-}
 
 
@@ -281,5 +286,6 @@
 #	filename ../data/soda/soda5-viewcells.xml
 #	filename ../scripts/viewcells_atlanta.xml
-#	filename ../data/soda/soda5-viewcells2.xml
+#	filename ../data/soda/soda-viewcells-5000.xml
+#	filename ../data/test1/test-viewcells.xml
 
 #	filename ../data/soda/soda5-viewcell-single.xm
@@ -288,8 +294,12 @@
 
 #	filename ../data/atlanta/viewcells_atlanta3.xml
+
 #	filename ../data/vienna/viewcells_vienna.xml
 #	filename ../data/vienna/viewcells_vienna2.xml
 #	filename ../data/vienna/vienna_simple-21-04-avs2-viewCells.xml
-	filename ../data/PowerPlant/power_plant_viewcells1.xml
+	filename ../data/vienna/vienna-viewcells-5000.xml
+
+
+#	filename ../data/PowerPlant/power_plant_viewcells1.xml
 }
 
@@ -303,41 +313,4 @@
 
 
-VspKdTree {
-	epsilon		1e-6
-
-	Construction {
-		samples 500000
-	}
-	
-	Termination {
-		maxDepth	 	40
-		minPvs			0
-		minRays			1
-		minSize			0.001
-		maxCostRatio		5.9
-		maxViewCells		169
-		missTolerance		4
-		maxRayContribution 	2.5
-	}
-	
-	maxTotalMemory	100
-	maxStaticMemory	40
-
-	splitType 	regular
-	#splitType 	heuristics
-	splitUseOnlyDrivingAxis true
-	ct_div_ci	0.0
-	
-	# maximal cost for merging a view cell
-	PostProcess {
-		maxCostRatio 0.005
-		minViewCells 10000
-		maxPvsSize   5000
-	}
-	
-	
-	Visualization {
-	}
-}
 
 VspBspTree {
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1189)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.cpp	(revision 1199)
@@ -17,7 +17,7 @@
 {
   // this should increase coherence of the samples
-  Environment::GetSingleton()->GetIntValue("Sampling.samplesPerPass", mSamplesPerPass);
-  Environment::GetSingleton()->GetIntValue("Sampling.totalSamples", mTotalSamples);
- 
+  Environment::GetSingleton()->GetIntValue("SamplingPreprocessor.samplesPerPass", mSamplesPerPass);
+  Environment::GetSingleton()->GetIntValue("SamplingPreprocessor.totalSamples", mTotalSamples);
+  
   mStats.open("stats.log");
 }
@@ -25,22 +25,43 @@
 SamplingPreprocessor::~SamplingPreprocessor()
 {
-	CLEAR_CONTAINER(mSampleRays);
-	CLEAR_CONTAINER(mVssSampleRays);
-}
-
-void
-SamplingPreprocessor::SetupRay(Ray &ray, 
-							   const Vector3 &point, 
-							   const Vector3 &direction,
-							   const int type,
-							   const Ray::Intersection &origin)
-{
-  ray.Clear();
-  
-	ray.mFlags |= Ray::STORE_KDLEAVES | Ray::STORE_BSP_INTERSECTIONS;
-	//  cout<<point<<" "<<direction<<endl;
-
-	ray.Init(point, direction, type);
-	ray.sourceObject = origin;
+  CLEAR_CONTAINER(mSampleRays);
+  CLEAR_CONTAINER(mVssSampleRays);
+}
+
+Intersectable *
+SamplingPreprocessor::CastRay(
+							  const Vector3 &origin,
+							  const Vector3 &direction
+							  )
+{
+
+  static Ray ray;
+  AxisAlignedBox3 box = mViewCellsManager->GetViewSpaceBox();
+  
+  AxisAlignedBox3 sbox = box;
+  sbox.Enlarge(Vector3(-Limits::Small));
+  if (!sbox.IsInside(origin))
+	return 0;
+	
+  ray.intersections.clear();
+  // do not store anything else then intersections at the ray
+  ray.Init(origin, direction, Ray::LOCAL_RAY);
+
+  ray.mFlags &= ~Ray::CULL_BACKFACES;
+
+
+
+  // cast ray to KD tree to find intersection with other objects
+  Intersectable *objectA = NULL;
+  Vector3 pointA;
+  float bsize = Magnitude(box.Size());
+  
+  if (mKdTree->CastRay(ray)) {
+	if (!mDetectEmptyViewSpace || DotProd(ray.intersections[0].mNormal, direction) < 0) {
+	  objectA = ray.intersections[0].mObject;
+	  pointA = ray.Extrap(ray.intersections[0].mT);
+	}
+  }
+  return objectA;
 }
 
@@ -58,107 +79,4 @@
 }
 
- 
-void
-SamplingPreprocessor::CastRays(const RayContainer &rays)
-{ 	
-  // cast ray to KD tree to find intersection with other objects
-  RayContainer::const_iterator it, it_end = rays.end();
-
-  VssRayContainer vssRays;
-  for (it = rays.begin(); it != it_end; ++it) {
-	mKdTree->CastRay(*(*it));
-	vssRays.push_back(new VssRay(*(*it)));
-  }
-  
-  mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
-  CLEAR_CONTAINER(vssRays);
-}
-
-int
-SamplingPreprocessor::CastRay(Ray &ray)
-{
-	// cast ray to KD tree to find intersection with other objects
-	mKdTree->CastRay(ray);
-	VssRay vssRay(ray);
-
-	mViewCellsManager->ComputeSampleContribution(vssRay, true, false);
-	
-	return vssRay.mPvsContribution;
-}
-
-
-
-int
-SamplingPreprocessor::CastEdgeSamples(
-									  Intersectable *object,
-									  const Vector3 &point,
-									  MeshInstance *mi,
-									  const int samples
-									  )
-{
-	Ray ray;
-	int maxTries = samples*10;
-	int i;
-	int rays = 0;
-	int edgeSamplesContributions = 0;
-	for (i=0; i < maxTries && rays < samples; i++) {
-		// pickup a random face of each mesh 
-		Mesh *mesh = mi->GetMesh();
-		int face = (int)RandomValue(0, (Real)((int)mesh->mFaces.size() - 1));
-		
-		Polygon3 poly(mesh->mFaces[face], mesh);
-		poly.Scale(1.001f);
-		// now extend a random edge of the face
-		int edge = (int)RandomValue(0, (Real)((int)poly.mVertices.size() - 1));
-		float t = RandomValue(0.0f, 1.0f);
-		Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
-			poly.mVertices.size()];
-		SetupRay(ray, point, target - point, Ray::LOCAL_RAY, Ray::Intersection(0, object, 0));
-		if (!mesh->CastRay(ray, mi)) {
-			// the rays which intersect the mesh have been discarded since they are not tangent
-			// to the mesh
-			rays++;
-			edgeSamplesContributions += CastRay(ray);
-		}
-	}
-	return edgeSamplesContributions;
-}
-
-KdNode *
-SamplingPreprocessor::GetNodeToSample(Intersectable *object)
-{
-	int pvsSize = object->mKdPvs.GetSize();
-	KdNode *nodeToSample = NULL;
-	
-	bool samplePvsBoundary = false;
-	if (pvsSize && samplePvsBoundary) {
-		// this samples the nodes from the boundary of the current PVS
-		// mail all nodes from the pvs
-		Intersectable::NewMail();
-		KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
-		
-		for (; i != object->mKdPvs.mEntries.end(); i++) {
-			KdNode *node = (*i).first;
-			node->Mail();
-		}
-		
-		int maxTries = 2*pvsSize;
-		Debug << "Finding random neighbour" << endl;	
-		for (int tries = 0; tries < 10; tries++) {
-			int index = (int)RandomValue(0, (Real)(pvsSize - 1));
-			PvsData data;
-			KdNode *node;
-			object->mKdPvs.GetData(index, node, data);
-			nodeToSample = mKdTree->FindRandomNeighbor(node, true);
-			if (nodeToSample)
-				break;
-		}
-	} else {
-		// just pickup a random node
-		//		nodeToSample = mKdTree->GetRandomLeaf(Plane3(normal, point));
-		nodeToSample = mKdTree->GetRandomLeaf();
-	}
-	return nodeToSample;
-}
 
 void
@@ -166,29 +84,29 @@
 {
 	// mail all nodes from the pvs
-	Intersectable::NewMail();
-	KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
-	for (; i != object->mKdPvs.mEntries.end(); i++) {
-		KdNode *node = (*i).first;
-		node->Mail();
-	}
-	Debug << "Get all neighbours from PVS" << endl;
-	vector<KdNode *> invisibleNeighbors;
-	// get all neighbors of all PVS nodes
-	i = object->mKdPvs.mEntries.begin();
-	for (; i != object->mKdPvs.mEntries.end(); i++) {
-		KdNode *node = (*i).first;
-		mKdTree->FindNeighbors(node, invisibleNeighbors, true);
-		AxisAlignedBox3 box = object->GetBox();
-		for (int j=0; j < invisibleNeighbors.size(); j++) {
-			int visibility = ComputeBoxVisibility(mSceneGraph,
-							      mKdTree,
-							      box,
-							      mKdTree->GetBox(invisibleNeighbors[j]),
-							      1e-6f);
-			//	      exit(0);
-		}
-		// now rank all the neighbors according to probability that a new
-		// sample creates some contribution
-	}
+  Intersectable::NewMail();
+  KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
+  for (; i != object->mKdPvs.mEntries.end(); i++) {
+	KdNode *node = (*i).first;
+	node->Mail();
+  }
+  Debug << "Get all neighbours from PVS" << endl;
+  vector<KdNode *> invisibleNeighbors;
+  // get all neighbors of all PVS nodes
+  i = object->mKdPvs.mEntries.begin();
+  for (; i != object->mKdPvs.mEntries.end(); i++) {
+	KdNode *node = (*i).first;
+	mKdTree->FindNeighbors(node, invisibleNeighbors, true);
+	AxisAlignedBox3 box = object->GetBox();
+	for (int j=0; j < invisibleNeighbors.size(); j++) {
+	  int visibility = ComputeBoxVisibility(mSceneGraph,
+											mKdTree,
+											box,
+											mKdTree->GetBox(invisibleNeighbors[j]),
+											1e-6f);
+	  //	      exit(0);
+	}
+	// now rank all the neighbors according to probability that a new
+	// sample creates some contribution
+  }
 }
 
@@ -197,147 +115,91 @@
 {
   
-  /// rays per pass
-  RayContainer passRays;
-
-
-  mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
-  
-  Vector3 point, normal, direction;
-  //Ray ray;
-
+  Debug << "type: sampling" << endl;
+  
+  cout<<"Sampling Preprocessor started\n"<<flush;
+  //  cout<<"Memory/ray "<<sizeof(VssRay)+sizeof(RssTreeNode::RayInfo)<<endl;
+
+  Randomize(0);
+  
   long startTime = GetTime();
   
-  int i;
   int totalSamples = 0;
 
-  int pvsSize = 0;
-
-  while (totalSamples < mTotalSamples) {
-		int passContributingSamples = 0;
-		int passSampleContributions = 0;
-		int passSamples = 0;
-		int index = 0;
-		
-		int reverseSamples = 0;
-		
-		for (i = 0; i < mObjects.size(); i++) {
-						
-			KdNode *nodeToSample = NULL;
-			Intersectable *object = mObjects[i];
-		
-			int pvsSize = 0;
-			
-			if (0 && pvsSize && mPass == 1000 ) {
-				VerifyVisibility(object);
+  // if not already loaded, construct view cells from file
+  if (!mLoadViewCells)
+  {
+	mViewCellsManager->SetViewSpaceBox(mKdTree->GetBox());
+
+	// construct view cells using it's own set of samples
+	mViewCellsManager->Construct(this);
+	
+	//-- several visualizations and statistics
+	Debug << "view cells construction finished: " << endl;
+	mViewCellsManager->PrintStatistics(Debug);
+  }
+  
+
+  
+  int samples = 0;
+  int i=0;
+  while (samples < mTotalSamples) {
+	for (i=0; i < mSamplesPerPass; i++, samples++) {
+	  
+	  if (i%10000 == 0)
+		cout<<"+";
+	  
+	  Vector3 origin, direction;
+	  mViewCellsManager->GetViewPoint(origin);
+	  direction = UniformRandomVector();
+
+	  
+	  ViewCell *viewcell = mViewCellsManager->GetViewCell(origin);
+	  
+	  if (viewcell && viewcell->GetValid()) {
+		// cast rays in both directions to make the number of samples comparable
+		// with the global sampling method which also casts a "double" ray per sample
+		for (int j=0; j < 2; j++) {
+		  Intersectable *object = CastRay(origin, direction);
+		  if (object) {
+			// if ray not outside of view space
+			float contribution;
+			int pvsContribution = 0;
+			float relativePvsContribution = 0;
+			if (object) {
+			  float pdf = 1.0f;
+			  if (viewcell->GetPvs().GetSampleContribution(object,
+														   pdf,
+														   contribution))
+				++pvsContribution;
+			  relativePvsContribution += contribution;
+			  viewcell->GetPvs().AddSample(object, pdf);
 			}
-			
-			int faceIndex = object->GetRandomSurfacePoint(point, normal);
-			
-			bool viewcellSample = true;
-			//int sampleContributions;
-			bool debug = false; //(object->GetId() >= 2199);
-			if (viewcellSample) {
-				//mKdTree->GetRandomLeaf(Plane3(normal, point));
-
-				nodeToSample = GetNodeToSample(object);
-
-				for (int k=0; k < mSamplesPerPass; k++) {
-					bool reverseSample = false;
-				
-					if (nodeToSample) {
-						AxisAlignedBox3 box = mKdTree->GetBox(nodeToSample);
-						Vector3 pointToSample = box.GetRandomPoint();
-						//						pointToSample.y = 0.9*box.Min().y + 0.1*box.Max().y;
-						if (object->GetRandomVisibleSurfacePoint( point, normal, pointToSample, 3 )) {
-							direction = pointToSample - point;
-						} else {
-							reverseSamples++;
-							reverseSample = true;
-							direction = point - pointToSample;
-							point = pointToSample;
-							//Debug << "point: " << pointToSample << endl;
-						}
-					}
-					else {
-						direction = UniformRandomVector(normal);
-					}
-					
-					Ray *ray = new Ray();
-
-					// construct a ray
-					SetupRay(*ray, point, direction, Ray::LOCAL_RAY, 
-							 Ray::Intersection(0, reverseSample ? NULL : object, faceIndex));
-
-					passRays.push_back(ray);
-					
-					//-- CORR matt: put block inside loop
-					/*if (sampleContributions) {
-						passContributingSamples ++;
-						passSampleContributions += sampleContributions;
-					}*/
-				}
-			} else {
-				// edge samples
-				// get random visible mesh
-				//				object->GetRandomVisibleMesh(Plane3(normal, point));
-			}
-	
-			// CORR matt: must add all samples
-			passSamples += mSamplesPerPass;
+		  }
+		  direction = -direction;
 		}
-	
-		//-------------------
-		// cast rays for view cells construction
-		ProcessViewCells(passRays,
-						 mObjects,
-						 passSampleContributions,
-						 passContributingSamples);
-
-		CLEAR_CONTAINER(passRays);
-		
-		totalSamples += passSamples; 
-		
-		//    if (pass>10)
-		//      HoleSamplingPass();
-    
-		mPass ++;
-        
-		pvsSize += passSampleContributions;
-		
-		float avgRayContrib = (passContributingSamples > 0) ? 
-			passSampleContributions / (float)passContributingSamples : 0;
-
-		cout << "#Pass " << mPass << " : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
-		cout << "#TotalSamples=" << totalSamples/1000 
-				 << "k   #SampleContributions=" << passSampleContributions << " (" 
-				 << 100*passContributingSamples/(float)passSamples<<"%)" << " avgPVS="
-				 << (float)pvsSize /(float)mObjects.size() << endl 
-				 << "avg ray contrib=" << avgRayContrib << endl
-				 << "reverse samples [%]" << reverseSamples/(float)passSamples*100.0f << endl;
-
-		mStats <<
-			"#Pass\n" <<mPass<<endl<<
-			"#Time\n" << TimeDiff(startTime, GetTime())*1e-3 << endl<<
-			"#TotalSamples\n" << totalSamples<< endl<<
-			"#SampleContributions\n" << passSampleContributions << endl << 
-			"#PContributingSamples\n"<<100*passContributingSamples/(float)passSamples<<endl <<
-			"#AvgPVS\n"<< pvsSize/(float)mObjects.size() << endl <<
-			"#AvgRayContrib\n" << avgRayContrib << endl;
-	}
-	
-	//cout << "#totalKdPvsSize=" << mKdTree->CollectLeafPvs() << endl;
-	
+	  }
+	  
+	  if (samples > mTotalSamples)
+		break;
+	}
+	
+	//	mVssRays.PrintStatistics(mStats);
+	mStats <<
+	  "#Time\n" << TimeDiff(startTime, GetTime())*1e-3<<endl<<
+	  "#TotalSamples\n" <<samples<<endl;
+
+	mViewCellsManager->PrintPvsStatistics(mStats);
+	// ComputeRenderError();
+  }
+  
   //  HoleSamplingPass();
 	if (0) {
-		Exporter *exporter = Exporter::GetExporter("ray-density.x3d"); 
-		exporter->SetExportRayDensity(true);
-		exporter->ExportKdTree(*mKdTree);
-		delete exporter;
-	}
-	
-	// construct view cells if not already constructed
-	if (!mViewCellsManager->ViewCellsConstructed())
-	  mViewCellsManager->ConstructSubdivision(mObjects, mVssSampleRays);
-
+	  Exporter *exporter = Exporter::GetExporter("ray-density.x3d"); 
+	  exporter->SetExportRayDensity(true);
+	  exporter->ExportKdTree(*mKdTree);
+	  delete exporter;
+	}
+	
+	
 	// $$JB temporary removed
 	//	mViewCellsManager->PostProcess(objects, mSampleRays);
@@ -346,59 +208,22 @@
 	Debug << "view cells after post processing: " << endl;
 	mViewCellsManager->PrintStatistics(Debug);
-
+	
 	//-- render simulation after merge
 	cout << "\nevaluating bsp view cells render time after merge ... ";
 	
-	 mRenderSimulator->RenderScene();
-	 SimulationStatistics ss;
-	 mRenderSimulator->GetStatistics(ss);
-	 
-	 cout << " finished" << endl;
-	 cout << ss << endl;
-	 Debug << ss << endl;
+	mRenderSimulator->RenderScene();
+	SimulationStatistics ss;
+	mRenderSimulator->GetStatistics(ss);
+	
+	cout << " finished" << endl;
+	cout << ss << endl;
+	Debug << ss << endl;
 	
 	// $$JB temporary removed
 	//mViewCellsManager->Visualize(objects, mSampleRays);	
-   
+	
 	return true;
 }
 
-void SamplingPreprocessor::ProcessViewCells(const RayContainer &newRays,
-											const ObjectContainer &objects,
-											int &sampleContributions,
-											int &contributingSamples)
-{
-  // cast rays to view cells
-  CastRays(newRays);
-
-  // save rays for view cells construction
-  if (!mViewCellsManager->ViewCellsConstructed())
-	{
-	  if ((int)mVssSampleRays.size() < mViewCellsManager->GetConstructionSamples())
-		{
-		  RayContainer::const_iterator it, it_end = newRays.end();
-		  
-		  for (it = newRays.begin(); it != it_end; ++ it)
-			mVssSampleRays.push_back(new VssRay(*(*it)));
-		}
-	  else
-		{
-		  // construct view cells
-		  mViewCellsManager->ConstructSubdivision(objects, mVssSampleRays);
-		  
-		  // throw away samples 
-		  //CLEAR_CONTAINER(mVssSampleRays);
-		}
-	}
-  // Need rays (with ordered intersections) for post processing => collect new rays
-  if (((int)mSampleRays.size() < mViewCellsManager->GetPostProcessSamples()) ||
-	  ((int)mSampleRays.size() < mViewCellsManager->GetVisualizationSamples()))
-	{
-	  RayContainer::const_iterator it, it_end = newRays.end();
-	  
-	  for (it = newRays.begin(); it != it_end; ++ it)
-		mSampleRays.push_back(new Ray(*(*it)));
-	}
-}
-
-}
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.cpp	(revision 1184)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.cpp	(revision 1199)
@@ -23,7 +23,7 @@
 void BoostPreprocessorThread::Main()
 {
-	Camera camera;
+  Camera camera;
 
-	if (0)
+  if (0)
 	{
 		// camera.LookAtBox(mPreprocessor->mKdTree->GetBox());
@@ -36,24 +36,24 @@
 		camera.SnapImage("camera.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph);
 	} 
+  
+  if (0) {
+	camera.LookInBox(mPreprocessor->mKdTree->GetBox());
+	camera.SetPosition(camera.mPosition + Vector3(-250,0,-550));
+	camera.SnapImage("camera2.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph);
+  }
 
-	if (0) {
-		camera.LookInBox(mPreprocessor->mKdTree->GetBox());
-		camera.SetPosition(camera.mPosition + Vector3(-250,0,-550));
-		camera.SnapImage("camera2.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph);
-	}
-
-	if (0) {
-		camera.SetPosition( mPreprocessor->mKdTree->GetBox().Center() - Vector3(0,-100,0) );
-		camera.SetDirection(Vector3(1, 0, 0));
-		camera.SnapImage("camera3.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph);
-	}
-
-	if (mPreprocessor->mComputeVisibility) {
-		mPreprocessor->ComputeVisibility();
-		//	mPreprocessor->ExportPreprocessedData("scene.vis");
-		mPreprocessor->PostProcessVisibility();
-	}
-
-	cerr << "Preprocessor main finished...\n";
+  if (0) {
+	camera.SetPosition( mPreprocessor->mKdTree->GetBox().Center() - Vector3(0,-100,0) );
+	camera.SetDirection(Vector3(1, 0, 0));
+	camera.SnapImage("camera3.jpg", mPreprocessor->mKdTree, mPreprocessor->mSceneGraph);
+  }
+  
+  if (mPreprocessor->mComputeVisibility) {
+	mPreprocessor->ComputeVisibility();
+	//	mPreprocessor->ExportPreprocessedData("scene.vis");
+	mPreprocessor->PostProcessVisibility();
+  }
+  
+  cerr << "Preprocessor main finished...\n";
   
 }
@@ -62,6 +62,6 @@
 BoostPreprocessorThread::~BoostPreprocessorThread()
 {
-	cerr << "Boost Preprocessor thread destructor ... \n";
-	DEL_PTR(mThread);
+  cerr << "Boost Preprocessor thread destructor ... \n";
+  DEL_PTR(mThread);
 }
 
@@ -69,5 +69,5 @@
 void BoostPreprocessorThread::InitThread()
 {
-	mThread = new boost::thread(*this);
+  mThread = new boost::thread(*this);
 }
 
@@ -75,6 +75,6 @@
 void BoostPreprocessorThread::RunThread()
 {
-	mThread->join();
+  mThread->join();
 }
- 
+
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1189)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1199)
@@ -1692,32 +1692,34 @@
 void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
 {
-	// update pvs of view cells tree if necessary
-	UpdatePvs();
-
-	ViewCellContainer::const_iterator it = mViewCells.begin();
-
-	stat.viewcells = 0;
-	stat.minPvs = 100000000;
-	stat.maxPvs = 0;
-	stat.avgPvs = 0.0f;
-
-	for (; it != mViewCells.end(); ++ it) 
-	{
-		ViewCell *viewcell = *it;
-
-		const int pvsSize = mViewCellsTree->GetPvsSize(viewcell);
-
-		if (pvsSize < stat.minPvs)
-			stat.minPvs = pvsSize;
-		if (pvsSize > stat.maxPvs)
-			stat.maxPvs = pvsSize;
-
-		stat.avgPvs += pvsSize;
-
-		++ stat.viewcells;
-	}
-
-	if (stat.viewcells)
-		stat.avgPvs/=stat.viewcells;
+  // update pvs of view cells tree if necessary
+  UpdatePvs();
+  
+  ViewCellContainer::const_iterator it = mViewCells.begin();
+  
+  stat.viewcells = 0;
+  stat.minPvs = 100000000;
+  stat.maxPvs = 0;
+  stat.avgPvs = 0.0f;
+  
+  for (; it != mViewCells.end(); ++ it) 
+	{
+	  ViewCell *viewcell = *it;
+
+	  //	  bool mCountKdPvs = false;
+	  const int pvsSize = mViewCellsTree->GetPvsSize(viewcell);
+
+
+	  if (pvsSize < stat.minPvs)
+		stat.minPvs = pvsSize;
+	  if (pvsSize > stat.maxPvs)
+		stat.maxPvs = pvsSize;
+	  
+	  stat.avgPvs += pvsSize;
+	  
+	  ++ stat.viewcells;
+	}
+  
+  if (stat.viewcells)
+	stat.avgPvs/=stat.viewcells;
 }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1189)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1199)
@@ -1833,4 +1833,16 @@
 	while (root->GetParent())
 	{
+// <<<<<<< .mine
+// 	case PVS_IN_LEAVES: //-- store pvs only in leaves
+// 		{			
+// 			// pvs is always stored directly in leaves
+// 			if (vc->IsLeaf())
+// 			{
+// 				if (!countKdPvs)
+// 					pvsSize = vc->GetPvs().GetSize();
+// 				else
+// 					pvsSize = CountKdPvs(dynamic_cast<ViewCellLeaf *>(vc));
+// 				break;
+// 			}
 		root = root->GetParent();
 	
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1112)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1199)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: po 10. VII 19:18:45 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: pá 11. VIII 14:29:54 2006
 # Project:  preprocessor.pro
 # Template: app
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.h	(revision 1112)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.h	(revision 1199)
@@ -682,4 +682,7 @@
   int mDirSplitDepth;
 
+  // depth till which the regular splits are applied for hybrid split type
+  int mHybridDepth;
+  
   // maximal number of rays maintained in the rss tree
   int mMaxRays;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.h	(revision 1020)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.h	(revision 1199)
@@ -176,4 +176,5 @@
 				Ray &ray,
 				float &nearestT,
+				Vector3 &nearestNormal,
 				int &nearestFace,
 				Intersectable *instance
@@ -183,8 +184,9 @@
   int
   RayFaceIntersection(const int faceIndex,
-					const Ray &ray,
-					float &t,
-					const float nearestT
-					);
+					  const Ray &ray,
+					  float &t,
+					  Vector3 &normal,
+					  const float nearestT
+					  );
   
   Plane3 GetFacePlane(const int faceIndex);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1189)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1199)
@@ -36,4 +36,6 @@
 #define DEBUG_SPLITS 0
 
+#define EVAL_VIEWCELLS 0
+  
 // Static variables
 int
@@ -156,5 +158,7 @@
 		exit(1);
 	  }
-	
+
+  Environment::GetSingleton()->GetIntValue("RssTree.hybridDepth", mHybridDepth);
+
   Environment::GetSingleton()->GetBoolValue("RssTree.randomize", randomize);
   Environment::GetSingleton()->GetBoolValue("RssTree.splitUseOnlyDrivingAxis", mSplitUseOnlyDrivingAxis);
@@ -568,7 +572,14 @@
   Debug<<"Split Info:"<<endl;
   Debug<<"axis="<<info.axis<<" ratio="<<info.costRatio<<endl;
-  Debug<<"viewcells="<<info.viewCells<<
-	" viewcells back="<<info.viewCellsBack<<
-	" viewcells back="<<info.viewCellsFront<<endl;
+  Debug<<"rays="<<info.rays<<
+  	" rays back="<<info.raysBack<<
+  	" rays front="<<info.raysFront<<endl;
+  Debug<<"c="<<info.contribution<<
+  	" c back="<<info.contributionBack<<
+  	" c front="<<info.contributionFront<<endl;
+
+  //  Debug<<"viewcells="<<info.viewCells<<
+  //	" viewcells back="<<info.viewCellsBack<<
+  //	" viewcells back="<<info.viewCellsFront<<endl;
 #endif
   
@@ -579,5 +590,5 @@
   }
 	
-#if 0	
+#if 0
   cout<<
 	"pvs="<<leaf->mPvsSize<<
@@ -620,5 +631,4 @@
 	switch (costMethod) {
 	case 0: {
-	  //		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
 	  float sum = info.pvsBack*(info.position - minBox) + info.pvsFront*(maxBox - info.position);
 	  float newCost = ct_div_ci + sum/sizeBox;
@@ -627,4 +637,20 @@
 	  break;
 	}
+	case 6: {
+	  float sum = info.raysBack*(info.position - minBox) + info.raysFront*(maxBox - info.position);
+	  float newCost = ct_div_ci + sum/sizeBox;
+	  float oldCost = info.rays;
+	  info.costRatio = newCost/oldCost;
+	  break;
+	}
+	case 7: {
+	  float benefit =
+		(sqr(info.contributionBack) + sqr(info.contributionFront))/
+		(2.0f*sqr(info.contribution));
+	  info.costRatio = 1.0f/(benefit + Limits::Small);
+	  break;
+	}
+
+	  
 	case 1: {
 	  float newContrib =
@@ -690,4 +716,5 @@
 					   )
 {
+  info.rays = 0;
   info.raysBack = 0;
   info.raysFront = 0;
@@ -699,4 +726,5 @@
 
 
+
   float sumWeights = Limits::Small;
   float sumWeightsBack = Limits::Small;
@@ -709,4 +737,5 @@
   Intersectable::NewMail();
 
+#if EVAL_VIEWCELLS
   // count the numebr of viewcells first
   for(RssTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
@@ -714,4 +743,5 @@
 	  ri++)
 	if ((*ri).mRay->IsActive()) {
+
 	  ViewCellContainer::const_iterator it = (*ri).mRay->mViewCells.begin();
 	  for (; it != (*ri).mRay->mViewCells.end(); ++it) {
@@ -722,4 +752,5 @@
 	  }
 	}
+#endif
   
   Intersectable::NewMail(3);
@@ -741,5 +772,5 @@
 	  sumWeights += weight;
 	  sumContribution += contribution;
-	  
+	  info.rays++;
 	  if (side <= 0) {
 		info.raysBack++;
@@ -755,8 +786,11 @@
 	  
 	  AddObject2Pvs((*ri).GetObject(), side, info.pvsBack, info.pvsFront);
+
+#if EVAL_VIEWCELLS
 	  AddViewcells2Pvs((*ri).mRay->mViewCells,
 					   side,
 					   info.viewCellsBack,
 					   info.viewCellsFront);
+#endif
 	}
 
@@ -775,5 +809,8 @@
   else
 	info.contributionFront = 0.0f;
-  
+
+  //  info.costRatio = 0.1 + Random(0.5f);
+  //  return;
+
   GetCostRatio(
 			   leaf,
@@ -804,4 +841,24 @@
   bool allowDirSplit = Magnitude(sBox.Size())*dirSplitBoxSize < Magnitude(bbox.Size());
 		
+  bool useCyclingAxis = true;
+
+  if (splitType == ESplitHeuristic ||
+	  (splitType == ESplitHybrid && leaf->depth > mHybridDepth))
+	useCyclingAxis = false;
+  
+  int cyclingAxis = 0;
+  
+  if (leaf->parent) 
+	cyclingAxis = (leaf->parent->axis + 1)%5;
+  
+  if (0 && useCyclingAxis) {
+	int axis = cyclingAxis;
+	info.position = (sBox.Min()[axis] + sBox.Max()[axis])*0.5f;
+	info.axis = axis;
+	info.costRatio = 0.5f; // not true but good for speeding up the subdivision at the top levels!
+	info.raysBack = info.raysFront = leaf->rays.size()/2;
+	return;
+  }
+
   
   for (int axis = 0; axis < 5; axis++)
@@ -811,5 +868,7 @@
 		) {
 	  nInfo[axis].axis = axis;
-	  if (!mSplitUseOnlyDrivingAxis || axis == sAxis || axis == dAxis) {
+	  if ((!useCyclingAxis && (!mSplitUseOnlyDrivingAxis || axis == sAxis || axis == dAxis))
+		  || (useCyclingAxis && (axis == cyclingAxis))
+		  ) {
 		
 		if (splitType == ESplitRegular) {
@@ -828,5 +887,5 @@
 		  } else
 			if (splitType == ESplitHybrid) {
-			  if (leaf->depth > 7)
+			  if (leaf->depth > mHybridDepth)
 				EvalCostRatioHeuristic(
 									   leaf,
@@ -894,5 +953,14 @@
   currInfo.pvsFront = leaf->GetPvsSize();
 
- 
+
+  float sumWeights = Limits::Small;
+  float sumWeightsBack = Limits::Small;
+  float sumWeightsFront = Limits::Small;
+  
+  float sumContribution = 0.0f;
+  float sumContributionBack = 0.0f;
+  float sumContributionFront = 0.0f;
+
+  
   float sizeBox = maxBox - minBox;
   
@@ -904,4 +972,5 @@
 
   currInfo.viewCells = 0;
+  currInfo.rays = 0;
 
   Intersectable::NewMail();
@@ -911,4 +980,12 @@
 	  ri++)
 	if ((*ri).mRay->IsActive()) {
+
+	  float weight, contribution;
+	  GetRayContribution(*ri, weight, contribution);
+
+	  sumWeights += weight;
+	  sumContribution += contribution;
+	  currInfo.rays++;
+
 	  Intersectable *object = (*ri).GetObject();
 	  if (object)
@@ -919,4 +996,5 @@
 		  object->mCounter++;
 	  
+#if EVAL_VIEWCELLS	 
 	  // and do the same for all viewcells
 	  ViewCellContainer::const_iterator it = (*ri).mRay->mViewCells.begin();
@@ -931,11 +1009,23 @@
 		  viewcell->mCounter++;
 	  }
-	}
-
+#endif
+	}
+
+  if (sumWeights!=0.0f)
+	currInfo.contribution = sumContribution/sumWeights;
+  else
+	currInfo.contribution = 0.0f;
+
+  sumWeightsFront = sumWeights;
+  sumContributionFront = sumContribution;
+
+  sumWeightsBack = 0;
+  sumContributionBack = 0;
+  
   currInfo.viewCellsBack = 0;
   currInfo.viewCellsFront = currInfo.viewCells;
- 
+  
   Intersectable::NewMail();
-	
+  
   for(vector<SortableEntry>::const_iterator ci = splitCandidates->begin();
 	  ci < splitCandidates->end();
@@ -945,5 +1035,16 @@
 	  currInfo.raysFront--;
 	  currInfo.raysBack++;
+
 	  RssTreeNode::RayInfo *rayInfo = (RssTreeNode::RayInfo *) (*ci).data;
+	  
+	  float weight, contribution;
+	  GetRayContribution(*rayInfo, weight, contribution);
+
+	  sumWeightsBack += weight;
+	  sumContributionBack += contribution;
+
+	  sumWeightsFront -= weight;
+	  sumContributionFront -= contribution;
+
 	  Intersectable *object = rayInfo->GetObject();
 	  if (object) {
@@ -955,4 +1056,6 @@
 		  currInfo.pvsFront--;
 	  }
+
+#if EVAL_VIEWCELLS	 
 	  ViewCellContainer::const_iterator it = rayInfo->mRay->mViewCells.begin();
 	  for (; it != rayInfo->mRay->mViewCells.end(); ++it) {
@@ -965,4 +1068,6 @@
 		  currInfo.viewCellsFront--;
 	  }
+#endif
+	  
 	  break;
 	}
@@ -973,4 +1078,15 @@
 	if (position > minBand && position < maxBand) {
 	  currInfo.position = position;
+
+	  
+	  if (sumWeightsBack!=0.0f)
+		info.contributionBack = sumContributionBack/sumWeightsBack;
+	  else
+		info.contributionBack = 0.0f;
+	  
+	  if (sumWeightsFront!=0.0f)
+		info.contributionFront = sumContributionFront/sumWeightsFront;
+	  else
+		info.contributionFront = 0.0f;
 	  
 	  GetCostRatio(
@@ -1192,5 +1308,5 @@
   // update stats
   stat.rayRefs -= (int)leaf->rays.size();
-  stat.rayRefs += info.raysBack + info.raysFront;
+  stat.rayRefs += back->rays.size() + front->rays.size();
 
   
@@ -2093,34 +2209,38 @@
   }
   
-  //  int numberOfTries = numberOfRays*4;
-  int numberOfTries = numberOfRays;
-  int generated = 0;
-
-  Intersectable::NewMail();
-  vector<Intersectable *> pvs(0);
-  pvs.reserve(leaf->GetPvsSize());
-  for(RssTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
-	  ri != leaf->rays.end();
-	  ri++) {
-	Intersectable *object = (*ri).GetObject();
-	if (object) {
-	  if (!object->Mailed()) {
-		object->Mail();
-		object->mCounter = 1;
-		pvs.push_back(object);
-		if (exporter)
-		  exporter->ExportIntersectable(object);
-	  } else {
-		object->mCounter++;
-	  }
-	}
-  }
-  // sort objects based on their mCounter
-  sort(pvs.begin(), pvs.end(), Intersectable::GreaterCounter);
-  
+
   float extendedConvexCombinationProb = 0.0f; //0.7f
   //  float silhouetteCheckPercentage = 1.0f; //0.5f
   float silhouetteCheckPercentage = 0.0f; //0.9f; // 0.5f;
   float silhouetteObjectCheckPercentage = 0.8f;
+
+  //  int numberOfTries = numberOfRays*4;
+  int numberOfTries = numberOfRays;
+  int generated = 0;
+
+  vector<Intersectable *> pvs(0);
+  if (silhouetteCheckPercentage != 0.0f) {
+	Intersectable::NewMail();
+	pvs.reserve(leaf->GetPvsSize());
+	for(RssTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
+		ri != leaf->rays.end();
+		ri++) {
+	  Intersectable *object = (*ri).GetObject();
+	  if (object) {
+		if (!object->Mailed()) {
+		  object->Mail();
+		  object->mCounter = 1;
+		  pvs.push_back(object);
+		  if (exporter)
+			exporter->ExportIntersectable(object);
+		} else {
+		  object->mCounter++;
+		}
+	  }
+	}
+	// sort objects based on their mCounter
+	sort(pvs.begin(), pvs.end(), Intersectable::GreaterCounter);
+  }
+  
   for (int i=0; generated < numberOfRays && i < numberOfTries; i++) {
 	bool useExtendedConvexCombination = ((nrays >= 2) && (Random(1.0f) <
@@ -2345,13 +2465,16 @@
 int
 RssTree::PruneRays(
-				   const int desired
+				   const int maxRays
 				   )
 {
-  bool globalPrunning = true;
+  bool globalPrunning = false;
 
   stack<RssTreeNode *> tstack;
   int prunned = 0;
 
-  Debug<<"Prunning rays...\nOriginal size "<<stat.rayRefs<<endl;
+  // prune more rays to amortize  the procedure
+  int desired = maxRays*0.8f;
+
+  Debug<<"Prunning rays...\nOriginal size "<<stat.rayRefs<<endl<<flush;
 
   if (globalPrunning) {
@@ -2363,7 +2486,7 @@
 		 GreaterWeightedPvsContribution);
 	
-	if ( desired >= allRays.size() )
+	if ( maxRays >= allRays.size() )
 	  return 0;
-	
+
 	float contributionThreshold = allRays[desired]->mWeightedPvsContribution;
 	
@@ -2387,4 +2510,8 @@
 	// prune random rays from each leaf so that the ratio's remain the same
 	PushRoots(tstack);
+
+	if ( maxRays >= stat.rayRefs )
+	  return 0;
+	
 	float ratio = desired/(float)stat.rayRefs;
 	
@@ -2412,5 +2539,5 @@
   
   
-  Debug<<"Remained "<<stat.rayRefs<<" rays"<<endl;
+  Debug<<"Remained "<<stat.rayRefs<<" rays"<<endl<<flush;
   
   return prunned;
@@ -2572,5 +2699,8 @@
 	  
 	  sumContributions += weight*ray->mPvsContribution;
-	  sumRelContributions += weight*ray->mRelativePvsContribution;
+	  //$$ 20.7. changed to sqr to pronouce higher contribution so that they do not get smoothed!!
+	  //sumRelContributions += weight*ray->mRelativePvsContribution;
+
+	  sumRelContributions += sqr(weight*ray->mRelativePvsContribution);
 	  
 	  //sumWeights += weight;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1197)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1199)
@@ -1,2 +1,6 @@
+#ifdef UNICODE
+#undef UNICODE
+#endif
+
 #include <windows.h>
 #include <stdio.h>
@@ -34,31 +38,31 @@
 int LoadMyDll()
 {
-	importFunction LoadRenderWidget;
-	
-    // Load DLL file
-	HINSTANCE hinstLib = LoadLibrary("QtGlRenderer.dll");
-	
-	if (hinstLib == NULL) 
-	{
-		cout << "ERROR: unable to load DLL\n";
-		return 1;
-	}
-
-	// Get function pointer
-	LoadRenderWidget = (importFunction)GetProcAddress(hinstLib, "LoadRenderWidget");
-	
-	if (LoadRenderWidget == NULL) 
-	{
-		cout << "ERROR: unable to find DLL function\n";
-		return 1;
-	}
-
-	// load the render window
-    rendererWidget = LoadRenderWidget(preprocessor);
-
-	// Unload DLL file
-    //FreeLibrary(hinstLib);
-
-	return 0;
+  importFunction LoadRenderWidget;
+
+  // Load DLL file
+  HINSTANCE hinstLib = LoadLibrary("QtGlRenderer.dll");
+  
+  if (hinstLib == NULL) 
+	{
+	  cout << "ERROR: unable to load DLL\n";
+	  return 1;
+	}
+  
+  // Get function pointer
+  LoadRenderWidget = (importFunction)GetProcAddress(hinstLib, "LoadRenderWidget");
+  
+  if (LoadRenderWidget == NULL) 
+	{
+	  cout << "ERROR: unable to find DLL function\n";
+	  return 1;
+	}
+  
+  // load the render window
+  rendererWidget = LoadRenderWidget(preprocessor);
+  
+  // Unload DLL file
+  //FreeLibrary(hinstLib);
+  
+  return 0;
 }
 
@@ -103,5 +107,5 @@
 
 	Debug.open("debug.log");
-
+  
 	Environment::GetSingleton()->Parse(argc, argv, USE_EXE_PATH);
 	MeshKdTree::ParseEnvironment();
@@ -112,7 +116,7 @@
 
 	if (preprocessorType == "vss")
-	{
+	  {
 		preprocessor = new VssPreprocessor();
-	}
+	  }
 	else
 	{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.h	(revision 860)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingPreprocessor.h	(revision 1199)
@@ -38,48 +38,16 @@
   HoleSamplingPass();
   
-  /** Casts a bundle of sample rays into the scene.
-		@param sampleContributions the number of sample contributions
-		@param contributingSamples the number of samples contributing
-	*/
-	void
-	CastRays(const RayContainer &rays);
-	
-	/** Casts a single ray into the scene.
-		@returns sample contributions
-	*/
-	int CastRay(Ray &ray);
-	
-	/** Verify if the exact visibility for this object was established.
-	*/
-	void
-	VerifyVisibility(Intersectable *object);
-
-	/** Sample the shiluette of objects in order to find visibility changes
-		along the visibility skeleton.
-	*/
-	int 
-	CastEdgeSamples(
-					Intersectable *object,
-					const Vector3 &point,
-					MeshInstance *mi,
-					const int samples
-					);
-
-	/** Processes the view cells during a pass.
-		@param newRays the newly cast rays
-		@param sampleContributions returns the accumulated contribution of the samples
-		@param contributingSamples returns the samples contributing to pvs
-	*/
-	
-	void ProcessViewCells(const RayContainer &newRays,
-						  const ObjectContainer &objects,
-						  int &sampleContributions,
-						  int &contributingSamples);
-
-	/**
-		Returns random node as target for the current sample ray.
-	*/
-	KdNode *GetNodeToSample(Intersectable *object);
-
+  
+  Intersectable *
+  CastRay(
+		  const Vector3 &origin,
+		  const Vector3 &direction
+		  );
+  
+  /** Verify if the exact visibility for this object was established.
+   */
+  void
+  VerifyVisibility(Intersectable *object);
+  
 
 protected:
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro	(revision 1112)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro	(revision 1199)
@@ -13,6 +13,6 @@
 
 
-win32:LIBPATH += GL $$NONGTP/Xerces/xerces/lib $$NONGTP/Devil/lib \
-  "d:/Programs/NVIDIA Corporation/Cg/lib" $$NONGTP/glut
+win32:LIBPATH += GL $$NONGTP/Xerces/xerces/lib $$NONGTP/Devil/lib $$NONGTP/Xe/xerces/lib \
+  "d:/Programs/NVIDIA Corporation/Cg/lib" $$NONGTP/glut $$NONGTP/Boost/lib
   
 unix:LIBPATH += ../support/src/xerces-c-src_2_7_0/lib ../support/devil/lib /usr/lib/qt3/lib64
@@ -30,5 +30,5 @@
 QT += opengl
 
-win32:LIBS += xerces-c_2.lib devil.lib ilu.lib ilut.lib cg.lib cgGL.lib glew32.lib 
+win32:LIBS += xerces-c_2.lib devil.lib ilu.lib ilut.lib cg.lib cgGL.lib glew32.lib boost_thread-vc71-mt-1_33_1.lib
 
 unix:LIBS += -lxerces-c -lIL -lILU -lILUT
@@ -53,5 +53,5 @@
 GzBinFileInputStream.cpp  GzFileInputSource.cpp \
 OcclusionQuery.cpp VspOspTree.cpp LogManager.cpp \
-SamplingStrategy.cpp
+SamplingStrategy.cpp KdIntersectable.cpp BoostPreprocessorThread.cpp
 
 #VspKdTree.cpp ResourceManager.cpp 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1076)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1199)
@@ -164,4 +164,5 @@
 					Ray &ray,
 					float &nearestT,
+					Vector3 &nearestNormal,
 					int &nearestFace,
 					Intersectable *instance
@@ -170,12 +171,14 @@
   float t;
   int hit = 0;
-  if (RayFaceIntersection(faceIndex, ray, t, nearestT) == Ray::INTERSECTION) {
+  Vector3 normal;
+  if (RayFaceIntersection(faceIndex, ray, t, normal, nearestT) == Ray::INTERSECTION) {
     switch (ray.GetType()) {
     case Ray::GLOBAL_RAY:
-      ray.intersections.push_back(Ray::Intersection(t, instance, faceIndex));
+      ray.intersections.push_back(Ray::Intersection(t, normal, instance, faceIndex));
       hit++;
       break;
     case Ray::LOCAL_RAY:
       nearestT = t;
+	  nearestNormal = normal;
       nearestFace = faceIndex;
       hit++;
@@ -183,5 +186,5 @@
     case Ray::LINE_SEGMENT:
       if (t <= 1.0f) {
-		ray.intersections.push_back(Ray::Intersection(t, instance, faceIndex));
+		ray.intersections.push_back(Ray::Intersection(t, normal, instance, faceIndex));
 		hit++;
       }
@@ -205,4 +208,5 @@
   int hits = 0;
   float nearestT = MAX_FLOAT;
+  Vector3 nearestNormal;
   int nearestFace = -1;
   
@@ -214,5 +218,5 @@
 		faceIndex < mFaces.size();
 		faceIndex++) {
-    hits += CastRayToFace(faceIndex, ray, nearestT, nearestFace, instance);
+    hits += CastRayToFace(faceIndex, ray, nearestT, nearestNormal, nearestFace, instance);
     if (mIsConvex && nearestFace != -1)
       break;
@@ -221,7 +225,7 @@
   if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
     if (ray.intersections.size())
-      ray.intersections[0] = Ray::Intersection(nearestT, instance, nearestFace);
+      ray.intersections[0] = Ray::Intersection(nearestT, nearestNormal, instance, nearestFace);
     else
-      ray.intersections.push_back(Ray::Intersection(nearestT, instance, nearestFace));
+      ray.intersections.push_back(Ray::Intersection(nearestT, nearestNormal, instance, nearestFace));
   }
   
@@ -240,6 +244,7 @@
   int hits = 0;
   float nearestT = MAX_FLOAT;
+  Vector3 nearestNormal;
   int nearestFace = -1;
-
+  
   if (ray.GetType() == Ray::LOCAL_RAY && ray.intersections.size())
     nearestT = ray.intersections[0].mT;
@@ -248,5 +253,5 @@
 		fi != faces.end();
 		fi++) {
-    hits += CastRayToFace(*fi, ray, nearestT, nearestFace, instance);
+    hits += CastRayToFace(*fi, ray, nearestT, nearestNormal, nearestFace, instance);
     if (mIsConvex && nearestFace != -1)
       break;
@@ -255,7 +260,7 @@
   if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
     if (ray.intersections.size())
-      ray.intersections[0] = Ray::Intersection(nearestT, instance, nearestFace);
+      ray.intersections[0] = Ray::Intersection(nearestT, nearestNormal,instance, nearestFace);
     else
-      ray.intersections.push_back(Ray::Intersection(nearestT, instance, nearestFace));
+      ray.intersections.push_back(Ray::Intersection(nearestT, nearestNormal,instance, nearestFace));
   }
   
@@ -316,4 +321,5 @@
 						  const Ray &ray,
 						  float &t,
+						  Vector3 &normal,
 						  const float nearestT
 						  )
@@ -342,4 +348,6 @@
   }
   
+  normal = plane.mNormal;
+
   t = (-plane.mD - DotProd(plane.mNormal, ray.GetLoc())) / dot;
 
