Index: /GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h	(revision 1528)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.h	(revision 1824)
@@ -52,4 +52,11 @@
 		 );
 
+	virtual int
+	CastGlobalRay(const SimpleRay &simpleRay,
+								VssRayContainer &vssRays,
+								const AxisAlignedBox3 &box,
+								const bool pruneInvalidRays
+								);
+
 protected:
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/run_test2
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/run_test2	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/run_test2	(revision 1824)
@@ -29,5 +29,5 @@
 VIEWCELLS=../data/vienna/vienna_cropped-gradient-viewcells.xml.gz
 
-PREFIX=../work/plots/osp-rss-1e5-n
+PREFIX=../work/plots/osp-rss-1e5
 
 #SCENE=../data/atlanta/atlanta2.x3d
@@ -42,6 +42,6 @@
 $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
  -rss_use_importance+ -rss_update_subdivision+ -rss_split=hybrid -hybrid_depth=10 \
- -view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-i-combined-update-ccb12.log \
--preprocessor_histogram_file=$PREFIX-i-combined-update-ccb12.hlog
+ -view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-i-combined-update-ccb12-n.log \
+-preprocessor_histogram_file=$PREFIX-i-combined-update-ccb12-n.hlog
 
 
@@ -60,7 +60,14 @@
 
 
-$COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
- -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
+# $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
+#  -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
 
+
+# $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
+#  -rss_use_importance+ -rss_use_rss_tree- -view_cells_filter_max_size=1 \
+#  -rss_initial_samples=500000 -rss_vss_samples_per_pass=500000 -preprocessor_ray_cast_method=0 \
+#   -preprocessor_stats=$PREFIX-i-global-b1.log \
+#  -preprocessor_histogram_file=$PREFIX-i-global-b1.hlog
+
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1789)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1824)
@@ -500,8 +500,9 @@
   PvsFilterStatistics 
   ApplyFilter2(ViewCell *viewCell,
-			   const bool useViewSpaceFilter,
-			   const float filterSize,
-			   ObjectPvs &pvs
-			   );
+							 const bool useViewSpaceFilter,
+							 const float filterSize,
+							 ObjectPvs &pvs,
+							 vector<AxisAlignedBox3> *filteredBoxes = NULL
+							 );
 
 	void ApplySpatialFilter(KdTree *kdTree,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1824)
@@ -148,20 +148,20 @@
 	
   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);
-	
+		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 = pvs.GetIterator();
-	
-	pvsSize = pvs.GetSize();
-	Intersectable::NewMail();
+		// 	// Render PVS
+		ObjectPvsIterator it = pvs.GetIterator();
+		
+		pvsSize = pvs.GetSize();
+		Intersectable::NewMail();
 	for (; it.HasMoreEntries(); ) {
 	  ObjectPvsEntry entry = it.Next();
@@ -364,41 +364,47 @@
 	  
 	  if (mUseSpatialFilter) {
-		// 9.11. 2006 -> experiment with new spatial filter
+			// 9.11. 2006 -> experiment with new spatial filter
 #if 0
-		mViewCellsManager->ApplySpatialFilter(mKdTree,
-											  mSpatialFilterSize*
-											  Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
-											  pvs);
+			mViewCellsManager->ApplySpatialFilter(mKdTree,
+																						mSpatialFilterSize*
+																						Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
+																						pvs);
 #else
-		// mSpatialFilter size is in range 0.001 - 0.1
-		mViewCellsManager->ApplyFilter2(viewcell,
-										mUseFilter,
-										100*mSpatialFilterSize,
-										pvs);
+			// mSpatialFilter size is in range 0.001 - 0.1
+			mViewCellsManager->ApplyFilter2(viewcell,
+																			mUseFilter,
+																			100*mSpatialFilterSize,
+																			pvs,
+																			&mPvsCache.filteredBoxes
+																			);
 #endif
 	  } else
-		pvs = viewcell->GetPvs();
+			pvs = viewcell->GetPvs();
 	}
 
 	// Render PVS
-	ObjectPvsIterator it = pvs.GetIterator();
-	
-	mPvsSize = pvs.GetSize();
-	
-	for (; it.HasMoreEntries(); ) {
-	  ObjectPvsEntry entry = it.Next();
-	  Intersectable *object = entry.mObject;
-	  
-	  if (mRenderVisibilityEstimates) {
+	if (mUseSpatialFilter && mRenderBoxes) {
+		for (int i=0; i < mPvsCache.filteredBoxes.size(); i++)
+			RenderBox(mPvsCache.filteredBoxes[i]);
+	} else {
+		ObjectPvsIterator it = pvs.GetIterator();
 		
-		float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f
-		glColor3f(visibility, 0.0f, 0.0f);
-		mUseForcedColors = true;
-		RenderIntersectable(object);
-		mUseForcedColors = false;
-	  } else {
-		mUseForcedColors = false;
-		RenderIntersectable(object);
-	  }
+		mPvsSize = pvs.GetSize();
+		for (; it.HasMoreEntries(); ) {
+			ObjectPvsEntry entry = it.Next();
+			Intersectable *object = entry.mObject;
+			
+			if (mRenderVisibilityEstimates) {
+				
+				float visibility = mTransferFunction*log10(entry.mData.mSumPdf + 1); // /5.0f
+				glColor3f(visibility, 0.0f, 0.0f);
+				mUseForcedColors = true;
+				RenderIntersectable(object);
+				mUseForcedColors = false;
+			} else {
+				mUseForcedColors = false;
+				RenderIntersectable(object);
+			}
+		}
 	}
 
@@ -412,5 +418,5 @@
 	  glColor3f(1.0f, 0.0f, 0.0f);
 	  gluSphere((::GLUquadric *)mSphere,
-				1e-3*Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 6, 6);
+							1e-3*Magnitude(mViewCellsManager->GetViewSpaceBox().Size()), 6, 6);
 	  glPopAttrib();
 	  glPopMatrix();
@@ -422,7 +428,7 @@
 
   } else {
-	ObjectContainer::const_iterator oi = mObjects.begin();
-	for (; oi != mObjects.end(); oi++)
-	  RenderIntersectable(*oi);
+		ObjectContainer::const_iterator oi = mObjects.begin();
+		for (; oi != mObjects.end(); oi++)
+			RenderIntersectable(*oi);
   }
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1594)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1824)
@@ -3,4 +3,5 @@
 
 #include <vector>
+#include <algorithm>
 #include "Matrix4x4.h"
 #include "Vector3.h"
@@ -46,17 +47,17 @@
 	  Intersectable *mObject;
 
-	/// the face of the intersectable
+		/// the face of the intersectable
 	  int mFace;
 
 	  Intersection(const float t,
-		 		   const Vector3 &normal,
-				   Intersectable *object,
-				   const int face): 
-	  mT(t), mNormal(normal), mObject(object), mFace(face) 
+								 const Vector3 &normal,
+								 Intersectable *object,
+								 const int face): 
+			mT(t), mNormal(normal), mObject(object), mFace(face) 
 	  {}
-
+		
 	  Intersection(): mT(0), mNormal(0,0,0), mObject(NULL), mFace(0) 
 	  {}
-
+		
 	  bool operator<(const Intersection &b) const 
 	  {
@@ -113,4 +114,8 @@
   void Init(const VssRay &vssRay);
 
+	void SortIntersections() {
+		sort(intersections.begin(), intersections.end());
+	}
+	
   Intersectable *GetIntersectionObject(const int i) const {
     return intersections[i].mObject;
@@ -215,4 +220,5 @@
 
   int GetType() const { return mType; }
+  void SetType(const int t) { mType = t; }
   
   // make such operation to slightly change the ray direction
@@ -313,9 +319,10 @@
   Vector3 mDirection;
   float mPdf;
-
-  SimpleRay() {}
+	int mType;
+	
+  SimpleRay(): mType(Ray::LOCAL_RAY) {}
   SimpleRay(const Vector3 &o, const Vector3 &d, const float p=1.0f):
-	mOrigin(o), mDirection(d), mPdf(p) {}
-
+		mOrigin(o), mDirection(d), mPdf(p), mType(Ray::LOCAL_RAY) {}
+	
   Vector3 Extrap(const float t) const {
 	return mOrigin + mDirection * t;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1545)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.h	(revision 1824)
@@ -74,5 +74,5 @@
 
 		Intersection(const Vector3 &p, const Vector3 &n, Intersectable *o, const int f):
-		mPoint(p), mNormal(n), mObject(o), mFaceId(f)
+			mPoint(p), mNormal(n), mObject(o), mFaceId(f)
 		{}
 
@@ -84,4 +84,5 @@
 		int mFaceId;
 	};
+
 
 	int ProcessRay(
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1786)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1824)
@@ -983,6 +983,6 @@
 int
 Preprocessor::GenerateRays(const int number,
-						   const SamplingStrategy &strategy,
-						   SimpleRayContainer &rays)
+													 const SamplingStrategy &strategy,
+													 SimpleRayContainer &rays)
 {
 	return strategy.GenerateSamples(number, rays);
@@ -991,6 +991,6 @@
 int
 Preprocessor::GenerateRays(const int number,
-						   const int sampleType,
-						   SimpleRayContainer &rays)
+													 const int sampleType,
+													 SimpleRayContainer &rays)
 {
 	const int startSize = (int)rays.size();
@@ -1037,6 +1037,9 @@
 	case SamplingStrategy::REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION:
 		return new ReverseViewSpaceBorderBasedDistribution(*this);
-	//case OBJECTS_INTERIOR_DISTRIBUTION:
-	//	return new ObjectsInteriorDistribution(*this);
+	case SamplingStrategy::GLOBAL_LINES_DISTRIBUTION:
+		return new GlobalLinesDistribution(*this);
+		
+		//case OBJECTS_INTERIOR_DISTRIBUTION:
+		//	return new ObjectsInteriorDistribution(*this);
 	default: // no valid strategy
 		Debug << "warning: no valid sampling strategy" << endl;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.h	(revision 1824)
@@ -116,11 +116,4 @@
 
 
-struct PvsCache {
-  PvsCache():mViewCell(NULL) {}
-  void Reset() { mViewCell = NULL; mPvs.Clear(); }
-  ViewCell *mViewCell;
-  ObjectPvs mPvs;
-};
-
 class QtGlRendererWidget : public QGLWidget, public GlRendererWidget
 {
@@ -156,5 +149,4 @@
   float mManipulatorLastQuat[4];
   float mManipulatorScale;
-  PvsCache mPvsCache;
   
   QtRendererControlWidget *mControlWidget;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1824)
@@ -73,11 +73,11 @@
   case SamplingStrategy::RSS_BASED_DISTRIBUTION:
   case SamplingStrategy::RSS_SILHOUETTE_BASED_DISTRIBUTION:
-	if (mRssTree) {
-	  result = GenerateImportanceRays(mRssTree, number, rays);
-	}
-	break;
-	
+		if (mRssTree) {
+			result = GenerateImportanceRays(mRssTree, number, rays);
+		}
+		break;
+		
   default:
-	result = Preprocessor::GenerateRays(number, sampleType, rays);
+		result = Preprocessor::GenerateRays(number, sampleType, rays);
   }
 
@@ -465,12 +465,17 @@
 
   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));
+		mDistributions.push_back(new RssBasedDistribution(*this));
+
+
+	if (1) {
+		//  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));
+	} else {
+		mDistributions.push_back(new GlobalLinesDistribution(*this));
+	}
   
   if (mLoadInitialSamples) {
@@ -495,5 +500,6 @@
 		if (mDistributions[i]->mType != SamplingStrategy::RSS_BASED_DISTRIBUTION)
 		  GenerateRays(mInitialSamples/count,
-					   mDistributions[i]->mType, rays);
+									 mDistributions[i]->mType,
+									 rays);
 
 	} else {
@@ -582,5 +588,7 @@
   
   rssPass++;
-  
+
+	//	mDistributions.resize(1);
+
   mRssTree = new RssTree;
   mRssTree->SetPass(mPass);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1824)
@@ -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
@@ -84,5 +84,5 @@
 
 SamplingPreprocessor {
-	totalSamples 50000000
+	totalSamples 100000000
 	samplesPerPass 5000000
 }
@@ -91,5 +91,5 @@
 	samplesPerPass 1000
 	initialSamples 3000000
-	vssSamples 50000000
+	vssSamples 100000000
 	vssSamplesPerPass 5000000
 	useImportanceSampling true
@@ -101,6 +101,6 @@
 		pvs false
 		rssTree false
-		rays false
-		numRays 2000
+		rays true
+		numRays 10000
 	}
 
@@ -110,5 +110,5 @@
 	storeInitialSamples false
 
-	useRssTree false
+	useRssTree true
 }
 
@@ -124,11 +124,11 @@
 #	splitType heuristic
 
-	minRays		100
+	minRays		200
 	minSize		0.001
  	maxCostRatio 1.0
 	maxRayContribution 1.0
-	maxRays		3000000
-	maxTotalMemory	200
-	maxStaticMemory	100
+	maxRays		10000000
+	maxTotalMemory	400
+	maxStaticMemory	200
 
 #	splitType regular
@@ -206,6 +206,6 @@
 	#type vspKdTree
 	#type bspTree
-	#type vspBspTree
-	type vspOspTree
+	type vspBspTree
+	#type vspOspTree
 	#type sceneDependent
 	
@@ -264,5 +264,5 @@
 
 #	filename ../data/Arena/viewcells-5000.xml
-#	filename ../data/Arena/viewcells-20000.xml
+filename ../data/Arena/viewcells-20000.xml
 
 #	filename ../data/atlanta/atlanta_viewcells_large.x3d
@@ -278,7 +278,5 @@
 #	filename ../data/test1/test-viewcells.xml
 
-#	filename ../data/soda/soda5-viewcell-single.xm
-#	filename ../data/soda/soda-viewcells-1000.xml.zip
-#	filename ../data/soda/soda-viewcells-vsposp.xml
+#	filename ../data/soda/soda-viewcells-1000.xml.gz
 
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1772)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1824)
@@ -32,5 +32,6 @@
 		VIEWCELL_BORDER_BASED_DISTRIBUTION,
 		VIEWSPACE_BORDER_BASED_DISTRIBUTION,
-		REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION
+		REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION,
+		GLOBAL_LINES_DISTRIBUTION
 	};
 
@@ -199,4 +200,15 @@
 };
 
+class GlobalLinesDistribution: public SamplingStrategy
+{
+public:
+  GlobalLinesDistribution(const Preprocessor &preprocessor):
+		SamplingStrategy(preprocessor) {
+		mType = GLOBAL_LINES_DISTRIBUTION;
+	}
+  
+  virtual bool GenerateSample(SimpleRay &ray) const;
+};
+
 
 /** This strategy generates samples inside of the objects, e.g.,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1816)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1824)
@@ -32,5 +32,5 @@
 
 // $$JB HACK
-#define USE_KD_PVS 0
+#define USE_KD_PVS 1
 #define KD_PVS_AREA (1e-5f)
 
@@ -856,5 +856,6 @@
 	viewCells = mViewCells;
 #endif
-	ViewCellContainer::iterator it = viewCells.begin(), it_end = viewCells.end();		
+	ViewCellContainer::iterator it = viewCells.begin(),
+	  it_end = viewCells.end();		
 	for (; it != it_end; ++it) {
 	  //(*it)->UpdatePvsCost();
@@ -872,5 +873,6 @@
 	// hack: normalize pvs size
 	int histoMaxVal;
-	Environment::GetSingleton()->GetIntValue("Preprocessor.histogram.maxValue", histoMaxVal);
+	Environment::GetSingleton()->GetIntValue(
+											 "Preprocessor.histogram.maxValue", histoMaxVal);
 	maxVal = max((float)histoMaxVal, maxPvs);
 		
@@ -1831,6 +1833,8 @@
 		if (evaluateFilter) {
 		  ObjectPvs filteredPvs = viewcell->GetPvs();
-		  PvsFilterStatistics fstat = ApplyFilter2(viewcell, false,
-												   1.0f, filteredPvs);
+		  PvsFilterStatistics fstat = ApplyFilter2(viewcell,
+																							 false,
+																							 2.0f,
+																							 filteredPvs);
 		  
 		  float filteredCost = filteredPvs.EvalPvsCost();
@@ -1970,6 +1974,6 @@
 
 float ViewCellsManager::ComputeSampleContribution(VssRay &ray,
-												  const bool addRays,
-												  const bool storeViewCells)
+																									const bool addRays,
+																									const bool storeViewCells)
 {
 	ViewCellContainer viewcells;
@@ -2026,4 +2030,7 @@
 					++ ray.mPvsContribution;
 					ray.mRelativePvsContribution += contribution;
+					// $$ test of different contribution measure
+					//					ray.mRelativePvsContribution += 1.0f/(viewcell->GetPvs().GetSize() + 10.0f);
+
 				}
 			}
@@ -2037,10 +2044,10 @@
 			if (ray.mOriginObject && 
 				viewcell->GetPvs().GetSampleContribution(ray.mOriginObject,
-														 ray.mPdf,
-														 contribution))
-			{
-				++ ray.mPvsContribution;
-				ray.mRelativePvsContribution += contribution;
-			}
+																								 ray.mPdf,
+																								 contribution))
+				{
+					++ ray.mPvsContribution;
+					ray.mRelativePvsContribution += contribution;
+				}
 #endif
 		}
@@ -2582,10 +2589,11 @@
 PvsFilterStatistics
 ViewCellsManager::ApplyFilter2(ViewCell *viewCell,
-							   const bool useViewSpaceFilter,
-							   const float filterSize,
-							   ObjectPvs &pvs
-							   )
-{
-	cout<<"y";
+															 const bool useViewSpaceFilter,
+															 const float filterSize,
+															 ObjectPvs &pvs,
+															 vector<AxisAlignedBox3> *filteredBoxes
+															 )
+{
+	//cout<<"y";
   PvsFilterStatistics stats;
 
@@ -2601,8 +2609,8 @@
   // first mark all object from this pvs
   while (pit.HasMoreEntries()) {		
-	ObjectPvsEntry entry = pit.Next();
-	
-	Intersectable *object = entry.mObject;
-	object->Mail();
+		ObjectPvsEntry entry = pit.Next();
+		
+		Intersectable *object = entry.mObject;
+		object->Mail();
   }
 #endif
@@ -2625,6 +2633,6 @@
    // and gobal estimate for the view cell
    // (total #rays intersecting the viewcell)
-#define MIN_LOCAL_SAMPLES 5
-
+  int minLocalSamples = 2;
+  
   float viewCellRadius = 0.5f*Magnitude(vbox.Diagonal());
   
@@ -2632,85 +2640,98 @@
   
   if (useViewSpaceFilter) {
-	//	float radius = Max(viewCellRadius/100.0f, avgRadius - viewCellRadius);
-	float radius = viewCellRadius/100.0f;
-	vbox.Enlarge(radius);
-	cout<<"vbox = "<<vbox<<endl;
-	ViewCellContainer viewCells;
-	ComputeBoxIntersections(vbox, viewCells);
-	
-	ViewCellContainer::const_iterator it = viewCells.begin(),
-	  it_end = viewCells.end();
-	int i = 0;
-	for (i=0; it != it_end; ++ it, ++ i)
-	  if ((*it) != viewCell) {
-		//cout<<"v"<<i<<" pvs="<<(*it)->GetPvs().mEntries.size()<<endl;
-		basePvs.MergeInPlace((*it)->GetPvs());
-	  }
-	
-	// update samples and globalC
-	samples = (float)pvs.GetSamples();
-	//	cout<<"neighboring viewcells = "<<i-1<<endl;
-	//	cout<<"Samples' = "<<samples<<endl;
+		//	float radius = Max(viewCellRadius/100.0f, avgRadius - viewCellRadius);
+		float radius = viewCellRadius/100.0f;
+		vbox.Enlarge(radius);
+		cout<<"vbox = "<<vbox<<endl;
+		ViewCellContainer viewCells;
+		ComputeBoxIntersections(vbox, viewCells);
+		
+		ViewCellContainer::const_iterator it = viewCells.begin(),
+			it_end = viewCells.end();
+		int i = 0;
+		for (i=0; it != it_end; ++ it, ++ i)
+			if ((*it) != viewCell) {
+				//cout<<"v"<<i<<" pvs="<<(*it)->GetPvs().mEntries.size()<<endl;
+				basePvs.MergeInPlace((*it)->GetPvs());
+			}
+		
+		// update samples and globalC
+		samples = (float)pvs.GetSamples();
+		//	cout<<"neighboring viewcells = "<<i-1<<endl;
+		//	cout<<"Samples' = "<<samples<<endl;
   }
-
+	
   // Minimal number of samples so that filtering takes place
-#define MIN_SAMPLES  100
+#define MIN_SAMPLES  50
+
   if (samples > MIN_SAMPLES) {
-	float globalC = 2.0f*filterSize/sqrt(samples);
-	
-	pit = basePvs.GetIterator();
-	
-	ObjectContainer objects;
-	
-	while (pit.HasMoreEntries())
-	  {		
-		ObjectPvsEntry entry = pit.Next();
-		
-		Intersectable *object = entry.mObject;
-		// compute filter size based on the distance and the numebr of samples
-		AxisAlignedBox3 box = object->GetBox();
-		
-		float distance = Distance(center, box.Center());
-		float globalRadius = distance*globalC;
-		
-		int objectSamples = (int)entry.mData.mSumPdf;
-		float localRadius = MAX_FLOAT;
-		if (objectSamples > MIN_LOCAL_SAMPLES)
-		  localRadius = filterSize*0.5f*Magnitude(box.Diagonal())/
-			sqrt((float)objectSamples);
-		
-		//	cout<<"lr="<<localRadius<<" gr="<<globalRadius<<endl;
-		
-		// now compute the filter size
-		float radius;
-
-		if (localRadius < globalRadius) {
-		  radius = localRadius;
-		  stats.mLocalFilterCount++;
-		} else {
-		  radius = globalRadius;
-		  stats.mGlobalFilterCount++;
-		}
-
-		stats.mAvgFilterRadius += radius;
-		
-		// cout<<"box = "<<box<<endl;
-		//	cout<<"distance = "<<distance<<endl;
-		//	cout<<"radiues = "<<radius<<endl;
-		
-		box.Enlarge(Vector3(radius));
-		
-		objects.clear();
-		// $$ warning collect objects takes only unmailed ones!
-		CollectObjects(box, objects);
-		//	cout<<"collected objects="<<objects.size()<<endl;
-		ObjectContainer::const_iterator noi = objects.begin();
-		for (; noi != objects.end(); ++ noi) {
-		  Intersectable *o = *noi;
-		  // $$ JB warning: pdfs are not correct at this point!	  
-		  pvs.AddSampleDirty(o, Limits::Small);
-		}
-	  }
-	stats.mAvgFilterRadius /= (stats.mLocalFilterCount + stats.mGlobalFilterCount);
+		float globalC = 2.0f*filterSize/sqrt(samples);
+		
+		pit = basePvs.GetIterator();
+		
+		ObjectContainer objects;
+		
+		while (pit.HasMoreEntries())
+			{		
+				ObjectPvsEntry entry = pit.Next();
+				
+				Intersectable *object = entry.mObject;
+				// compute filter size based on the distance and the numebr of samples
+				AxisAlignedBox3 box = object->GetBox();
+				
+				float distance = Distance(center, box.Center());
+				float globalRadius = distance*globalC;
+				
+				int objectSamples = (int)entry.mData.mSumPdf;
+				float localRadius = MAX_FLOAT;
+				
+				localRadius = filterSize*0.5f*Magnitude(box.Diagonal())/
+					sqrt((float)objectSamples);
+				
+				//	cout<<"lr="<<localRadius<<" gr="<<globalRadius<<endl;
+				
+				// now compute the filter size
+				float radius;
+
+#if 0
+				if (objectSamples <= 1) {
+					if (localRadius > globalRadius) {
+						radius = 0.5flRadius;
+						stats.mLocalFilterCount++;
+					} else {
+						radius = globalRadius;
+						stats.mGlobalFilterCount++;
+					}
+				} else {
+					radius = localRadius;
+					stats.mLocalFilterCount++;
+				}
+#else
+				radius = 0.5f*globalRadius + 0.5f*localRadius;
+				stats.mLocalFilterCount++;
+				stats.mGlobalFilterCount++;
+#endif
+				
+				stats.mAvgFilterRadius += radius;
+				
+				// cout<<"box = "<<box<<endl;
+				//	cout<<"distance = "<<distance<<endl;
+				//	cout<<"radiues = "<<radius<<endl;
+				
+				box.Enlarge(Vector3(radius));
+				if (filteredBoxes)
+					filteredBoxes->push_back(box);
+				objects.clear();
+				// $$ warning collect objects takes only unmailed ones!
+				CollectObjects(box, objects);
+				//	cout<<"collected objects="<<objects.size()<<endl;
+				ObjectContainer::const_iterator noi = objects.begin();
+				for (; noi != objects.end(); ++ noi) {
+					Intersectable *o = *noi;
+					// $$ JB warning: pdfs are not correct at this point!	  
+					pvs.AddSampleDirty(o, Limits::Small);
+				}
+			}
+		stats.mAvgFilterRadius /= (stats.mLocalFilterCount + stats.mGlobalFilterCount);
   }
   
@@ -2721,6 +2742,6 @@
   pit = basePvs.GetIterator();
   while (pit.HasMoreEntries()) {		
-	ObjectPvsEntry entry = pit.Next();
-	pvs.AddSampleDirty(entry.mObject, entry.mData.mSumPdf);
+		ObjectPvsEntry entry = pit.Next();
+		pvs.AddSampleDirty(entry.mObject, entry.mData.mSumPdf);
   }
 #endif
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp	(revision 1786)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp	(revision 1824)
@@ -23,23 +23,26 @@
 	if (ray.GetType() == Ray::LOCAL_RAY && !ray.intersections.empty())
 		nearestT = ray.intersections[0].mT;
-
+	
 	const int hitCode = mItem.CastRay(ray, t, nearestT, nearestNormal);
 
 	nearestT = t;
 
-	if ((hitCode == Ray::INTERSECTION) && (ray.GetType() == Ray::LOCAL_RAY))
-	{
-		if (!ray.intersections.empty())
-		{
-			ray.intersections[0] = Ray::Intersection(nearestT, nearestNormal, this, 0);
+	if (hitCode == Ray::INTERSECTION) {
+		if (ray.GetType() == Ray::LOCAL_RAY && !ray.intersections.empty()) {
+			ray.intersections[0] = Ray::Intersection(nearestT,
+																							 nearestNormal,
+																							 this,
+																							 0);
 		}
-		else
-		{
-			ray.intersections.push_back(Ray::Intersection(nearestT, nearestNormal, this, 0));
+		else {
+			ray.intersections.push_back(Ray::Intersection(nearestT,
+																										nearestNormal,
+																										this,
+																										0));
 		}
 		
 		return 1;
 	}
-
+	
 	return 0;
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1772)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1824)
@@ -183,4 +183,5 @@
   Vector3 GetRandomPoint() const;
   Vector3 GetRandomSurfacePoint() const;
+	Vector3 GetUniformRandomSurfacePoint() const;
 
   Vector3 GetPoint(const Vector3 &p) const {
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1824)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: ?t 23. XI 14:54:07 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: út 28. XI 19:46:06 2006
 # Project:  preprocessor.pro
 # Template: app
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1761)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1824)
@@ -677,39 +677,39 @@
 	  ObjectContainer::const_iterator mi;
 	  for ( mi = leaf->mObjects.begin();
-			mi != leaf->mObjects.end();
-			mi++) {
-		Intersectable *object = *mi;
-		if (!object->Mailed() ) {
-		  object->Mail();
-		  if (ray.mFlags & Ray::STORE_TESTED_OBJECTS)
-			ray.testedObjects.push_back(object);
-
-		  static int oi=1;
-		  if (MeshDebug) 
-			cout<<"Object "<<oi++;
-		  
-		  hits += object->CastRay(ray);
-
-		  if (MeshDebug) {
-			if (!ray.intersections.empty()) 
-			cout<<"nearest t="<<ray.intersections[0].mT<<endl;
-		  else
-			cout<<"nearest t=-INF"<<endl;
-		  }	  
-		}
+					mi != leaf->mObjects.end();
+					mi++) {
+			Intersectable *object = *mi;
+			if (!object->Mailed() ) {
+				object->Mail();
+				if (ray.mFlags & Ray::STORE_TESTED_OBJECTS)
+					ray.testedObjects.push_back(object);
+				
+				static int oi=1;
+				if (MeshDebug) 
+					cout<<"Object "<<oi++;
+				
+				hits += object->CastRay(ray);
+				
+				if (MeshDebug) {
+					if (!ray.intersections.empty()) 
+						cout<<"nearest t="<<ray.intersections[0].mT<<endl;
+					else
+						cout<<"nearest t=-INF"<<endl;
+				}	  
+			}
 	  }
 	  
 	  if (hits && ray.GetType() == Ray::LOCAL_RAY)
-		if (ray.intersections[0].mT <= maxt)
-		  break;
+			if (ray.intersections[0].mT <= maxt)
+				break;
 	  
 	  // get the next node from the stack
 	  if (tStack.empty())
-		break;
+			break;
 	  
 	  entp = extp;
 	  mint = maxt;
 	  if (ray.GetType() == Ray::LINE_SEGMENT && mint > 1.0f)
-		break;
+			break;
 	  
 	  RayTraversalData &s  = tStack.top();
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1824)
@@ -336,5 +336,5 @@
 	  leaf->dirBBox.Initialize();
 	  leaf->dirBBox.SetMin(2, 0.0f);
-	  leaf->dirBBox.SetMax(2, 1.0f);
+	  leaf->dirBBox.SetMax(2, 0.0f);
 	  mRoots[i] = leaf;
 	}
@@ -391,5 +391,4 @@
   // make the z axis (unused) a unit size
   // important for volume computation
-
   
   //  if ( forcedBoundingBox ) 
@@ -2230,9 +2229,5 @@
 	dirVector = dirBox.GetPoint(dVector);
 	
-	direction = Vector3(sin(dirVector.x), sin(dirVector.y), cos(dirVector.x));
-	
-	
-	// shift the origin a little bit
-	direction.Normalize();
+	direction = VssRay::GetInvDirParam(dirVector.x, dirVector.y);
 	
 	//	float dist = Min(avgLength*0.5f, Magnitude(GetBBox(leaf).Size()));
@@ -2243,5 +2238,5 @@
 #if 1
 	if (box.ComputeMinMaxT(origin, direction, &minT, &maxT) && minT < maxT)
-	  dist = maxT;
+	  dist = (maxT + 1e-2*boxSize);
 #else
 	dist = 0.5f*boxSize;
@@ -2373,4 +2368,8 @@
 		w1*leaf->rays[r1].GetDir() +
 		w2*leaf->rays[r2].GetDir();
+
+	  // shift the origin a little bit
+	  direction.Normalize();
+	  
 	} else {
 	  Vector3 dirVector;
@@ -2405,9 +2404,7 @@
 	  dirVector = dirBox.GetPoint(dVector);
 
-	  direction = Vector3(sin(dirVector.x), sin(dirVector.y), cos(dirVector.x));
-	}
-
-	// shift the origin a little bit
-	direction.Normalize();
+	  direction = VssRay::GetInvDirParam(dirVector.x,dirVector.y);
+	}
+	
 	
 	//	float dist = Min(avgLength*0.5f, Magnitude(GetBBox(leaf).Size()));
@@ -2628,5 +2625,5 @@
 	  if (node->IsLeaf()) {
 		RssTreeLeaf *leaf = (RssTreeLeaf *)node;
-		// prunned += PruneRaysRandom(leaf, ratio);
+		//		prunned += PruneRaysRandom(leaf, ratio);
 		prunned += PruneRaysContribution(leaf, ratio);
 	  } else {
@@ -2759,6 +2756,6 @@
 // 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 = 1.0f;
-//float passSampleWeightDecay = 0.0001f;
 
 float
@@ -2768,13 +2765,13 @@
   float weight;
   if (1) 
-	weight = 1.0f/sqr(passDiff + passSampleWeightDecay);
+		weight = 1.0f/(passDiff + passSampleWeightDecay);
   else 
-	switch (passDiff) {
+		switch (passDiff) {
 	  case 0:
-	  //	  weight = 1.0f;
-	  //	  break;
-	default:
-	  weight = 1.0f;
-	  break;
+			//	  weight = 1.0f;
+			//	  break;
+		default:
+			weight = 1.0f;
+			break;
 	  // 	case 1:
 // 	  weight = 0.5f;
@@ -2823,25 +2820,58 @@
 	float sumRelContributions = 0.0f;
 	float sumWeights = 0.0f;
+	float maxContribution = 0.0f;
+	float maxRelContribution = 0.0f;
+	float sumLength = 0;
+	
 	for (; it != it_end; ++it) {
 	  VssRay *ray = (*it).mRay;
+	  float sumLength = ray->Length();
+
 	  float weight = GetSampleWeight(ray->mPass);
 	  
-	  sumContributions += weight*ray->mPvsContribution;
-	  //$$ 20.7. changed to sqr to pronouce higher contribution so that they do not get smoothed!!
+	  float c1 = weight*ray->mPvsContribution;
+	  float c2 = weight*ray->mRelativePvsContribution;
+	  sumContributions += c1;
+	  if (c1 > maxContribution)
+		maxContribution = c1;
+	  
+	  //$$ 20.7. changed to sqr to pronouce higher contribution so that
+	  // they do not get smoothed!!
 	  //sumRelContributions += weight*ray->mRelativePvsContribution;
-
-	  sumRelContributions += sqr(weight*ray->mRelativePvsContribution);
-	  
+	  
+	  sumRelContributions += c2;
+	  if (c2 > maxRelContribution)
+		maxRelContribution = c2;
+
 	  //sumWeights += weight;
 	  sumWeights += 1.0f;
 	}
+
+	float distImportance = 0.0f;
+
+	if (leaf->rays.size()) {
+	  // compute average length of the ray 
+	  float avgLength = sumLength/leaf->rays.size();
+	  // compute estimated area of the visible surface corresponding to these rays
+	  float ss = GetBBox(leaf).SurfaceArea()/2.0f;
+	  float sd = GetDirBBox(leaf).SurfaceArea();
+	  float s = ss + avgLength*(2*sqrt(ss*sd) + avgLength*sd);
+	  
+	  distImportance = s/leaf->rays.size();
+	}
+	
 	// $$ 
 	// sumWeights = leaf->mTotalRays;
-	  
-	if (sumWeights != 0.0f) 
+
+	if (sumWeights != 0.0f) {
 	  leaf->mImportance =
-		(weightAbsContributions*sumContributions +
-		 (1.0f - weightAbsContributions)*sumRelContributions)/sumWeights;
-	else
+			sqr(((weightAbsContributions*sumContributions +
+						(1.0f - weightAbsContributions)*sumRelContributions)/sumWeights));
+	  
+	  //	  leaf->mImportance =
+	  //		(weightAbsContributions*maxContribution +
+	  //		 (1.0f - weightAbsContributions)*maxRelContribution)/sumWeights;
+	  
+	} else
 	  leaf->mImportance = 0.0f;
 	
@@ -2856,5 +2886,5 @@
 RssTreeLeaf::GetImportance()  const
 {
-  //return sqr(mImportance);
+  //  return sqr(mImportance);
   return mImportance;
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.cpp	(revision 1359)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VssTree.cpp	(revision 1824)
@@ -1751,5 +1751,5 @@
 	  origin = GetBBox(leaf).GetRandomPoint();
 	  Vector3 dirVector = GetDirBBox(leaf).GetRandomPoint();
-	  direction = Vector3(sin(dirVector.x), sin(dirVector.y), cos(dirVector.x));
+	  direction = VssRay::GetInvDirParam(dirVector.x,dirVector.y);
 	}
 	//cout<<"dir vector.x="<<dirVector.x<<"direction'.x="<<atan2(direction.x, direction.y)<<endl;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1824)
@@ -14,5 +14,5 @@
 class KdNode;
 
-#define ABS_CONTRIBUTION_WEIGHT 0.8f
+#define ABS_CONTRIBUTION_WEIGHT 0.5f
 
 class VssRay {
@@ -137,4 +137,5 @@
 
   static float VssRay::GetDirParam(const int axis, const Vector3 dir);
+  static Vector3 VssRay::GetInvDirParam(const float alpha, const float beta);
 
   float GetSize() const { return  1.0f/mInvSize; }
@@ -203,5 +204,6 @@
   static Vector3
   GetDirection(const float a, const float b) {
-	return Vector3(sin(a), sin(b), cos(a));
+	return GetInvDirParam(a, b);
+	//return Vector3(sin(a), sin(b), cos(a));
   }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1771)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1824)
@@ -150,13 +150,13 @@
 		{
 		  VssRay *vssRay = new VssRay(
-									  hitA.mPoint,
-									  hitB.mPoint,
-									  hitA.mObject,
-									  hitB.mObject,
-									  mPreprocessor.mPass,
-									  simpleRay.mPdf
-									  );
+																	hitA.mPoint,
+																	hitB.mPoint,
+																	hitA.mObject,
+																	hitB.mObject,
+																	mPreprocessor.mPass,
+																	simpleRay.mPdf
+																	);
 		  if (validB)
-			vssRay->mFlags |= VssRay::Valid;
+				vssRay->mFlags |= VssRay::Valid;
 		  
 		  vssRays.push_back(vssRay);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1580)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1824)
@@ -8,4 +8,5 @@
 VssRay::mailID = 0;
 
+#define OLD_PARAM 0
 
 VssRay::VssRay(
@@ -230,5 +231,25 @@
 VssRay::GetDirParam(const int axis, const Vector3 dir)
 {
+  Vector3 d = Normalize(dir);
+#if OLD_PARAM
   return (axis == 0) ? atan2(dir.x, dir.z) : asin(dir.y);
+#else
+  //  x = cos(p0)sin(p1)
+  //  y = cos(p1)
+  //  z = sin(p0)sin(p1)
+  return (axis == 0) ? atan2(dir.z, dir.x) : acos(dir.y);
+#endif
+}
+
+Vector3 VssRay::GetInvDirParam(const float alpha, const float beta)
+{
+#if OLD_PARAM
+  return Normalize(Vector3(sin(alpha), sin(beta), cos(alpha)));
+
+#else
+  return Normalize(Vector3(cos(alpha)*sin(beta),
+						   cos(beta),
+						   sin(alpha)*sin(beta)));
+#endif
 }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1584)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1824)
@@ -22,11 +22,14 @@
 
 int InternalRayCaster::CastRay(const SimpleRay &simpleRay,
-							   VssRayContainer &vssRays,
-							   const AxisAlignedBox3 &box,
-							   const bool castDoubleRay,
-							   const bool pruneInvalidRays
-							   )
-{
-  //cout << "internal ray" << endl;
+															 VssRayContainer &vssRays,
+															 const AxisAlignedBox3 &box,
+															 const bool castDoubleRay,
+															 const bool pruneInvalidRays
+															 )
+{
+	if (simpleRay.mType == Ray::GLOBAL_RAY)
+		return CastGlobalRay(simpleRay, vssRays, box, pruneInvalidRays);
+	
+	//cout << "internal ray" << endl;
   static Ray ray;
   int hits = 0;
@@ -53,32 +56,135 @@
 	}
   
-  mPreprocessor.SetupRay(ray, simpleRay.mOrigin, -simpleRay.mDirection);
-  ray.mFlags &= ~Ray::CULL_BACKFACES;
   
   if (castDoubleRay && mKdTree->CastRay(ray)) 
-	{
-	  hitB.mObject = ray.intersections[0].mObject;
-	  hitB.mPoint = ray.Extrap(ray.intersections[0].mT);
-	  hitB.mNormal = ray.intersections[0].mNormal;
+		{
+			mPreprocessor.SetupRay(ray, simpleRay.mOrigin, -simpleRay.mDirection);
+			ray.mFlags &= ~Ray::CULL_BACKFACES;
+			hitB.mObject = ray.intersections[0].mObject;
+			hitB.mPoint = ray.Extrap(ray.intersections[0].mT);
+			hitB.mNormal = ray.intersections[0].mNormal;
+		}
+  
+  return ProcessRay(
+										simpleRay,
+										hitA,
+										hitB,
+										vssRays,
+										box,
+										castDoubleRay,
+										pruneInvalidRays
+										);
+}
+
+
+int
+InternalRayCaster::CastGlobalRay(const SimpleRay &simpleRay,
+																 VssRayContainer &vssRays,
+																 const AxisAlignedBox3 &box,
+																 const bool pruneInvalidRays
+																 )
+{
+  static Ray ray;
+  int hits = 0;
+	mPreprocessor.SetupRay(ray, simpleRay.mOrigin, simpleRay.mDirection);
+
+	float tmin, tmax;
+	if (!(box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)))
+		return 0;
+
+	// shift the ray origin to tmin
+	//	Vector3 origin = ray.Extrap(tmin);
+	//	mPreprocessor.SetupRay(ray, origin, simpleRay.mDirection);
+	ray.SetType(Ray::GLOBAL_RAY);
+	ray.mFlags &= ~Ray::CULL_BACKFACES;
+
+
+	VssRay *vssRay;
+	
+  if (mKdTree->CastRay(ray)) {
+		// sort intersections
+		ray.SortIntersections();
+		//cout<<"I="<<ray.intersections.size()<<endl;
+
+		
+		Ray::Intersection &hit = ray.intersections[0];
+
+		if (DotProd(hit.mNormal, ray.GetDir()) < 0) {
+			// insert intial segment
+			vssRay = new VssRay(
+													ray.Extrap(tmin),
+													ray.Extrap(hit.mT),
+													NULL,
+													hit.mObject,
+													mPreprocessor.mPass,
+													simpleRay.mPdf
+													);
+			vssRay->mFlags |= VssRay::Valid;
+			vssRays.push_back(vssRay);
+			++hits;
+		}
+				
+		hit = ray.intersections[ray.intersections.size()-1];
+		if (DotProd(hit.mNormal, ray.GetDir()) > 0) {
+			
+			// insert termination segment
+			vssRay = new VssRay(
+													ray.Extrap(tmax),
+													ray.Extrap(hit.mT),
+													NULL,
+													hit.mObject,
+													mPreprocessor.mPass,
+													simpleRay.mPdf
+													);
+			vssRay->mFlags |= VssRay::Valid;
+			vssRays.push_back(vssRay);
+			++hits;
+		}
+		
+		// insert the rest of segments
+		for (int i=0; i < ray.intersections.size() - 1; i++) {
+			Ray::Intersection &hitA = ray.intersections[i];
+			Ray::Intersection &hitB = ray.intersections[i + 1];
+			if (DotProd(hitA.mNormal, ray.GetDir()) > 0 &&
+					DotProd(hitB.mNormal, ray.GetDir()) < 0
+					) {
+				
+				vssRay = new VssRay(
+														ray.Extrap(hitA.mT),
+														ray.Extrap(hitB.mT),
+														hitA.mObject,
+														hitB.mObject,
+														mPreprocessor.mPass,
+														simpleRay.mPdf
+														);
+				vssRay->mFlags |= VssRay::Valid;
+				vssRays.push_back(vssRay);
+				++hits;
+				
+				vssRay = new VssRay(
+														ray.Extrap(hitB.mT),
+														ray.Extrap(hitA.mT),
+														hitB.mObject,
+														hitA.mObject,
+														mPreprocessor.mPass,
+														simpleRay.mPdf
+														);
+				
+				vssRay->mFlags |= VssRay::Valid;
+				vssRays.push_back(vssRay);
+				++hits;
+			}
+		}
 	}
-  
-  return ProcessRay(
-					simpleRay,
-					hitA,
-					hitB,
-					vssRays,
-					box,
-					castDoubleRay,
-					pruneInvalidRays
-					);
-}
-
+	
+	return hits;
+}
 
 void InternalRayCaster::CastRays16(const int index,
-								   SimpleRayContainer &rays, 
-								   VssRayContainer &vssRays,
-								   const AxisAlignedBox3 &sbox,
-								   const bool castDoubleRays,
-								   const bool pruneInvalidRays)
+																	 SimpleRayContainer &rays, 
+																	 VssRayContainer &vssRays,
+																	 const AxisAlignedBox3 &sbox,
+																	 const bool castDoubleRays,
+																	 const bool pruneInvalidRays)
 {
 	const int num = 16;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1824)
@@ -56,4 +56,13 @@
 };
 
+	struct PvsCache {
+		PvsCache():mViewCell(NULL) {}
+		void Reset() { mViewCell = NULL; mPvs.Clear(); filteredBoxes.clear(); }
+		ViewCell *mViewCell;
+		ObjectPvs mPvs;
+		vector<AxisAlignedBox3> filteredBoxes;
+	};
+
+
 struct RenderCostSample {
 
@@ -147,4 +156,5 @@
 protected:
 
+	PvsCache mPvsCache;
 
   vector<OcclusionQuery *> mOcclusionQueries;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1772)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1824)
@@ -2310,5 +2310,43 @@
 }
 
-
-}
-
+Vector3
+AxisAlignedBox3::GetUniformRandomSurfacePoint() const
+{
+	// get face based on its surface area
+	float pdf[7];
+	pdf[0] = 0.0f;
+	int i;
+	for (i=0; i < 6; i++) {
+		pdf[i+1] = pdf[i] + GetFace(i).GetArea();
+	}
+	
+	float x = RandomValue(0, pdf[6]);
+	for (i=0; i < 6; i++) {
+		if (x < pdf[i])
+			break;
+	}
+
+	const int idx = i-1;
+	
+	const Rectangle3 face = GetFace(idx);
+	
+	Vector3 point = Vector3(0,0,0);
+	float sum = 0.0f;
+
+	for (i = 0; i < 4; ++ i) 
+	{
+		const float r = RandomValue(0, 1);
+		sum += r;
+		point += face.mVertices[i] * r;
+	}
+
+	point *= 1.0f / sum;
+
+	//normal = face.GetNormal();
+
+	return point;
+}
+
+
+}
+
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1772)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1824)
@@ -219,5 +219,10 @@
 		faceIndex < mFaces.size();
 		faceIndex++) {
-    hits += CastRayToFace(faceIndex, ray, nearestT, nearestNormal, nearestFace, instance);
+    hits += CastRayToFace(faceIndex,
+													ray,
+													nearestT,
+													nearestNormal,
+													nearestFace,
+													instance);
     if (mIsConvex && nearestFace != -1)
       break;
@@ -226,7 +231,13 @@
   if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
     if (ray.intersections.size())
-      ray.intersections[0] = Ray::Intersection(nearestT, nearestNormal, instance, nearestFace);
+      ray.intersections[0] = Ray::Intersection(nearestT,
+																							 nearestNormal,
+																							 instance,
+																							 nearestFace);
     else
-      ray.intersections.push_back(Ray::Intersection(nearestT, nearestNormal, instance, nearestFace));
+      ray.intersections.push_back(Ray::Intersection(nearestT,
+																										nearestNormal,
+																										instance,
+																										nearestFace));
   }
   
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1785)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1824)
@@ -386,5 +386,38 @@
 }
 
-}
-
-
+
+bool
+GlobalLinesDistribution::GenerateSample(SimpleRay &ray) const
+{
+	Vector3 origin, termination, direction; 
+	
+	origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
+
+	termination = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
+	
+	direction = termination - origin;
+	//direction = UniformRandomVector();
+
+
+	// $$ jb the pdf is yet not correct for all sampling methods!
+	const float c = Magnitude(direction);
+	if (c <= Limits::Small) 
+		return false;
+	
+	
+	direction *= 1.0f / c;
+	
+	// a little offset
+	//	origin += direction * 0.001f;
+	
+	// $$ jb the pdf is yet not correct for all sampling methods!
+	const float pdf = 1.0f;
+
+	ray = SimpleRay(origin, direction, pdf);
+	ray.mType = Ray::GLOBAL_RAY;
+	return true;
+}
+
+}
+
+
