Index: /GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env	(revision 685)
+++ /GTP/trunk/Lib/Vis/Preprocessing/scripts/default.env	(revision 697)
@@ -235,4 +235,9 @@
 		clipPlaneAxis 1
 		clipPlanePos 0.35
+	}
+
+	Filter {
+		width 10.0
+		maxSize 4
 	}
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 697)
@@ -345,5 +345,10 @@
 	void CollectRays(VssRayContainer &rays);
 
-
+	/** Intersects box with the tree and returns the number of intersected boxes.
+		@returns number of view cells found
+	*/
+	int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const;
+
+	// pointer to the hierarchy of view cells
 	ViewCellsTree *mViewCellsTree;
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 679)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 697)
@@ -54,7 +54,18 @@
 					   const float epsilon) const;
 
+	/** Computes the intersection of the box with the node geometry.
+	*/
+	int ComputeIntersection(const AxisAlignedBox3 &box) const;
+
 	/** Computes bounding box of the geometry.
 	*/
-	void IncludeInBox(AxisAlignedBox3 &box);
+	void GetBoundingBox(AxisAlignedBox3 &box) const;
+
+	/** Returns 
+		1 of geometry in front of plane
+		0 if plane intersects geometry,
+		-1 if geometry in back of plane
+	*/
+	int Side(const Plane3 &plane) const;
 
 	/** Splits the polygon and returns the part of the polygon inside of the node geometry.
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 647)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 697)
@@ -111,5 +111,5 @@
   void Include(const int &axis, const float &newBound);
 
-  
+
   int
   Side(const Plane3 &plane) const;
@@ -277,4 +277,8 @@
 
   Rectangle3 GetFace(const int face) const;
+ 
+  /** Extracts plane of bounding box.
+  */
+  Plane3 GetPlane(const int face) const;
   
   // For a given point returns the region, where the point is located
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/UnigraphicsParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/UnigraphicsParser.cpp	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/UnigraphicsParser.cpp	(revision 697)
@@ -14,5 +14,5 @@
 
 
-
+#define ROTATE_SCENE 1
 // HACK
 static void RotateMesh(Mesh *mesh)
@@ -158,5 +158,5 @@
       if (meshGrouping != 0 &&
 					currentMesh->mFaces.size() >=  meshGrouping) {
-		if (1)
+		if (ROTATE_SCENE)
 			RotateMesh(currentMesh);
 				currentMesh->Preprocess();
@@ -177,5 +177,5 @@
 	  if (1)
 		RotateMesh(currentMesh);
-  cout << "here9999" << endl;	  
+ 
     currentMesh->Preprocess();
     MeshInstance *mi = new MeshInstance(currentMesh);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 697)
@@ -35,8 +35,10 @@
 
 /** Probably Visible Set */
-class PrVs {
+class PrVs 
+{
+public:
   /// viewcells
-  ViewCellContainer mVviewCells;
-  /// aggregatred pvs
+  ViewCellContainer mViewCells;
+  /// aggregated pvs
   ObjectPvs mPvs;
 
@@ -62,4 +64,5 @@
   };
   
+
   /// view cell container types
   enum {BSP, KD, VSP_KD, VSP_BSP};
@@ -94,10 +97,10 @@
 		@param storeViewCells true if view cells should be stored in the ray
 	*/
-  float ComputeSampleContributions(const VssRayContainer &rays,
+	float ComputeSampleContributions(const VssRayContainer &rays,
 								   const bool addContributions,
 								   const bool storeViewCells);
 
-  /** Add sample contributions to the viewcells they intersect */
-  void AddSampleContributions(const VssRayContainer &rays);
+	/** Add sample contributions to the viewcells they intersect */
+	void AddSampleContributions(const VssRayContainer &rays);
   
 
@@ -218,9 +221,8 @@
 	virtual void GetPvsStatistics(PvsStatistics &stat);
 
-  virtual void GetPrVS(const Vector3 &viewPoint,
-					   PrVs &prvs
-					   ) {}
+	virtual void GetPrVS(const Vector3 &viewPoint, PrVs &prvs);
   
-  /** Get a viewcell containing the specified point */
+	/** Get a viewcell containing the specified point 
+	*/
 	virtual ViewCell *GetViewCell(const Vector3 &point) const = 0;
   
@@ -383,6 +385,17 @@
 	void EvalViewCellPartition(Preprocessor *preprocessor);
 
+
 protected:
 
+	/** Returns the bounding box of filter width.
+	*/
+	AxisAlignedBox3 GetFilterBBox(const Vector3 &viewPoint, const float width) const;
+
+	/** Intersects box with the tree and returns the number of intersected boxes.
+		@returns number of view cells found
+	*/
+	virtual int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const {return 0;};
+
+	virtual void TestFilter(const ObjectContainer &objects) {};
 
 	/**
@@ -486,7 +499,11 @@
 	/// if rays should be used to collect merge candidates
 	bool mUseRaysForMerge;
-	
+	/// merge the view cells?
 	bool mMergeViewCells;
-	
+
+	/// the width of the box filter
+	float mFilterWidth;
+	int mMaxFilterSize;
+
 	//-- visualization options
 	
@@ -783,8 +800,12 @@
 	void CollectMergeCandidates(const VssRayContainer &rays, vector<MergeCandidate> &candidates);
 
+	/** Returns true if this view cell is equivavalent to a spatial node.
+	*/
 	bool EqualToSpatialNode(ViewCell *viewCell) const;
 
+
 protected:
 
+	int ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const;
 	
 	/** Returns node of the spatial hierarchy corresponding to the view cell
@@ -818,4 +839,8 @@
 	ViewCell *ConstructSpatialMergeTree(BspNode *root);
 
+	void TestFilter(const ObjectContainer &objects);
+
+
+
 	/// the view space partition BSP tree.
 	VspBspTree *mVspBspTree;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 697)
@@ -28,4 +28,5 @@
 int VspBspTree::sFrontAndBackId = 0;
 
+typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
 
 
@@ -1889,4 +1890,77 @@
 
 
+int VspBspTree::ComputeBoxIntersections(const AxisAlignedBox3 &box, 
+										ViewCellContainer &viewCells) const
+{
+	stack<bspNodePair> nodeStack;
+	BspNodeGeometry *rgeom = new BspNodeGeometry();
+
+	ConstructGeometry(mRoot, *rgeom);
+
+	nodeStack.push(bspNodePair(mRoot, rgeom));
+  
+	ViewCell::NewMail();
+
+	while (!nodeStack.empty()) 
+	{
+		BspNode *node = nodeStack.top().first;
+		BspNodeGeometry *geom = nodeStack.top().second;
+		nodeStack.pop();
+
+		const int side = geom->ComputeIntersection(box);
+		
+		switch (side)
+		{
+		case -1:
+			// node geometry is contained in box
+			CollectViewCells(node, true, viewCells, true);
+			break;
+
+		case 0:
+			if (node->IsLeaf())
+			{
+				BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
+			
+				if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid())
+				{
+					leaf->GetViewCell()->Mail();
+					viewCells.push_back(leaf->GetViewCell());
+				}
+			}
+			else 
+			{
+				BspInterior *interior = dynamic_cast<BspInterior *>(node);
+			
+				BspNode *first = interior->GetFront();
+				BspNode *second = interior->GetBack();
+            
+				BspNodeGeometry *firstGeom = new BspNodeGeometry();
+				BspNodeGeometry *secondGeom = new BspNodeGeometry();
+
+				geom->SplitGeometry(*firstGeom,
+									*secondGeom,
+									interior->GetPlane(),
+									mBox,
+									//0.0000001f);
+									mEpsilon);
+
+				nodeStack.push(bspNodePair(first, firstGeom));
+				nodeStack.push(bspNodePair(second, secondGeom));
+			}
+			
+			break;
+		default:
+			// default: cull
+			break;
+		}
+		
+		DEL_PTR(geom);
+		
+	}
+
+	return (int)viewCells.size();
+}
+
+
 float VspBspTree::EvalAxisAlignedSplitCost(const VspBspTraversalData &data,
 										   const AxisAlignedBox3 &box,
@@ -2629,7 +2703,4 @@
 	}
 }
-
-
-typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
 
 
@@ -3281,6 +3352,5 @@
 		
 		AxisAlignedBox3 box;
-		box.Initialize();
-		geom->IncludeInBox(box);
+		geom->GetBoundingBox(box);
 
 		const int side = beam.ComputeIntersection(box);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 685)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 697)
@@ -1249,4 +1249,14 @@
 					"20000");
 
+	RegisterOption("ViewCells.Filter.maxSize",
+					optInt,
+					"view_cells_filter_max_size=",
+					"4");
+
+	RegisterOption("ViewCells.Filter.width",
+					optFloat,
+					"view_cells_filter_width=",
+					"10.0");
+
 	RegisterOption("ViewCells.loadFromFile",
 					optBool,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 697)
@@ -2915,4 +2915,71 @@
 
 
+void BspNodeGeometry::GetBoundingBox(AxisAlignedBox3 &box) const
+{
+	box.Initialize();
+	Polygon3::IncludeInBox(mPolys, box);
+}
+
+
+int BspNodeGeometry::Side(const Plane3 &plane) const
+{
+	PolygonContainer::const_iterator it, it_end = mPolys.end();
+
+	bool onFrontSide = false;
+	bool onBackSide = false;
+
+	for (it = mPolys.begin(); it != it_end; ++ it)
+	{
+        const int side = (*it)->Side(plane, 0.0f);
+
+		if (side == -1)
+			onBackSide = true;
+		else if (side == 1)
+			onFrontSide = true;
+		
+		if ((side == 0) || (onBackSide && onFrontSide))
+			return 0;
+	}
+
+	if (onFrontSide)
+		return 1;
+
+	return -1;
+}
+
+
+int BspNodeGeometry::ComputeIntersection(const AxisAlignedBox3 &box) const
+{
+	AxisAlignedBox3 boundingBox;
+	GetBoundingBox(boundingBox);
+
+	const bool overlap = Overlap(boundingBox, box);
+
+	// no intersections with bounding box
+	if (!overlap)
+	{
+		return 1;
+	}
+	int result = -1;
+
+	// 1: box does not intersect geometry
+	// 0: box intersects geometry
+	// -1: box contains geometry
+	for (int i = 0; i < 6; ++ i) 
+	{		
+		const int side = Side(box.GetPlane(i));
+		
+		// box does not intersects geometry
+		if (side == 1)
+			return 1;
+
+		if (side == 0)
+            result = 0;
+  }
+
+  return result;
+}
+
+
 Vector3 BspNodeGeometry::CenterOfMass() const
 {
@@ -3154,10 +3221,4 @@
 
 
-void BspNodeGeometry::IncludeInBox(AxisAlignedBox3 &box)
-{
-	Polygon3::IncludeInBox(mPolys, box);
-}
-
-
 bool BspTree::Export(ofstream &stream)
 {
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h	(revision 639)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Plane3.h	(revision 697)
@@ -40,4 +40,7 @@
   }
 
+  enum {BACK_SIDE = -1, INTERSECTS = 0, FRONT_SIDE = 1};
+		 
+		
   /** Returns 1 if v is on front side, -1 if on back side, 0 if on plane.
   */
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VssPreprocessor.cpp	(revision 697)
@@ -852,2 +852,4 @@
   return true;
 }
+
+
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 557)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 697)
@@ -1570,4 +1570,29 @@
 }
 
+
+Plane3 AxisAlignedBox3::GetPlane(const int face) const
+{
+	switch (face) 
+	{
+        
+	case 0:
+		return Plane3(Vector3(-1, 0, 0), mMin);
+	case 1: 
+		return Plane3(Vector3(1, 0, 0), mMax);
+	case 2:
+		return Plane3(Vector3(0, -1, 0), mMin);
+	case 3:
+		return Plane3(Vector3(0, 1, 0), mMax);
+	case 4:
+		return Plane3(Vector3(0, 0, -1), mMin);
+	case 5:
+		return Plane3(Vector3(0, 0, 1), mMax);
+	}
+
+	// should not come here
+	return Plane3();
+}
+
+
 int
 AxisAlignedBox3::GetFaceVisibilityMask(const Rectangle3 &rectangle) const
@@ -1578,4 +1603,5 @@
   return mask;
 }
+
 
 int
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 694)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 697)
@@ -19,4 +19,20 @@
 #define TEST_EMPTY_VIEW_CELLS 0
 
+
+
+template <typename T> class myless
+{
+public:
+	//bool operator() (HierarchyNode *v1, HierarchyNode *v2) const
+	bool operator() (T v1, T v2) const
+	{
+		return (v1->GetMergeCost() < v2->GetMergeCost());
+	}
+};
+
+typedef priority_queue<ViewCell *, vector<ViewCell *>, myless<vector<ViewCell *>::value_type> > FilterQueue;
+
+
+
 ViewCellsManager::ViewCellsManager():
 mRenderer(NULL),
@@ -67,5 +83,7 @@
 	environment->GetBoolValue("ViewCells.evaluateViewCells", mEvaluateViewCells);
 	environment->GetBoolValue("ViewCells.showVisualization", mShowVisualization);
-	
+	environment->GetIntValue("ViewCells.Filter.maxSize", mMaxFilterSize);
+	environment->GetFloatValue("ViewCells.Filter.width", mFilterWidth);
+
 	char buf[100];
 	environment->GetStringValue("ViewCells.samplingType", buf);
@@ -118,4 +136,5 @@
 	Debug << "sampling type: " << mSamplingType << endl;
 	Debug << "show visualization: " << mShowVisualization << endl;
+	Debug << "filter width: " << mFilterWidth << endl;
 
 	Debug << endl;
@@ -173,5 +192,5 @@
 			{
 				Ray *pray = (*it)->mPiercingRays[0];
-				Debug << "view cell " << (*it)->GetId() << " not empty, pvs: " << (*it)->GetPvs().GetSize() << " " << pray->intersections.size() << endl;
+				Debug << "view cell " << (*it)->GetId() << " not empty, pvs: " << (*it)->GetPvs().GetSize() << " " << (int)pray->intersections.size() << endl;
 
 				exporter->ExportRays((*it)->mPiercingRays);
@@ -282,4 +301,9 @@
 	disposeRays(initialSamples, outRays);
 	
+	cout << "testing filter ... ";
+
+	TestFilter(preprocessor->mObjects);
+
+	cout << "finished" << endl;
 
 	// -- stats after contruction
@@ -533,4 +557,25 @@
 
   return true;
+}
+
+
+AxisAlignedBox3 ViewCellsManager::GetFilterBBox(const Vector3 &viewPoint, 
+												const float width) const
+{
+	Vector3 min = viewPoint - width * 0.5f;
+	Vector3 max = viewPoint + width * 0.5;
+
+	return AxisAlignedBox3(min, max);
+}
+
+
+void ViewCellsManager::GetPrVS(const Vector3 &viewPoint, PrVs &prvs)
+{
+	const AxisAlignedBox3 box = GetFilterBBox(viewPoint, mFilterWidth);
+
+	ViewCellContainer viewCells;
+	ComputeBoxIntersections(box, viewCells);
+
+		
 }
 
@@ -2767,7 +2812,5 @@
 		mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells);
 	}
-
-}
-
+}
 
 
@@ -3524,4 +3567,10 @@
 
 
+int VspBspViewCellsManager::ComputeBoxIntersections(const AxisAlignedBox3 &box, ViewCellContainer &viewCells) const
+{
+	return mVspBspTree->ComputeBoxIntersections(box, viewCells);
+}
+
+
 int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,
 											const Vector3 &termination,
@@ -3859,4 +3908,8 @@
 		newVol += lVol;
 		subdivVol += (*it)->GetVolume();
+		
+		float thres = 0.9;
+		if ((lVol < ((*it)->GetVolume() * thres)) || (lVol * thres > ((*it)->GetVolume())))
+			Debug << "warning: " << lVol << " " << (*it)->GetVolume() << endl;
 	}
 	
@@ -3874,4 +3927,42 @@
 }
 
+
+void VspBspViewCellsManager::TestFilter(const ObjectContainer &objects)
+{
+	Exporter *exporter = Exporter::GetExporter("filter.x3d");
+
+	if (exporter)
+	{
+		AxisAlignedBox3 testBox = mViewSpaceBox;
+		Vector3 bsize = mViewSpaceBox.Size();
+
+		testBox.Enlarge(Vector3(-bsize[0] * 0.3, 0, -bsize[2] * 0.4));
+		
+		ViewCellContainer viewCells;
+        
+		mVspBspTree->ComputeBoxIntersections(testBox, viewCells);
+		cout << "view cells: " << viewCells.size() << endl;
+		
+		exporter->SetWireframe();
+
+		exporter->SetForcedMaterial(RgbColor(1,1,1));
+		exporter->ExportBox(testBox);
+		
+		exporter->SetFilled();
+		exporter->ResetForcedMaterial();
+        for (int i = 0; i < viewCells.size(); ++ i)
+		{
+			BspNodeGeometry geom;
+				
+			mVspBspTree->ConstructGeometry(viewCells[i], geom);
+			exporter->ExportPolygons(geom.GetPolys());
+		}		
+
+		exporter->SetForcedMaterial(RgbColor(1,0,0));
+		exporter->ExportGeometry(objects);
+
+		delete exporter;
+	}
+}
 
 
