Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1996)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.h	(revision 1999)
@@ -150,5 +150,5 @@
 		with respect to the previous ray.
 	*/
-	void EnqueueRays(VssRayContainer &samples);
+	void EnqueueRays(VssRayContainer &samples, VssRayContainer &invalidSamples);
 
 	/** Hepler function for adaptive border sampling. It finds 
@@ -191,4 +191,5 @@
 
 	void VisualizeViewCell(ViewCell *vc);
+	void VisualizeViewCell(const ObjectContainer &objects);
 
 	/** Exchanges view cell triangle pvs with bvh leaf pvs.
@@ -201,4 +202,9 @@
 	void CompileViewCellsList();
 
+	void GetObjectPvs(ObjectContainer &trianglePvs) const;
+
+	bool HasContribution(VssRay &ray);
+
+	void IntersectWithViewCell();
 
 	//////////////////////
@@ -220,10 +226,4 @@
 	// stats
 
-	/*int mSampleContriPerPass;
-	int mTotalSampleContri;
-	int mReverseSamples;
-	int mBorderSamples;
-	int mGvsPass;*/
-
 	ofstream mGvsStatsStream;
 	GvsStatistics mGvsStats;
@@ -241,4 +241,6 @@
 
 	int mMaxViewCells;
+
+	ObjectContainer mTrianglePvs;
 };
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1996)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1999)
@@ -211,4 +211,5 @@
 	DEL_PTR(renderer);
 	DEL_PTR(mRayCaster);
+
 #ifdef USE_CG
 	DEL_PTR(mGlobalLinesRenderer);
@@ -1110,15 +1111,4 @@
 	cout << mKdTree->GetBox() << endl;
 
-	if (0)
-	{
-		Exporter *exporter = Exporter::GetExporter("dummykd.x3d");
-			
-		if (exporter)
-		{
-			exporter->ExportKdTree(*mKdTree, true);
-			delete exporter;
-		}
-	}
-
 	int rayCastMethod;
 	Environment::GetSingleton()->
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1941)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1999)
@@ -205,5 +205,5 @@
 
 BvhInterior::~BvhInterior() 
-{ 
+{
 	DEL_PTR(mFront); 
 	DEL_PTR(mBack);
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1990)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1999)
@@ -311,9 +311,9 @@
 	// question: rather create view cells resource manager?
 	if (!ViewCellsTreeConstructed())
-	{
+	{cout << "here6" << endl;
 		CLEAR_CONTAINER(mViewCells);
 	}
 	else
-	{
+	{cout << "here7" << endl;
 		DEL_PTR(mViewCellsTree);
 	}
@@ -682,16 +682,24 @@
 	if (success)
 	{
-		//vm->ResetViewCells();
-		//hack
-		vm->mViewCells.clear();
-		ViewCellContainer leaves;
-		vm->mViewCellsTree->CollectLeaves(vm->mViewCellsTree->GetRoot(), leaves);
-
-		ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-		for (it = leaves.begin(); it != it_end; ++ it)
-		{
-			vm->mViewCells.push_back(*it);
-		}
+		if (0)
+		{
+			vm->ResetViewCells();
+		}
+		else
+		{
+			//hack: should work with reset function
+			ViewCellContainer leaves;
+
+			vm->mViewCells.clear();
+			vm->mViewCellsTree->CollectLeaves(vm->mViewCellsTree->GetRoot(), leaves);
+		
+			ViewCellContainer::const_iterator it, it_end = leaves.end();
+
+			for (it = leaves.begin(); it != it_end; ++ it)
+			{
+				vm->mViewCells.push_back(*it);
+			}
+		}
+
 		vm->mViewCellsFinished = true;
 		vm->mMaxPvsSize = (int)objects->size();
@@ -2943,5 +2951,4 @@
 							   )
 {
-  //cout<<"y";
   PvsFilterStatistics stats;
 
@@ -6387,8 +6394,5 @@
 	ViewCellsManager *vm = 
 		ViewCellsManager::LoadViewCells(filename, objects, finalizeViewCells, bconverter);
-#if 0
-	// insert scene objects in tree
-	mOspTree->InsertObjects(mOspTree->GetRoot(), *objects);
-#endif
+
 	return vm;
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1890)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1999)
@@ -517,5 +517,5 @@
 
 ViewCellsTree::~ViewCellsTree()
-{
+{cout<<"here1002";
 	DEL_PTR(mRoot);
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1996)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1999)
@@ -73,5 +73,5 @@
 	if (castDoubleRay)
 	{
-	  cerr<<"HERE"<<endl;
+	  //cerr<<"HERE"<<endl;
 	  Vector3 dir = -simpleRay.mDirection;
 		hittriangle = mlrtaIntersectAS(
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1995)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1999)
@@ -13,4 +13,5 @@
 class Polygon3;
 class Mesh;
+struct Triangle3;
 
 /**
@@ -358,4 +359,10 @@
   void ExtractPolys(PolygonContainer &polys) const;
 
+  /** Returns true if the mesh intersects the bounding box.
+  */
+  bool Intersects(const Mesh &mesh) const;
+   /** Returns true if the triangle intersects the bounding box.
+  */
+  bool Intersects(const Triangle3 &tri) const;
   /** Splits the box into two separate boxes with respect to the split plane
   */
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1995)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1999)
@@ -38,4 +38,10 @@
 	DEL_PTR(mFront);
 	DEL_PTR(mBack);
+}
+
+
+KdLeaf::~KdLeaf()
+{
+	DEL_PTR(mViewCell);  
 }
 
@@ -77,5 +83,7 @@
 KdTree::~KdTree()
 {
-	DEL_PTR(mRoot);
+    DEL_PTR(mRoot);
+
+	CLEAR_CONTAINER(mKdIntersectables);
 }
 
@@ -1439,4 +1447,5 @@
 }
 
+
 KdIntersectable *
 KdTree::GetOrCreateKdIntersectable(KdNode *node)
@@ -1532,61 +1541,38 @@
 
 
-void KdTree::InsertObjects(KdNode *node, const ObjectContainer &objects)
-{/*
-	stack<KdObjectsTraversalData> tStack;
+void KdTree::GetBoxIntersections(const AxisAlignedBox3 &box,
+								 vector<KdLeaf *> &leaves)
+{
+	stack<KdNode *> tStack;
+
+	tStack.push(mRoot);
 
 	while (!tStack.empty())
 	{
-		KdObjectsTraversalData tData = tStack.top();
-        tStack.pop();
-
-		KdNode *node = tData.node;
+		KdNode *node = tStack.top();
+		tStack.pop();
 		
 		if (node->IsLeaf())
 		{
-			KdLeaf *leaf = dynamic_cast<KdLeaf *>(node);
-
-			ObjectContainer::const_iterator oit, oit_end = tData.objects->end();
-
-			for (oit = tData.objects->begin(); oit != oit_end; ++ oit)
-			{
-				leaf->mObjects.push_back(*oit);
-			}
+			leaves.push_back(dynamic_cast<KdLeaf *>(node));
 		}
 		else // interior
 		{
-			KdObjectsTraversalData frontData, backData;
 			KdInterior *interior = dynamic_cast<KdInterior *>(node);
 
-			frontData.objects = new ObjectContainer();
-			backData.objects = new ObjectContainer();
-
-			ObjectContainer::const_iterator oit, oit_end = tData.objects->end();
-			
-		    for (oit = tData.objects->begin(); oit != oit_end; ++ oit) 
+			if (box.Max(interior->mAxis) >= interior->mPosition)
 			{
-				Intersectable *object = *oit;
-		
-				// determine the side of this ray with respect to the plane
-				const AxisAlignedBox3 box = object->GetBox();
-
-				if (box.Max(interior->mAxis) >= interior->mPosition)
-				{
-					frontData.objects->push_back(object);
-				}
-
-				if (box.Min(interior->mAxis) < interior->mPosition)
-				{
-					backData.objects->push_back(object);
-				}
+				tStack.push(interior->mFront);
 			}
 
-			tStack.push(backData);
-			tStack.push(frontData);
-		}
-
-		DEL_PTR(tData.objects);
-	}*/
-}
-
-}
+			if (box.Min(interior->mAxis) < interior->mPosition)
+			{
+				tStack.push(interior->mBack);
+			}
+		}
+	}
+}
+
+
+
+}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1867)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1999)
@@ -108,5 +108,4 @@
 	
 	int mPvsSizeDecr;
-
   
 	float mVolume;
@@ -153,4 +152,5 @@
 
 public:
+
 	ViewCell();
 
@@ -243,7 +243,8 @@
 	}
 
-  static bool GreaterOrEqualPvs(const ViewCell *a, const ViewCell *b) {
-	return !SmallerPvs(a, b);
-  }
+	static bool GreaterOrEqualPvs(const ViewCell *a, const ViewCell *b) 
+	{
+		return !SmallerPvs(a, b);
+	}
 
 	static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b) 
@@ -260,5 +261,5 @@
 		@hack The function is available for leaves also to have a common interface,
 		but it should be less than zero for leaves.
-		*/
+	*/
 	void SetMergeCost(const float mergeCost);
 
@@ -269,32 +270,32 @@
 	float GetMergeCost() const;
 
-  void UpdatePvsCost() {
-	mPvsCost = GetPvs().EvalPvsCost();
-  }
-
-  void SetPvsCost(const float c) {
-	mPvsCost = c;
-  }
-
-  float GetPvsCost() const {
-	return mPvsCost;
-  }
+	void UpdatePvsCost() {
+		mPvsCost = GetPvs().EvalPvsCost();
+	}
+
+	void SetPvsCost(const float c) {
+		mPvsCost = c;
+	}
+
+	float GetPvsCost() const {
+		return mPvsCost;
+	}
 
 	//////////
 	//-- mailing stuff
 
-  //	static void NewMail(const int reserve = 1) 
-  //	{
-  //		sMailId += sReservedMailboxes;
-  //		sReservedMailboxes = reserve;
-  //	}
-
-  //	void Mail() { mMailbox = sMailId; }
-  //	bool Mailed() const { return mMailbox == sMailId; }
-
-  //	void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
-  //	bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
-
-  //	int IncMail() { return ++ mMailbox - sMailId; }
+	//	static void NewMail(const int reserve = 1) 
+	//	{
+	//		sMailId += sReservedMailboxes;
+	//		sReservedMailboxes = reserve;
+	//	}
+
+	//	void Mail() { mMailbox = sMailId; }
+	//	bool Mailed() const { return mMailbox == sMailId; }
+
+	//	void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
+	//	bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
+
+	//	int IncMail() { return ++ mMailbox - sMailId; }
 
 
@@ -302,13 +303,14 @@
 	// both mailId and mailbox should be unique for each thread!!!
 
-  //static int sMailId;
-  //static int sReservedMailboxes;
-	
-  int GetFilteredPvsSize() const {
-	return mFilteredPvsSize;
-  }
-
-  void SetFilteredPvsSize(const int s) {
-	mFilteredPvsSize = s;
+	//static int sMailId;
+	//static int sReservedMailboxes;
+
+	int GetFilteredPvsSize() const 
+	{
+		return mFilteredPvsSize;
+	}
+
+	void SetFilteredPvsSize(const int s) {
+		mFilteredPvsSize = s;
   }
 
@@ -341,6 +343,7 @@
 	bool mPvsSizeValid;
 
-  /// Filter cost of the pvs
-  int mFilteredPvsSize;
+
+	/// Filter cost of the pvs
+	int mFilteredPvsSize;
 
 };
@@ -356,5 +359,5 @@
 
 	ViewCellInterior(Mesh *mesh);
-	
+
 	/** Sets pointer from parent to child and vice versa.
 	*/
@@ -368,14 +371,15 @@
 		mCost = c;
 	}
-	
+
 	float GetCost() const {
 		return mCost;
 	}
-  
-  ViewCellContainer mChildren;
+
+	ViewCellContainer mChildren;
 
 protected:
-  /** overall cost resulting from the merge */
-  float mCost;
+
+	/// Pverall cost resulting from the merge.
+	float mCost;
 };
 
@@ -449,5 +453,7 @@
 
 public:
+
 	ViewCellsTree();
+
 	/** View cells tree constructor taking a view cell mnanager as parameter
 	*/
@@ -509,5 +515,4 @@
 	float GetPvsCost(ViewCell *vc) const;
   
-
 	/** Returns number of entries associated with this view cell. 
 
@@ -587,7 +592,9 @@
 	void ReadEnvironment();
 
-	/////////////////////////////////////////////////////////////////
-	//                    merge related stuff                      //
-	/////////////////////////////////////////////////////////////////
+
+	//////////////////////////////////////////////////////////////
+	//                    merge related stuff                   //
+	//////////////////////////////////////////////////////////////
+
 
 	/** Computes render cost of the merged pvs.
@@ -623,5 +630,5 @@
 		@returns difference in pvs size
 	*/
-	ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, float &pvsDiff); //const;
+	ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, float &pvsDiff);
 
 	/** Shuffles, i.e. takes border leaf from view cell 1 and adds it 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1989)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1999)
@@ -192,5 +192,5 @@
   }
 
-  ~KdLeaf() { DEL_PTR(mViewCell);  }
+  ~KdLeaf();
 	
 	void AddPassingRay2(const Ray &ray,
@@ -411,4 +411,7 @@
   KdNode *
   GetNode(const Vector3 &point, const float maxArea) const;
+
+  void GetBoxIntersections(const AxisAlignedBox3 &box, 
+						  vector<KdLeaf *> &leaves);
 
   int
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1970)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1999)
@@ -211,5 +211,5 @@
 	////////////
 	//-- initialize external ray caster
-	
+
 	if (preprocessor->InitRayCast(externKdTree, internKdTree))
 	{
@@ -258,5 +258,5 @@
 	}
 	
-	
+
 	bool useHwGlobalLines;
 	Environment::GetSingleton()->GetBoolValue("Preprocessor.useHwGlobalLines",
@@ -272,5 +272,4 @@
 	
 	preprocessor->PrepareHwGlobalLines();
-
 	globalLinesRenderer->Run();
 
@@ -367,6 +366,8 @@
 	}	
 #endif
+
 	// release memory
 	Cleanup();
+	delete pt;
 
 	return returnCode;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1990)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1999)
@@ -32,12 +32,5 @@
 class Intersectable {
 public:
-  // last mail id -> warning not thread safe!
-  // both mailId and mailbox should be unique for each thread!!!
-  static int sMailId;
-  static int sReservedMailboxes;
-
-  /// Mailbox used for traversals
-  int mMailbox;
-  
+ 
   /// unique object Id
   int mId;
@@ -101,4 +94,13 @@
   int IncMail() { return ++ mMailbox - sMailId; }
 
+   // last mail id -> warning not thread safe!
+  // both mailId and mailbox should be unique for each thread!!!
+  static int sMailId;
+  static int sReservedMailboxes;
+
+  /// Mailbox used for traversals
+  int mMailbox;
+  
+
   ////////////////////////////////////////////////////
   virtual AxisAlignedBox3 GetBox() const = 0;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 1623)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 1999)
@@ -97,5 +97,5 @@
  // typedef map<int, ViewCell *> ViewCellsMap;
   //ViewCellsMap mViewCells;
-ViewCellContainer mViewCells;
+  ViewCellContainer mViewCells;
 
   ViewCellsManager *mViewCellsManager;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1996)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1999)
@@ -16,5 +16,5 @@
 {
   
-#define GVS_DEBUG 0
+#define GVS_DEBUG 1
 
 struct VizStruct
@@ -31,6 +31,6 @@
 GvsPreprocessor::GvsPreprocessor(): 
 Preprocessor(), 
-mSamplingType(SamplingStrategy::VIEWCELL_BASED_DISTRIBUTION),
-//mSamplingType(SamplingStrategy::DIRECTION_BASED_DISTRIBUTION),
+//mSamplingType(SamplingStrategy::VIEWCELL_BASED_DISTRIBUTION),
+mSamplingType(SamplingStrategy::DIRECTION_BASED_DISTRIBUTION),
 mProcessedViewCells(0),
 mCurrentViewCell(NULL)
@@ -144,60 +144,68 @@
 			delete newRay;
 		}
-		else if (0 && GVS_DEBUG && (mVssRays.size() < 9))
+		
+
+		return 1;
+	}
+
+	return 0;
+}
+
+// #id: 1270
+bool GvsPreprocessor::HasContribution(VssRay &ray)
+{
+	if (!ray.mTerminationObject)
+		return false;
+
+	bool result;
+
+	if (!mPerViewCell)
+	{
+		// store the rays + the intersected view cells
+		const bool storeViewCells = false; //GVS_DEBUG;
+
+		mViewCellsManager->ComputeSampleContribution(ray, 
+													 true, 
+													 storeViewCells,
+													 true);
+
+		result = ray.mPvsContribution > 0;
+	}
+	else
+	{
+		Intersectable *obj = ray.mTerminationObject;
+
+		if (!obj->mCounter)
 		{
-			mVssRays.push_back(new VssRay(oldRay));
-			mVssRays.push_back(new VssRay(currentRay));
-			mVssRays.push_back(new VssRay(*newRay));
-		}
-
-		return 1;
-	}
-
-	return 0;
-}
-
-
-bool GvsPreprocessor::HandleRay(VssRay *vssRay)
-{
-	// store the rays + the intersected view cells
-	const bool storeRaysForViz = false; //GVS_DEBUG;
-
-	if (!mPerViewCell)
-	{
-		mViewCellsManager->ComputeSampleContribution(*vssRay, 
-													 true, 
-													 storeRaysForViz,
-													 true);
-	}
-	else
-	{
-		mViewCellsManager->ComputeSampleContribution(*vssRay, 
+			obj->mCounter = 1;
+			mTrianglePvs.push_back(obj);
+
+			/*mViewCellsManager->ComputeSampleContribution(ray, 
 													 true, 
 													 mCurrentViewCell,
-													 true);
-	}
-
-	// some pvs contribution for this ray?
-	if (!vssRay->mPvsContribution)
+													 true);*/
+			
+			result = true;
+		}
+		else
+		{
+			result = false;
+		}
+	}
+
+	return result;
+}
+
+
+bool GvsPreprocessor::HandleRay(VssRay *vssRay)
+{
+	if (!HasContribution(*vssRay))
 		return false;
 
-	if (GVS_DEBUG)
+	if (0 && GVS_DEBUG)
 		mVssRays.push_back(new VssRay(*vssRay));
 
 	// add new ray to ray queue
 	mRayQueue.push(vssRay);
-
-	if (storeRaysForViz)
-	{
-		VssRay *nray = new VssRay(*vssRay);
-		nray->mFlags = vssRay->mFlags;
-
-		// store ray in contributing view cell
-		ViewCellContainer::const_iterator vit, vit_end = vssRay->mViewCells.end();
-		for (vit = vssRay->mViewCells.begin(); vit != vit_end; ++ vit)
-		{			
-			(*vit)->GetOrCreateRays()->push_back(nray);				
-		}
-	}
 
 	++ mGvsStats.mTotalContribution;
@@ -399,9 +407,11 @@
 	}
 
+	int castRays = (int)simpleRays.size();
+
+	VssRayContainer invalidSamples;
+
 	// handle rays
-	EnqueueRays(vssRays);
-	
-	int castRays = simpleRays.size();
-	
+	EnqueueRays(vssRays, invalidSamples);
+
     // recursivly subdivide each edge
 	for (int i = 0; i < numBorderSamples; ++ i)
@@ -414,6 +424,8 @@
 								  currentRay);
 	}
-
+	
 	mGvsStats.mBorderSamples += castRays;
+
+	CLEAR_CONTAINER(invalidSamples);
 
 	return castRays;
@@ -442,5 +454,5 @@
 	if (!intersects)
 	{
-		cerr << "big error!! no intersection " << pt1 << " " << pt2 << endl;
+		//cerr << "big error!! no intersection " << pt1 << " " << pt2 << endl;
 		return false;
 	}
@@ -562,7 +574,10 @@
 	CastRays(simpleRays, samples, castDoubleRays, pruneInvalidRays);
 	
+	VssRayContainer invalidSamples;
+
 	// add to ray queue
-	EnqueueRays(samples);
-
+	EnqueueRays(samples, invalidSamples);
+
+	CLEAR_CONTAINER(invalidSamples);
 	//Debug << "generated " <<  numSamples << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
 	return (int)simpleRays.size();
@@ -570,5 +585,5 @@
 
 
-void GvsPreprocessor::EnqueueRays(VssRayContainer &samples)
+void GvsPreprocessor::EnqueueRays(VssRayContainer &samples, VssRayContainer &invalidSamples)
 {
 	// add samples to ray queue
@@ -576,5 +591,8 @@
 	for (vit = samples.begin(); vit != vit_end; ++ vit)
 	{
-		HandleRay(*vit);
+		VssRay *ray = *vit;
+
+		if (!HandleRay(ray))
+			invalidSamples.push_back(ray);
 	}
 }
@@ -597,5 +615,5 @@
 		castSamples += newSamples;
 
-		//cout << newSamples << " ";	
+		//cout << "new samples: " << newSamples << " " << "queue: "  << (int)mRayQueue.size() << endl;
 		delete ray;
 	}
@@ -639,5 +657,6 @@
 
 
-void GvsPreprocessor::VisualizeViewCell(ViewCell *vc)
+//void GvsPreprocessor::VisualizeViewCell(ViewCell *vc)
+void GvsPreprocessor::VisualizeViewCell(const ObjectContainer &objects)
 {
     Intersectable::NewMail();
@@ -651,5 +670,5 @@
 		return;
 
-	ObjectPvsIterator pit = vc->GetPvs().GetIterator();
+	/*ObjectPvsIterator pit = vc->GetPvs().GetIterator();
 
 	// output PVS of view cell
@@ -669,4 +688,14 @@
 
 		exporter->ExportIntersectable(intersect);
+	}*/
+	ObjectContainer::const_iterator oit, oit_end = objects.end();
+
+	for (oit = objects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *intersect = *oit;
+		
+		m = RandomMaterial();
+		exporter->SetForcedMaterial(m);
+		exporter->ExportIntersectable(intersect);
 	}
 
@@ -682,5 +711,9 @@
 	exporter->SetForcedMaterial(m);
 
-	mViewCellsManager->ExportViewCellGeometry(exporter, vc, NULL, NULL);
+	//mViewCellsManager->ExportViewCellGeometry(exporter, vc, NULL, NULL);
+	//mViewCellsManager->ExportViewCellGeometry(exporter, mCurrentViewCell, NULL, NULL);
+
+	AxisAlignedBox3 bbox = mCurrentViewCell->GetMesh()->mBox;
+	exporter->ExportBox(bbox);
 	//exporter->SetFilled();
 
@@ -720,4 +753,8 @@
 void GvsPreprocessor::ProcessViewCell()
 {
+	//Intersectable::NewMail();
+	// compute direct intersections with view cell
+	IntersectWithViewCell();
+
 	mGvsStats.mPerViewCellSamples = 0;
 	int oldContribution = mGvsStats.mTotalContribution;
@@ -736,5 +773,5 @@
 		passSamples += newSamples;
 		mGvsStats.mPerViewCellSamples += newSamples;
-		//cout << "here4 " << passSamples % (mSamplesPerPass + 1) << endl;
+		//cout << "here2 " << passSamples % (mSamplesPerPass + 1) << endl;
 
 		if (passSamples >= mSamplesPerPass)
@@ -774,30 +811,62 @@
 		{
 			mViewCells.push_back(mViewCellsManager->GetViewCell((int)mViewCells.size()));
+			continue;
 		}
-		else
+		
+		// HACK
+		const int tries = 10000;
+		int i = 0;
+
+		for (i = 0; i < tries; ++ i)
 		{
-			// HACK
-			const int tries = 10000;
-			int i = 0;
-
-			for (i = 0; i < tries; ++ i)
+			const int idx = (int)RandomValue(0.0f, (float)mViewCellsManager->GetNumViewCells() - 0.5f);
+	
+			ViewCell *viewCell = mViewCellsManager->GetViewCell(idx);
+
+			if (!viewCell->Mailed())
 			{
-				const int idx = (int)RandomValue(0.0f, (float)mViewCellsManager->GetNumViewCells() - 0.5f);
-	
-				ViewCell *viewCell = mViewCellsManager->GetViewCell(idx);
-
-				if (!viewCell->Mailed())
+				viewCell->Mail();
+				break;
+			}
+
+			mViewCells.push_back(viewCell);
+		}
+
+		if (i == tries)
+		{
+			cerr << "big error! no view cell found" << endl;
+			return;
+		}
+	}
+}
+
+
+void GvsPreprocessor::IntersectWithViewCell()
+{
+	mCurrentViewCell->GetMesh()->ComputeBoundingBox();
+	AxisAlignedBox3 box = mCurrentViewCell->GetMesh()->mBox;
+	//cout << "box: " << box << endl;
+	vector<KdLeaf *> leaves;
+
+	mKdTree->GetBoxIntersections(box, leaves);
+
+	vector<KdLeaf *>::const_iterator lit, lit_end = leaves.end();
+
+	for (lit = leaves.begin(); lit != leaves.end(); ++ lit)
+	{
+		KdLeaf *leaf = *lit;
+		ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+		for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+		{
+			TriangleIntersectable *triObj = dynamic_cast<TriangleIntersectable *>(*oit);
+
+			if (box.Intersects(triObj->GetItem()))
+			{
+				if (!triObj->mCounter)
 				{
-					viewCell->Mail();
-					break;
+					triObj->mCounter = 1;
+					mTrianglePvs.push_back(triObj);
 				}
-
-				mViewCells.push_back(viewCell);
-			}
-
-			if (i == tries)
-			{
-				cerr << "big error! no view cell found" << endl;
-				return;
 			}
 		}
@@ -808,21 +877,31 @@
 void GvsPreprocessor::PerViewCellComputation()
 {
+	// hack: reset counter
+	ObjectContainer::const_iterator oit, oit_end = mObjects.end();
+
+	for (oit = mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		(*oit)->mCounter = 0;
+	}
+
 	while (NextViewCell())
 	{
-		cout << "\n***********************\nprocessing view cell " << mProcessedViewCells << endl;
+		cout << "\n***********************\n" 
+			 << "processing view cell " << mProcessedViewCells 
+			 << " (id: " << mCurrentViewCell->GetId() << ")" << endl;
 
 		// compute the pvs of the current view cell
 		ProcessViewCell();
 
-		mGvsStats.mTrianglePvs = mCurrentViewCell->GetPvs().GetSize();
+		//mGvsStats.mTrianglePvs = mCurrentViewCell->GetPvs().GetSize();
+		mGvsStats.mTrianglePvs = (int)mTrianglePvs.size();
+
+		ObjectContainer objectPvs;
 
 		// exchange triangle pvs with objects
-		UpdatePvs(mCurrentViewCell);
-
-		if (GVS_DEBUG)
-		{
-			VisualizeViewCell(mCurrentViewCell);
-			CLEAR_CONTAINER(mVssRays);
-		}
+		//UpdatePvs(mCurrentViewCell);
+		GetObjectPvs(objectPvs);
+
+		cout << "triangle pvs of " << (int)mTrianglePvs.size() << " was converted to object pvs of " << (int)objectPvs.size() << endl;
 
 		////////
@@ -830,10 +909,21 @@
 		
 		mGvsStats.mViewCells = mProcessedViewCells;//mPass;
-		mGvsStats.mPerViewCellPvs = mCurrentViewCell->GetPvs().GetSize();
-		mGvsStats.mTotalPvs += mCurrentViewCell->GetPvs().GetSize();
+		//mGvsStats.mPerViewCellPvs = mCurrentViewCell->GetPvs().GetSize();
+		mGvsStats.mPerViewCellPvs = (int)mTrianglePvs.size();
+
+		mGvsStats.mTotalPvs += mGvsStats.mPerViewCellPvs;
 		mGvsStats.mTotalSamples += mGvsStats.mPerViewCellSamples;
 
 		mGvsStats.Stop();
 		mGvsStats.Print(mGvsStatsStream);
+
+		mTrianglePvs.clear();
+
+		if (GVS_DEBUG)
+		{
+			//VisualizeViewCell(mCurrentViewCell);
+			VisualizeViewCell(objectPvs);
+			CLEAR_CONTAINER(mVssRays);
+		}
 
 		// is this really necessary?
@@ -871,4 +961,28 @@
 
 	currentViewCell->SetPvs(newPvs);
+}
+
+ 
+void GvsPreprocessor::GetObjectPvs(ObjectContainer &objectPvs) const
+{
+	BvhLeaf::NewMail();
+
+	ObjectContainer::const_iterator oit, oit_end = mTrianglePvs.end();
+
+	for (oit = mTrianglePvs.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *intersect = *oit;
+	
+		BvhLeaf *bv = intersect->mBvhLeaf;
+
+		if (!bv || bv->Mailed())
+			continue;
+		
+		bv->Mail();
+
+		objectPvs.push_back(bv);
+		// hack: reset counter
+		(*oit)->mCounter = 0;
+	}
 }
 
@@ -978,4 +1092,5 @@
 	
 	vector<VizStruct>::const_iterator vit, vit_end = vizContainer.end();
+	
 	for (vit = vizContainer.begin(); vit != vit_end; ++ vit)
 	{
@@ -989,4 +1104,5 @@
 
 	VssRayContainer::const_iterator rit, rit_end = mVssRays.end();
+
 	for (rit = mVssRays.begin(); rit != rit_end; ++ rit)
 	{
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 1928)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 1999)
@@ -883,5 +883,5 @@
 
 		Debug << "exchanging boxes" << endl;
-int i = 0;
+		int i = 0;
 		// remove view cells and exchange them with the 
 		// view cells specialized for the current hierarchy node type
@@ -910,5 +910,7 @@
 			}
 
+			// delete old view cell
 			DEL_PTR(vc);
+
 //			(*vit).second = bspVc;
 			(*vit) = bspVc;
@@ -924,17 +926,20 @@
 		mVspTree->mBoundingBox = mViewSpaceBox;
 
-//		ViewCellsMap::iterator vit, vit_end = mViewCells.end();
-ViewCellContainer::iterator vit, vit_end = mViewCells.end();
+		// ViewCellsMap::iterator vit, vit_end = mViewCells.end();
+		ViewCellContainer::iterator vit, vit_end = mViewCells.end();
+
 		// reset view cells using the current node type
 		for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
 		{
 			//ViewCell *vc = (*vit).second;
-	ViewCell *vc = (*vit);
+			ViewCell *vc = (*vit);
+			
+			if (!vc->IsLeaf()) // exchange only leaves
+				continue;
+
 			VspViewCell *vspVc = new VspViewCell();
+
 			vspVc->SetPvs(vc->GetPvs());
 			vspVc->SetId(vc->GetId());
-
-			if (!vc->IsLeaf()) // exchange only leaves
-				continue;
 
 			if (vc->IsRoot())
@@ -947,5 +952,7 @@
 			}
 			
-			//DEL_PTR(vc);
+			// exchange view cell with new one
+			DEL_PTR(vc);
+
 			//(*vit).second = vspVc;
 			(*vit) = vspVc;
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1981)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1999)
@@ -9,4 +9,6 @@
 #include "Mesh.h"
 #include "Halton.h"
+#include "Triangle3.h"
+
 
 namespace GtpVisibilityPreprocessor {
@@ -556,10 +558,10 @@
 AxisAlignedBox3::IsInside(const Vector3 &v) const
 {
-  return ! (v.x < mMin.x ||
-	    v.x > mMax.x ||
-	    v.y < mMin.y ||
-	    v.y > mMax.y ||
-	    v.z < mMin.z ||
-	    v.z > mMax.z);
+  return ! ((v.x < mMin.x) ||
+	    (v.x > mMax.x) ||
+	    (v.y < mMin.y) ||
+	    (v.y > mMax.y) ||
+	    (v.z < mMin.z) ||
+	    (v.z > mMax.z));
 }
 #endif
@@ -2353,4 +2355,31 @@
 }
 
+
+ bool AxisAlignedBox3::Intersects(const Mesh &mesh) const
+ {
+	 VertexContainer::const_iterator vit, vit_end = mesh.mVertices.end();
+
+	 for (vit = mesh.mVertices.begin(); vit != vit_end; ++ vit)
+	 {
+		if (IsInside(*vit))
+			return true;
+	 }
+	 
+	 return false;
+ }
+
+
+ bool AxisAlignedBox3::Intersects(const Triangle3 &tri) const
+ {
+	 if (IsInside(tri.mVertices[0]) ||
+		 IsInside(tri.mVertices[1]) ||
+		 IsInside(tri.mVertices[2]))
+	 {
+			return true;
+	 }
+
+	 return false;
+ }
+
 /*
 int inline GetIntersection(const float fDst1, 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1877)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.h	(revision 1999)
@@ -197,4 +197,5 @@
 
 	float GetArea() const {return mItem.GetArea();}
+
 	int Type() const
 	{
@@ -219,6 +220,4 @@
 
 
-
-
 }
 
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1996)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1999)
@@ -233,5 +233,5 @@
 	Vector3 point;
 	Vector3 normal;
-	//cout << "y";
+	
 	const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
 
@@ -347,5 +347,5 @@
 	Vector3 point;
 	Vector3 normal;
-	//cout << "y";
+	
 	const int i = (int)RandomValue(0, (float)mPreprocessor.mObjects.size() - 0.5f);
 
