Index: /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 558)
+++ /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 562)
@@ -25,9 +25,10 @@
 	type vss
 #	type rss
+	detectEmptyViewSpace true
 }
 
 VssPreprocessor {
 	samplesPerPass  100000
-	initialSamples 800000
+	initialSamples 1800000
 	vssSamples 0
 	vssSamplesPerPass 500000
@@ -36,5 +37,5 @@
 	storeInitialSamples false
 	useViewSpaceBox true
-	testBeamSampling true
+#	testBeamSampling true
 }
 
@@ -259,5 +260,5 @@
 VspBspTree {
 	Construction {
-		samples 300000
+		samples 900000
 		epsilon 0.005
 		randomize false
@@ -323,6 +324,6 @@
 	PostProcess {
 		maxCostRatio 0.1
-		minViewCells 100
-		useRaysForMerge true
+		minViewCells 110
+		useRaysForMerge false
 	}
 }
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 557)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 562)
@@ -60,4 +60,6 @@
 		/// how often this branch has missed the max-cost ratio
 		int mMaxCostMisses;
+		/// if this node is a kd-node (i.e., boundaries are axis aligned
+		bool mIsKdNode;
 		/// bounding box of current view space.
 		///AxisAlignedBox3 mBbox;
@@ -79,6 +81,6 @@
 		mProbability(0.0),
 		mGeometry(NULL),
-		mMaxCostMisses(0)
-		//,mIsAxisAligned(false)
+		mMaxCostMisses(0), 
+		mIsKdNode(false)
 		{}
 		
@@ -97,5 +99,6 @@
 		mProbability(p),
 		mGeometry(geom),
-		mMaxCostMisses(0)
+		mMaxCostMisses(0),
+		mIsKdNode(false)
 		{}
 
@@ -111,5 +114,6 @@
 		mProbability(0),
 		mGeometry(geom),
-		mMaxCostMisses(0)
+		mMaxCostMisses(0),
+		mIsKdNode(false)
 		{}
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 561)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 562)
@@ -254,10 +254,21 @@
 	*/
 	virtual bool CheckValidity(ViewCell *vc, 
-							   float minPvsRatio, 
-							   float maxPvsRatio) const;
+							   int minPvsSize, 
+							   int maxPvsSize) const;
+
+	
+	/** Sets validity of view cell
+	*/
+	virtual void SetValidity(ViewCell *vc, 
+							 int minPvsSize, 
+							 int maxPvsSize) const;
 
 	/** Returns maximal allowed pvs size.
 	*/
 	int GetMaxPvsSize() const;
+
+	/** Returns maximal allowed pvs size.
+	*/
+	int GetMinPvsSize() const;
 
 	/** Returns maximal ratio. i.e., currentPVs / maxPvs,
@@ -338,4 +349,5 @@
 
 	int mMaxPvsSize;
+	int mMinPvsSize;
 	float mMaxPvsRatio;
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 561)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 562)
@@ -329,4 +329,7 @@
 		float minT, maxT;
 
+		//static Ray hray;
+		//hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT);
+
 		// TODO: not very efficient to implictly cast between rays types
 		if (mBox.GetRaySegment(*ray, minT, maxT))
@@ -393,4 +396,7 @@
 							  geom);
 
+	// first node is kd node
+	tData.mIsKdNode = true;
+
 	tStack.push(tData);
 
@@ -510,5 +516,5 @@
 		}
 		
-		if (!mViewCellsManager->CheckValidity(viewCell, 0.0, mViewCellsManager->GetMaxPvsRatio()))
+		if (0 && !mViewCellsManager->CheckValidity(viewCell, 0, mViewCellsManager->GetMaxPvsSize()))
 		{
 			viewCell->SetValid(false);
@@ -880,5 +886,5 @@
 	box.Initialize();
 	
-	//TODO: for kd split geometry already is box
+	//TODO: for kd split geometry already is box => only take minmax vertices
 	if (1)
 	{
@@ -997,17 +1003,17 @@
 	const int pvsSize = data.mPvs;
 
+	RayInfoContainer::const_iterator rit, rit_end = data.mRays->end();
+
 	// this is the main ray classification loop!
-	for(RayInfoContainer::iterator ri = data.mRays->begin();
-		ri != data.mRays->end(); ++ ri)
-	{
-		if (!(*ri).mRay->IsActive())
-			continue;
+	for(rit = data.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		//if (!(*rit).mRay->IsActive())	continue;
 
 		// determine the side of this ray with respect to the plane
 		float t;
-		int side = (*ri).ComputeRayIntersection(axis, position, t);
-	
-		AddObjToPvs((*ri).mRay->mTerminationObject, side, pvsFront, pvsBack, pvsTotal);
-		AddObjToPvs((*ri).mRay->mOriginObject, side, pvsFront, pvsBack, pvsTotal);
+		const int side = (*rit).ComputeRayIntersection(axis, position, t);
+	
+		AddObjToPvs((*rit).mRay->mTerminationObject, side, pvsFront, pvsBack, pvsTotal);
+		AddObjToPvs((*rit).mRay->mOriginObject, side, pvsFront, pvsBack, pvsTotal);
 	}
 
@@ -1015,7 +1021,7 @@
 	float pOverall;
 
-	// -- simplified computation for mid split
-	
-	
+	//-- compute heurstics
+	//   we take simplified computation for mid split
+		
 	pOverall = data.mProbability;
 
@@ -1046,9 +1052,11 @@
 	}
 
-	//Debug << axis << " " << pvsSize << " " << pvsBack << " " << pvsFront << endl;
-	//Debug << pFront << " " << pBack << " " << pOverall << endl;
+#ifdef _DEBUG
+	Debug << axis << " " << pvsSize << " " << pvsBack << " " << pvsFront << endl;
+	Debug << pFront << " " << pBack << " " << pOverall << endl;
+#endif
 
 	const float newCost = pvsBack * pBack + pvsFront * pFront;
-	const float oldCost = (float)pvsSize * pOverall;
+	const float oldCost = (float)pvsSize * pOverall + Limits::Small;
 
 	return  (mCtDivCi + newCost) / oldCost;
@@ -1098,5 +1106,6 @@
 	for (int i = 0; i < limit; ++ i)
 	{
-		//-- assure that no index is taken twice
+		// the already taken candidates are stored behind maxIdx
+		// => assure that no index is taken twice
 		const int candidateIdx = (int)RandomValue(0, (Real)(-- maxIdx));
 		Polygon3 *poly = (*data.mPolygons)[candidateIdx];
@@ -1127,5 +1136,7 @@
 										   &fGeom, &bGeom, 
 										   pFront, pBack,
-										   onlyAxisAligned);	 
+										   data.mIsKdNode);	 
+
+	bool isAxisAlignedSplit = false;
 
 	if (candidateCost < lowestCost)
@@ -1136,6 +1147,5 @@
 		// assign already computed values
 		// we can do this because we always save the
-		// computed values from the axis aligned splits
-		
+		// computed values from the axis aligned splits		
 		frontData.mGeometry = fGeom;
 		backData.mGeometry = bGeom;
@@ -1146,4 +1156,5 @@
 		//! error also computed if cost ratio is missed
 		++ mStat.splits[axis];
+		isAxisAlignedSplit = true;
 	}
 	else
@@ -1152,4 +1163,6 @@
 		DEL_PTR(bGeom);
 	}
+
+	frontData.mIsKdNode = backData.mIsKdNode = (data.mIsKdNode && isAxisAlignedSplit);
 
 #ifdef _DEBUG
@@ -1295,8 +1308,11 @@
 		const int cf = rayInf.ComputeRayIntersection(candidatePlane, t);
 
-        if (cf >= 0)
-			++ raysFront;
-		if (cf <= 0)
-			++ raysBack;
+        if (0)
+		{
+			if (cf >= 0)
+				++ raysFront;
+			if (cf <= 0)
+				++ raysBack;
+		}
 
 		if (mSplitPlaneStrategy & LEAST_RAY_SPLITS)
@@ -1368,5 +1384,8 @@
 
 	// normalize cost by sum of linear factors
-	return cost / (float)mCostNormalizer;
+	if(0)
+		return cost / (float)mCostNormalizer;
+	else
+		return cost;
 }
 
@@ -1644,5 +1663,7 @@
 				BspViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell();
 			
-				if (!mViewCellsManager->CheckValidity(viewCell, 0.0, mViewCellsManager->GetMaxPvsRatio()))
+				if (!mViewCellsManager->CheckValidity(viewCell,
+													  mViewCellsManager->GetMinPvsSize(), 
+													  mViewCellsManager->GetMaxPvsSize()))
 				{
 					vector<BspLeaf *>::const_iterator it, it_end = viewCell->mLeaves.end();
@@ -1681,4 +1702,6 @@
 		}
 	}
+
+	Debug << "invalid leaves: " << mStat.invalidLeaves << endl;
 }
 
@@ -1918,5 +1941,5 @@
 
 int VspBspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
-						   const bool onlyUnmailed) const
+							  const bool onlyUnmailed) const
 {
 	stack<bspNodePair> nodeStack;
@@ -1937,16 +1960,13 @@
 	nodeStack.push(bspNodePair(mRoot, rgeom));
 
-	Debug << "here77" << endl;
-
 	while (!nodeStack.empty())
 	{
 		BspNode *node = nodeStack.top().first;
 		BspNodeGeometry *geom = nodeStack.top().second;
-
+	
 		nodeStack.pop();
 
 		if (node->IsLeaf())
-		{	
-			Debug << "here22" << endl;
+		{
 			// test if this leaf is in valid view space
 			if (node->TreeValid() &&
@@ -1954,85 +1974,88 @@
 				(!onlyUnmailed || !node->Mailed()))
 			{
-				Debug << "here" << endl;
 				bool isAdjacent = true;
-#if 1
-
-				// test all planes of current node if still adjacent
-				for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i)
+
+				if (1)
 				{
-					const int cf =
-						Polygon3::ClassifyPlane(geom->mPolys,
-												halfSpaces[i],
-												mEpsilon);
-
-					if (cf == Polygon3::BACK_SIDE)
+					// test all planes of current node if still adjacent
+					for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i)
 					{
-						isAdjacent = false;
+						const int cf =
+							Polygon3::ClassifyPlane(geom->mPolys,
+													halfSpaces[i],
+													mEpsilon);
+
+						if (cf == Polygon3::BACK_SIDE)
+						{
+							isAdjacent = false;
+						}
 					}
 				}
-#else // TODO: why is this wrong??
-				// test all planes of current node if still adjacent
-				for (int i = 0; (i < (int)nodeGeom.mPolys.size()) && isAdjacent; ++ i)
+				else
 				{
-					Debug << "here33" << endl;
-					Polygon3 *poly = nodeGeom.mPolys[i];
-
-					const int cf =
-						Polygon3::ClassifyPlane(geom->mPolys,
-												poly->GetSupportingPlane(),
-												mEpsilon);
-
-					if (cf == Polygon3::BACK_SIDE)
+					// TODO: why is this wrong??
+					// test all planes of current node if still adjacent
+					for (int i = 0; (i < (int)nodeGeom.mPolys.size()) && isAdjacent; ++ i)
 					{
-						isAdjacent = false;
+						Polygon3 *poly = nodeGeom.mPolys[i];
+
+						const int cf =
+							Polygon3::ClassifyPlane(geom->mPolys,
+													poly->GetSupportingPlane(),
+													mEpsilon);
+
+						if (cf == Polygon3::BACK_SIDE)
+						{
+							isAdjacent = false;
+						}
 					}
 				}
-#endif
-				Debug << "here2" << endl;
 				// neighbor was found
 				if (isAdjacent)
+				{	
 					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
+				}
+			}
+		}
+		else
+		{
+			BspInterior *interior = dynamic_cast<BspInterior *>(node);
+
+			const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys,
+												   interior->GetPlane(),
+												   mEpsilon);
+			
+			BspNode *front = interior->GetFront();
+			BspNode *back = interior->GetBack();
+            
+			BspNodeGeometry *fGeom = new BspNodeGeometry();
+			BspNodeGeometry *bGeom = new BspNodeGeometry();
+
+			geom->SplitGeometry(*fGeom,
+								*bGeom,
+								interior->GetPlane(),
+								mBox,
+								mEpsilon);
+		
+			if (cf == Polygon3::FRONT_SIDE)
+			{
+				nodeStack.push(bspNodePair(interior->GetFront(), fGeom));
+				DEL_PTR(bGeom);
 			}
 			else
 			{
-				BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
-				const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys,
-													   interior->GetPlane(),
-													   mEpsilon);
-			
-				BspNode *front = interior->GetFront();
-				BspNode *back = interior->GetBack();
-            
-				BspNodeGeometry *fGeom = new BspNodeGeometry();
-				BspNodeGeometry *bGeom = new BspNodeGeometry();
-
-				geom->SplitGeometry(*fGeom,
-									*bGeom,
-									interior->GetPlane(),
-									mBox,
-									mEpsilon);
-		
-				if (cf == Polygon3::FRONT_SIDE)
+				if (cf == Polygon3::BACK_SIDE)
 				{
-					nodeStack.push(bspNodePair(interior->GetFront(), fGeom));
-					DEL_PTR(bGeom);
+					nodeStack.push(bspNodePair(interior->GetBack(), bGeom));
+					DEL_PTR(fGeom);
 				}
 				else
-				{
-					if (cf == Polygon3::BACK_SIDE)
-					{
-						nodeStack.push(bspNodePair(interior->GetBack(), bGeom));
-						DEL_PTR(fGeom);
-					}
-					else
-					{	// random decision
-						nodeStack.push(bspNodePair(front, fGeom));
-						nodeStack.push(bspNodePair(back, bGeom));
-					}
+				{	// random decision
+					nodeStack.push(bspNodePair(front, fGeom));
+					nodeStack.push(bspNodePair(back, bGeom));
 				}
 			}
 		}
-
+	
 		DEL_PTR(geom);
 	}
@@ -2792,5 +2815,6 @@
 	mergeStats.Start();
 	// TODO: REMOVE LATER for performance!
-	const bool showMergeStats = true;
+	const bool showMergeStats = false;
+
 	//BspMergeCandidate::sOverallCost = mBox.SurfaceArea() * mStat.maxPvs;
 	long startTime = GetTime();
@@ -2808,5 +2832,5 @@
 		mergeStats.nodes = CollectMergeCandidates(leaves);
 	}
-	
+		
 
 	mergeStats.collectTime = TimeDiff(startTime, GetTime());
@@ -2814,9 +2838,14 @@
 	startTime = GetTime();
 
+	// number of view cells withouth the invalid ones
 	int nViewCells = mStat.Leaves() - mStat.invalidLeaves;
-	int pass = 0;
-	const int nextPass = 200;
-
-	cout << "starting merge ... ";
+	Debug << "number of view cells taken into account: " << nViewCells << endl;
+	// pass is needed for statistics. the last n passes are
+	// recorded
+	const int maxPasses = 1000;
+	int pass = max(nViewCells - mMergeMinViewCells - maxPasses, 0);
+	const int nextPass = 50;
+
+	cout << "starting merge ... " << endl;
 
 	//-- use priority queue to merge leaf pairs
@@ -2825,7 +2854,10 @@
 		    mMergeMaxCostRatio * BspMergeCandidate::sOverallCost))
 	{
-		/*Debug << "abs mergecost: " << mMergeQueue.top().GetMergeCost() << " rel mergecost: "
+#ifdef _DEBUG
+		Debug << "abs mergecost: " << mMergeQueue.top().GetMergeCost() << " rel mergecost: "
 			  << mMergeQueue.top().GetMergeCost() / BspMergeCandidate::sOverallCost 
-			  << " max ratio: " << mMergeMaxCostRatio << endl;*/
+			  << " max ratio: " << mMergeMaxCostRatio << endl;
+#endif
+
 		BspMergeCandidate mc = mMergeQueue.top();
 		mMergeQueue.pop();
@@ -2841,9 +2873,11 @@
 
 			MergeViewCells(mc.GetLeaf1(), mc.GetLeaf2());
-						
-			
+					
 			// increase absolute merge cost
 			BspMergeCandidate::sOverallCost += mc.GetMergeCost();
 			
+
+			-- nViewCells;
+			++ mergeStats.merged;
 
 			if (showMergeStats)
@@ -2858,19 +2892,17 @@
 				mergeStats.accTreeDist += dist;
 
-
-				if (((mergeStats.merged % nextPass) == 0) || (nViewCells == mMergeMinViewCells))
+				//Debug << "viewcells: " << nViewCells << " mergemin " << mMergeMinViewCells << endl;
+				if ((mergeStats.merged == pass) || (nViewCells == mMergeMinViewCells))
 				{
+					pass += nextPass;
 					mStats 
 						<< "#Pass\n" << pass ++ << endl
 						<< "#Merged\n" << mergeStats.merged << endl 
 						<< "#Viewcells\n" << nViewCells << endl 
-						<< "#OverallCost\n" << BspMergeCandidate::sOverallCost << endl 
+						<< "#OverallCost\n" << BspMergeCandidate::sOverallCost << endl
 						<< "#CurrentCost\n" << mergeCost << endl
-						<< "#RelCost\n" << mc.GetMergeCost() / BspMergeCandidate::sOverallCost << endl
+						<< "#RelativeCost\n" << mergeCost / BspMergeCandidate::sOverallCost << endl
 						<< "#CurrentPvs\n" << mc.GetLeaf1()->GetViewCell()->GetPvs().GetSize() << endl;
-
-					cout << "exporting view cells ... ";
-								
-				
+					
 					ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
 					
@@ -2882,5 +2914,5 @@
 						while (!viewCells.empty() && (viewCells.back()->GetId() == -2))
 						{
-							DEL_PTR(viewCells.back());
+							//DEL_PTR(viewCells.back());
 							viewCells.pop_back();
 						}
@@ -2897,16 +2929,20 @@
 					}
 				
-					cout << "finished" << endl;
-					// not part of any leaf
-					//CLEAR_CONTAINER(mOldViewCells);
-					mOldViewCells.clear();
-
-					int newVcSize = (int)mNewViewCells.size();
-					// add new view cells to container
+					int newVcSize = 0;
+					// add new view cells to container only if they don't have been 
+					// merged in the mean time
 					while (!mNewViewCells.empty())
 					{
-						viewCells.push_back(mNewViewCells.back());
+						if (mNewViewCells.back()->GetId() != -2)
+						{
+							viewCells.push_back(mNewViewCells.back());
+							++ newVcSize;
+						}
+
 						mNewViewCells.pop_back();
 					}
+
+					// delete the view cells which were merged
+					CLEAR_CONTAINER(mOldViewCells);
 
 					char s[64];
@@ -2916,9 +2952,9 @@
 					if (exporter)
 					{
+						cout << "exporting " << nViewCells << " merged view cells ... ";
 						exporter->ExportGeometry(objects);
-						Debug << "vc size " << (int)viewCells.size() << " merge queue size: " << (int)mMergeQueue.size() << endl;
+						//Debug << "vc size " << (int)viewCells.size() << " merge queue size: " << (int)mMergeQueue.size() << endl;
 						ViewCellContainer::const_iterator it, it_end = viewCells.end();
 		
-						// new view cells are on the back
 						int i = 0;
 						for (it = viewCells.begin(); it != it_end; ++ it)
@@ -2926,14 +2962,15 @@
 							Material m;
 							// assign special material to new view cells
-							if (i >= (viewCells.size() - newVcSize))
+							// new view cells are on the back of container
+							if (i ++ >= (viewCells.size() - newVcSize))
 							{
 								//m = RandomMaterial();
-								m.mDiffuseColor.r = RandomValue(0.5, 1.0);
-								m.mDiffuseColor.g = RandomValue(0.5, 1.0);
-								m.mDiffuseColor.b = RandomValue(0.5, 1.0);
+								m.mDiffuseColor.r = RandomValue(0.5f, 1.0f);
+								m.mDiffuseColor.g = RandomValue(0.5f, 1.0f);
+								m.mDiffuseColor.b = RandomValue(0.5f, 1.0f);
 							}
 							else
 							{
-								float col = RandomValue(0.1, 0.4);
+								float col = RandomValue(0.1f, 0.4f);
 								m.mDiffuseColor.r = col;
 								m.mDiffuseColor.g = col;
@@ -2944,14 +2981,11 @@
 							mViewCellsManager->ExportVcGeometry(exporter, *it);
 						}
+						delete exporter;
+						cout << "finished" << endl;
+					}
 					
-						delete exporter;
-					}
-					cout << "finished " << endl;
-
 				}
 			}
-
-			-- nViewCells;
-			++ mergeStats.merged;
+			mNewViewCells.clear();
 		}
 		// merge candidate not valid, because one of the leaves was already
@@ -2964,5 +2998,7 @@
 	}
 
-
+	// view cells which were merged and are not part of any leaf
+	CLEAR_CONTAINER(mOldViewCells);
+	
 	cout << "finished merge" << endl;
 	mergeStats.mergeTime = TimeDiff(startTime, GetTime());
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 561)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 562)
@@ -26,5 +26,6 @@
 mTotalArea(0.0f),
 mViewCellsFinished(false),
-mMaxPvsSize(99999),
+mMaxPvsSize(9999999),
+mMinPvsSize(1), // only empty view cells are invalid
 mMaxPvsRatio(1.0)
 {
@@ -39,5 +40,10 @@
 mPostProcessSamples(0),
 mVisualizationSamples(0),
-mViewCellsFinished(false)
+mTotalAreaValid(false),
+mTotalArea(0.0f),
+mViewCellsFinished(false),
+mMaxPvsSize(9999999),
+mMinPvsSize(1), // only empty view cells are invalid
+mMaxPvsRatio(1.0)
 {
 	mViewSpaceBox.Initialize();
@@ -111,9 +117,9 @@
 
 bool ViewCellsManager::CheckValidity(ViewCell *vc, 
-									 float minPvsRatio, 
-									 float maxPvsRatio) const
-{
-	if ((vc->GetPvs().GetSize() > mMaxPvsSize * maxPvsRatio) ||
-		(vc->GetPvs().GetSize() < mMaxPvsSize * minPvsRatio))
+									 int minPvsSize, 
+									 int maxPvsSize) const
+{
+	if ((vc->GetPvs().GetSize() > mMaxPvsSize) ||
+		(vc->GetPvs().GetSize() < mMinPvsSize))
 	{	
 		return false;
@@ -121,4 +127,12 @@
 
 	return true;
+}
+
+
+void ViewCellsManager::SetValidity(ViewCell *vc, 
+								   int minPvs, 
+								   int maxPvs) const
+{
+	vc->SetValid(CheckValidity(vc, minPvs, maxPvs));
 }
 
@@ -427,4 +441,11 @@
 
 
+int ViewCellsManager::GetMinPvsSize() const
+{
+	return mMinPvsSize;
+}
+
+
+
 float ViewCellsManager::GetMaxPvsRatio() const
 {
@@ -442,7 +463,9 @@
 	// matt TODO: remove this!!
 	Ray hray(ray);
+	//static Ray hray;
+	//hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT);
+	
 	float tmin = 0, tmax = 1.0;
 
-	//hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT);
 	if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
 		return;
@@ -451,7 +474,5 @@
 	Vector3 termination = hray.Extrap(tmax);
 
-	CastLineSegment(origin,
-					termination,
-					viewcells);
+	CastLineSegment(origin, termination, viewcells);
 	//Debug << "constribution: " << (int)viewcells.size() << endl;
 	// copy viewcells memory efficiently
@@ -2373,5 +2394,5 @@
 										 ViewCell *vc) const
 {
-	if (CheckValidity(vc, 0.0, mMaxPvsRatio) && (mColorCode == 0)) // Random color
+	if (CheckValidity(vc, mMinPvsSize, mMaxPvsSize) && (mColorCode == 0)) // Random color
 		return;
 
@@ -2406,5 +2427,5 @@
 	}
 
-	m.mDiffuseColor.b = CheckValidity(vc, 0.0, mMaxPvsRatio) ? 1.0f : 0.0f;
+	m.mDiffuseColor.b = CheckValidity(vc, mMinPvsSize, mMaxPvsSize) ? 1.0f : 0.0f;
 	m.mDiffuseColor.r = importance;
 	m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
@@ -2488,7 +2509,8 @@
 	
 	mViewCellsFinished = true;
+	mMaxPvsSize = (int)objects->size();
 
 	FinalizeViewCells(true);
-
+	
 	Debug << (int)mViewCells.size() << " view cells loaded" << endl;
 
