Index: /GTP/trunk/Lib/Vis/Preprocessing/src/run_test2
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/run_test2	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/run_test2	(revision 1785)
@@ -2,5 +2,5 @@
 
 #COMMAND="./release/preprocessor.exe -preprocessor_quit_on_finish+"
-COMMAND="../scripts/preprocessor.sh -preprocessor_quit_on_finish+ -preprocessor_use_gl_renderer-"
+COMMAND="../scripts/preprocessor.sh -preprocessor_quit_on_finish+ -preprocessor_use_gl_renderer- -preprocessor_evaluate_filter+"
 
 #SCENE="../data/vienna/vienna-buildings.x3d;../data/vienna/vienna-roofs.x3d;../data/vienna/vienna-roads.x3d"
@@ -29,5 +29,5 @@
 VIEWCELLS=../data/vienna/vienna_cropped-gradient-viewcells.xml.gz
 
-PREFIX=../work/plots/osp-rss-1e5
+PREFIX=../work/plots/osp-rss-1e5-n
 
 #SCENE=../data/atlanta/atlanta2.x3d
@@ -35,7 +35,7 @@
 
 
-$COMMAND -preprocessor=sampling -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
--view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-r-reference.log \
--preprocessor_histogram_file=$PREFIX-r-reference.hlog
+# $COMMAND -preprocessor=sampling -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
+# -view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-r-reference.log \
+# -preprocessor_histogram_file=$PREFIX-r-reference.hlog
 
 
@@ -47,16 +47,20 @@
 
 
-#######
-#######
-$COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
--rss_use_importance- -rss_object_based_sampling- -rss_directional_sampling+ \
--view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-r-directional-based-b3.log \
--preprocessor_histogram_file=$PREFIX-r-directional-based-b3.hlog
+# #######
+# #######
+# $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
+# -rss_use_importance- -rss_object_based_sampling- -rss_directional_sampling+ \
+# -view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-r-directional-based-b3.log \
+# -preprocessor_histogram_file=$PREFIX-r-directional-based-b3.hlog
+
+# $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
+# -rss_use_importance- -rss_object_based_sampling- -rss_directional_sampling- \
+# -view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-r-spatial-based-bb3.log \
+# -preprocessor_histogram_file=$PREFIX-r-spatial-based-bb3.hlog
+
 
 $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
--rss_use_importance- -rss_object_based_sampling- -rss_directional_sampling- \
--view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-r-spatial-based-bb3.log \
--preprocessor_histogram_file=$PREFIX-r-spatial-based-bb3.hlog
+ -rss_use_importance+ -rss_use_rss_tree- -view_cells_filter_max_size=1 \
+ -preprocessor_stats=$PREFIX-i-mixed-b1.log \
+ -preprocessor_histogram_file=$PREFIX-i-mixed-b1.hlog
 
-
-
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/OcclusionQuery.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/OcclusionQuery.cpp	(revision 1145)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/OcclusionQuery.cpp	(revision 1785)
@@ -8,5 +8,5 @@
 namespace GtpVisibilityPreprocessor {
 
-bool OcclusionQuery::sUseArbQueries = true;
+bool OcclusionQuery::sUseArbQueries = false;
 
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1757)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1785)
@@ -35,8 +35,4 @@
 static CGprofile sCgFragmentProfile;
 
-GLuint frontDepthMap;
-GLuint backDepthMap;
-
-const int depthMapSize = 512;
 
 //static vector<OcclusionQuery *> sQueries;
@@ -60,148 +56,15 @@
 
 void
-QtGlRendererBuffer::EvalRenderCostSample(RenderCostSample &sample,
-										 const bool useOcclusionQueries,
-										 const int threshold
-										 )
-{
-	// choose a random view point
-	mViewCellsManager->GetViewPoint(mViewPoint);
-	sample.mPosition = mViewPoint;
-	//cout << "viewpoint: " << mViewPoint << endl;
-
-	// take a render cost sample by rendering a cube
-	Vector3 directions[6];
-
-	directions[0] = Vector3(1,0,0);
-	directions[1] = Vector3(0,1,0);
-	directions[2] = Vector3(0,0,1);
-	directions[3] = Vector3(-1,0,0);
-	directions[4] = Vector3(0,-1,0);
-	directions[5] = Vector3(0,0,-1);
-
-	sample.mVisibleObjects = 0;
-
-	// reset object counters
-	ObjectContainer::const_iterator it, it_end = mObjects.end();
-
-	for (it = mObjects.begin(); it != it_end; ++ it) 
-	{
-		(*it)->mCounter = 0;
-	}
-
-	++ mFrame;
-
-	//glCullFace(GL_FRONT);
-	glCullFace(GL_BACK);
-	glDisable(GL_CULL_FACE);
-	
-
-	// query all 6 directions for a full point sample
-	for (int i = 0; i < 6; ++ i) 
-	{
-		mViewDirection = directions[i];
-		SetupCamera();
-
-		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-		//glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);	glDepthMask(GL_TRUE);
-		glDepthFunc(GL_LESS);
-
-		mUseFalseColors = true;
-
-		// the actual scene rendering fills the depth (for occlusion queries)
-		// and the frame buffer (for item buffer)
-		RenderScene();
-
-
-		if (0) 
-		{
-			char filename[256];
-			sprintf(filename, "snap/frame-%04d-%d.png", mFrame, i);
-			QImage im = toImage();
-			im.save(filename, "PNG");
-		}
-         
-		// evaluate the sample
-		if (useOcclusionQueries) 
-		{
-			EvalQueryWithOcclusionQueries();
-		}
-		else 
-		{
-			EvalQueryWithItemBuffer();
-		}
-	}  
-
-	// now evaluate the statistics over that sample
-	// currently only the number of visible objects is taken into account
-	sample.Reset();
-
-	for (it = mObjects.begin(); it != it_end; ++ it) 
-	{
-		Intersectable *obj = *it;
-		if (obj->mCounter >= threshold) 
-		{
-			++ sample.mVisibleObjects;
-			sample.mVisiblePixels += obj->mCounter;
-		}
-	}
-
-	//cout << "RS=" << sample.mVisibleObjects << " ";
-}
-
-
-QtGlRendererBuffer::~QtGlRendererBuffer()
-{
-#if USE_CG
-  if (sCgFragmentProgram)
-		cgDestroyProgram(sCgFragmentProgram);
-	if (sCgContext)
-		cgDestroyContext(sCgContext);
-#endif
-}
-
-
-void
-QtGlRendererBuffer::SampleRenderCost(const int numSamples,
-									 vector<RenderCostSample> &samples,
-									 const bool useOcclusionQueries,
-									 const int threshold
-									 )
+QtGlRendererBuffer::MakeCurrent()
 {
   makeCurrent();
-
-  if (mPixelBuffer == NULL)
-	  mPixelBuffer = new unsigned int[GetWidth()*GetHeight()];
-  
-  // using 90 degree projection to capture 360 view with 6 samples
-  SetupProjection(GetHeight(), GetHeight(), 90.0f);
-
-  //samples.resize(numSamples);
-  halton.Reset();
-  
-  // the number of queries queried in batch mode
-  const int numQ = 500;
-
-  //const int numQ = (int)mObjects.size();
-  if (useOcclusionQueries)
-  {
-	  cout << "\ngenerating " << numQ << " queries ... ";
-	  OcclusionQuery::GenQueries(mOcclusionQueries, numQ);
-	  cout << "finished" << endl;
-  }
-
-  // sampling queries 
-  for (int i = 0; i < numSamples; ++ i)
-  {
-	  cout << ".";
-	  EvalRenderCostSample(samples[i], useOcclusionQueries, threshold);
-  }
-
+}
+
+void
+QtGlRendererBuffer::DoneCurrent()
+{
   doneCurrent();
-
-}
-  
-
+}
+  
 
 QtGlRendererBuffer::QtGlRendererBuffer(const int w,
@@ -210,17 +73,14 @@
 									   ViewCellsManager *viewcells,
 									   KdTree *tree):
-  QGLPixelBuffer(QSize(w, h)), GlRendererBuffer(sceneGraph, viewcells, tree) {
-  
-  Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", mPvsStatFrames);
-  mPvsErrorBuffer.resize(mPvsStatFrames);
-  ClearErrorBuffer();
-
-  mPixelBuffer = NULL;
-  
-  makeCurrent();
+  QGLPixelBuffer(QSize(w, h)),
+  //QGLWidget(NULL, w, h),
+  GlRendererBuffer(sceneGraph, viewcells, tree)
+{
+  MakeCurrent();
   InitGL();
-  doneCurrent();
-  
-}
+  DoneCurrent();
+}
+
+
 
 float
@@ -238,5 +98,5 @@
   //static int query = -1;
   //if (query == -1)
-//	  glGenOcclusionQueriesNV(1, (unsigned int *)&query);
+  //	  glGenOcclusionQueriesNV(1, (unsigned int *)&query);
 
   OcclusionQuery query;
@@ -247,4 +107,5 @@
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	glEnable( GL_CULL_FACE );
+	glCullFace(GL_BACK);
 	
 	RenderScene();
@@ -254,5 +115,4 @@
 	glDisable( GL_CULL_FACE );
 
-	
 	query.BeginQuery();
 	
@@ -271,29 +131,37 @@
 	if (pixelCount > 0)
 	  return -1.0f; // backfacing polygon found -> not a valid viewspace sample
+
   } else
 	glDisable( GL_CULL_FACE );
 	
 
-  ViewCell *viewcell = NULL;
-  
-  PrVs prvs;
-  
-  mViewCellsManager->SetMaxFilterSize(0);
-  mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth());
-  viewcell = prvs.mViewCell;
-  
-  //  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
-  pvsSize = 0;
+  //  ViewCell *viewcell = NULL;
+  
+  //  PrVs prvs;
+  
+  //  mViewCellsManager->SetMaxFilterSize(0);
+  //  mViewCellsManager->GetPrVS(mViewPoint, prvs, mViewCellsManager->GetFilterWidth());
+  //  viewcell = prvs.mViewCell;
+  
+  ObjectPvs pvs;
+  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
+	
   if (viewcell) {
+	mViewCellsManager->ApplyFilter2(viewcell,
+									false,
+									1.0f,
+									pvs);
+	
+	pvsSize = 0;
 	SetupCamera();
 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
 	glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
 	
-	// Render PVS
-	ObjectPvsIterator it = viewcell->GetPvs().GetIterator();
-
-	pvsSize = viewcell->GetPvs().GetSize();
-	
+	  
+	// 	// Render PVS
+	ObjectPvsIterator it = pvs.GetIterator();
+	
+	pvsSize = pvs.GetSize();
+	Intersectable::NewMail();
 	for (; it.HasMoreEntries(); ) {
 	  ObjectPvsEntry entry = it.Next();
@@ -301,18 +169,20 @@
 	  RenderIntersectable(object);
 	}
-
+	
 	//	glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
 	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+	
+	
 	mUseFalseColors = true;
-
+	
 	query.BeginQuery();
-
+	
 	SetupCamera();
-
+	
 	RenderScene();
 	
 	query.EndQuery();
 	
-
+	
 	unsigned int pixelCount;
 	// reenable other state
@@ -321,567 +191,66 @@
 	
 	pErrorPixels = ((float)pixelCount)/(GetWidth()*GetHeight());
-	if (mSnapErrorFrames && pErrorPixels > 0.01) {
-	  
-	  char filename[256];
-	  sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels);
-	  QImage im = toImage();
-	  string str = mSnapPrefix + filename;
-	  QString qstr(str.c_str());
-
-	  im.save(qstr, "PNG");
-	  if (1) { //0 && mFrame == 1543) {
-		int x,y;
-		int lastIndex = -1;
-		for (y=0; y < im.height(); y++)
-		  for (x=0; x < im.width(); x++) {
-			QRgb p = im.pixel(x,y);
-			int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16);
-			if (qGreen(p) != 255 && index!=0) {
-			  if (index != lastIndex) {
-				//				Debug<<"ei="<<index<<" ";
-				lastIndex = index;
-			  }
+  } else
+	pErrorPixels = 0.0f;
+  
+  if (mSnapErrorFrames && pErrorPixels > 0.001f) {
+	
+	char filename[256];
+	sprintf(filename, "error-frame-%04d-%0.5f.png", mFrame, pErrorPixels);
+	QImage im = toImage();
+	string str = mSnapPrefix + filename;
+	QString qstr(str.c_str());
+	
+	im.save(qstr, "PNG");
+	if (1) { //0 && mFrame == 1543) {
+	  int x,y;
+	  int lastIndex = -1;
+	  for (y=0; y < im.height(); y++)
+		for (x=0; x < im.width(); x++) {
+		  QRgb p = im.pixel(x,y);
+		  int index = qRed(p) + (qGreen(p)<<8) + (qBlue(p)<<16);
+		  if (qGreen(p) != 255 && index!=0) {
+			if (index != lastIndex) {
+			  //				Debug<<"ei="<<index<<" ";
+			  lastIndex = index;
 			}
 		  }
-	  }
-
-
-	  mUseFalseColors = false;
-	  glPushAttrib(GL_CURRENT_BIT);
-	  glColor3f(0,1,0);
-	  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-	  SetupCamera();
-	  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	  
-	  // Render PVS
-	  ObjectPvsIterator it = viewcell->GetPvs().GetIterator();
-	  for (; it.HasMoreEntries(); ) {
-		ObjectPvsEntry entry = it.Next();
-		Intersectable *object = entry.mObject;
-		RenderIntersectable(object);
-	  }
-
-	  im = toImage();
-	  sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels);
-	  str = mSnapPrefix + filename;
-	  qstr = str.c_str();
-	  im.save(qstr, "PNG");
-	  glPopAttrib();
-	}
+		}
+	}
+	
+	
+	mUseFalseColors = false;
+	glPushAttrib(GL_CURRENT_BIT);
+	glColor3f(0,1,0);
 	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-  }
-
-  if (viewcell && mViewCellsManager->GetMaxFilterSize() > 0)
-	mViewCellsManager->DeleteLocalMergeTree(viewcell);
+	SetupCamera();
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	
+	// Render PVS
+	Intersectable::NewMail();
+
+	ObjectPvsIterator it = pvs.GetIterator();
+	for (; it.HasMoreEntries(); ) {
+	  ObjectPvsEntry entry = it.Next();
+	  Intersectable *object = entry.mObject;
+	  RenderIntersectable(object);
+	}
+	
+	im = toImage();
+	sprintf(filename, "error-frame-%04d-%0.5f-pvs.png", mFrame, pErrorPixels);
+	str = mSnapPrefix + filename;
+	qstr = str.c_str();
+	im.save(qstr, "PNG");
+	glPopAttrib();
+  }
+  
+  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   
   return pErrorPixels;
 }
 
-
-void
-QtGlRendererBuffer::ClearErrorBuffer()
-{
-  for (int i=0; i < mPvsStatFrames; i++) {
-	mPvsErrorBuffer[i].mError = 1.0f;
-  }
-}
-
-
-void
-QtGlRendererBuffer::EvalPvsStat()
-{
-  mPvsStat.Reset();
-  halton.Reset();
-
-  makeCurrent();
-
-  SetupProjection(GetWidth(), GetHeight());
-  
-  for (int i=0; i < mPvsStatFrames; i++) {
-	float err;
-	// set frame id for saving the error buffer
-	mFrame = i;
-	RandomViewPoint();
-
-	// atlanta problematic frames: 325 525 691 1543
-#if 0
-	if (mFrame != 325 &&
-		mFrame != 525 &&
-		mFrame != 691 &&
-		mFrame != 1543)
-	  mPvsErrorBuffer[i] = -1;
-	else {
-	  Debug<<"frame ="<<mFrame<<" vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
-	}
-#endif
-	if (mPvsErrorBuffer[i].mError > 0.0f) {
-	  int pvsSize;
-
-
-	  float error = GetPixelError(pvsSize);
-	  mPvsErrorBuffer[i].mError = error;
-	  mPvsErrorBuffer[i].mPvsSize = pvsSize;
-
-	  emit UpdatePvsErrorItem(i,
-							  mPvsErrorBuffer[i]);
-	  
-	  cout<<"("<<i<<","<<mPvsErrorBuffer[i].mError<<")";
-	  //	  swapBuffers();
-	}
-	
-	err = mPvsErrorBuffer[i].mError;
-	
-	if (err >= 0.0f) {
-	  if (err > mPvsStat.maxError)
-		mPvsStat.maxError = err;
-	  mPvsStat.sumError += err;
-	  mPvsStat.sumPvsSize += mPvsErrorBuffer[i].mPvsSize;
-	  
-	  if (err == 0.0f)
-		mPvsStat.errorFreeFrames++;
-	  mPvsStat.frames++;
-	}
-  }
-
-  glFinish();
-  doneCurrent();
-
-  cout<<endl<<flush;
-  //  mRenderingFinished.wakeAll();
-}
-
-
-
-
-
-
-
-void QtGlRendererBuffer::SampleBeamContributions(Intersectable *sourceObject,
-											   Beam &beam,
-											   const int desiredSamples,
-											   BeamSampleStatistics &stat)
-{
-	// TODO: should be moved out of here (not to be done every time)
-	// only back faces are interesting for the depth pass
-	glShadeModel(GL_FLAT);
-	glDisable(GL_LIGHTING);
-
-	// needed to kill the fragments for the front buffer
-	glEnable(GL_ALPHA_TEST);
-	glAlphaFunc(GL_GREATER, 0);
-
-	// assumes that the beam is constructed and contains kd-tree nodes
-	// and viewcells which it intersects
-  
-  
-	// Get the number of viewpoints to be sampled
-	// Now it is a sqrt but in general a wiser decision could be made.
-	// The less viewpoints the better for rendering performance, since less passes
-	// over the beam is needed.
-	// The viewpoints could actually be generated outside of the bounding box which
-	// would distribute the 'efective viewpoints' of the object surface and thus
-	// with a few viewpoints better sample the viewpoint space....
-
-	//TODO: comment in
-	//int viewPointSamples = sqrt((float)desiredSamples);
-	int viewPointSamples = max(desiredSamples / (GetWidth() * GetHeight()), 1);
-	
-	// the number of direction samples per pass is given by the number of viewpoints
-	int directionalSamples = desiredSamples / viewPointSamples;
-	
-	Debug << "directional samples: " << directionalSamples << endl;
-	for (int i = 0; i < viewPointSamples; ++ i) 
-	{
-		Vector3 viewPoint = beam.mBox.GetRandomPoint();
-		
-		// perhaps the viewpoint should be shifted back a little bit so that it always lies
-		// inside the source object
-		// 'ideally' the viewpoints would be distributed on the soureObject surface, but this
-        // would require more complicated sampling (perhaps hierarchical rejection sampling of
-		// the object surface is an option here - only the mesh faces which are inside the box
-		// are considered as candidates) 
-		
-		SampleViewpointContributions(sourceObject,
-									 viewPoint,
-									 beam,
-									 directionalSamples,
-									 stat);
-	}
-
-
-	// note:
-	// this routine would be called only if the number of desired samples is sufficiently
-	// large - for other rss tree cells the cpu based sampling is perhaps more efficient
-	// distributing the work between cpu and gpu would also allow us to place more sophisticated
-	// sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
-	// in order that thios scheme is working well the gpu render buffer should run in a separate
-	// thread than the cpu sampler, which would not be such a big problem....
-
-	// disable alpha test again
-	glDisable(GL_ALPHA_TEST);
-}
-
-
-
-void QtGlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject,
-													const Vector3 viewPoint,
-													Beam &beam,
-													const int samples,
-                                                    BeamSampleStatistics &stat)
-{
-    // 1. setup the view port to match the desired samples
-	glViewport(0, 0, samples, samples);
-
-	// 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
-	SetupProjectionForViewPoint(viewPoint, beam, sourceObject);
-
-
-	// 3. reset z-buffer to 0 and render the source object for the beam
-	//    with glCullFace(Enabled) and glFrontFace(GL_CW)
-	//    save result to the front depth map
-	//    the front depth map holds ray origins
-
-
-	// front depth buffer must be initialised to 0
-	float clearDepth;
-	
-	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
-	glClearDepth(0.0f);
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
-
-	//glFrontFace(GL_CW);
-	glEnable(GL_CULL_FACE);
-	glCullFace(GL_FRONT);
-	glColorMask(0, 0, 0, 0);
-	
-
-	// stencil is increased where the source object is located
-	glEnable(GL_STENCIL_TEST);	
-	glStencilFunc(GL_ALWAYS, 0x1, 0x1);
-	glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-
-
-#if 0
-	static int glSourceObjList = -1;	 
-	if (glSourceObjList != -1) 
-	{
-		glSourceObjList = glGenLists(1);
-		glNewList(glSourceObjList, GL_COMPILE);
-
-		RenderIntersectable(sourceObject);
-	
-		glEndList();
-	}
-	glCallList(glSourceObjList);
-
-#else
-	RenderIntersectable(sourceObject);
-
-#endif	
-
-	 // copy contents of the front depth buffer into depth texture
-	glBindTexture(GL_TEXTURE_2D, frontDepthMap);	
-	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
-
-
-	// reset clear function
-	glClearDepth(clearDepth);
-
-	
-	
-	// 4. set up the termination depth buffer (= standard depth buffer)
-	//    only rays which have non-zero entry in the origin buffer are valid since
-	//    they realy start on the object surface (this is tagged by setting a
-	//    stencil buffer bit at step 3).
-	
-	glStencilFunc(GL_EQUAL, 0x1, 0x1);
-	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glDepthMask(1);
-
-	glEnable(GL_DEPTH_TEST);
-		
-	glEnable(GL_CULL_FACE);
-	glCullFace(GL_BACK);
-
-	// setup front depth buffer
-	glEnable(GL_TEXTURE_2D);
-	
-#if USE_CG
-	// bind pixel shader implementing the front depth buffer functionality
-	cgGLBindProgram(sCgFragmentProgram);
-	cgGLEnableProfile(sCgFragmentProfile);
-#endif
-
-	// 5. render all objects inside the beam 
-	//    we can use id based false color to read them back for gaining the pvs
-
-	glColorMask(1, 1, 1, 1);
-
-	
-	// if objects not stored in beam => extract objects
-	if (beam.mFlags & !Beam::STORE_OBJECTS)
-	{
-		vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
-
-		Intersectable::NewMail();
-		for (it = beam.mKdNodes.begin(); it != it_end; ++ it)
-		{
-			mKdTree->CollectObjects(*it, beam.mObjects);
-		}
-	}
-
-
-	//    (objects can be compiled to a gl list now so that subsequent rendering for
-	//    this beam is fast - the same hold for step 3)
-	//    Afterwards we have two depth buffers defining the ray origin and termination
-	
-
-#if 0
-	static int glObjList = -1; 
-	if (glObjList != -1) 
-	{
-		glObjList = glGenLists(1);
-		glNewList(glObjList, GL_COMPILE);
-	
-		ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
-		for (it = beam.mObjects.begin(); it != it_end; ++ it)
-		{
-			// render all objects except the source object
-			if (*it != sourceObject)
-				RenderIntersectable(*it);
-		}
-		
-		glEndList();
-	}
-
-	glCallList(glObjList);
-#else
-	ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
-	for (it = beam.mObjects.begin(); it != it_end; ++ it)
-	{	
-		// render all objects except the source object
-		if (*it != sourceObject)
-			RenderIntersectable(*it);
-	}
-#endif
-	
-   
-
-	// 6. Use occlusion queries for all viewcell meshes associated with the beam ->
-	//     a fragment passes if the corresponding stencil fragment is set and its depth is
-	//     between origin and termination buffer
-
-	// create new queries if necessary
-	OcclusionQuery::GenQueries(mOcclusionQueries, (int)beam.mViewCells.size());
-
-	// check whether any backfacing polygon would pass the depth test?
-	// matt: should check both back /front facing because of dual depth buffer
-	// and danger of cutting the near plane with front facing polys.
-	
-	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-	glDepthMask(GL_FALSE);
-	glDisable(GL_CULL_FACE);
-
-  
-	ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
-
-	int queryIdx = 0;
-
-	for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
-	{
-		mOcclusionQueries[queryIdx ++]->BeginQuery();
-
-		RenderIntersectable(*vit);
-		
-		mOcclusionQueries[queryIdx]->EndQuery();
-
-		++ queryIdx;
-	}
-
-
-
-	// at this point, if possible, go and do some other computation
-
-
-	
-	// 7. The number of visible pixels is the number of sample rays which see the source
-	//    object from the corresponding viewcell -> remember these values for later update
-	//   of the viewcell pvs - or update immediately?
-
-	queryIdx = 0;
-
-	for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
-	{
-		// fetch queries
-		unsigned int pixelCount = mOcclusionQueries[queryIdx ++]->GetQueryResult();
-
-		if (pixelCount)
-			Debug << "view cell " << (*vit)->GetId() << " visible pixels: " << pixelCount << endl;
-	}
-	
-
-	// 8. Copmpute rendering statistics
-	// In general it is not neccessary to remember to extract all the rays cast. I hope it
-	// would be sufficient to gain only the intergral statistics about the new contributions
-	// and so the rss tree would actually store no new rays (only the initial ones)
-	// the subdivision of the tree would only be driven by the statistics (the glrender could
-	// evaluate the contribution entropy for example)
-	// However might be an option to extract/store only those the rays which made a contribution
-	// (new viewcell has been discovered) or relative contribution greater than a threshold ... 
-
-	ObjectContainer pvsObj;
-	stat.pvsSize = ComputePvs(beam.mObjects, pvsObj);
-	
-	// to gain ray source and termination
-	// copy contents of ray termination buffer into depth texture
-	// and compare with ray source buffer
-#if 0
-	VssRayContainer rays;
-
-	glBindTexture(GL_TEXTURE_2D, backDepthMap);	
-	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
-
-	ComputeRays(Intersectable *sourceObj, rays);
-
-#endif
-
-
-
-	//-- cleanup
-
-
-	// reset gl state
-	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-	glDepthMask(GL_TRUE);
-	glEnable(GL_CULL_FACE);
-	glDisable(GL_STENCIL_TEST);
-#if USE_CG
-	cgGLDisableProfile(sCgFragmentProfile);
-#endif
-	glDisable(GL_TEXTURE_2D);
-
-	// remove objects from beam
-	if (beam.mFlags & !Beam::STORE_OBJECTS)
-		beam.mObjects.clear();
-}
-
-
-void QtGlRendererBuffer::SetupProjectionForViewPoint(const Vector3 &viewPoint, 
-												   const Beam &beam, 
-												   Intersectable *sourceObject)
-{
-	float left, right, bottom, top, znear, zfar;
-
-	beam.ComputePerspectiveFrustum(left, right, bottom, top, znear, zfar,
-								   mSceneGraph->GetBox());
-
-	//Debug << left << " " << right << " " << bottom << " " << top << " " << znear << " " << zfar << endl;
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	glFrustum(left, right, bottom, top, znear, zfar);
-	//glFrustum(-1, 1, -1, 1, 1, 20000);
-
-    const Vector3 center = viewPoint + beam.GetMainDirection() * (zfar - znear) * 0.3f;
-	const Vector3 up = 
-		Normalize(CrossProd(beam.mPlanes[0].mNormal, beam.mPlanes[4].mNormal));
-
-#ifdef GTP_DEBUG
-	Debug << "view point: " << viewPoint << endl;
-	Debug << "eye: " << center << endl;
-	Debug << "up: " << up << endl;
-#endif
-
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
-	gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z, 
-			  center.x, center.y, center.z,			  
-			  up.x, up.y, up.z);
-}		
-
-  
-void QtGlRendererBuffer::InitGL()
-{
- makeCurrent(); 
- GlRenderer::InitGL();
-
-#if 1
-	// initialise dual depth buffer textures
-	glGenTextures(1, &frontDepthMap);
-	glBindTexture(GL_TEXTURE_2D, frontDepthMap);
-	
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize, 
-				 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
-	glGenTextures(1, &backDepthMap);
-	glBindTexture(GL_TEXTURE_2D, backDepthMap);
-	
-	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize, 
-		depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
-#if USE_CG
-	// cg initialization
-	cgSetErrorCallback(handleCgError);
-	sCgContext = cgCreateContext();
-	
-	if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))
-		sCgFragmentProfile = CG_PROFILE_ARBFP1;
-	else 
-	{
-	  // try FP30
-	  if (cgGLIsProfileSupported(CG_PROFILE_FP30))
-            sCgFragmentProfile = CG_PROFILE_FP30;
-	  else 
-	  {
-		  Debug << "Neither arbfp1 or fp30 fragment profiles supported on this system" << endl;
-		  exit(1);
-	  }
-  }
-
- sCgFragmentProgram = cgCreateProgramFromFile(sCgContext,
-											   CG_SOURCE, "../src/dual_depth.cg",
-											   sCgFragmentProfile,
-											   NULL, 
-											   NULL);
-
-  if (!cgIsProgramCompiled(sCgFragmentProgram))
-	  cgCompileProgram(sCgFragmentProgram);
-
-  cgGLLoadProgram(sCgFragmentProgram);
-  cgGLBindProgram(sCgFragmentProgram);
-
-  Debug << "---- PROGRAM BEGIN ----\n" <<
-	  cgGetProgramString(sCgFragmentProgram, CG_COMPILED_PROGRAM) << "---- PROGRAM END ----\n";
-
-#endif
-
-#endif
-  doneCurrent();
-}
-
-
-void QtGlRendererBuffer::ComputeRays(Intersectable *sourceObj, VssRayContainer &rays)
-{
-	for (int i = 0; i < depthMapSize * depthMapSize; ++ i)
-	{
-		//todo glGetTexImage()
-	}
-}
-
-
-
-int QtGlRendererBuffer::ComputePvs(ObjectContainer &objects, 
-								   ObjectContainer &pvs) const
+int
+QtGlRendererBuffer::ComputePvs(ObjectContainer &objects, 
+							   ObjectContainer &pvs) const
 {
 	int pvsSize = 0;
@@ -922,4 +291,11 @@
 	return pvsSize;
 }
+
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+
+
 
 
@@ -1702,4 +1078,5 @@
   if (mViewCellsManager) 
   	mViewCellsManager->SetMaxFilterSize(number);
+  mPvsCache.Reset();
   updateGL();
 }
@@ -1709,4 +1086,5 @@
 {
   mSpatialFilterSize = 1e-3*number;
+  mPvsCache.Reset();
   updateGL();
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1784)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1785)
@@ -1228,4 +1228,5 @@
 				 "true");
 
+  
    RegisterOption("VssPreprocessor.enlargeViewSpace",
 				 optBool,
@@ -1725,4 +1726,9 @@
 					"true");
 
+	RegisterOption("Preprocessor.evaluateFilter",
+				   optBool,
+				   "preprocessor_evaluate_filter",
+				   "false");
+
 	RegisterOption("Preprocessor.delayVisibilityComputation",
 				   optBool,
@@ -1891,4 +1897,9 @@
 					optBool,
 					"rss_use_importance",
+					"true");
+
+	RegisterOption("RssPreprocessor.useRssTree",
+					optBool,
+					"rss_use_rss_tree",
 					"true");
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1779)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1785)
@@ -138,5 +138,5 @@
 	// renderer will be constructed when the scene graph and viewcell manager will be known
 	renderer = NULL;
-  
+	
 	Environment::GetSingleton()->GetBoolValue("Preprocessor.delayVisibilityComputation",
 											  mDelayVisibilityComputation);
@@ -705,14 +705,5 @@
 	mViewCellsManager->SetRenderer(mRenderSimulator);
 
-	if (mUseGlRenderer || mUseGlDebugger)
-	{
-		// NOTE: render texture should be power of 2 and square
-		// renderer must be initialised
-		// $$matt
-		//		renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
-		//		renderer->makeCurrent();
-
-	}
-
+	
 	mViewCellsManager->SetPreprocessor(this);
 	return true;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1757)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1785)
@@ -48,81 +48,25 @@
 		KdTree *tree);
 
-	~QtGlRendererBuffer();
-
-	/** Evaluates render cost of a point sample.
-	@param sample the render cost sample to be evaluated
-	@param useOcclusionQueries if occlusion queries should be used or item buffer
-	@param threshold number of pixels / samples from where an object is considered visible.
-	*/
-	void EvalRenderCostSample(RenderCostSample &sample,
-		const bool useOcclusionQueries,
-		const int threshold);
-
-	/** Evaluates render cost of a number of point samples. The point samples
-	are distributed uniformly over the defined view space.
-
-	@param numSamples the number of point samples taken
-	@param samples stores the taken point samples in a container
-	@param useOcclusionQueries if occlusion queries should be used or item buffer
-	@param threshold number of pixels / samples from where an object is considered visible.
-	*/
-	void SampleRenderCost(const int numSamples, 
-		vector<RenderCostSample> &samples,
-		const bool useOcclusionQueries,
-		const int threshold = 0);
-
-
-  void
-  EvalPvsStat();
-
-  void
-  ClearErrorBuffer();
-  
+  ~QtGlRendererBuffer() {}
+
+  virtual void MakeCurrent();
+  virtual void DoneCurrent();
 
   virtual int GetWidth() const { return width(); }
   virtual int GetHeight() const { return height(); }
 
-
- 
-  void SampleBeamContributions(
-							   Intersectable *sourceObject,
-							   Beam &beam,
-							   const int samples,
-							   BeamSampleStatistics &stat
-							   );
-
-  void
-  SampleViewpointContributions(
-							   Intersectable *sourceObject,
-							   const Vector3 viewPoint,
-							   Beam &beam,
-							   const int desiredSamples,
-							   BeamSampleStatistics &stat
-							   );
-
-  void InitGL();
-
-  /** Computes rays from information gained with hw sampling-
-  */
-  void ComputeRays(Intersectable *sourceObj, VssRayContainer &rays);
-
-  int ComputePvs() const;
-
+  int ComputePvs() const { return 0; }
+  
   float
   GetPixelError(int &pvsSize);
-
+  
   int ComputePvs(ObjectContainer &objects, ObjectContainer &pvs) const;
      
-   
-private:
-  	
-	void SetupProjectionForViewPoint(const Vector3 &viewPoint, 
-									 const Beam &beam, 
-									 Intersectable *sourceObject);
-
-
+  
+  
+  
 public:
   signals:
-	void UpdatePvsErrorItem(int i, GlRendererBuffer::PvsErrorEntry &);
+  void UpdatePvsErrorItem(int i, GlRendererBuffer::PvsErrorEntry &);
 };
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1785)
@@ -15,5 +15,4 @@
 
 
-#define USE_RSS_TREE 1
 
 namespace GtpVisibilityPreprocessor {
@@ -38,4 +37,7 @@
   Environment::GetSingleton()->GetIntValue("RssPreprocessor.vssSamplesPerPass", mRssSamplesPerPass);
   Environment::GetSingleton()->GetBoolValue("RssPreprocessor.useImportanceSampling", mUseImportanceSampling);
+
+  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.useRssTree",
+											mUseRssTree);
 
   Environment::GetSingleton()->GetBoolValue("RssPreprocessor.Export.pvs", mExportPvs);
@@ -48,5 +50,7 @@
 
   Environment::GetSingleton()->GetBoolValue("RssPreprocessor.loadInitialSamples", mLoadInitialSamples);
+
   Environment::GetSingleton()->GetBoolValue("RssPreprocessor.storeInitialSamples", mStoreInitialSamples);
+
   Environment::GetSingleton()->GetBoolValue("RssPreprocessor.updateSubdivision", mUpdateSubdivision);
   
@@ -353,6 +357,7 @@
 	//	renderer->mRenderingFinished.wait(&mutex);
 	//	mutex.unlock();
-
+	
 	renderer->EvalPvsStat();
+
 	mStats <<
 	  "#AvgPvsRenderError\n" <<renderer->mPvsStat.GetAvgError()<<endl<<
@@ -364,5 +369,5 @@
 
 void
-NormalizeRatios(vector<SamplingStrategy *> distributions)
+NormalizeRatios(vector<SamplingStrategy *> &distributions)
 {
   int i;
@@ -397,38 +402,28 @@
 	distributions[i]->mRatio/=sumRatios;
   
-
+  
+  cout<<"New ratios: ";
+  for (i=0 ; i < distributions.size(); i++)
+	cout<<distributions[i]->mRatio<<" ";
+  cout<<endl;
 }
 
 void
-NormalizeRatios(float ratios[4])
-{
-  int i;
-  float sumRatios;
-  sumRatios = ratios[0] + ratios[1] + ratios[2] + ratios[3];
-  if (sumRatios == 0.0f) {
-	ratios[0] = ratios[1] = ratios[2] = 1.0f;
-	sumRatios = 4.0f;
-  }
-  
-  for (i=0 ; i < 4; i++)
-	ratios[i]/=sumRatios;
-
-#define MIN_RATIO 0.1f
-
-#if USE_RSS_TREE
-  i = 0;
-#else
-  i = 1;
+EvaluateRatios(vector<SamplingStrategy *> &distributions)
+{
+  // now evaluate the ratios for the next pass
+#define TIME_WEIGHT 0.5f
+  for (int i=0; i < distributions.size(); i++) {
+	distributions[i]->mRatio = distributions[i]->mContribution/
+	  (TIME_WEIGHT*distributions[i]->mTime +
+	   (1 - TIME_WEIGHT)*distributions[i]->mRays);
+
+#if 1
+	distributions[i]->mRatio = sqr(distributions[i]->mRatio);
 #endif
-  
-  for (; i < 4; i++)
-	if (ratios[i] < MIN_RATIO)
-	  ratios[i] = MIN_RATIO;
-
-  sumRatios = ratios[0] + ratios[1] + ratios[2] + ratios[3];
-  for (i=0 ; i < 4; i++)
-	ratios[i]/=sumRatios;
-  
-}
+  }
+}
+
+
 
 bool
@@ -443,4 +438,5 @@
   Randomize(0);
   
+  // use ray buffer to export ray animation
   const bool useRayBuffer = false;
   
@@ -468,8 +464,13 @@
   int rssSamples = 0;
 
-  mDistributions.push_back(new RssBasedDistribution(*this));
-  mDistributions.push_back(new SpatialBoxBasedDistribution(*this));
-  mDistributions.push_back(new DirectionBasedDistribution(*this));
-  mDistributions.push_back(new ReverseObjectBasedDistribution(*this));
+  if (mUseRssTree)
+	mDistributions.push_back(new RssBasedDistribution(*this));
+
+  //  mDistributions.push_back(new SpatialBoxBasedDistribution(*this));
+  //  mDistributions.push_back(new DirectionBasedDistribution(*this));
+  mDistributions.push_back(new ObjectDirectionBasedDistribution(*this));
+  //  mDistributions.push_back(new ReverseObjectBasedDistribution(*this));
+  mDistributions.push_back(new ObjectBasedDistribution(*this));
+  mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(*this));
   
   if (mLoadInitialSamples) {
@@ -483,10 +484,16 @@
 	
 	if (mUseImportanceSampling) {
-	  GenerateRays(mInitialSamples/3, SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION, rays);
-	  //	  GenerateRays(mInitialSamples/3, SamplingStrategy::OBJECT_BASED_DISTRIBUTION, rays);
-	  GenerateRays(mInitialSamples/3, SamplingStrategy::DIRECTION_BASED_DISTRIBUTION, rays);
-	  GenerateRays(mInitialSamples/3, SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION, rays);
-	  //	GenerateRays(mInitialSamples/4, OBJECT_DIRECTION_BASED_DISTRIBUTION, rays);
-	  
+	  int count = 0;
+	  int i;
+
+	  // Generate initial samples
+	  for (i=0; i < mDistributions.size(); i++)
+		if (mDistributions[i]->mType != SamplingStrategy::RSS_BASED_DISTRIBUTION)
+		  count++;
+	  
+	  for (i=0; i < mDistributions.size(); i++)
+		if (mDistributions[i]->mType != SamplingStrategy::RSS_BASED_DISTRIBUTION)
+		  GenerateRays(mInitialSamples/count,
+					   mDistributions[i]->mType, rays);
 
 	} else {
@@ -584,19 +591,19 @@
   if (mUseImportanceSampling) {
 
-#if USE_RSS_TREE	
-	mRssTree->Construct(mObjects, mVssRays);
-#endif
-	
-	mRssTree->stat.Print(mStats);
-	cout<<"RssTree root PVS size = "<<mRssTree->GetRootPvsSize()<<endl;
-	
-	if (mExportRssTree) {
-	  ExportRssTree("rss-tree-100.x3d", mRssTree, Vector3(1,0,0));
-	  ExportRssTree("rss-tree-001.x3d", mRssTree, Vector3(0,0,1));
-	  ExportRssTree("rss-tree-101.x3d", mRssTree, Vector3(1,0,1));
-	  ExportRssTree("rss-tree-101m.x3d", mRssTree, Vector3(-1,0,-1));
-	  ExportRssTreeLeaves(mRssTree, 10);
-	}
-	
+	if (mUseRssTree) {
+	  mRssTree->Construct(mObjects, mVssRays);
+	
+	  mRssTree->stat.Print(mStats);
+	  cout<<"RssTree root PVS size = "<<mRssTree->GetRootPvsSize()<<endl;
+	  
+	  if (mExportRssTree) {
+		ExportRssTree("rss-tree-100.x3d", mRssTree, Vector3(1,0,0));
+		ExportRssTree("rss-tree-001.x3d", mRssTree, Vector3(0,0,1));
+		ExportRssTree("rss-tree-101.x3d", mRssTree, Vector3(1,0,1));
+		ExportRssTree("rss-tree-101m.x3d", mRssTree, Vector3(-1,0,-1));
+		ExportRssTreeLeaves(mRssTree, 10);
+	  }
+	}
+
 	if (mExportPvs) {
 	  ExportPvs("rss-pvs-initial.x3d", mRssTree);
@@ -621,129 +628,38 @@
 	if (mUseImportanceSampling) {
 
-#if USE_RSS_TREE	
-	  static float ratios[] = {0.9f,0.05f,0.05f,0.05f};
-#else
-	  static float ratios[] = {0.0f,0.05f,0.05f,0.05f};
-#endif
-	  NormalizeRatios(ratios);
-	  	  
-	  cout<<"New ratios: "<<ratios[0]<<" "<<ratios[1]<<" "<<ratios[2]<<" "<<ratios[3]<<endl;
-
-	  //float ratios[] = {1.0f,0.0f,0.0f};
-	  
-	  int nrays[4];
-	  float contributions[4];
-	  float times[4];
+	  NormalizeRatios(mDistributions);
 	  
 	  long t1;
 
-	  t1 = GetTime();
-	  
-	  GenerateRays(int(mRssSamplesPerPass*ratios[0]),
-				   SamplingStrategy::RSS_BASED_DISTRIBUTION,
-				   rays);
-	  
-	  rays.NormalizePdf((float)rays.size());
-	  
-	  CastRays(rays, tmpVssRays, true);
-	  castRays += (int)rays.size();
-#if ADD_RAYS_IN_PLACE 
-	  contributions[0] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
-#else
-	  contributions[0] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
-#endif
-	  times[0] = TimeDiff(t1, GetTime());
-	  nrays[0] = (int)rays.size();
-	  
-	  mStats<<"#RssRelContrib"<<endl<<contributions[0]/nrays[0]<<endl;
-	  
-	  vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
-	  rays.clear();
-	  tmpVssRays.clear();
-	  if (ratios[1]!=0.0f) {
+	  for (int i=0; i < mDistributions.size(); i++) {
 		t1 = GetTime();
-		GenerateRays(int(mRssSamplesPerPass*ratios[1]), SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION, rays);
-		CastRays(rays, tmpVssRays, true);
-		castRays += (int)rays.size();
-#if ADD_RAYS_IN_PLACE 
-		contributions[1] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
-#else
-		contributions[1] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
-#endif
-	  times[1] = TimeDiff(t1, GetTime());
-	  nrays[1] = (int)rays.size();
-
-	  mStats<<"#SpatialRelContrib"<<endl<<contributions[1]/nrays[1]<<endl;
-		
-		vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
-		
 		rays.clear();
 		tmpVssRays.clear();
+		if (mDistributions[i]->mRatio != 0) {
+		  GenerateRays(int(mRssSamplesPerPass*mDistributions[i]->mRatio),
+					   mDistributions[i]->mType,
+					   rays);
+		  
+		  rays.NormalizePdf((float)rays.size());
+		  
+		  CastRays(rays, tmpVssRays, true);
+		  castRays += (int)rays.size();
+		  
+#if ADD_RAYS_IN_PLACE 
+		  mDistributions[i]->mContribution =
+			mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
+#else
+		  mDistributions[i]->mContribution =
+			mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
+#endif
+		}
+
+		mDistributions[i]->mTime = TimeDiff(t1, GetTime());
+		mDistributions[i]->mRays = (int)rays.size();
+		//		mStats<<"#RssRelContrib"<<endl<<contributions[0]/nrays[0]<<endl;
+		vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
 	  }
-	  
-	  
-	  if (ratios[2]!=0.0f) {
-		t1 = GetTime();
-		GenerateRays(int(mRssSamplesPerPass*ratios[2]), SamplingStrategy::DIRECTION_BASED_DISTRIBUTION, rays);
-		CastRays(rays, tmpVssRays, true);
-		castRays += (int)rays.size();
-#if ADD_RAYS_IN_PLACE 
-		contributions[2] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
-#else
-		contributions[2] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
-#endif
-		times[2] = TimeDiff(t1, GetTime());
-		nrays[2] = (int)rays.size();
-		
-		mStats<<"#DirectionalRelContrib"<<endl<<contributions[2]/nrays[2]<<endl;
-		
-		vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
-		
-		rays.clear();
-		tmpVssRays.clear();
-	  }
-	  
-	  if (ratios[3]!=0.0f) {
-		t1 = GetTime();
-		GenerateRays(int(mRssSamplesPerPass*ratios[3]),
-					 SamplingStrategy::REVERSE_OBJECT_BASED_DISTRIBUTION, rays);
-		CastRays(rays, tmpVssRays, true);
-		castRays += (int)rays.size();
-#if ADD_RAYS_IN_PLACE 
-		contributions[3] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, true, false);
-#else
-		contributions[3] = mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
-#endif
-		times[3] = TimeDiff(t1, GetTime());
-		nrays[3] = (int)rays.size();
-		
-		mStats<<"#DirectionalRelContrib"<<endl<<contributions[3]/nrays[3]<<endl;
-		
-		vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
-		
-		rays.clear();
-		tmpVssRays.clear();
-	  }
-
-	  
-	  // now evaluate the ratios for the next pass
-#define TIME_WEIGHT 0.5f
-
-#if 1
-	  ratios[0] = sqr(contributions[0]/(TIME_WEIGHT*times[0] + (1 - TIME_WEIGHT)*nrays[0]));
-	  ratios[1] = sqr(contributions[1]/(TIME_WEIGHT*times[1] + (1 - TIME_WEIGHT)*nrays[1]));
-	  ratios[2] = sqr(contributions[2]/(TIME_WEIGHT*times[2] + (1 - TIME_WEIGHT)*nrays[2]));
-	  ratios[3] = sqr(contributions[3]/(TIME_WEIGHT*times[3] + (1 - TIME_WEIGHT)*nrays[3]));
-#else
-	  ratios[0] = contributions[0]/(TIME_WEIGHT*times[0] + (1 - TIME_WEIGHT)*nrays[0]);
-	  ratios[1] = contributions[1]/(TIME_WEIGHT*times[1] + (1 - TIME_WEIGHT)*nrays[1]);
-	  ratios[2] = contributions[2]/(TIME_WEIGHT*times[2] + (1 - TIME_WEIGHT)*nrays[2]);
-	  ratios[3] = contributions[3]/(TIME_WEIGHT*times[3] + (1 - TIME_WEIGHT)*nrays[3]);
-	  
-#endif	  
-
-#if !USE_RSS_TREE
-	  ratios[0] = 0;
-#endif
+
+	  EvaluateRatios(mDistributions);
 	  
 	  // add contributions of all rays at once...
@@ -803,22 +719,23 @@
 	}
 
-	if (0 && mPass > 0) {
-		char buf[100];
+
+	if (renderer && mPass > 0) {
+	  char buf[100];
 	  if (mUseImportanceSampling)
-	  {
-		sprintf(buf, "snap/i-%02d-", mPass);
-
-		renderer->SetSnapPrefix(buf);
-	  }
+		{
+		  sprintf(buf, "snap/i-%02d-", mPass);
+		  
+		  renderer->SetSnapPrefix(buf);
+		}
 	  else
-	  {
-		sprintf(buf, "snap/r-%02d-", mPass);
-
-		renderer->SetSnapPrefix(buf);
-	  }
-
+		{
+		  sprintf(buf, "snap/r-%02d-", mPass);
+		  
+		  renderer->SetSnapPrefix(buf);
+		}
+	  
 	  renderer->SetSnapErrorFrames(true);
 	}
-
+	
 	ComputeRenderError();
 	
@@ -845,5 +762,4 @@
 	  sprintf(filename, "rss-crays-%04d.x3d", rssPass);
 	  ExportRays(filename, contributingRays, mExportNumRays);
-	  
 	}
 
@@ -853,6 +769,6 @@
 	// do not add those rays which have too low or no contribution....
 
-#if USE_RSS_TREE	
-	if (mUseImportanceSampling) {
+	
+	if (mUseRssTree && mUseImportanceSampling) {
 	  Debug<<"Adding rays...\n"<<flush;
 	  mRssTree->AddRays(vssRays);
@@ -869,5 +785,4 @@
 	  }
 	}
-#endif
 	
 	if (mExportPvs) {
@@ -878,8 +793,8 @@
 	
 	
-	if (!mUseImportanceSampling)
+	if (!mUseImportanceSampling || !mUseRssTree)
 	  CLEAR_CONTAINER(vssRays);
 	// otherwise the rays get deleted by the rss tree update according to RssTree.maxRays ....
-
+	
 	if (totalSamples >= mRssSamples + mInitialSamples)
 	  break;
@@ -889,25 +804,22 @@
 	mPass++;
 	mRssTree->SetPass(mPass);
-
-	
   }
   
   if (mUseViewcells) {
 
-	if(0)
-	  {
-		VssRayContainer selectedRays;
-		int desired = mViewCellsManager->GetVisualizationSamples();
-		
-		mVssRays.SelectRays(desired, selectedRays);
-		
-		mViewCellsManager->Visualize(mObjects, selectedRays);
+	if(0) {
+	  VssRayContainer selectedRays;
+	  int desired = mViewCellsManager->GetVisualizationSamples();
+	  
+	  mVssRays.SelectRays(desired, selectedRays);
+	  
+	  mViewCellsManager->Visualize(mObjects, selectedRays);
 	  }
 	
 	// view cells after sampling
 	mViewCellsManager->PrintStatistics(Debug);
-
+	
 	EvalViewCellHistogram();
-
+	
 	//-- render simulation after merge
 	cout << "\nevaluating bsp view cells render time after sampling ... ";
@@ -920,5 +832,4 @@
 	cout << ss << endl;
 	Debug << ss << endl;
-	
   }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1785)
@@ -7,5 +7,5 @@
 
 #filename ../data/Arena/arena-low-lods.obj
-# filename ../data/Arena/arena-high-lods.obj
+ filename ../data/Arena/arena-high-lods.obj
 # filename ../data/City4M/City4M.obj
 # filename ../data/CityModel/CityModel.obj
@@ -55,4 +55,7 @@
 	quitOnFinish true
 	computeVisibility true
+
+	evaluateFilter false
+
 	applyVisibilityFilter false
 	applyVisibilitySpatialFilter false
@@ -89,5 +92,4 @@
 	initialSamples 3000000
 	vssSamples 50000000
-#	vssSamples 1000000
 	vssSamplesPerPass 5000000
 	useImportanceSampling true
@@ -107,4 +109,6 @@
 	loadInitialSamples false
 	storeInitialSamples false
+
+	useRssTree false
 }
 
@@ -158,7 +162,7 @@
 		minCost 1
 		maxDepth 30
-		maxCostRatio 0.95
+		maxCostRatio 0.98
 		ct_div_ci 0.5
-		maxNodes 200000
+		maxNodes 500000
 #500000	
 	}
@@ -271,5 +275,5 @@
 #	filename ../data/soda/soda5-viewcells.xml
 #	filename ../scripts/viewcells_atlanta.xml
-#	filename ../data/soda/soda-viewcells-5000.xml
+#	filename ../data/soda/soda-viewcells.xml.gz
 #	filename ../data/test1/test-viewcells.xml
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1785)
@@ -204,4 +204,6 @@
   ofstream mStats;
 
+  GlRendererBuffer *renderer;
+
 protected:
 
@@ -233,5 +235,4 @@
 	vector<FaceParentInfo> mFaceParents;
 
-	GlRendererBuffer *renderer;
 
 	/// if box around view space should be used
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1784)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1785)
@@ -118,12 +118,15 @@
 BvhLeaf::BvhLeaf(const AxisAlignedBox3 &bbox):
 BvhNode(bbox), 
-mSubdivisionCandidate(NULL)
-{
-	mActiveNode = this;
+mSubdivisionCandidate(NULL),
+mGlList(0)
+{
+  mActiveNode = this;
 }
 
 
 BvhLeaf::BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent):
-BvhNode(bbox, parent)
+  BvhNode(bbox, parent),
+  mGlList(0)
+  
 {
 	mActiveNode = this;
@@ -134,5 +137,7 @@
 				 BvhInterior *parent, 
 				 const int numObjects):
-BvhNode(bbox, parent)
+  BvhNode(bbox, parent),
+  mGlList(0)
+
 {
 	mObjects.reserve(numObjects);
@@ -295,5 +300,5 @@
 	Environment::GetSingleton()->GetIntValue("BvHierarchy.minRaysForVisibility", mMinRaysForVisibility);
 	Environment::GetSingleton()->GetIntValue("BvHierarchy.maxTests", mMaxTests);
-	Environment::GetSingleton()->GetBoolValue("BvHierarchy.Construction.useInitialSubdivision", mApplyInitialPartition);
+	//	Environment::GetSingleton()->GetBoolValue("BvHierarchy.Construction.useInitialSubdivision", mApplyInitialPartition);
 	
 	mInitialObjectsSize = 50;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h	(revision 1785)
@@ -27,4 +27,5 @@
   int mRssSamples;
   bool mUseImportanceSampling;
+  bool mUseRssTree;
 
   bool mExportPvs;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1784)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1785)
@@ -26,5 +26,4 @@
 
 
-#define ABS_CONTRIBUTION_WEIGHT 1.0f
 
 // warning: Should not count origin object for sampling 
@@ -33,5 +32,5 @@
 
 // $$JB HACK
-#define USE_KD_PVS 0
+#define USE_KD_PVS 1
 #define KD_PVS_AREA (1e-5f)
 
@@ -1826,10 +1825,13 @@
 		
 		stat.avgPvs += pvsCost;
-		
-		const bool evaluateFilter = true;
+
+		bool evaluateFilter;
+		Environment::GetSingleton()->GetBoolValue("Preprocessor.evaluateFilter", evaluateFilter);
+		
 		
 		if (evaluateFilter) {
 		  ObjectPvs filteredPvs = viewcell->GetPvs();
-		  PvsFilterStatistics fstat = ApplyFilter2(viewcell, false, 1.0f, filteredPvs);
+		  PvsFilterStatistics fstat = ApplyFilter2(viewcell, false,
+												   1.0f, filteredPvs);
 		  
 		  float filteredCost = filteredPvs.EvalPvsCost();
@@ -2032,4 +2034,8 @@
 	ViewCell::NewMail();
 
+	//	if (ray.mPdf!=1.0f)
+	//	  cout<<ray.mPdf<<" ";
+	
+	
 	// traverse the view space subdivision
 	CastLineSegment(origin, termination, viewcells);
@@ -5852,6 +5858,10 @@
 	//Ray hray(ray);
 
+	//	if (ray.mPdf!=1.0f)
+	//	  cout<<ray.mPdf<<" ";
+
 	float tmin = 0, tmax = 1.0;
 
+	
 	if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
 		return 0;
@@ -5867,7 +5877,7 @@
 	if (storeViewCells)
 	{	
-		// copy viewcells memory efficiently
-		ray.mViewCells.reserve(viewcells.size());
-		ray.mViewCells = viewcells;
+	  // copy viewcells memory efficiently
+	  ray.mViewCells.reserve(viewcells.size());
+	  ray.mViewCells = viewcells;
 	}
 
@@ -5877,43 +5887,42 @@
 	Intersectable *originObj = GetIntersectable(ray, false);
 	  
-	for (; it != viewcells.end(); ++ it) 
-	{
-		ViewCell *viewcell = *it;
-
-		if (viewcell->GetValid())
+	for (; it != viewcells.end(); ++ it) {
+	  ViewCell *viewcell = *it;
+	  
+	  if (viewcell->GetValid())
 		{	// if ray not outside of view space
-			float contribution;
-
-			if (terminationObj) 
+		  float contribution;
+		  
+		  if (terminationObj) 
 			{
-				// todo: maybe not correct for kd node pvs
-				if (viewcell->GetPvs().GetSampleContribution(
-						terminationObj, ray.mPdf, contribution))
+			  // todo: maybe not correct for kd node pvs
+			  if (viewcell->GetPvs().GetSampleContribution(
+														   terminationObj, ray.mPdf, contribution))
 				{
-					++ ray.mPvsContribution;
+				  ++ ray.mPvsContribution;
 				}
-
-				ray.mRelativePvsContribution += contribution;
+			  
+			  ray.mRelativePvsContribution += contribution;
 			}
 			
-			////////////////
-			//-- for directional sampling it is important to count 
-			//-- only contributions made in one direction!
-			//-- the other contributions of this sample will be counted for the opposite ray!
-
+		  ////////////////
+		  //-- for directional sampling it is important to count 
+		  //-- only contributions made in one direction!
+		  //-- the other contributions of this sample will be counted for the opposite ray!
+		  
 #if SAMPLE_ORIGIN_OBJECTS
-
-			if (originObj && 
-				viewcell->GetPvs().GetSampleContribution(originObj,
-														 ray.mPdf,
-														 contribution))
-			  {
-				++ ray.mPvsContribution;
-				ray.mRelativePvsContribution += contribution;
-			  }
+		  
+		  if (originObj && 
+			  viewcell->GetPvs().GetSampleContribution(originObj,
+													   ray.mPdf,
+													   contribution))
+			{
+			  ++ ray.mPvsContribution;
+			  ray.mRelativePvsContribution += contribution;
+			}
 #endif
 		}
 	}
-
+	
 	if (!addRays)
 	{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1758)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.cpp	(revision 1785)
@@ -25,4 +25,8 @@
 static bool nvQuerySupport = false;
 
+GLuint frontDepthMap;
+GLuint backDepthMap;
+
+const int depthMapSize = 512;
 
 static void InitExtensions() 
@@ -80,6 +84,6 @@
   mUseForcedColors = false;
   mRenderBoxes = false;
-  mUseGlLists = true;
-  //mUseGlLists = false;
+  //  mUseGlLists = true;
+  mUseGlLists = false;
 }
 
@@ -133,6 +137,6 @@
   case Intersectable::BVH_INTERSECTABLE: {
 
-	  BvhNode *node = dynamic_cast<BvhNode *>(object);
-
+	BvhNode *node = dynamic_cast<BvhNode *>(object);
+	
 	if (mRenderBoxes)
 	  RenderBox(node->GetBoundingBox());
@@ -143,5 +147,5 @@
   case Intersectable::KD_INTERSECTABLE: {
 	KdNode *node = (dynamic_cast<KdIntersectable *>(object))->GetItem();
-
+	
 	if (mRenderBoxes)
 	  RenderBox(mKdTree->GetBox(node));
@@ -293,4 +297,6 @@
   glLoadIdentity();
 
+  glFrontFace(GL_CCW);
+  glCullFace(GL_BACK);
   glEnable(GL_CULL_FACE);
   glShadeModel(GL_FLAT);
@@ -402,4 +408,5 @@
 GlRenderer::RenderScene()
 {
+  Intersectable::NewMail();
   static int glList = -1;
   if (mUseGlLists) {
@@ -459,7 +466,11 @@
 GlRenderer(sceneGraph, viewcells, tree)  
 {
-	mPixelBuffer = NULL;
-
-	// implement width and height in subclasses
+  Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", mPvsStatFrames);
+  mPvsErrorBuffer.resize(mPvsStatFrames);
+  ClearErrorBuffer();
+  
+  mPixelBuffer = NULL;
+  
+  // implement width and height in subclasses
 }
 
@@ -647,6 +658,24 @@
   if (node->IsLeaf()) {
 	BvhLeaf *leaf = (BvhLeaf *) node;
-	for (int i=0; i < leaf->mObjects.size(); i++)
-	  RenderIntersectable(leaf->mObjects[i]);
+
+#if 0
+	if (leaf->mGlList == 0) {
+	  leaf->mGlList = glGenLists(1);
+	  if (leaf->mGlList != 0)
+		glNewList(leaf->mGlList, GL_COMPILE);
+	  
+	  for (int i=0; i < leaf->mObjects.size(); i++)
+		RenderIntersectable(leaf->mObjects[i]);
+	  
+	  if (leaf->mGlList != 0)
+		glEndList();
+	}
+	
+	if (leaf->mGlList != 0)
+	  glCallList(leaf->mGlList);
+#else
+	  for (int i=0; i < leaf->mObjects.size(); i++)
+		RenderIntersectable(leaf->mObjects[i]);
+#endif
   } else {
 	BvhInterior *in = (BvhInterior *)node;
@@ -675,3 +704,672 @@
 }
 
-}
+
+
+
+
+
+
+void
+GlRendererBuffer::EvalRenderCostSample(RenderCostSample &sample,
+									   const bool useOcclusionQueries,
+									   const int threshold
+									   )
+{
+  // choose a random view point
+  mViewCellsManager->GetViewPoint(mViewPoint);
+  sample.mPosition = mViewPoint;
+  //cout << "viewpoint: " << mViewPoint << endl;
+  
+  // take a render cost sample by rendering a cube
+  Vector3 directions[6];
+  
+  directions[0] = Vector3(1,0,0);
+  directions[1] = Vector3(0,1,0);
+  directions[2] = Vector3(0,0,1);
+  directions[3] = Vector3(-1,0,0);
+  directions[4] = Vector3(0,-1,0);
+  directions[5] = Vector3(0,0,-1);
+  
+  sample.mVisibleObjects = 0;
+  
+  // reset object counters
+  ObjectContainer::const_iterator it, it_end = mObjects.end();
+  
+  for (it = mObjects.begin(); it != it_end; ++ it) 
+	{
+	  (*it)->mCounter = 0;
+	}
+
+  ++ mFrame;
+  
+  //glCullFace(GL_FRONT);
+  glCullFace(GL_BACK);
+  glDisable(GL_CULL_FACE);
+  
+  
+	// query all 6 directions for a full point sample
+  for (int i = 0; i < 6; ++ i) 
+	{
+	  mViewDirection = directions[i];
+	  SetupCamera();
+	  
+	  glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+	  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	  //glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);	glDepthMask(GL_TRUE);
+	  glDepthFunc(GL_LESS);
+	  
+	  mUseFalseColors = true;
+	  
+	  // the actual scene rendering fills the depth (for occlusion queries)
+	  // and the frame buffer (for item buffer)
+	  RenderScene();
+	  
+	  
+	  if (0) 
+		{
+		  char filename[256];
+		  sprintf(filename, "snap/frame-%04d-%d.png", mFrame, i);
+		  //		  QImage im = toImage();
+		  //		  im.save(filename, "PNG");
+		}
+	  
+	  // evaluate the sample
+	  if (useOcclusionQueries) 
+		{
+		  EvalQueryWithOcclusionQueries();
+		}
+	  else 
+		{
+		  EvalQueryWithItemBuffer();
+		}
+	}  
+  
+  // now evaluate the statistics over that sample
+  // currently only the number of visible objects is taken into account
+  sample.Reset();
+  
+  for (it = mObjects.begin(); it != it_end; ++ it) 
+	{
+	  Intersectable *obj = *it;
+	  if (obj->mCounter >= threshold) 
+		{
+		  ++ sample.mVisibleObjects;
+		  sample.mVisiblePixels += obj->mCounter;
+		}
+	}
+  
+  //cout << "RS=" << sample.mVisibleObjects << " ";
+}
+
+
+GlRendererBuffer::~GlRendererBuffer()
+{
+#if USE_CG
+  if (sCgFragmentProgram)
+		cgDestroyProgram(sCgFragmentProgram);
+	if (sCgContext)
+		cgDestroyContext(sCgContext);
+#endif
+}
+
+
+void
+GlRendererBuffer::SampleRenderCost(const int numSamples,
+								   vector<RenderCostSample> &samples,
+								   const bool useOcclusionQueries,
+								   const int threshold
+								   )
+{
+  MakeCurrent();
+
+  if (mPixelBuffer == NULL)
+	  mPixelBuffer = new unsigned int[GetWidth()*GetHeight()];
+  
+  // using 90 degree projection to capture 360 view with 6 samples
+  SetupProjection(GetHeight(), GetHeight(), 90.0f);
+
+  //samples.resize(numSamples);
+  halton.Reset();
+  
+  // the number of queries queried in batch mode
+  const int numQ = 500;
+
+  //const int numQ = (int)mObjects.size();
+  if (useOcclusionQueries)
+  {
+	  cout << "\ngenerating " << numQ << " queries ... ";
+	  OcclusionQuery::GenQueries(mOcclusionQueries, numQ);
+	  cout << "finished" << endl;
+  }
+
+  // sampling queries 
+  for (int i = 0; i < numSamples; ++ i)
+  {
+	  cout << ".";
+	  EvalRenderCostSample(samples[i], useOcclusionQueries, threshold);
+  }
+
+  DoneCurrent();
+}
+  
+
+
+
+
+void
+GlRendererBuffer::ClearErrorBuffer()
+{
+  for (int i=0; i < mPvsStatFrames; i++) {
+	mPvsErrorBuffer[i].mError = 1.0f;
+  }
+}
+
+
+void
+GlRendererBuffer::EvalPvsStat()
+{
+  mPvsStat.Reset();
+  halton.Reset();
+
+  MakeCurrent();
+
+  SetupProjection(GetWidth(), GetHeight());
+
+  cout<<"mPvsStatFrames="<<mPvsStatFrames<<endl;
+  
+  for (int i=0; i < mPvsStatFrames; i++) {
+	float err;
+	// set frame id for saving the error buffer
+	mFrame = i;
+	RandomViewPoint();
+
+	// atlanta problematic frames: 325 525 691 1543
+#if 0
+	if (mFrame != 325 &&
+		mFrame != 525 &&
+		mFrame != 691 &&
+		mFrame != 1543)
+	  mPvsErrorBuffer[i] = -1;
+	else {
+	  Debug<<"frame ="<<mFrame<<" vp="<<mViewPoint<<" vd="<<mViewDirection<<endl;
+	}
+#endif
+	
+	if (mPvsErrorBuffer[i].mError > 0.0f) {
+	  int pvsSize;
+
+
+	  float error = GetPixelError(pvsSize);
+	  mPvsErrorBuffer[i].mError = error;
+	  mPvsErrorBuffer[i].mPvsSize = pvsSize;
+
+	  //	  emit UpdatePvsErrorItem(i,
+	  //							  mPvsErrorBuffer[i]);
+
+	  cout<<"("<<i<<","<<mPvsErrorBuffer[i].mError<<")";
+	  //	  swapBuffers();
+	}
+	
+	err = mPvsErrorBuffer[i].mError;
+	
+	if (err >= 0.0f) {
+	  if (err > mPvsStat.maxError)
+		mPvsStat.maxError = err;
+	  mPvsStat.sumError += err;
+	  mPvsStat.sumPvsSize += mPvsErrorBuffer[i].mPvsSize;
+	  
+	  if (err == 0.0f)
+		mPvsStat.errorFreeFrames++;
+	  mPvsStat.frames++;
+	}
+  }
+
+  glFinish();
+  DoneCurrent();
+
+  cout<<endl<<flush;
+  //  mRenderingFinished.wakeAll();
+}
+
+
+
+
+
+
+
+void GlRendererBuffer::SampleBeamContributions(Intersectable *sourceObject,
+											   Beam &beam,
+											   const int desiredSamples,
+											   BeamSampleStatistics &stat)
+{
+	// TODO: should be moved out of here (not to be done every time)
+	// only back faces are interesting for the depth pass
+	glShadeModel(GL_FLAT);
+	glDisable(GL_LIGHTING);
+
+	// needed to kill the fragments for the front buffer
+	glEnable(GL_ALPHA_TEST);
+	glAlphaFunc(GL_GREATER, 0);
+
+	// assumes that the beam is constructed and contains kd-tree nodes
+	// and viewcells which it intersects
+  
+  
+	// Get the number of viewpoints to be sampled
+	// Now it is a sqrt but in general a wiser decision could be made.
+	// The less viewpoints the better for rendering performance, since less passes
+	// over the beam is needed.
+	// The viewpoints could actually be generated outside of the bounding box which
+	// would distribute the 'efective viewpoints' of the object surface and thus
+	// with a few viewpoints better sample the viewpoint space....
+
+	//TODO: comment in
+	//int viewPointSamples = sqrt((float)desiredSamples);
+	int viewPointSamples = max(desiredSamples / (GetWidth() * GetHeight()), 1);
+	
+	// the number of direction samples per pass is given by the number of viewpoints
+	int directionalSamples = desiredSamples / viewPointSamples;
+	
+	Debug << "directional samples: " << directionalSamples << endl;
+	for (int i = 0; i < viewPointSamples; ++ i) 
+	{
+		Vector3 viewPoint = beam.mBox.GetRandomPoint();
+		
+		// perhaps the viewpoint should be shifted back a little bit so that it always lies
+		// inside the source object
+		// 'ideally' the viewpoints would be distributed on the soureObject surface, but this
+        // would require more complicated sampling (perhaps hierarchical rejection sampling of
+		// the object surface is an option here - only the mesh faces which are inside the box
+		// are considered as candidates) 
+		
+		SampleViewpointContributions(sourceObject,
+									 viewPoint,
+									 beam,
+									 directionalSamples,
+									 stat);
+	}
+
+
+	// note:
+	// this routine would be called only if the number of desired samples is sufficiently
+	// large - for other rss tree cells the cpu based sampling is perhaps more efficient
+	// distributing the work between cpu and gpu would also allow us to place more sophisticated
+	// sample distributions (silhouette ones) using the cpu and the jittered once on the GPU
+	// in order that thios scheme is working well the gpu render buffer should run in a separate
+	// thread than the cpu sampler, which would not be such a big problem....
+
+	// disable alpha test again
+	glDisable(GL_ALPHA_TEST);
+}
+
+
+
+void GlRendererBuffer::SampleViewpointContributions(Intersectable *sourceObject,
+													const Vector3 viewPoint,
+													Beam &beam,
+													const int samples,
+                                                    BeamSampleStatistics &stat)
+{
+    // 1. setup the view port to match the desired samples
+	glViewport(0, 0, samples, samples);
+
+	// 2. setup the projection matrix and view matrix to match the viewpoint + beam.mDirBox
+	SetupProjectionForViewPoint(viewPoint, beam, sourceObject);
+
+
+	// 3. reset z-buffer to 0 and render the source object for the beam
+	//    with glCullFace(Enabled) and glFrontFace(GL_CW)
+	//    save result to the front depth map
+	//    the front depth map holds ray origins
+
+
+	// front depth buffer must be initialised to 0
+	float clearDepth;
+	
+	glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth);
+	glClearDepth(0.0f);
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+
+	// glFrontFace(GL_CCW);
+	glEnable(GL_CULL_FACE);
+	glCullFace(GL_FRONT);
+	glColorMask(0, 0, 0, 0);
+	
+
+	// stencil is increased where the source object is located
+	glEnable(GL_STENCIL_TEST);	
+	glStencilFunc(GL_ALWAYS, 0x1, 0x1);
+	glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+
+
+#if 0
+	static int glSourceObjList = -1;	 
+	if (glSourceObjList != -1) 
+	{
+		glSourceObjList = glGenLists(1);
+		glNewList(glSourceObjList, GL_COMPILE);
+
+		RenderIntersectable(sourceObject);
+	
+		glEndList();
+	}
+	glCallList(glSourceObjList);
+
+#else
+	RenderIntersectable(sourceObject);
+
+#endif	
+
+	 // copy contents of the front depth buffer into depth texture
+	glBindTexture(GL_TEXTURE_2D, frontDepthMap);	
+	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
+
+
+	// reset clear function
+	glClearDepth(clearDepth);
+
+	
+	
+	// 4. set up the termination depth buffer (= standard depth buffer)
+	//    only rays which have non-zero entry in the origin buffer are valid since
+	//    they realy start on the object surface (this is tagged by setting a
+	//    stencil buffer bit at step 3).
+	
+	glStencilFunc(GL_EQUAL, 0x1, 0x1);
+	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	glDepthMask(1);
+
+	glEnable(GL_DEPTH_TEST);
+		
+	glEnable(GL_CULL_FACE);
+	glCullFace(GL_BACK);
+
+	// setup front depth buffer
+	glEnable(GL_TEXTURE_2D);
+	
+#if USE_CG
+	// bind pixel shader implementing the front depth buffer functionality
+	cgGLBindProgram(sCgFragmentProgram);
+	cgGLEnableProfile(sCgFragmentProfile);
+#endif
+
+	// 5. render all objects inside the beam 
+	//    we can use id based false color to read them back for gaining the pvs
+
+	glColorMask(1, 1, 1, 1);
+
+	
+	// if objects not stored in beam => extract objects
+	if (beam.mFlags & !Beam::STORE_OBJECTS)
+	{
+		vector<KdNode *>::const_iterator it, it_end = beam.mKdNodes.end();
+
+		Intersectable::NewMail();
+		for (it = beam.mKdNodes.begin(); it != it_end; ++ it)
+		{
+			mKdTree->CollectObjects(*it, beam.mObjects);
+		}
+	}
+
+
+	//    (objects can be compiled to a gl list now so that subsequent rendering for
+	//    this beam is fast - the same hold for step 3)
+	//    Afterwards we have two depth buffers defining the ray origin and termination
+	
+
+#if 0
+	static int glObjList = -1; 
+	if (glObjList != -1) 
+	{
+		glObjList = glGenLists(1);
+		glNewList(glObjList, GL_COMPILE);
+	
+		ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
+		for (it = beam.mObjects.begin(); it != it_end; ++ it)
+		{
+			// render all objects except the source object
+			if (*it != sourceObject)
+				RenderIntersectable(*it);
+		}
+		
+		glEndList();
+	}
+
+	glCallList(glObjList);
+#else
+	ObjectContainer::const_iterator it, it_end = beam.mObjects.end();
+	for (it = beam.mObjects.begin(); it != it_end; ++ it)
+	{	
+		// render all objects except the source object
+		if (*it != sourceObject)
+			RenderIntersectable(*it);
+	}
+#endif
+	
+   
+
+	// 6. Use occlusion queries for all viewcell meshes associated with the beam ->
+	//     a fragment passes if the corresponding stencil fragment is set and its depth is
+	//     between origin and termination buffer
+
+	// create new queries if necessary
+	OcclusionQuery::GenQueries(mOcclusionQueries, (int)beam.mViewCells.size());
+
+	// check whether any backfacing polygon would pass the depth test?
+	// matt: should check both back /front facing because of dual depth buffer
+	// and danger of cutting the near plane with front facing polys.
+	
+	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+	glDepthMask(GL_FALSE);
+	glDisable(GL_CULL_FACE);
+
+  
+	ViewCellContainer::const_iterator vit, vit_end = beam.mViewCells.end();
+
+	int queryIdx = 0;
+
+	for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		mOcclusionQueries[queryIdx ++]->BeginQuery();
+
+		RenderIntersectable(*vit);
+		
+		mOcclusionQueries[queryIdx]->EndQuery();
+
+		++ queryIdx;
+	}
+
+
+
+	// at this point, if possible, go and do some other computation
+
+
+	
+	// 7. The number of visible pixels is the number of sample rays which see the source
+	//    object from the corresponding viewcell -> remember these values for later update
+	//   of the viewcell pvs - or update immediately?
+
+	queryIdx = 0;
+
+	for (vit = beam.mViewCells.begin(); vit != vit_end; ++ vit)
+	{
+		// fetch queries
+		unsigned int pixelCount = mOcclusionQueries[queryIdx ++]->GetQueryResult();
+
+		if (pixelCount)
+			Debug << "view cell " << (*vit)->GetId() << " visible pixels: " << pixelCount << endl;
+	}
+	
+
+	// 8. Copmpute rendering statistics
+	// In general it is not neccessary to remember to extract all the rays cast. I hope it
+	// would be sufficient to gain only the intergral statistics about the new contributions
+	// and so the rss tree would actually store no new rays (only the initial ones)
+	// the subdivision of the tree would only be driven by the statistics (the glrender could
+	// evaluate the contribution entropy for example)
+	// However might be an option to extract/store only those the rays which made a contribution
+	// (new viewcell has been discovered) or relative contribution greater than a threshold ... 
+
+	ObjectContainer pvsObj;
+	stat.pvsSize = ComputePvs(beam.mObjects, pvsObj);
+	
+	// to gain ray source and termination
+	// copy contents of ray termination buffer into depth texture
+	// and compare with ray source buffer
+#if 0
+	VssRayContainer rays;
+
+	glBindTexture(GL_TEXTURE_2D, backDepthMap);	
+	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, depthMapSize, depthMapSize);
+
+	ComputeRays(Intersectable *sourceObj, rays);
+
+#endif
+
+
+
+	//-- cleanup
+
+
+	// reset gl state
+	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+	glDepthMask(GL_TRUE);
+	glEnable(GL_CULL_FACE);
+	glDisable(GL_STENCIL_TEST);
+#if USE_CG
+	cgGLDisableProfile(sCgFragmentProfile);
+#endif
+	glDisable(GL_TEXTURE_2D);
+
+	// remove objects from beam
+	if (beam.mFlags & !Beam::STORE_OBJECTS)
+		beam.mObjects.clear();
+}
+
+
+void GlRendererBuffer::SetupProjectionForViewPoint(const Vector3 &viewPoint, 
+												   const Beam &beam, 
+												   Intersectable *sourceObject)
+{
+	float left, right, bottom, top, znear, zfar;
+
+	beam.ComputePerspectiveFrustum(left, right, bottom, top, znear, zfar,
+								   mSceneGraph->GetBox());
+
+	//Debug << left << " " << right << " " << bottom << " " << top << " " << znear << " " << zfar << endl;
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	glFrustum(left, right, bottom, top, znear, zfar);
+	//glFrustum(-1, 1, -1, 1, 1, 20000);
+
+    const Vector3 center = viewPoint + beam.GetMainDirection() * (zfar - znear) * 0.3f;
+	const Vector3 up = 
+		Normalize(CrossProd(beam.mPlanes[0].mNormal, beam.mPlanes[4].mNormal));
+
+#ifdef GTP_DEBUG
+	Debug << "view point: " << viewPoint << endl;
+	Debug << "eye: " << center << endl;
+	Debug << "up: " << up << endl;
+#endif
+
+	glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+	gluLookAt(viewPoint.x, viewPoint.y, viewPoint.z, 
+			  center.x, center.y, center.z,			  
+			  up.x, up.y, up.z);
+}		
+
+  
+void GlRendererBuffer::InitGL()
+{
+  MakeCurrent(); 
+  GlRenderer::InitGL();
+
+#if 1
+	// initialise dual depth buffer textures
+	glGenTextures(1, &frontDepthMap);
+	glBindTexture(GL_TEXTURE_2D, frontDepthMap);
+	
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize, 
+				 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+	glGenTextures(1, &backDepthMap);
+	glBindTexture(GL_TEXTURE_2D, backDepthMap);
+	
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapSize, 
+				 depthMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+	
+#if USE_CG
+	// cg initialization
+	cgSetErrorCallback(handleCgError);
+	sCgContext = cgCreateContext();
+	
+	if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))
+		sCgFragmentProfile = CG_PROFILE_ARBFP1;
+	else 
+	{
+	  // try FP30
+	  if (cgGLIsProfileSupported(CG_PROFILE_FP30))
+            sCgFragmentProfile = CG_PROFILE_FP30;
+	  else 
+	  {
+		  Debug << "Neither arbfp1 or fp30 fragment profiles supported on this system" << endl;
+		  exit(1);
+	  }
+  }
+
+ sCgFragmentProgram = cgCreateProgramFromFile(sCgContext,
+											   CG_SOURCE, "../src/dual_depth.cg",
+											   sCgFragmentProfile,
+											   NULL, 
+											   NULL);
+
+  if (!cgIsProgramCompiled(sCgFragmentProgram))
+	  cgCompileProgram(sCgFragmentProgram);
+
+  cgGLLoadProgram(sCgFragmentProgram);
+  cgGLBindProgram(sCgFragmentProgram);
+
+  Debug << "---- PROGRAM BEGIN ----\n" <<
+	  cgGetProgramString(sCgFragmentProgram, CG_COMPILED_PROGRAM) << "---- PROGRAM END ----\n";
+
+#endif
+
+#endif
+  DoneCurrent();
+}
+
+
+void GlRendererBuffer::ComputeRays(Intersectable *sourceObj, VssRayContainer &rays)
+{
+	for (int i = 0; i < depthMapSize * depthMapSize; ++ i)
+	{
+		//todo glGetTexImage()
+	}
+}
+
+
+
+
+
+
+
+
+
+
+
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1784)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1785)
@@ -327,5 +327,5 @@
 	*/
 	BvhLeaf(const AxisAlignedBox3 &bbox);
-	BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent);
+  BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent);
 	BvhLeaf(const AxisAlignedBox3 &bbox, BvhInterior *parent, const int numObjects);
 
@@ -363,15 +363,17 @@
 
 public:
-
-	/// objects
-	ObjectContainer mObjects;
-
+  // gl list use to store the geometry on the gl server
+  int mGlList;
+  
+  /// objects
+  ObjectContainer mObjects;
+  
 protected:
-
-	/// pointer to a split plane candidate splitting this leaf
-	SubdivisionCandidate *mSubdivisionCandidate;
-
-	/// the active node which will be accounted for in the pvs
-	BvhNode *mActiveNode;
+  
+  /// pointer to a split plane candidate splitting this leaf
+  SubdivisionCandidate *mSubdivisionCandidate;
+  
+  /// the active node which will be accounted for in the pvs
+  BvhNode *mActiveNode;
 };
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1761)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1785)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: Thu Nov 16 14:37:00 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: ?t 23. XI 14:54:07 2006
 # Project:  preprocessor.pro
 # Template: app
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1757)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1785)
@@ -2179,5 +2179,5 @@
   int startIndex = (int)rays.size();
 
-  Debug<<"B"<<flush;
+  //  Debug<<"B"<<flush;
 
   AxisAlignedBox3 box = GetBBox(leaf);
@@ -2192,5 +2192,5 @@
   }
 
-  Debug<<"R"<<flush;
+  //  Debug<<"R"<<flush;
   
   for (int i=0; i < numberOfRays; i++) {
@@ -2229,7 +2229,6 @@
 	origin = box.GetPoint(pVector);
 	dirVector = dirBox.GetPoint(dVector);
-
+	
 	direction = Vector3(sin(dirVector.x), sin(dirVector.y), cos(dirVector.x));
-
 	
 	
@@ -2253,5 +2252,5 @@
 #if 0
 	static int counter = 0;
-	Debug<<counter++<<flush;
+	//	Debug<<counter++<<flush;
 
 	if (counter > 10374968) {
@@ -2268,5 +2267,5 @@
   }
 
-  Debug<<"D"<<flush;
+  //  Debug<<"D"<<flush;
   
   float density = 1.0f;
@@ -2692,10 +2691,18 @@
   
   // always generate at leat n ray per leaf
-  int fixedPerLeaf = 0;
+  int fixedPerLeaf = 1;
   // int fixedPerLeaf = 0;
   int fixed = fixedPerLeaf*(int)leaves.size();
-  int iGenerated = numberOfRays;
+
+  // check if the number of fixed is not too big
+
+  if (fixed >= numberOfRays/2) {
+	fixedPerLeaf = 0;
+	fixed = 0;
+  }
+  
+  int iGenerated = numberOfRays - fixed;
   float ratioPerLeaf = iGenerated /(avgContrib*numberOfLeaves);
-
+  
   k = 0;
 
@@ -2749,10 +2756,9 @@
 }
 
-float weightAbsContributions = 0.0f;
+float weightAbsContributions = ABS_CONTRIBUTION_WEIGHT;
 // if small very high importance of the last sample
 // if 1.0f then weighs = 1 1/2 1/3 1/4
 float passSampleWeightDecay = 1.0f;
 //float passSampleWeightDecay = 0.0001f;
-
 
 float
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1785)
@@ -14,4 +14,5 @@
 class KdNode;
 
+#define ABS_CONTRIBUTION_WEIGHT 0.8f
 
 class VssRay {
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1766)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1785)
@@ -313,8 +313,21 @@
 		}
 
-		qApp->exec();	
+		int frames;
+		Environment::GetSingleton()->GetIntValue("Preprocessor.pvsRenderErrorSamples", frames);
+		if (frames) {
+		  // NOTE: render texture should be power of 2 and square
+		  // renderer must be initialised
+		  // $$matt
+		  preprocessor->renderer = 
+			new QtGlRendererBuffer(512, 512,
+								   preprocessor->mSceneGraph,
+								   preprocessor->mViewCellsManager,
+								   preprocessor->mKdTree);
+		  //		preprocessor->Getrenderer->makeCurrent();
+		}
+		qApp->exec();
 #endif
 	  }
-	
+
 	if (!guiSupported) {
 	  preprocessor->mUseGlRenderer = false;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1608)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1785)
@@ -190,4 +190,5 @@
 				 KdTree *tree);
 
+  virtual ~GlRendererBuffer();
 
 	/** Evaluates render cost of a point sample.
@@ -196,5 +197,5 @@
 		@param threshold number of pixels / samples from where an object is considered visible.
 	*/
-	void EvalRenderCostSample(RenderCostSample &sample,
+  virtual void EvalRenderCostSample(RenderCostSample &sample,
 							  const bool useOcclusionQueries,
 							  const int threshold);
@@ -208,23 +209,26 @@
 		@param threshold number of pixels / samples from where an object is considered visible.
 	*/
-	void SampleRenderCost(const int numSamples, 
-						  vector<RenderCostSample> &samples,
-						  const bool useOcclusionQueries,
-						  const int threshold = 0)
-	{}
+  virtual void SampleRenderCost(const int numSamples, 
+								vector<RenderCostSample> &samples,
+								const bool useOcclusionQueries,
+								const int threshold = 0);
+  
 
 	/** Implerment in subclasses.
 	*/
-	void EvalPvsStat() {};
-
-	void ClearErrorBuffer();
-  
-
-  virtual int GetWidth() const { return 0; }
-  virtual int GetHeight() const { return 0; }
-
-
-  void RandomViewPoint();
-  void SampleBeamContributions(
+  virtual void EvalPvsStat();
+
+  virtual void ClearErrorBuffer();
+  
+
+  virtual int GetWidth() const = 0;
+  virtual int GetHeight() const  = 0; 
+
+  virtual void MakeCurrent() = 0;
+  virtual void DoneCurrent() = 0;
+  
+
+  virtual void RandomViewPoint();
+  virtual void SampleBeamContributions(
 							   Intersectable *sourceObject,
 							   Beam &beam,
@@ -233,5 +237,5 @@
 							   );
 
-  void
+  virtual void
   SampleViewpointContributions(
 							   Intersectable *sourceObject,
@@ -242,17 +246,17 @@
 							   );
 
-  void InitGL();
+  virtual void InitGL();
 
   /** Computes rays from information gained with hw sampling-
   */
-  void ComputeRays(Intersectable *sourceObj, VssRayContainer &rays);
-
-  int ComputePvs() const;
-
-  float
-  GetPixelError(int &pvsSize);
-
-  int ComputePvs(ObjectContainer &objects, ObjectContainer &pvs) const;
-
+  virtual void ComputeRays(Intersectable *sourceObj, VssRayContainer &rays);
+
+  virtual int ComputePvs() const = 0;
+
+  virtual float
+  GetPixelError(int &pvsSize) = 0;
+  
+  virtual int ComputePvs(ObjectContainer &objects, ObjectContainer &pvs) const = 0;
+  
   PvsRenderStatistics mPvsStat;
    
@@ -270,9 +274,9 @@
   
 protected:
-	unsigned int *mPixelBuffer;
-  
-	static void GenQueries(const int numQueries);
+  unsigned int *mPixelBuffer;
+  
+  static void GenQueries(const int numQueries);
 	
-	void SetupProjectionForViewPoint(const Vector3 &viewPoint, 
+  virtual void SetupProjectionForViewPoint(const Vector3 &viewPoint, 
 									 const Beam &beam, 
 
@@ -281,9 +285,9 @@
 	/** Evaluates query for one direction using item buffer.
 	*/
-	void EvalQueryWithItemBuffer();
+  virtual void EvalQueryWithItemBuffer();
 
 	/** Evaluates query for one direction using occlusion queries.
 	*/
-	void EvalQueryWithOcclusionQueries();
+  virtual void EvalQueryWithOcclusionQueries();
 
 public:
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.cpp	(revision 1763)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.cpp	(revision 1785)
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1772)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1785)
@@ -11,5 +11,5 @@
 
 SamplingStrategy::SamplingStrategy(const Preprocessor &preprocessor): 
-mPreprocessor(preprocessor)
+  mPreprocessor(preprocessor), mRatio(1.0f)
 {
 }
