Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 366)
@@ -56,5 +56,5 @@
 
 Sampling {
-	totalSamples	200000
+	totalSamples	20000000
 	samplesPerPass  3
 }
@@ -68,5 +68,6 @@
 	maxViewCells 0
 	
-	minPvsDif 10
+	minPvsDif 100
+#	maxPvsSize 200
 	
 #	filename ../data/atlanta/atlanta_viewcells_large.x3d
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 366)
@@ -4,4 +4,6 @@
 #include "MeshKdTree.h"
 #include "Triangle3.h"
+
+ViewCell::HierarchyType ViewCell::sHierarchy = BSP;
 
 ViewCell::ViewCell(): MeshInstance(NULL), mPiercingRays(0)
@@ -13,5 +15,19 @@
 }
 
-ViewCellPvs &ViewCell::GetPvs() 
+ViewCell *ViewCell::Generate(Mesh *mesh)
+{
+	switch(sHierarchy)
+	{
+	case KD:
+		return new ViewCell(mesh);
+	case BSP:
+		return new BspViewCell(mesh);
+	default:
+		Debug << "should not come here" << endl;
+		return NULL;
+	}
+}
+
+ViewCellPvs &ViewCell::GetPvs()
 {
 	return mPvs;
@@ -28,5 +44,6 @@
 {
 	// maximal max viewcells
-	int limit = maxViewCells > 0 ? Min((int)objects.size(), maxViewCells) : (int)objects.size();
+	int limit = maxViewCells > 0 ? 
+		Min((int)objects.size(), maxViewCells) : (int)objects.size();
 
 	for (int i = 0; i < limit; ++ i)
@@ -39,5 +56,5 @@
 			MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
 
-			ViewCell *viewCell = new ViewCell(inst->GetMesh());
+			ViewCell *viewCell = Generate(inst->GetMesh());
 			viewCells.push_back(viewCell);
 		}
@@ -78,10 +95,10 @@
 	mesh->Preprocess();
 
-	return new ViewCell(mesh);
+	return Generate(mesh);
 }
 
 ViewCell *ViewCell::Merge(ViewCell &front, ViewCell &back)
 {
-	ViewCell *vc = new ViewCell();
+	ViewCell *vc = Generate();
 	// merge pvs
 	vc->mPvs.Merge(front.mPvs, back.mPvs);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 366)
@@ -148,4 +148,5 @@
 typedef Pvs<Intersectable *> ViewCellPvs;
 
+
 #endif
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 366)
@@ -7,4 +7,5 @@
 
 class ViewCell;
+class BspViewCell;
 class Plane3;
 class BspTree;  
@@ -230,17 +231,19 @@
 public:
 	BspLeaf();
-	BspLeaf(ViewCell *viewCell);
+	BspLeaf(BspViewCell *viewCell);
 	BspLeaf(BspInterior *parent);
-	BspLeaf(BspInterior *parent, ViewCell *viewCell);
+	BspLeaf(BspInterior *parent, BspViewCell *viewCell);
 
 	/** @return true since it is an interior node 
 	*/
 	bool IsLeaf() const;
-	/** Returns pointer from view cell.
-	*/
-	ViewCell *GetViewCell();
+	
+	/** Returns pointer of view cell.
+	*/
+	BspViewCell *GetViewCell() const;
+
 	/** Sets pointer to view cell.
 	*/
-	void SetViewCell(ViewCell *viewCell);
+	void SetViewCell(BspViewCell *viewCell);
 
 	/** Generates new view cell and adds rays to the PVS.
@@ -257,5 +260,5 @@
 
 	/// if NULL this does not correspond to feasible viewcell
-	ViewCell *mViewCell;
+	BspViewCell *mViewCell;
 };
 
@@ -379,8 +382,13 @@
 					  const bool onlyUnmailed) const;
 
-	/** Extracts geometry associated with the split plane leading to this node.
-	*/
-	void ConstructGeometry(BspNode *n, PolygonContainer &polys) const;
+	/** Constructs geometry associated with the half space intersections 
+		leading to this node.
+	*/
+	void ConstructGeometry(BspNode *n, PolygonContainer &cell) const;
 	
+	/** Construct geometry of view cell.
+	*/
+	void ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const;
+
 	/** Returns random leaf of BSP tree.
 		@param halfspace defines the halfspace from which the leaf is taken.
@@ -413,4 +421,8 @@
 	*/
 	bool MergeViewCells(BspLeaf *front, BspLeaf *back) const;
+
+	/** Traverses tree and counts PVS size of all view cells
+	*/
+	int CountViewCellPvs() const;
 
 protected:
@@ -644,4 +656,5 @@
 	void ExtractSplitPlanes(BspNode *n, vector<Plane3 *> &planes, vector<bool> &sides) const;
 
+	int CountPvs(const BoundedRayContainer &rays) const;
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
@@ -663,5 +676,6 @@
 		  BLOCKED_RAYS = 128,
 		  LEAST_RAY_SPLITS = 256,
-		  BALANCED_RAYS = 512
+		  BALANCED_RAYS = 512,
+		  PVS = 1024
 		};
 
@@ -742,5 +756,3 @@
 };
 
-//}; // GtpVisibilityPreprocessor
-
 #endif
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Ray.h	(revision 366)
@@ -56,4 +56,17 @@
   };
   
+  struct BspIntersection
+  {
+	  float mT;
+	  BspLeaf *leaf;
+	  BspIntersection(float t, BspLeaf *l): mT(t), leaf(l)
+	  {}
+
+	  bool operator<(const BspIntersection &b) const 
+	  {
+		  return mT	< b.mT;
+	  }
+  };
+
   // I should have some abstract cell data type !!! here
   // corresponds to the spatial elementary cell
@@ -62,7 +75,7 @@
   
   vector<Intersection> intersections;
+  vector<BspIntersection> bspIntersections;
   vector<KdLeaf *> kdLeaves;
   vector<MeshInstance *> meshes;
-  vector<BspLeaf *> bspLeaves;
   
   // constructors
@@ -197,4 +210,6 @@
   int ClassifyPlane(const Plane3 &plane, const float minT, const float maxT) const;
 
+  void Insert(const BspIntersection &bspi);
+
 private:
   Vector3 loc, dir;		// Describes ray origin and vector
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 366)
@@ -260,5 +260,5 @@
 }
 
-BspLeaf::BspLeaf(ViewCell *viewCell): 
+BspLeaf::BspLeaf(BspViewCell *viewCell): 
 mViewCell(viewCell)
 {
@@ -269,15 +269,15 @@
 {}
 
-BspLeaf::BspLeaf(BspInterior *parent, ViewCell *viewCell): 
+BspLeaf::BspLeaf(BspInterior *parent, BspViewCell *viewCell): 
 BspNode(parent), mViewCell(viewCell)
 {
 }
 
-ViewCell *BspLeaf::GetViewCell()
+BspViewCell *BspLeaf::GetViewCell() const
 {
 	return mViewCell;
 }
 
-void BspLeaf::SetViewCell(ViewCell *viewCell)
+void BspLeaf::SetViewCell(BspViewCell *viewCell)
 {
 	mViewCell = viewCell;
@@ -297,5 +297,6 @@
 	contributingSamples = 0;
 
-	mViewCell = new ViewCell();
+	mViewCell = dynamic_cast<BspViewCell *>(ViewCell::Generate());
+	mViewCell->mBspLeaves.push_back(this);
 
     BoundedRayContainer::const_iterator it, it_end = rays.end();
@@ -320,5 +321,5 @@
 		}
 
-		ray->bspLeaves.push_back(this);
+		ray->bspIntersections.push_back(BspIntersection(this, (*it)->mMinT);
 
 		if (storeRays)
@@ -711,5 +712,6 @@
 		{
 			// add view cell to leaf
-			leaf->SetViewCell(tData.mViewCell);
+			leaf->SetViewCell(dynamic_cast<BspViewCell *>(tData.mViewCell));
+			leaf->mViewCell->mBspLeaves.push_back(leaf);
 		}
 
@@ -1244,4 +1246,7 @@
 	float sumBalancedRays = 0;
 	float sumRaySplits = 0;
+	float pvsSize = 0;
+
+	Intersectable::NewMail();
 
 	BoundedRayContainer::const_iterator rit, rit_end = rays.end();
@@ -1264,4 +1269,18 @@
 		{
 			sumRaySplits += sLeastRaySplitsTable[classification];
+		}
+
+		if (sSplitPlaneStrategy & PVS)
+		{
+			vector<Ray::Intersection>::const_iterator it, 
+				it_end = ray->intersections.end();
+
+			for (it = ray->intersections.begin(); it != it_end; ++ it)
+			{
+				if (!(*it).mObject->Mailed())
+				{
+					(*it).mObject->Mail();
+				}
+			}
 		}
 	}
@@ -1597,17 +1616,73 @@
 }
 
+int BspTree::CountViewCellPvs() const
+{
+	int count = 0;
+	stack<BspNode *> nodeStack;
+	nodeStack.push(mRoot);
+
+	ViewCell::NewMail();
+
+	// exclude root cell
+	mRootCell->Mail();
+
+	while (!nodeStack.empty()) 
+	{
+		BspNode *node = nodeStack.top();
+		nodeStack.pop();
+
+		if (node->IsLeaf()) 
+		{
+			ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->mViewCell;
+
+			if (!viewCell->Mailed()) 
+			{
+				viewCell->Mail();
+				count += viewCell->GetPvs().GetSize();
+			}
+		}
+		else 
+		{
+			BspInterior *interior = dynamic_cast<BspInterior *>(node);
+
+			nodeStack.push(interior->mFront);
+			nodeStack.push(interior->mBack);
+		}
+	}
+	return count;
+}
 
 bool BspTree::MergeViewCells(BspLeaf *front, BspLeaf *back) const
 {
-	ViewCell *viewCell = ViewCell::Merge(*front->mViewCell, *back->mViewCell);
+	BspViewCell *viewCell = 
+		dynamic_cast<BspViewCell *>(ViewCell::Merge(*front->mViewCell, *back->mViewCell));
 	
 	if (!viewCell)
 		return false;
 
-	DEL_PTR(front->mViewCell);
-	DEL_PTR(back->mViewCell);
-
-	front->SetViewCell(viewCell);
-	back->SetViewCell(viewCell);
+	// change view cells of all leaves associated with the
+	// previous view cells
+
+	BspViewCell *fVc = front->mViewCell;
+	BspViewCell *bVc = back->mViewCell;
+
+	vector<BspLeaf *> fLeaves = fVc->mBspLeaves;
+	vector<BspLeaf *> bLeaves = bVc->mBspLeaves;
+
+	vector<BspLeaf *>::const_iterator it;
+	
+	for (it = fLeaves.begin(); it != fLeaves.end(); ++ it)
+	{
+		(*it)->SetViewCell(viewCell);
+		viewCell->mBspLeaves.push_back(*it);
+	}
+	for (it = bLeaves.begin(); it != bLeaves.end(); ++ it)
+	{
+		(*it)->SetViewCell(viewCell);
+		viewCell->mBspLeaves.push_back(*it);
+	}
+	
+	DEL_PTR(fVc);
+	DEL_PTR(bVc);
 
 	return true;
@@ -1616,10 +1691,19 @@
 bool BspTree::ShouldMerge(BspLeaf *front, BspLeaf *back) const
 {
-	if (front->mViewCell->GetPvs().Diff(back->mViewCell->GetPvs()) < 
-		sMinPvsDif)
-		return true;
-	
-	if (back->mViewCell->GetPvs().Diff(front->mViewCell->GetPvs()) < 
-		sMinPvsDif)
+	ViewCell *fvc = front->mViewCell;
+	ViewCell *bvc = back->mViewCell;
+
+	if ((fvc == mRootCell) || (bvc == mRootCell) || (fvc == bvc))
+		return false;
+
+	/*Debug << "merge (" << sMinPvsDif << ")" << endl;
+	Debug << "size f: " << fvc->GetPvs().GetSize() << ", "
+		  << "size b: " << bvc->GetPvs().GetSize() << endl;
+	
+	Debug << "diff f: " << fvc->GetPvs().Diff(bvc->GetPvs()) << ", "
+		  << "diff b: " << bvc->GetPvs().Diff(fvc->GetPvs()) << endl;*/
+
+    if ((fvc->GetPvs().Diff(bvc->GetPvs()) < sMinPvsDif) &&
+	    (bvc->GetPvs().Diff(fvc->GetPvs()) < sMinPvsDif))
 		return true;
 
@@ -1965,4 +2049,14 @@
 }
 
+void BspTree::ConstructGeometry(BspViewCell *vc, PolygonContainer &cell) const
+{
+	vector<BspLeaf *> leaves = vc->mBspLeaves;
+
+	vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
+
+	for (it = leaves.begin(); it != it_end; ++ it)
+		ConstructGeometry(*it, cell);
+}
+
 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 
 						   const bool onlyUnmailed) const
@@ -2121,2 +2215,27 @@
 	return NULL;
 }
+
+int BspTree::CountPvs(const BoundedRayContainer &rays) const
+{
+	int pvsSize = 0;
+
+	BoundedRayContainer::const_iterator rit, rit_end = rays.end();
+	vector<BspLeaf *>::const_iterator lit;
+
+	ViewCell::NewMail();
+
+	for (rit = rays.begin(); rit != rit_end; ++ rit)
+	{
+		Ray *ray = (*rit)->mRay;
+		
+		for (lit = ray->bspLeaves.begin(); lit != ray->bspLeaves.end(); ++ lit)
+		{
+			if ((*lit)->mViewCell->Mailed())
+			{
+				pvsSize += (*lit)->mViewCell->GetPvs().GetSize();
+			}
+		}
+	}
+
+	return pvsSize;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 366)
@@ -11,4 +11,5 @@
 class BspPvs;
 struct Triangle3;
+class BspLeaf;
 
 /**
@@ -54,5 +55,4 @@
 	static ViewCell *Merge(ViewCell &front, ViewCell &back);
 
-
 	/// Ray set description of the rays passing through this node.	
 	PassingRaySet mPassingRays;
@@ -60,4 +60,14 @@
 	/// Rays piercing this view cell.
 	RayContainer mPiercingRays;
+
+	/// view cells types
+	enum HierarchyType {BSP, KD};
+
+	/** Generates view cells of type specified by view cells type.
+	*/
+	static ViewCell *Generate(Mesh *mesh = NULL);
+
+	/// type of view cells hierarchy (KD, BSP)
+	static HierarchyType sHierarchy;
 
 protected:
@@ -67,5 +77,14 @@
 };
 
-//}; // GtpVisibilityPreprocessor
+class BspViewCell: public ViewCell
+{
+public:
+	BspViewCell(): mBspLeaves(0) {}
+	BspViewCell(Mesh *mesh): 
+	ViewCell(mesh), mBspLeaves(0) {}
+
+	/// Leaves which hold this view cell.
+	vector<BspLeaf *> mBspLeaves;
+};
 
 #endif
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 339)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 366)
@@ -9,6 +9,5 @@
 Preprocessor::Preprocessor():
 mKdTree(NULL),
-mBspTree(NULL),
-mViewCellsType(BSP_VIEW_CELLS)
+mBspTree(NULL)
 {
 }
@@ -52,10 +51,8 @@
 	environment->GetStringValue("ViewCells.hierarchy", viewCellsStr);
 
-	int vcType = BSP_VIEW_CELLS;
-  
 	if (strcmp(viewCellsStr, "bspTree") == 0)
-	   	mViewCellsType = BSP_VIEW_CELLS;
+		ViewCell::sHierarchy = ViewCell::BSP;
 	else if (strcmp(viewCellsStr, "kdTree") == 0)
-	   	mViewCellsType = KD_VIEW_CELLS;
+		ViewCell::sHierarchy = ViewCell::KD;
 	else if (strcmp(viewCellsStr, "sceneDependent") == 0)
 	{
@@ -67,9 +64,4 @@
 		exit(1);
 	}
-
-	if (mViewCellsType == KD_VIEW_CELLS)
-		Debug << "kdtree" << endl;
-	else if (mViewCellsType == BSP_VIEW_CELLS)
-		Debug << "bsptree" << endl;
 
 	return true;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp	(revision 362)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Ray.cpp	(revision 366)
@@ -194,4 +194,12 @@
 }
 
+
+void Ray::Insert(const BspIntersection &bspi)
+{
+	vector<BspIntersection>::iterator it;
+
+	while (it !=
+}
+
 ostream &
 operator<<(ostream &s, const PassingRaySet &set)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 344)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 366)
@@ -42,5 +42,5 @@
   // construction method. For "from rays" construction, wait until there is
   // a certain number of rays collected
-  if (p->mViewCellsType == Preprocessor::BSP_VIEW_CELLS &&
+  if (ViewCell::sHierarchy == ViewCell::BSP &&
 	  !(BspTree::sConstructionMethod == BspTree::FROM_RAYS)) 
   {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 329)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 366)
@@ -115,10 +115,4 @@
   /// the view cell corresponding to unbounded space
   ViewCell mUnbounded;
-
-  /// view cell hierarchy types
-  enum {BSP_VIEW_CELLS, KD_VIEW_CELLS, SCENE_DEPENDENT};
-
-  /// type of the view cells
-  int mViewCellsType;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 365)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 366)
@@ -121,6 +121,8 @@
 		for (j=1; j < ((int)ray.bspLeaves.size() - 1); ++ j) 
 		{
-			if (ray.bspLeaves[j]->GetViewCell() != &mUnbounded)
-				ray.bspLeaves[j]->GetViewCell()->
+			BspLeaf *leaf = ray.bspIntersections.leaf;
+
+			if (leaf->GetViewCell() != &mUnbounded)
+				leaf->GetViewCell()->
 					AddPassingRay(ray, contributingSamples ? 1 : 0);
 		}
@@ -162,5 +164,5 @@
 	}
 
-	if (mViewCellsType == BSP_VIEW_CELLS)
+	if (ViewCell::sHierarchy == ViewCell::BSP)
 	{
 		// cast ray to BSP tree to get intersection with view cells
@@ -376,13 +378,12 @@
 		int passSamples = 0;
 		int index = 0;
-		Real maxTime = 0;
-		int maxTimeIdx = 0;
+		
 		int reverseSamples = 0;
 		bool collectSamplesForBsp = 
-			(mViewCellsType == BSP_VIEW_CELLS) &&
+			(ViewCell::sHierarchy == ViewCell::BSP) &&
 			(BspTree::sConstructionMethod == BspTree::FROM_RAYS) &&
 			(totalSamples < mBspConstructionSamples);
 			
-		cout << "totalSamples: "  << totalSamples << endl;
+		//cout << "totalSamples: "  << totalSamples << endl;
 
 		for (i = 0; i < objects.size(); i++) {
@@ -392,5 +393,5 @@
 		
 			int pvsSize = 0;
-			if (mViewCellsType == KD_VIEW_CELLS)
+			if (ViewCell::sHierarchy == ViewCell::KD)
 				pvsSize = object->mKdPvs.GetSize();
 						
@@ -402,6 +403,4 @@
 			int faceIndex = object->GetRandomSurfacePoint(point, normal);
 			
-			long samplesPerObjStart = GetTime();
-
 			bool viewcellSample = true;
 			int sampleContributions;
@@ -456,5 +455,5 @@
 					}
 					//-------------------
-					if (mViewCellsType == BSP_VIEW_CELLS) 
+					if (ViewCell::sHierarchy == ViewCell::BSP) 
 					{
 						ProcessBspViewCells(collectSamplesForBsp,
@@ -471,13 +470,4 @@
 				//				object->GetRandomVisibleMesh(Plane3(normal, point));
 			}
-				
-			// measure maximal time for samples per object
-			Real t = TimeDiff(samplesPerObjStart, GetTime());
-
-			if (t > maxTime)
-			{
-				maxTime = t;
-				maxTimeIdx = i;
-			}
 	
 			// CORR matt: must add all samples
@@ -494,5 +484,5 @@
 		int pvsSize = 0;
         
-		if (mViewCellsType == BSP_VIEW_CELLS) {
+		if (ViewCell::sHierarchy == ViewCell::BSP) {
 			for (i=0; i < mViewCells.size(); i++) {
 				ViewCell *vc = mViewCells[i];
@@ -506,6 +496,4 @@
 		}
 
-		Debug << "maximal time needed for pass: " << maxTime << " (object " << maxTimeIdx << ")" << endl;
-
 		float avgRayContrib = (passContributingSamples > 0) ? 
 			passSampleContributions/(float)passContributingSamples : 0;
@@ -529,5 +517,5 @@
 	}
 	
-	if (mViewCellsType == KD_VIEW_CELLS)	
+	if (ViewCell::sHierarchy == ViewCell::KD)	
 		cout << "#totalPvsSize=" << mKdTree->CollectLeafPvs() << endl;
   
@@ -535,17 +523,17 @@
 	if (mBspTree)
 	{
+		cout << "starting post processing ... ";
+
+		Debug << "original pvs size: " << mBspTree->CountViewCellPvs() << endl;
+
+		long startTime = GetTime();
 		int merged = PostprocessViewCells(mSampleRays);
-		Debug << "merged " << merged << " view cells" << endl;
-
-		ViewCellContainer vc;
-		mBspTree->CollectViewCells(vc);
-
-		ViewCellContainer::const_iterator it, it_end = vc.end();
-
-		int mergedPvs = 0;
-		for (it = vc.begin(); it != it_end; ++ it)
-			mergedPvs += (*it)->GetPvs().GetSize();
-
-		Debug << "merged pvs size: " << mergedPvs << endl;
+		
+		cout << "finished" << endl;
+		cout << "merged " << merged << " view cells in "
+			 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
+
+		//-- recount pvs
+		Debug << "merged pvs size: " << mBspTree->CountViewCellPvs() << endl;
 
 	}
@@ -557,5 +545,5 @@
 		exporter->ExportKdTree(*mKdTree);
 
-		if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS))
+		if (mBspTree && (ViewCell::sHierarchy == ViewCell::BSP))
 			exporter->ExportBspTree(*mBspTree);
 
@@ -580,5 +568,5 @@
 	//-- several visualizations and statistics
 	if (1) {
-	if (mBspTree && (mViewCellsType == BSP_VIEW_CELLS))
+		if (mBspTree && (ViewCell::sHierarchy == ViewCell::BSP))
 	{
 		bool exportSplits = false;
@@ -672,9 +660,12 @@
 	RayContainer::const_iterator rit, rit_end = rays.end();
 	vector<BspLeaf *>::const_iterator lit;
-if (0)
+
 	for (rit = rays.begin(); rit != rays.end(); ++ rit)
 	{  
 		// traverse leaves stored in the rays and compare and merge consecutive
 		// leaves (i.e., the neighbors in the tree)
+		if ((*rit)->bspLeaves.empty())
+			continue;
+
 		lit = (*rit)->bspLeaves.begin();
 
@@ -693,4 +684,5 @@
 		}
 	}
+
 	return merged;
 }
@@ -775,5 +767,5 @@
 			for (int i = 0; i < (int)bspLeaves.size(); ++ i)
 			{
-				if (bspLeaves[i] == ray->bspLeaves[j]) 
+				if (bspLeaves[i]->GetViewCell() == ray->bspLeaves[j]->GetViewCell()) 
 				{
 					vcRays[i].push_back(*ray);
@@ -799,10 +791,10 @@
 		ViewCellPvsMap::iterator it = vc->GetPvs().mEntries.begin();
 
+		exporter->SetWireframe();
+
 		Material m;//= RandomMaterial();
 		m.mDiffuseColor = RgbColor(0, 1, 0);
 		exporter->SetForcedMaterial(m);
 
-		exporter->SetWireframe();
-
 		if (vc->GetMesh())
 			exporter->ExportViewCell(vc);
@@ -810,14 +802,8 @@
 		{
             PolygonContainer cell;
-
-			mBspTree->ConstructGeometry(bspLeaves[i], cell);
+			// export view cell
+			mBspTree->ConstructGeometry(bspLeaves[i]->GetViewCell(), cell);
 			exporter->ExportPolygons(cell);
 			CLEAR_CONTAINER(cell);
-
-			/*vector<BspLeaf *> neighbors;
-			mBspTree->FindNeighbors(bspLeaves[j], neighbors);
-			for (int j = 0; j < (int)neighbors.size(); ++ j)
-			{	if (neighbors[j]->mViewCell == bspLeaves[j]->mViewCell)
-				{}}*/
 		}
 
