Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 265)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 308)
@@ -1,64 +1,24 @@
 #include "ViewCell.h"
 #include "Mesh.h"
+#include "Intersectable.h"
 #include "MeshKdTree.h"
 #include "Triangle3.h"
 
-ViewCell::ViewCell(): mMesh(NULL)
+ViewCell::ViewCell(): MeshInstance(NULL)
 {
 }
 
-ViewCell::ViewCell(Mesh *mesh): mMesh(mesh), mPvs(NULL) 
+ViewCell::ViewCell(Mesh *mesh): MeshInstance(mesh)
 {
 }
 
-ViewCell::~ViewCell()
-{
-	// NOTE: should I really do this here? (I know that there is only one mesh per view cell)
-	DEL_PTR(mMesh);
-}
-
-Mesh *ViewCell::GetMesh() 
-{
-	return mMesh;
-}
-
-BspPvs *ViewCell::GetPVS() 
+ViewCellPvs &ViewCell::GetPvs() 
 {
 	return mPvs;
 }
 
-AxisAlignedBox3 ViewCell::GetBox()
-{
-	return mMesh->mBox;
-}
-  
-int ViewCell::CastRay(Ray &ray) 
-{
-	return 0;
-}
-  
-bool ViewCell::IsConvex() 
-{
-	return mMesh->mIsConvex;
-}
-
-bool ViewCell::IsWatertight() 
-{
-	return mMesh->mIsWatertight;
-}
-
-float ViewCell::IntersectionComplexity() 
-{
-	return (float)mMesh->mFaces.size();
-}
-
 int ViewCell::Type() const 
 { 
-	return VIEWCELL; 
-}
-
-void  ViewCell::GetRandomSurfacePoint(Vector3 &point, Vector3 &normal) 
-{
-	point = Vector3(0,0,0);
+	return VIEW_CELL; 
 }
 
@@ -122,2 +82,7 @@
 	return new ViewCell(mesh);
 }
+
+void ViewCell::AddPassingRay(const Ray &ray, const int contributions)
+{
+	mPassingRays.AddRay(ray, contributions);
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 265)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 308)
@@ -7,4 +7,5 @@
 class BspNode;
 class Ray;
+class Intersectable;
 
 struct LtKdNode
@@ -92,4 +93,41 @@
 };
 
+
+struct LtIntersectable
+{
+  bool operator()(const Intersectable *a,
+		  const Intersectable *b) const
+  {
+	  return a < b;
+  }
+};
+
+struct ViewCellPvsData {
+  int mVisibleSamples;
+  ViewCellPvsData() {}
+  ViewCellPvsData(const int samples): mVisibleSamples(samples) {}
+};
+
+typedef std::map<Intersectable *, ViewCellPvsData, LtIntersectable> ViewCellPvsMap;
+
+class ViewCellPvs 
+{
+public:
+	ViewCellPvs(): mEntries() {}
+
+	ViewCellPvsMap mEntries;
+ 
+	int Compress() {return 0;}
+	int GetSize() {return (int)mEntries.size();}
+
+	ViewCellPvsData *Find(Intersectable *obj);
+	int AddObject(Intersectable *obj);
+
+	void GetData(const int index, 
+				 Intersectable *&obj,
+				 ViewCellPvsData &data);
+
+};
+
 #endif
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 306)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 308)
@@ -24,5 +24,5 @@
 	Polygon3();
 	Polygon3(const VertexContainer &vertices);
-	Polygon3(Intersectable *parent);
+	Polygon3(MeshInstance *parent);
 
 	/** Copies all the vertices of the face.
@@ -81,6 +81,6 @@
 	Material *mMaterial;
 	
-	/// pointer to the intersectable this polygon is derived from
-	Intersectable *mParent;
+	/// pointer to the mesh instance this polygon is derived from
+	MeshInstance *mParent;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 306)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 308)
@@ -327,4 +327,12 @@
 	bool Export(const string filename);
 
+	void CollectViewCells(BspNode *n, ViewCellContainer &viewCells);
+
+	/** A ray is cast possible intersecting the tree.
+		@param the ray that is cast.
+		@returns the number of intersections with objects stored in the tree.
+	*/
+	int CastRay(Ray &ray);
+
 	//static bool displayDebug;
 protected:
@@ -368,8 +376,7 @@
 	    @param tStack current traversal stack
 		@param tData traversal data also holding node to be subdivided
-		@param viewCellContainer if not null, a new viewcell is created and stored in the container
 		@returns new root of the subtree
 	*/
-	BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, ViewCellContainer *viewCells = NULL);
+	BspNode *Subdivide(BspTraversalStack &tStack, BspTraversalData &tData);
 
 	/** Selects a splitting plane. 
@@ -436,11 +443,5 @@
 		@returns number of polygons
 	*/
-	int AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys, Intersectable *parent);
-
-	/** A ray is cast possible intersecting the tree.
-		@param the ray that is cast.
-		@returns the number of intersections with objects stored in the tree.
-	*/
-	int CastRay(Ray &ray);
+	int AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
 
 	/** returns next candidate index and reorders polygons so no candidate is chosen two times
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Camera.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Camera.h	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Camera.h	(revision 308)
@@ -24,5 +24,5 @@
     mWidth = 640;
     mHeight = 480;
-    mFovy = 60*M_PI/180;
+    mFovy = 60*M_PI/180.0f;
   }
   
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 245)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 308)
@@ -11,5 +11,5 @@
 class KdLeaf;
 class MeshInstance;
-
+class ViewCell;
 
 // -------------------------------------------------------------------
@@ -59,4 +59,5 @@
   vector<KdLeaf *> leaves;
   vector<MeshInstance *> meshes;
+  vector<ViewCell *> viewCells;
 
   // constructors
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h	(revision 271)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h	(revision 308)
@@ -107,5 +107,5 @@
   CastRay(
 	  Ray &ray,
-	  MeshInstance *instance
+	   MeshInstance *instance
 	  );
 
@@ -114,5 +114,5 @@
 			 Ray &ray,
 			 const vector<int> &faces,
-			 MeshInstance *instance
+			 Intersectable *instance
 			 );
 
@@ -123,5 +123,5 @@
 		float &nearestT,
 		int &nearestFace,
-		MeshInstance *instance
+		Intersectable *instance
 		);
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 307)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 308)
@@ -424,5 +424,4 @@
 				interior->ProcessPolygons(&coincident, mStoreSplitPolys);
 
-				//Debug << "split node on level " << tData.mDepth << " bk: " << backPolys->size() << " frnt: " << frontPolys->size() << endl;
 				mStat.splits += splits;
 
@@ -437,9 +436,14 @@
 		else // reached leaf => subdivide current viewcell
 		{
-			//if (tData.mPolygons->size() > 0)
-			//	Debug << "Subdividing further: polygon size: " << (int)tData.mPolygons->size() << ", view cell: " << tData.mViewCell << endl;
-
-			BspNode *root = Subdivide(tStack, tData, viewCells);		
-
+			//if (tData.mPolygons->size() > 0) Debug << "Subdividing further: polygon size: " << (int)tData.mPolygons->size() << ", view cell: " << tData.mViewCell << endl;
+			BspNode *root = Subdivide(tStack, tData);		
+
+			if (viewCells && root->IsLeaf())
+			{	// generate new view cell for each leaf
+				ViewCell *viewCell = new ViewCell();
+				viewCells->push_back(viewCell);
+				
+				dynamic_cast<BspLeaf *>(root)->SetViewCell(viewCell);
+		}
 			if (!mRoot) // tree empty => new root
 				mRoot = root;
@@ -448,5 +452,5 @@
 }
 
-int BspTree::AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys, Intersectable *parent)
+int BspTree::AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent)
 {
 	FaceContainer::const_iterator fi;
@@ -498,5 +502,5 @@
 			mesh = dynamic_cast<MeshInstance *>(object)->GetMesh();
 			break;
-		case Intersectable::VIEWCELL:
+		case Intersectable::VIEW_CELL:
 			mesh = dynamic_cast<ViewCell *>(object)->GetMesh();
 			break;
@@ -586,5 +590,13 @@
 
 		// subdivide leaf node
-		BspNode *root = Subdivide(tStack, tData, viewCells);
+		BspNode *root = Subdivide(tStack, tData);
+
+		if (viewCells && root->IsLeaf())
+		{	// generate new view cell for each leaf
+			ViewCell *viewCell = new ViewCell();
+			viewCells->push_back(viewCell);
+
+			dynamic_cast<BspLeaf *>(root)->SetViewCell(viewCell);
+		}
 
 		// empty tree => new root corresponding to unbounded space
@@ -598,6 +610,5 @@
 
 
-BspNode *BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, 
-							ViewCellContainer *viewCells)
+BspNode *BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData)
 {
 	//-- terminate traversal  
@@ -605,5 +616,6 @@
 	{
 #ifdef _DEBUG
-		Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " << (int)tData.mPolygons->size() << endl;
+		Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " 
+			  << (int)tData.mPolygons->size() << endl;
 #endif
 
@@ -611,23 +623,14 @@
 
 		BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
-
-		//-- new viewcells are generated and added to each leaf
-		if (viewCells)
-		{
-			ViewCell *viewCell = new ViewCell();
-			leaf->SetViewCell(viewCell);
-			viewCells->push_back(viewCell);
-			// Debug << "creating new viewcell" << endl;
-		}
-		//-- add viewcell stored in split polygon
-		else if (!leaf->GetViewCell())
+		
+		// add view cell to leaf
+		if (!leaf->GetViewCell())
 			leaf->SetViewCell(tData.mViewCell);
-		//else Debug << "Leaf already has view cell " << endl;
 
 		// remaining polygons are discarded or added to node
-		tData.mNode->ProcessPolygons(tData.mPolygons, mStoreSplitPolys);
+		leaf->ProcessPolygons(tData.mPolygons, mStoreSplitPolys);
 		DEL_PTR(tData.mPolygons);
 
-		return tData.mNode;
+		return leaf;
 	}
 
@@ -644,17 +647,17 @@
 										  &coincident);
 
-	//-- extract view cells from coincident polygons according to plane normal
 	ViewCell *frontViewCell = mViewCell;
 	ViewCell *backViewCell = mViewCell;
-	
-    if (!viewCells)
-	{	// extract the pointer to the view cells
-		ExtractViewCells(&backViewCell,
-						 &frontViewCell,
-						 coincident, 
-						 interior->mPlane, 
-						 frontPolys->empty(), 
-						 backPolys->empty());
-	}
+
+#ifdef _DEBUG	
+	if (frontPolys->empty() && backPolys->empty() && (coincident.size() > 2))
+	{	for (PolygonContainer::iterator it = coincident.begin(); it != coincident.end(); ++it)
+			Debug << (*it) << " " << (*it)->GetArea() << " " << (*it)->mParent << endl ;
+		Debug << endl;}
+#endif
+
+	//-- extract view cells from coincident polygons according to plane normal
+   	ExtractViewCells(&backViewCell, &frontViewCell, coincident, interior->mPlane, 
+						 frontPolys->empty(), backPolys->empty());
 	
 	// don't need coincident polygons anymore
@@ -684,6 +687,7 @@
 	PolygonContainer::const_iterator it, it_end = coincident.end();
 
+	//-- find first view cells in front and back leafs
 	for (it = coincident.begin(); !(foundFront && foundBack) && 
-		(it < coincident.end()); ++it)
+		(it != it_end); ++ it)
 	{
 		if (DotProd((*it)->GetSupportingPlane().mNormal, splitPlane.mNormal > 0))
@@ -996,5 +1000,5 @@
 		if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS)
 		{
-			Intersectable *viewCell = (*it)->mParent;
+			MeshInstance *viewCell = (*it)->mParent;
 		
 			if (classification == Polygon3::FRONT_SIDE)
@@ -1011,5 +1015,5 @@
 		val += sLeastSplitsFactor * sumSplits / (float)polys.size();
 
-	if ((sSplitPlaneStrategy & LARGEST_POLY_AREA) && sumPolyArea) 
+	if (sSplitPlaneStrategy & LARGEST_POLY_AREA) 
 		val += sLargestPolyAreaFactor * (float)polys.size() / sumPolyArea; // HACK
 
@@ -1022,11 +1026,11 @@
 		ObjectContainer::const_iterator frontIt, frontIt_end = frontViewCells.end();
 	
-		Intersectable *intersect = NULL;
+		Intersectable *vc = NULL;
 		// increase counter for view cells in front of plane
 		for (frontIt = frontViewCells.begin(); frontIt != frontIt_end; ++frontIt)
 		{
-			if (*frontIt != intersect)
+			if (*frontIt != vc)
 			{
-				intersect = *frontIt;
+				vc = *frontIt;
 				sumBalancedViewCells += 1.0f;
 			}
@@ -1034,11 +1038,11 @@
 
 		ObjectContainer::const_iterator backIt, backIt_end = backViewCells.end();
-		intersect = NULL;
+		vc = NULL;
 		// decrease counter for view cells on back side of plane
 		for (backIt = backViewCells.begin(); backIt != backIt_end; ++backIt)
 		{
-			if (*backIt != intersect)
+			if (*backIt != vc)
 			{
-				intersect = *backIt;
+				vc = *backIt;
 				sumBalancedViewCells -= 1.0f;
 			}
@@ -1136,54 +1140,4 @@
 }
 
-int BspTree::CollectLeafPvs()
-{
-	int totalPvsSize = 0;
-  
-	stack<BspNode *> nodeStack;
-  
-	nodeStack.push(mRoot);
-  
-	while (!nodeStack.empty()) 
-	{
-		BspNode *node = nodeStack.top();
-		
-		nodeStack.pop();
-		
-		if (node->IsLeaf()) 
-		{
-			BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
-
-			ViewCell *viewcell = leaf->GetViewCell();
-			
-			if (!viewcell->Mailed()) 
-			{
-				viewcell->Mail(); // what does mail mean?
-					
-				// add this node to pvs of all nodes it can see
-				BspPvsMap::iterator ni; 
-	  
-	/*			for (ni = object->mBspPvs.mEntries.begin(); ni != object->mKdPvs.mEntries.end(); ni++) 
-				{
-					BspNode *node = (*ni).first;
-	    
-					// $$ JB TEMPORARY solution -> should add object PVS or explictly computed
-					// BSP tree PVS
-	    			if (leaf->mBspPvs.AddNodeSample(node))
-						totalPvsSize++;
-				}*/
-			}
-		} else 
-		{
-			// traverse tree
-			BspInterior *interior = (BspInterior *)node;
-      
-			nodeStack.push(interior->GetFront());
-			nodeStack.push(interior->GetBack());
-		}
-	}
-
-	return totalPvsSize;
-}
-
 AxisAlignedBox3 BspTree::GetBoundingBox() const
 {
@@ -1303,22 +1257,18 @@
 			extp = splitPlane->FindIntersection(ray.GetLoc(), extp, &maxt);
 
-		} else // compute intersections with objects in leaf
+		} else // reached leaf => intersection with view cell
 		{
 			BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
-			//ray.leaves.push_back(leaf);
-      // TODO
-   			/*ObjectContainer::const_iterator mi;
-			for (mi = leaf->mObjects.begin(); mi != leaf->mObjects.end(); ++mi) 
+			
+			//ray.mBspLeaves.push_back(leaf);
+			
+			if (!leaf->mViewCell->Mailed())
 			{
-				Intersectable *object = *mi;
-				if (!object->Mailed()) 
-				{
-					object->Mail();
-					//ray.meshes.push_back(mesh);
-					hits += object->CastRay(ray);
-				}
-			}*/
-
-			if (hits && ray.GetType() == Ray::LOCAL_RAY)
+				ray.viewCells.push_back(leaf->mViewCell);
+				mViewCell->Mail();
+				++ hits;
+			}
+
+   			if (hits && ray.GetType() == Ray::LOCAL_RAY)
 				if (ray.intersections[0].mT <= maxt)
 					break;
@@ -1355,3 +1305,33 @@
 	return false;
 }
+
+void BspTree::CollectViewCells(BspNode *n, ViewCellContainer &viewCells)
+{
+	stack<BspNode *> nodeStack;
+
+	nodeStack.push(n);
+
+	while (!nodeStack.empty()) 
+	{
+		BspNode *node = nodeStack.top();
+		nodeStack.pop();
+
+		if (node->IsLeaf()) 
+		{
+			ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->mViewCell;
+
+			if (!viewCell->Mailed()) 
+			{
+				viewCell->Mail();
+				viewCells.push_back(viewCell);
+			}
+		}
+		else 
+		{
+			BspInterior *interior = dynamic_cast<BspInterior *>(node);
+			nodeStack.push(interior->mFront);
+			nodeStack.push(interior->mBack);
+		}
+	}
+}
 //} // GtpVisibilityPreprocessor
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 268)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 308)
@@ -2,8 +2,7 @@
 #define _ViewCell_H__
 
-#include "Intersectable.h"
+#include "Mesh.h"
 #include "Containers.h"
-
-class Mesh;
+#include "Ray.h"
 
 //namespace GtpVisibilityPreprocessor {
@@ -12,36 +11,20 @@
 class BspPvs;
 struct Triangle3;
+
 /**
-	View cell represented as a mesh
+	View cell with an optional mesh representation
 */
-class ViewCell: public Intersectable
+class ViewCell: public MeshInstance
 {
 public:
 	ViewCell();
-	/** Default constructor taking a mesh which represents the shape of
-		the viewcell.
+	/** Constructor taking a mesh representing the shape of	the viewcell.
 	*/
 	ViewCell(Mesh *mesh);
-
-	/** Returns pointer to the mesh which represents the shape of the viewcell.
+	/** Returns PvS. 
 	*/
-	Mesh *GetMesh();
-
-	/** Returns pointer to PVS. 
-		@returns PVS, i.e., the visible BSP tree nodes.
-	*/
-	BspPvs *GetPVS();
-
-	AxisAlignedBox3 GetBox();
-  
-	int CastRay(Ray &ray);
-  
-	bool IsConvex();
-	bool IsWatertight();
-	float IntersectionComplexity();
+	ViewCellPvs &GetPvs();
 
 	int Type() const;
-
-	void GetRandomSurfacePoint(Vector3 &point, Vector3 &normal);
 
 	/** Derives viewcells from object container.
@@ -60,11 +43,13 @@
 	static ViewCell *ExtrudeViewCell(const Triangle3 &baseTri, const float height);
 
+	void AddPassingRay(const Ray &ray, const int contributions);	
+
 protected:
 
-	/// the mesh defining the geometry of this viewcell
-	Mesh *mMesh;
-	/// the PVS (i.e., the visible bsp tree nodes)
-	BspPvs *mPvs;
+	/// the potentially visible objects
+	ViewCellPvs mPvs;
 
+	/** Ray set description of the rays passing through this node */
+	PassingRaySet mPassingRays;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 304)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 308)
@@ -16,8 +16,9 @@
 Preprocessor::~Preprocessor()
 {
-  CLEAR_CONTAINER(mViewCells);
-  DEL_PTR(mBspTree);
-  DEL_PTR(mKdTree);
-  DEL_PTR(mRootViewCell);
+	DeleteViewCells();
+		
+	DEL_PTR(mBspTree);
+	DEL_PTR(mKdTree);
+	DEL_PTR(mRootViewCell);
 }
 
@@ -26,4 +27,12 @@
 {
 	return X3dParser().ParseFile(filename, mViewCells);
+}
+
+void Preprocessor::DeleteViewCells()
+{
+	for (int i = 0; i < mViewCells.size(); ++ i)
+		delete mViewCells[i]->GetMesh();
+
+	CLEAR_CONTAINER(mViewCells);
 }
 
@@ -90,10 +99,10 @@
 	DEL_PTR(mBspTree);
 	DEL_PTR(mRootViewCell);
-	mRootViewCell = new ViewCell();
+	mRootViewCell = new ViewCell(NULL);
 	mBspTree = new BspTree(mRootViewCell);
 
 	ObjectContainer objects;
 	RayContainer rays;
-ViewCellContainer dummy;
+
 	switch (BspTree::sConstructionMethod)
 	{
@@ -102,10 +111,10 @@
 		break;
 	case BspTree::SCENE_GEOMETRY:
-		CLEAR_CONTAINER(mViewCells); // we generate new view cells
+		DeleteViewCells(); // we generate new view cells
 		mSceneGraph->CollectObjects(&objects);
 		mBspTree->Construct(objects, &mViewCells);
 		break;
 	case BspTree::RAYS:
-		CLEAR_CONTAINER(mViewCells); // we generate new view cells	
+		DeleteViewCells(); // we generate new view cells	
 		mBspTree->Construct(rays, &mViewCells);
 		break;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 256)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 308)
@@ -51,4 +51,7 @@
 									);
 
+	/** Adds objects samples to view cells.
+	*/
+	int AddObjectSamples(Intersectable *obj, const Ray &ray);
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 292)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 308)
@@ -102,5 +102,5 @@
     ExportMeshInstance((MeshInstance *)object);
 	break;
-  case Intersectable::VIEWCELL:
+  case Intersectable::VIEW_CELL:
 	ExportViewCell((ViewCell *)object);
     break;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h	(revision 245)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h	(revision 308)
@@ -13,5 +13,5 @@
   KdPvs mKdPvs;
   
-  enum { MESH_INSTANCE, TRANSFORMED_MESH_INSTANCE, SPHERE, VIEWCELL };
+  enum { MESH_INSTANCE, TRANSFORMED_MESH_INSTANCE, SPHERE, VIEW_CELL };
   
   Intersectable():mailbox(0) {}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 297)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 308)
@@ -90,4 +90,6 @@
   virtual void BspTreeStatistics(ostream &s);
 
+  void DeleteViewCells();
+
   /// scene graph loaded from file
   SceneGraph *mSceneGraph;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.cpp	(revision 240)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.cpp	(revision 308)
@@ -2,4 +2,5 @@
 using namespace std;
 #include "Pvs.h"
+#include "Intersectable.h"
 
 KdPvsData *
@@ -87,2 +88,45 @@
 	data = (*i).second;
 }
+
+ViewCellPvsData *ViewCellPvs::Find(Intersectable *obj)
+{
+	ViewCellPvsMap::iterator i = mEntries.find(obj);
+	
+	if (i != mEntries.end()) 
+	{
+		//    cout<<node<<" "<<(*i).first<<" "<<(*i).second.mVisibleSamples<<endl;
+		return &(*i).second;
+	} 
+	else
+	  return NULL;
+}
+
+int ViewCellPvs::AddObject(Intersectable *obj)
+{
+	int result;
+  
+	ViewCellPvsData *data = Find(obj);
+
+	if (data) 
+	{
+		data->mVisibleSamples ++;
+		result = 0;
+	} 
+	else 
+	{
+		mEntries[obj] = ViewCellPvsData(1);
+		result = 1;
+	}
+
+	return  result;
+}
+
+void ViewCellPvs::GetData(const int index, Intersectable *&obj, ViewCellPvsData &data)
+{
+	ViewCellPvsMap::iterator i = mEntries.begin();
+  
+	for (int k = 0; k!=index && i != mEntries.end(); i++, k++);
+
+	obj = (*i).first;
+	data = (*i).second;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 306)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 308)
@@ -2,5 +2,5 @@
 #include "Mesh.h"
 #include "ViewCellBsp.h" // TODO: erase this
-#include "Intersectable.h"
+#include "Mesh.h"
 #include "AxisAlignedBox3.h"
 
@@ -16,5 +16,5 @@
 {}
 
-Polygon3::Polygon3(Intersectable *parent): mMaterial(NULL), mParent(parent)
+Polygon3::Polygon3(MeshInstance *parent): mMaterial(NULL), mParent(parent)
 {
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 257)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 308)
@@ -6,6 +6,7 @@
 #include "MutualVisibility.h"
 #include "Polygon3.h"
-
-SamplingPreprocessor::SamplingPreprocessor()
+#include "ViewCell.h"
+
+SamplingPreprocessor::SamplingPreprocessor(): mPass(0)
 {
   // this should increase coherence of the samples
@@ -23,4 +24,6 @@
   ray.leaves.clear();
   ray.meshes.clear();
+  ray.viewCells.clear();
+
   //  cout<<point<<" "<<direction<<endl;
   ray.Init(point, direction, Ray::LOCAL_RAY);
@@ -57,4 +60,26 @@
 
 
+int SamplingPreprocessor::AddObjectSamples(Intersectable *obj, const Ray &ray)
+{
+	int contributingSamples = 0;
+	int j;
+
+	if (mPass > 10)
+		for (j=1; j < ray.viewCells.size() - 1; j++) 
+		{
+			ray.viewCells[j]->AddPassingRay(ray, contributingSamples ? 1 : 0);
+		}
+
+	// add object to view cell
+	for (j=0; j < ray.viewCells.size(); j++) 
+	{
+		ViewCell *vc = ray.viewCells[j];
+		contributingSamples += vc->GetPvs().AddObject(obj);
+	}
+
+	return contributingSamples;
+}
+
+
 void
 SamplingPreprocessor::HoleSamplingPass()
@@ -74,6 +99,9 @@
 SamplingPreprocessor::CastRay(Intersectable *object, Ray &ray)
 {
+	int sampleContributions = 0;
+
+#ifndef TEST_BSP_VIEWCELLS
 	mKdTree->CastRay(ray);
-	int sampleContributions = 0;
+	
 	if (ray.leaves.size()) {
 		sampleContributions += AddNodeSamples(object, ray);
@@ -83,4 +111,20 @@
 		}
 	}
+#else
+	mBspTree->CastRay(ray);
+
+	if (ray.viewCells.size() > 0) // view cell found
+	{
+		++ sampleContributions;
+	
+		//  cast ray to KD tree to find intersections with other objects
+		mKdTree->CastRay(ray);
+
+		if (ray.intersections.size()) 
+		{
+			sampleContributions += AddObjectSamples(ray.intersections[0].mObject, ray);
+		}
+	}
+#endif
 	return sampleContributions;
 }
@@ -190,12 +234,11 @@
 		int passSamples = 0;
 		int index = 0;
-		
-		for (i =0; i < objects.size(); i++) {
+		Debug << "************************************" << endl;
+		Debug << "totalSamples: " << totalSamples << " (" << mTotalSamples << ")" << endl;
+		for (i = 0; i < objects.size(); i++) {
 			KdNode *nodeToSample = NULL;
 			Intersectable *object = objects[i];
-			
+		
 			int pvsSize = object->mKdPvs.GetSize();
-			
-			
 			
 			if (0 && pvsSize) {
@@ -210,5 +253,5 @@
 				
 				int maxTries = 2*pvsSize;
-				
+				Debug << "Finding random neighbour" << endl;	
 				for (int tries = 0; tries < 10; tries++) {
 					index = RandomValue(0, pvsSize - 1);
@@ -230,5 +273,5 @@
 					node->Mail();
 				}
-				
+				Debug << "Get all neighbours from PVS" << endl;
 				vector<KdNode *> invisibleNeighbors;
 				// get all neighbors of all PVS nodes
@@ -251,5 +294,5 @@
 			}
 			
-			
+		
 			object->GetRandomSurfacePoint(point, normal);
 			bool viewcellSample = true;
@@ -278,4 +321,5 @@
 					
 					// construct a ray
+
 					SetupRay(ray, point, direction);
 					sampleContributions = CastRay(object, ray);
@@ -310,6 +354,4 @@
 		}
 		
-		
-	
 		totalSamples += passSamples;
 		
@@ -319,11 +361,18 @@
 		
 		mPass++;
-    
+
 		int pvsSize = 0;
+#ifdef TEST_BSP_VIEWCELLS    
+		for (i=0; i < mViewCells.size(); i++) {
+			ViewCell *vc = mViewCells[i];
+			pvsSize += vc->GetPvs().GetSize();
+		}
+		Debug << "pvs size: " << pvsSize << endl;
+#else
 		for (i=0; i < objects.size(); i++) {
 			Intersectable *object = objects[i];
 			pvsSize += object->mKdPvs.GetSize();
 		}
-    
+#endif		
 		cout << "#Pass " << mPass<<" : t = " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
 		cout << "#TotalSamples=" << totalSamples/1000 
@@ -343,5 +392,5 @@
 			"#AvgRayContrib\n" << passSampleContributions/(float)passContributingSamples << endl;
 	}
-	
+  Debug << "Collecting leaf pvs" << endl;
   int totalPvsSize = mKdTree->CollectLeafPvs();
   cout << "#totalPvsSize=" << totalPvsSize << endl;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/MeshKdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/MeshKdTree.cpp	(revision 245)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/MeshKdTree.cpp	(revision 308)
@@ -277,5 +277,5 @@
   }
   
-  float oldCost = node->mFaces.size();
+  float oldCost = (float)node->mFaces.size();
   float newCost = mCt_div_ci + minSum/boxArea;
   float ratio = newCost/oldCost;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp	(revision 258)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp	(revision 308)
@@ -54,5 +54,5 @@
 		    float &nearestT,
 		    int &nearestFace,
-		    MeshInstance *instance
+		    Intersectable *instance
 		    )
 {
@@ -121,5 +121,5 @@
 			     Ray &ray,
 			     const vector<int> &faces,
-			     MeshInstance *instance
+			     Intersectable *instance
 			     )
 {
