Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1379)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1381)
@@ -732,89 +732,31 @@
 }
 
-#if 0 // matt: implemented interface samplestrategy
-bool
-Preprocessor::GenerateRays(
-						   const int number,
-						   const int sampleType,
-						   SimpleRayContainer &rays
-						   )
-{
-  Vector3 origin, direction; 
-  int startSize = (int)rays.size();
-  for (int i=0; (int)rays.size() - startSize  < number; i ++) {
-	// now get the direction
-	switch (sampleType) {
-	case OBJECT_BASED_DISTRIBUTION: {
-	  mViewCellsManager->GetViewPoint(origin);
-	  Vector3 point;
-	  Vector3 normal;
-	  int i = RandomValue(0, mObjects.size() - 1);
-	  Intersectable *object = mObjects[i];
-	  object->GetRandomSurfacePoint(point, normal);
-	  direction = point - origin;
-	}
-	  break;
-	case OBJECT_DIRECTION_BASED_DISTRIBUTION: {
-	  int i = RandomValue(0, mObjects.size() - 1);
-	  Intersectable *object = mObjects[i];
-	  Vector3 normal;
-	  object->GetRandomSurfacePoint(origin, normal);
-	  direction = UniformRandomVector(normal);
-	  origin += 0.1f*direction;
-	}
-	  break;
-	case DIRECTION_BASED_DISTRIBUTION:
-	  mViewCellsManager->GetViewPoint(origin);
-	  direction = UniformRandomVector();
-	  break;
-	case DIRECTION_BOX_BASED_DISTRIBUTION: {
-	  mViewCellsManager->GetViewPoint(origin);
-	  float alpha = RandomValue(0.0f, 2*M_PI);
-	  float beta = RandomValue(-M_PI/2, M_PI/2);
-	  direction = VssRay::GetDirection(alpha, beta);
-	  break;
-	}
-	case SPATIAL_BOX_BASED_DISTRIBUTION:
-	  mViewCellsManager->GetViewPoint(origin);
-	  direction = mKdTree->GetBox().GetRandomPoint() - origin;
-	  break;
-	default:
-	  // unsuported distribution type
-	  return false;
-	}
-	// $$ jb the pdf is yet not correct for all sampling methods!
-	float pdf = 1.0f;
-	float c = Magnitude(direction);
-	if (c > Limits::Small) {
-	  direction*=1.0f/c;
-	  rays.AddRay(SimpleRay(origin, direction, pdf));
-	}
-  }
-  return true;
-}
-#endif
 bool Preprocessor::GenerateRays(const int number,
 								const int sampleType,
 								SimpleRayContainer &rays)
 {
-	Vector3 origin, direction; 
-	
 	const int startSize = (int)rays.size();
 	SamplingStrategy *strategy = GenerateSamplingStrategy(sampleType);
 
 	if (!strategy)
+	{
 		return false;
+	}
 
 	for (int i=0; (int)rays.size() - startSize < number; ++ i) 
 	{
 		SimpleRay newRay;
-		bool success = strategy->GenerateSample(newRay);
-
-		if (success)
+
+		if (strategy->GenerateSample(newRay))
+		{
+#if 1
 			rays.AddRay(newRay);
+#else
+			GenerateRayBundle(rays, newRay, 16, 0);
+#endif
+		}	
 	}
 
 	delete strategy;
-
     return true;
 }
@@ -1417,7 +1359,40 @@
 		return CastInternalRay(viewPoint, direction, probability, vssRays, box);
 	}
-#if DEBUG_RAYCAST
+#if DEBUG_RAYCAST	
   Debug<<"CRF "<<flush;
 #endif	
+}
+
+
+bool Preprocessor::GenerateRayBundle(SimpleRayContainer &rayBundle,									
+									 const SimpleRay &mainRay,
+									 const int number,
+									 const int pertubType) const
+{
+	rayBundle.push_back(mainRay);
+
+	const float pertubOrigin = 10.0f;
+	const float pertubDir = 0.0f;
+
+	for (int i = 0; i < number - 1; ++ i)
+	{
+		Vector3 pertub;
+
+		pertub.x = RandomValue(0.0f, pertubDir);
+		pertub.y = RandomValue(0.0f, pertubDir);
+		pertub.z = RandomValue(0.0f, pertubDir);
+		const Vector3 newDir = mainRay.mDirection + pertub;
+		//const Vector3 newDir = mainRay.mDirection;
+
+		pertub.x = RandomValue(0.0f, pertubOrigin);
+		pertub.y = RandomValue(0.0f, pertubOrigin);
+		pertub.z = RandomValue(0.0f, pertubOrigin);
+		const Vector3 newOrigin = mainRay.mOrigin + pertub;
+		//const Vector3 newOrigin = mainRay.mOrigin;
+
+		rayBundle.push_back(SimpleRay(newOrigin, newDir, 0));
+	}
+
+	return true;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1379)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1381)
@@ -150,4 +150,10 @@
 			   );
   
+  bool GenerateRayBundle(
+	  SimpleRayContainer &rayBundle,
+	  const SimpleRay &mainRay,
+	  const int number,
+	  const int shuffleType) const;
+
   virtual void CastRays(SimpleRayContainer &rays,
 						VssRayContainer &vssRays);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1344)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1381)
@@ -324,6 +324,4 @@
 int ViewCellsManager::Construct(Preprocessor *preprocessor, VssRayContainer *outRays)
 {
-	mPreprocessor = preprocessor;
-
 	int numSamples = 0;
 
@@ -331,12 +329,18 @@
 	VssRayContainer initialSamples;
 
+	// store pointer to preprocessor for further use during construction
+	mPreprocessor = preprocessor;
+	
+	
+	///////////////////////////////////////////////////////
+	//-- Initial sampling for the construction of the view cell hierarchy. 
+	//-- We use uniform sampling / box based sampling.
+	
+	long startTime = GetTime();
+
 	cout << "view cell construction: casting " << mInitialSamples << " initial samples ... ";
-
-	long startTime = GetTime();
-
-	//-- construction rays => we use uniform samples for this
-
+	// cast initial samples
 	CastPassSamples(mInitialSamples, mSamplingType,	initialSamples);
-	
+
 	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
 
@@ -356,16 +360,18 @@
 		  << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
 
-	// take post processing time
-	startTime = GetTime();
-
-	//-- stats after construction
+
+	///////////////////////////////////////////
+	//-- Initial hierarchy construction finished
+	//-- We can do some stats and visualization
+	
 	ResetViewCells();
   	Debug << "\nView cells after initial sampling:\n" << mCurrentViewCellsStats << endl;
 
-	if (0) // export initial view cells
+
+	//-- optionally export initial view cells
+	if (0) 
 	{
 		const char filename[] = "view_cells.wrl";
 		Exporter *exporter = Exporter::GetExporter(filename);
-
 	
 		if (exporter)
@@ -385,11 +391,19 @@
 	}
 
-	//-- guided rays are used for further sampling
+
+	////////////////////////////////////////////////
+	//
+	//-- Cast some more sampling after initial construction.
+	//-- The additional rays can be used to gain
+	//-- some more information before the bottom-up merge
+	//-- note: guided rays could be used for this task
+
+	// time spent after initial construction
+	startTime = GetTime();
+
 	const int n = mConstructionSamples; //+initialSamples;
-
 	// should we use directional samples?
 	bool dirSamples = (mSamplingType == Preprocessor::DIRECTION_BASED_DISTRIBUTION);
 
-	//-- do some more sampling
 	while (numSamples < n)
 	{
@@ -412,5 +426,4 @@
 
 		cout << "finished" << endl;
-
 		cout << "computing sample contribution for " << (int)constructionSamples.size() << " samples ... ";
 
@@ -421,25 +434,16 @@
 		cout << "finished" << endl;
 
-
 		disposeRays(constructionSamples, outRays);
-
 		cout << "total samples: " << numSamples << endl;
 	}
 
-	//-- post processing
-	VssRayContainer postProcessSamples;
-
-	cout << "casting " << mPostProcessSamples << " post processing samples ... ";
-
-	// cast post processing samples rays  (storing the view cells if wanted)
-	CastPassSamples(mPostProcessSamples,
-					mSamplingType, 
-					postProcessSamples);
-
-	cout << "finished" << endl;
-
-	// stats before post processing (i.e., merge)
+	
+	////////////////////////////////////////////////
+	//-- get stats after the additional sampling step
+	//-- and before the bottom-up merge step
+
 	EvaluateViewCellsStats();
-	Debug << "\noriginal view cell partition before post process:\n" << mCurrentViewCellsStats << endl;
+	Debug << "\noriginal view cell partition before post process:\n" 
+		  << mCurrentViewCellsStats << endl;
 
 	mRenderer->RenderScene();
@@ -450,7 +454,22 @@
 
 
+
+	///////////////////////////////////////////////
+	//
+	//-- post processing of the initial construction
+	//-- We can bottom-up merge the view cells in this step
+
+
+	// we can additionally cast some post processing sample rays.
+	// These rays can be used to store the view cells with the rays
+	VssRayContainer postProcessSamples;
+	cout << "casting " << mPostProcessSamples << " post processing samples ... ";
+	
+	CastPassSamples(mPostProcessSamples, mSamplingType, postProcessSamples);
+
+	cout << "finished" << endl;
 	cout << "starting post processing and visualization" << endl;
 
-	// store view cells for postprocessing
+	// store view cells for post processing?
 	const bool storeViewCells = true;
 
@@ -458,6 +477,5 @@
 		ComputeSampleContributions(postProcessSamples, true, storeViewCells);
 
-	//-- post processing (e.g.,merging) of the view cells
-	if (1) PostProcess(preprocessor->mObjects, postProcessSamples);
+	PostProcess(preprocessor->mObjects, postProcessSamples);
 
 	cout << "time needed for post processing (merge) step: "
@@ -470,6 +488,8 @@
 
 	
-	//return 1;
-	// evaluation of the paritition, i.e., a number of new samples are cast
+	/////////////////////////////////////////////////////////////////////
+	//-- Evaluation of the resulting view cell partition. 
+	//-- We cast a number of new samples and measure the render cost
+
 	if (mEvaluateViewCells)
 	{
@@ -477,10 +497,13 @@
 	}
 
+	
+	///////////////////////////////////
+	//-- Finally, we do some visualization
+
 	if (mShowVisualization)
 	{
-		//-- visualization
 		VssRayContainer visualizationSamples;
 
-		//-- construction rays => we use uniform samples for this
+		//-- visualization rays, e.g., to show some samples in the scene
 		CastPassSamples(mVisualizationSamples,
 					    Preprocessor::DIRECTION_BASED_DISTRIBUTION, 
