Index: /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 581)
+++ /trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 582)
@@ -176,9 +176,11 @@
 	# samples used for view cell construction
 	Construction {
-		samples 1200000
+		samples 800000
 		samplesPerPass 300000
 	}
 
-	active 150
+	#number of active view cells
+	active 250
+	maxStaticMemory	40
 
 	exportToFile false
@@ -268,5 +270,5 @@
 	PostProcess {
 		maxCostRatio 0.005
-		minViewCells 1000
+		minViewCells 1
 		maxPvsSize   5000
 	}
@@ -279,5 +281,5 @@
 VspBspTree {
 	Construction {
-		samples 900000
+		samples 300000
 		epsilon 0.005
 		randomize false
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 580)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.h	(revision 582)
@@ -218,5 +218,5 @@
 	/** Construct geometry of view cell.
 	*/
-	void ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const;
+	void ConstructGeometry(ViewCell *vc, BspNodeGeometry &geom) const;
 
 	/** Returns random leaf of BSP tree.
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 580)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 582)
@@ -2196,5 +2196,5 @@
 
 	VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(
-		mViewCellsManager->MergeViewCells(*fVc, *bVc));
+		mViewCellsManager->MergeViewCells(fVc, bVc));
 
 	// if merge was unsuccessful
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 581)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 582)
@@ -308,4 +308,5 @@
 {
 	environment->GetBoolValue("ViewCells.Visualization.exportMergedViewCells", mExportMergedViewCells);
+	environment->GetFloatValue("ViewCells.maxStaticMemory", mMaxMemory);
 
 	//-- merge options
@@ -314,7 +315,24 @@
 	environment->GetFloatValue("ViewCells.PostProcess.maxCostRatio", mMergeMaxCostRatio);
 	
+
+	Debug << "========= view cell tree options ================\n";
+	Debug << "minimum view cells: " << mMergeMinViewCells << endl;
+	Debug << "max cost ratio: " << mMergeMaxCostRatio << endl;
+	Debug << "max memory: " << mMaxMemory << endl;
+
 	MergeCandidate::sRenderCostWeight = mRenderCostWeight;
 
 	mStats.open("mergeStats.log");
+}
+
+
+// return memory usage in MB
+float ViewCellsTree::GetMemUsage() const
+{
+	return 0;
+		/*(sizeof(ViewCellsTree) +
+		 mBspStats.Leaves() * sizeof(BspLeaf) +
+		 mBspStats.Interior() * sizeof(BspInterior) +
+		 mBspStats.accumRays * sizeof(RayInfo)) / (1024.0f * 1024.0f);*/
 }
 
@@ -387,8 +405,5 @@
 									  const ObjectContainer &objects)
 {
-	// number of view cells equals the number of leaves 
-	// (without the invalid ones )
-	//mNumViewCells = mBspStats.Leaves();//- mBspStats.invalidLeaves;
-	mNumViewCells = (int)mViewCellsManager->GetViewCells().size();
+	mNumActiveViewCells = (int)mViewCellsManager->GetViewCells().size();
 
 	float variance = 0;
@@ -432,5 +447,5 @@
 	// view cell manager. They will change with
 	// subsequent merges
-	ViewCellContainer &viewCells = mViewCellsManager->GetViewCells();
+	ViewCellContainer &activeViewCells = mViewCellsManager->GetViewCells();
 
 
@@ -455,5 +470,5 @@
 	float realExpectedCost = mExpectedCost;
 	float realAvgRenderCost = mAvgRenderCost;
-	int realNumViewCells = mNumViewCells;
+	int realNumActiveViewCells = mNumActiveViewCells;
 	
 	// maximal ratio of old expected render cost to expected render
@@ -461,5 +476,5 @@
 	float avgCostMaxDeviation;
 	int maxMergesPerPass;
-	int numActiveViewCells = 0;
+	int numMergedViewCells = 0;
 
 	environment->GetIntValue("ViewCells.PostProcess.maxMergesPerPass", maxMergesPerPass);
@@ -472,5 +487,5 @@
 	//-- use priority queue to merge leaf pairs
 
-	while (!mMergeQueue.empty() && (realNumViewCells > mMergeMinViewCells))
+	while (!mMergeQueue.empty())// && (realNumActiveViewCells > mMergeMinViewCells))
 	{
 		//-- reset merge queue if the ratio of current expected cost / real expected cost
@@ -495,8 +510,9 @@
 			mExpectedCost = realExpectedCost;
 			mAvgRenderCost = realAvgRenderCost;
-			mNumViewCells = realNumViewCells;
+			mNumActiveViewCells = realNumActiveViewCells;
 			
-			const int numActiveViewCells = UpdateMergedViewCells(viewCells);
-
+			const int numMergedViewCells = UpdateActiveViewCells(activeViewCells);
+		
+			// recompute priorities => reset render cost
 		    ResetMergeQueue();
 
@@ -509,5 +525,5 @@
 			if (mExportMergedViewCells)
 			{
-				ExportMergedViewCells(viewCells, objects, numActiveViewCells);
+				ExportMergedViewCells(activeViewCells, objects, numMergedViewCells);
 			}
 		}
@@ -524,5 +540,6 @@
 		mMergeQueue.pop();
 	
-		// both view cells equal!
+		// both view cells equal
+		// NOTE: do I really still need this? probably cannot happen!!
 		if (mc.mLeftViewCell == mc.mRightViewCell)
 			continue;
@@ -532,5 +549,5 @@
 			ViewCell::NewMail();
 						
-			-- realNumViewCells;
+			-- realNumActiveViewCells;
 			++ mergeStats.merged;
 			++ mergedPerPass;
@@ -547,5 +564,5 @@
 			mDeviation += mc.GetDeviationIncr();
 						
-			realExpectedCost = totalCost / (float)realNumViewCells;
+			realExpectedCost = totalCost / (float)realNumActiveViewCells;
 			
 			const float currentMergeCost = mc.GetMergeCost();
@@ -557,8 +574,9 @@
 
 			totalPvs += pvsDiff;
+
 			// set timestamp
 			mergedVc->SetTimeStamp(mergeStats.merged);
 
-			realAvgRenderCost = (float)totalPvs / (float)realNumViewCells;
+			realAvgRenderCost = (float)totalPvs / (float)realNumActiveViewCells;
 #if VC_HISTORY
 			if (mc.mLeftViewCell->IsSibling(mc.mRightViewCell))
@@ -566,5 +584,5 @@
 #endif
 			if (((mergeStats.merged % statsOut) == 0) || 
-				(realNumViewCells == mMergeMinViewCells))
+				(realNumActiveViewCells == mMergeMinViewCells))
 			{
 				cout << "merged " << mergeStats.merged << " view cells" << endl;
@@ -573,5 +591,5 @@
 					<< "#Pass\n" << pass << endl
 					<< "#Merged\n" << mergeStats.merged << endl 
-					<< "#Viewcells\n" << realNumViewCells << endl 
+					<< "#Viewcells\n" << realNumActiveViewCells << endl 
 					<< "#CurrentCost\n" << currentMergeCost << endl
 					<< "#RelativeCost\n" << currentMergeCost / mOverallCost << endl
@@ -584,5 +602,5 @@
 					<< "#AvgRenderCost\n" << mAvgRenderCost << endl
 					<< "#expectedCostRatio\n" << mExpectedCost / realExpectedCost << endl
-					<< "#Deviation\n" << mDeviation / (float)realNumViewCells << endl
+					<< "#Deviation\n" << mDeviation / (float)realNumActiveViewCells << endl
 					<< "#TotalDeviation\n" << mDeviation<< endl;
 			}
@@ -592,6 +610,9 @@
 			// merge candidate not valid, because one of the leaves was already
 			// merged with another one => validate and reinsert into queue
-			SetMergeCandidateValid(mc);
-			mMergeQueue.push(mc);
+			if (ValidateMergeCandidate(mc))
+			{
+				EvalMergeCost(mc);
+				mMergeQueue.push(mc);
+			}
 		}
 	}
@@ -600,29 +621,27 @@
 	mExpectedCost = realExpectedCost;
 	mAvgRenderCost = realAvgRenderCost;
-	mNumViewCells = realNumViewCells;
-
-	UpdateMergedViewCells(viewCells);
+	mNumActiveViewCells = realNumActiveViewCells;
+
+	UpdateActiveViewCells(activeViewCells);
 	ResetMergeQueue();
-
 
 	// create a root node if the merge was not done till root level,
 	// else take the single node as new root
-	if ((int)viewCells.size() > 1)
-	{
-		Debug << "here888" << endl;
-		ViewCellInterior *root = new ViewCellInterior();
+	if ((int)activeViewCells.size() > 1)
+	{
+		Debug << "creating root of view cell hierarchy for " << (int)activeViewCells.size() << " view cells" << endl;
+		for (int i = 0;  i < activeViewCells.size(); ++ i){
+			Debug << "here233 " << activeViewCells[i]->GetParent() << endl;
+			Debug << "here233 " << activeViewCells[i] << endl;
+		}
+		ViewCellInterior *root = mViewCellsManager->MergeViewCells(activeViewCells);
 
 		root->SetTimeStamp(mergeStats.merged + 1);
-
-		ViewCellContainer::const_iterator it, it_end = viewCells.end();
-		for (it = viewCells.begin(); it != it_end; ++ it)
-			root->SetupChildLink(*it);
-
 		mRoot = root;
 	}
-	else if ((int)viewCells.size() == 1)
-	{
-		Debug << "here555" << endl;
-		mRoot = viewCells[0];
+	else if ((int)activeViewCells.size() == 1)
+	{
+		Debug << "setting root of the merge history" << endl;
+		mRoot = activeViewCells[0];
 	}
 
@@ -668,6 +687,9 @@
 		
 		// recalculate cost
-		SetMergeCandidateValid(mc);
-		buf.push_back(mc);				
+		if (ValidateMergeCandidate(mc))
+		{
+			EvalMergeCost(mc);
+			buf.push_back(mc);				
+		}
 	}
 
@@ -684,14 +706,21 @@
 
 
-int ViewCellsTree::UpdateMergedViewCells(ViewCellContainer &viewCells)
-{
-	int numActiveViewCells = 0;
-
+int ViewCellsTree::UpdateActiveViewCells(ViewCellContainer &viewCells)
+{
+	int numMergedViewCells = 0;
+
+	Debug << "updating active vc: " << viewCells.size() << endl;
 	// find all already merged view cells and remove them from view cells
+		
+	// sort out all view cells which are not active anymore, i.e., they
+	// were already part of a merge
 	int i = 0;
 
+	ViewCell::NewMail();
+
 	while (1)
 	{
-		while (!viewCells.empty() && (!viewCells.back()->GetParent()))
+		// remove all merged view cells from end of the vector
+		while (!viewCells.empty() && (viewCells.back()->GetParent()))
 		{
 			viewCells.pop_back();
@@ -703,22 +732,26 @@
 
 		// already merged view cell, put it to end of vector
-		if (!viewCells[i]->IsRoot())
+		if (viewCells[i]->GetParent())
 			swap(viewCells[i], viewCells.back());
 		
-		++ i;
-	}
+		viewCells[i ++]->Mail();
+	}
+
 
 	// add new view cells to container only if they don't have been 
 	// merged in the mean time
-	while (!mActiveViewCells.empty())
-	{
-		if (!mActiveViewCells.back()->GetParent())
-		{
-			viewCells.push_back(mActiveViewCells.back());
-			++ numActiveViewCells;
-		}
-
-		mActiveViewCells.pop_back();
-	}
+	ViewCellContainer::const_iterator ait, ait_end = mMergedViewCells.end();
+	for (ait = mMergedViewCells.begin(); ait != ait_end; ++ ait)
+	{
+		ViewCell *vc = mMergedViewCells.back();
+		if (!vc->GetParent() && !vc->Mailed())
+		{
+			vc->Mail();
+			viewCells.push_back(vc);
+			++ numMergedViewCells;
+		}
+	}
+
+	mMergedViewCells.clear();
 
 	// update standard deviation
@@ -737,11 +770,6 @@
 
 	mDeviation /= (float)viewCells.size();
-
-	// clear the view cells which were merged
-	mInactiveViewCells.clear();
-	// remove the new view cells
-	mActiveViewCells.clear();
-
-	return numActiveViewCells;
+	
+	return numMergedViewCells;
 }
 
@@ -749,5 +777,5 @@
 void ViewCellsTree::ExportMergedViewCells(ViewCellContainer &viewCells, 
 										  const ObjectContainer &objects,
-										  const int numActiveViewCells)
+										  const int numMergedViewCells)
 {
 	
@@ -771,5 +799,5 @@
 			// assign special material to new view cells
 			// new view cells are on the back of container
-			if (i ++ >= (viewCells.size() - numActiveViewCells))
+			if (i ++ >= (viewCells.size() - numMergedViewCells))
 			{
 				//m = RandomMaterial();
@@ -798,5 +826,5 @@
 ViewCellInterior *ViewCellsTree::MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff) //const
 {
-	ViewCellInterior *vc = mViewCellsManager->MergeViewCells(*l, *r);
+	ViewCellInterior *vc = mViewCellsManager->MergeViewCells(l, r);
 
 	// if merge was unsuccessful
@@ -817,17 +845,6 @@
 
 
-	//-- clean up old view cells
-	if (0 && !mExportMergedViewCells)
-	{
-		DEL_PTR(l);
-		DEL_PTR(r);
-	}
-	else 
-	{
-		mInactiveViewCells.push_back(l);
-		mInactiveViewCells.push_back(r);
-		
-		mActiveViewCells.push_back(vc);
-	}
+	// new view cells are stored in this vector
+	mMergedViewCells.push_back(vc);
 
 	pvsDiff = vc->GetPvs().GetSize() - pvs1 - pvs2;
@@ -1018,5 +1035,5 @@
 	
 	return mRenderCostWeight * (renderCost1 + renderCost2) +
-		  (1.0f - mRenderCostWeight) * (dev1 + dev2) / (float)mNumViewCells;
+		  (1.0f - mRenderCostWeight) * (dev1 + dev2) / (float)mNumActiveViewCells;
 }
 
@@ -1112,5 +1129,5 @@
 	{
 		const float penalty = EvalPvsPenalty(vc->GetPvs().GetSize(), lower, upper);
-		return (mAvgRenderCost - penalty) * (mAvgRenderCost - penalty) / (float)mNumViewCells;
+		return (mAvgRenderCost - penalty) * (mAvgRenderCost - penalty) / (float)mNumActiveViewCells;
 	}
 
@@ -1128,5 +1145,5 @@
 	{
 		const float penalty = EvalPvsPenalty(vc->GetPvs().GetSize(), lower, upper);
-		return fabs(mAvgRenderCost - penalty) / (float)mNumViewCells;
+		return fabs(mAvgRenderCost - penalty) / (float)mNumActiveViewCells;
 	}
 
@@ -1153,5 +1170,5 @@
 
 
-void ViewCellsTree::SetMergeCandidateValid(MergeCandidate &mc) const
+bool ViewCellsTree::ValidateMergeCandidate(MergeCandidate &mc) const
 {
 	while (mc.mLeftViewCell->mParent)
@@ -1165,5 +1182,5 @@
 	}
 
-	EvalMergeCost(mc);
+	return mc.mLeftViewCell != mc.mRightViewCell;
 }
 
@@ -1210,7 +1227,7 @@
 
 	if (1)
-		newDev = fabs(mAvgRenderCost - newPenalty) / (float)mNumViewCells;
+		newDev = fabs(mAvgRenderCost - newPenalty) / (float)mNumActiveViewCells;
 	else
-		newDev = fabs(mExpectedCost - newCost) / (float)mNumViewCells;
+		newDev = fabs(mExpectedCost - newCost) / (float)mNumActiveViewCells;
 	
 	oldDev = GetDeviation(vc1) + GetDeviation(vc2);
@@ -1251,17 +1268,17 @@
 	TraversalQueue tqueue;
 	tqueue.push(mRoot);
-	Debug << "here34 " << numViewCells << endl;
+	
 	while (!tqueue.empty())
 	{
 		ViewCell *vc = tqueue.top();
-		tqueue.pop();
-		Debug << "here7 " << vc->GetTimeStamp() << endl;
-		if (vc->IsLeaf())
-		{
-			Debug << "here6" << endl;
+		
+		// save the view cells if it is a leaf or if enough view cells have already been traversed
+		// because of the priority queue, this will be the optimal set of v
+		if (vc->IsLeaf() || ((viewCells.size() + tqueue.size()) >= numViewCells))
+		{
 			viewCells.push_back(vc);
 		}
-		else if (viewCells.size() + tqueue.size() < numViewCells)
-		{	Debug << "here4" << endl;
+		else 
+		{	
 			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
 
@@ -1273,4 +1290,6 @@
 			}
 		}
+
+		tqueue.pop();
 	}
 }
@@ -1390,5 +1409,5 @@
 bool MergeCandidate::IsValid() const
 {
-	return !(mLeftViewCell->mParent && mRightViewCell->mParent);
+	return !(mLeftViewCell->mParent || mRightViewCell->mParent);
 }
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 581)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 582)
@@ -135,5 +135,10 @@
 		@returns new view cell based on the merging.
 	*/
-	ViewCellInterior *MergeViewCells(ViewCell &front, ViewCell &back) const;
+	ViewCellInterior *MergeViewCells(ViewCell *front, ViewCell *back) const;
+
+	/** Merges a container of view cells.
+		@returns new view cell based on the merging.
+	*/
+	ViewCellInterior *MergeViewCells(ViewCellContainer &children) const;
 	
 	/** Generates view cell of type specified by this manager
@@ -429,5 +434,5 @@
 	float mMaxPvsRatio;
 
-	int mNumActiveViewCells;
+	int mNumMergedViewCells;
 
 	ViewCellsStatistics mViewCellsStats;
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 580)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 582)
@@ -132,5 +132,5 @@
 	Debug << "max plane candidates: " << mMaxRayCandidates << endl;
 	Debug << "randomize: " << randomize << endl;
-//	Debug << "minimum view cells: " << mMergeMinViewCells << endl;
+
 	Debug << "using area for pvs: " << mUseAreaForPvs << endl;
 	Debug << "render cost weight: " << mRenderCostWeight << endl;
@@ -2049,5 +2049,5 @@
 
 
-void VspBspTree::ConstructGeometry(BspViewCell *vc, 
+void VspBspTree::ConstructGeometry(ViewCell *vc, 
 								   BspNodeGeometry &vcGeom) const
 {
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 581)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 582)
@@ -1325,4 +1325,9 @@
 		"false");
 
+	RegisterOption("ViewCells.maxStaticMemory", 
+		optFloat, 
+		"view_cells_max_static_mem=", 
+		"8.0");
+
 
 	/************************************************************************************/
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 580)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 582)
@@ -1030,4 +1030,5 @@
 }
 
+
 void BspTree::SortSplitCandidates(const PolygonContainer &polys, 
 								  const int axis, 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 581)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 582)
@@ -325,7 +325,8 @@
 	float GetDeviation(ViewCell *vc) const;
 
-	/** Recalculates this merge candidate and sets valid.
-	*/
-	void SetMergeCandidateValid(MergeCandidate &mc) const;
+	/** Tries to set this merge candidate to valid. 
+		@returns false if both view cells are the same
+	*/
+	bool ValidateMergeCandidate(MergeCandidate &mc) const;
 
 	/** Merge view cells of leaves l1 and l2.
@@ -360,8 +361,15 @@
 
 	/** Updates the current top level of view cells.
-	*/
-	int UpdateMergedViewCells(ViewCellContainer &viewCells);
+		@returns number of newly merged view cells
+	*/
+	int UpdateActiveViewCells(ViewCellContainer &viewCells);
 
 	void ComputeCommonPvs(ViewCellInterior *interior);
+
+
+	/** Returns memory usage of view cells.
+	*/
+	float GetMemUsage() const;
+
 
 
@@ -375,6 +383,6 @@
 	
 		
-	ViewCellContainer mInactiveViewCells;
-	ViewCellContainer mActiveViewCells;
+	ViewCellContainer mMergedViewCells;
+	
 
 	/// weights between variance and render cost increase (must be between zero and one)
@@ -389,5 +397,5 @@
 	int mUseAreaForPvs;
 
-	int mNumViewCells;
+	int mNumActiveViewCells;
 
 	/// minimal number of view cells
@@ -402,5 +410,5 @@
 	MergeQueue mMergeQueue;
 
-	
+	float mMaxMemory;
 
 };
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 581)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 582)
@@ -56,5 +56,5 @@
 	environment->GetBoolValue("ViewCells.PostProcess.useRaysForMerge", mUseRaysForMerge);
 	
-	environment->GetIntValue("ViewCells.active", mNumActiveViewCells);
+	environment->GetIntValue("ViewCells.active", mNumMergedViewCells);
 
 	mMinPvsSize = emptyViewCells ? 1 : 0;
@@ -107,4 +107,7 @@
 {
 	cout << "disposing samples ... ";
+	long startTime = GetTime();
+	int n = (int)rays.size();
+
 	if (outRays)
 	{
@@ -121,4 +124,5 @@
 	}
 	cout << "finished" << endl;
+	Debug << "disposed " << n << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
 }
 
@@ -519,5 +523,5 @@
 
 
-ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCell &left, ViewCell &right) const
+ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCell *left, ViewCell *right) const
 {
 	// generate parent view cell
@@ -525,21 +529,39 @@
 
 	// merge pvs
-	vc->GetPvs().Merge(left.GetPvs(), right.GetPvs());
+	vc->GetPvs().Merge(left->GetPvs(), right->GetPvs());
 
 	//-- merge ray sets
 	if (0)
 	{
-		stable_sort(left.mPiercingRays.begin(), left.mPiercingRays.end());
-		stable_sort(right.mPiercingRays.begin(), right.mPiercingRays.end());
-
-		std::merge(left.mPiercingRays.begin(), left.mPiercingRays.end(),
-				   right.mPiercingRays.begin(), right.mPiercingRays.end(),
+		stable_sort(left->mPiercingRays.begin(), left->mPiercingRays.end());
+		stable_sort(right->mPiercingRays.begin(), right->mPiercingRays.end());
+
+		std::merge(left->mPiercingRays.begin(), left->mPiercingRays.end(),
+				   right->mPiercingRays.begin(), right->mPiercingRays.end(),
 				   vc->mPiercingRays.begin());
 	}
 
 
-	vc->SetupChildLink(&left);
-	vc->SetupChildLink(&right);
-
+	vc->SetupChildLink(left);
+	vc->SetupChildLink(right);
+
+
+	return vc;
+}
+
+
+ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCellContainer &children) const
+{
+	ViewCellInterior *vc = new ViewCellInterior();//GenerateViewCell();
+
+	ViewCellContainer::const_iterator it, it_end = children.end();
+
+	for (it = children.begin(); it != it_end; ++ it)
+	{
+		// merge pvs
+		vc->GetPvs().Merge(vc->GetPvs(), (*it)->GetPvs());
+
+		vc->SetupChildLink(*it);
+	}
 
 	return vc;
@@ -845,8 +867,9 @@
 		if (!mOnlyValidViewCells || (*it)->GetValid())
 		{
-			ExportColor(exporter, *it);
-			ExportViewCellGeometry(exporter, *it);
-		}
-	}
+			ExportColor(exporter, *it);		
+			ExportViewCellGeometry(exporter, *it);		
+		}
+	}
+
 }
 
@@ -1175,9 +1198,11 @@
 		VssRayContainer vcRays;
 		Intersectable::NewMail();
-#if 0
-		BspViewCell *vc = dynamic_cast<BspViewCell *>(mViewCells[i]);
-#else
-		BspViewCell *vc = dynamic_cast<BspViewCell *>(mViewCells[Random((int)mViewCells.size())]);
-#endif
+		ViewCell *vc;
+
+		if (0)
+			vc = mViewCells[i];
+		else
+			vc = mViewCells[Random((int)mViewCells.size())];
+
 		cout << "creating output for view cell " << i << " ... ";
 
@@ -1213,6 +1238,8 @@
 
 			//-- export view cell
+#if VC_HISTORY
 			mBspTree->ConstructGeometry(vc, vcGeom);
 			exporter->ExportPolygons(vcGeom.mPolys);
+#endif
 		}
 
@@ -1271,12 +1298,12 @@
 		// cast line segment to get intersections with bsp leaves
 		CastLineSegment(vssRay->mTermination, vssRay->mOrigin, viewCells);
-
+#if VC_HISTORY
 		ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
 		for (vit = viewCells.begin(); vit != vit_end; ++ vit)
 		{
-			BspViewCell *vc = dynamic_cast<BspViewCell *>(*vit);
+			ViewCell *vc = *vit;
 			ray->intersections.push_back(BspIntersection(0, vc->mLeaf));
 		}
-
+#endif
 		mBspRays.push_back(ray);
 	}
@@ -1334,7 +1361,8 @@
 	{
 		BspNodeGeometry geom;
-		mBspTree->ConstructGeometry(
-			dynamic_cast<BspViewCell *>(vc), geom);
+#if VC_HISTORY
+		mBspTree->ConstructGeometry(vc, geom);
 		exporter->ExportPolygons(geom.mPolys);
+#endif
 	}
 }
@@ -2081,5 +2109,5 @@
 	{
 		// we can use the view cells tree hierarchy to get the right set
-		mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells);
+		mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumMergedViewCells);
 	}
 
@@ -2380,5 +2408,5 @@
 			for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit)
 			{
-				BspViewCell *vc = dynamic_cast<BspViewCell *>(*vit);
+				ViewCell *vc = *vit;
 
 				vm = RandomMaterial();
@@ -2547,5 +2575,5 @@
 			for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit)
 			{
-				BspViewCell *vc = dynamic_cast<BspViewCell *>(*vit);
+				ViewCell *vc = *vit;
 
 				ViewCellContainer leaves;
@@ -2658,15 +2686,10 @@
 		VssRayContainer vcRays;
 		Intersectable::NewMail();
-		BspViewCell *vc;
+		ViewCell *vc;
 	
 		if (0) // largest view cell pvs first
-		{
-			vc = dynamic_cast<BspViewCell *>(mViewCells[i]);
-		}
+			vc = mViewCells[i];
 		else
-		{
-			vc = dynamic_cast<BspViewCell *>
-				(mViewCells[Random((int)mViewCells.size())]);
-		}
+			vc = mViewCells[Random((int)mViewCells.size())];
 
         if (1)
@@ -2678,8 +2701,10 @@
 				for	(int j = 0; j < (int)ray->mViewCells.size(); ++ j)
 				{
-					BspViewCell *bspVc = dynamic_cast<BspViewCell *>(ray->mViewCells[j]);
-					BspLeaf *leaf = bspVc->mLeaf;
-					if (vc == bspVc)
+					ViewCell *rayvc = ray->mViewCells[j];
+#if VC_HISTORY
+					BspLeaf *leaf = rayvc->mLeaf;
+					if (vc == rayvc)
 						vcRays.push_back(ray);
+#endif
 				}
 			}
@@ -2835,6 +2860,5 @@
 
 	BspNodeGeometry geom;
-	mVspBspTree->
-		ConstructGeometry(dynamic_cast<BspViewCell *>(vc), geom);
+	mVspBspTree->ConstructGeometry(vc, geom);
 	exporter->ExportPolygons(geom.mPolys);
 }
@@ -2845,5 +2869,4 @@
 	ViewCellContainer leaves;
 	mViewCellsTree->CollectLeaves(vc, leaves);
-
 
 	int maxDist = 0;
@@ -2886,6 +2909,6 @@
 
 	BspNodeGeometry geom;
-	BspViewCell *bspVc = dynamic_cast<BspViewCell *>(vc);
-	mVspBspTree->ConstructGeometry(bspVc, geom);
+	
+	mVspBspTree->ConstructGeometry(vc, geom);
 
 	Mesh *mesh = new Mesh();
@@ -2984,6 +3007,5 @@
 void VspBspViewCellsManager::Finalize(ViewCell *viewCell, const bool createMesh)
 {
-	BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCell);
-	CreateMesh(vc);
+	CreateMesh(viewCell);
 
 	float area = 0;
@@ -2991,5 +3013,5 @@
 
 	ViewCellContainer leaves;
-	mViewCellsTree->CollectLeaves(vc, leaves);
+	mViewCellsTree->CollectLeaves(viewCell, leaves);
 
 	ViewCellContainer::const_iterator it, it_end = leaves.end();
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/common.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/common.h	(revision 574)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/common.h	(revision 582)
@@ -145,5 +145,6 @@
 							while (0)
 #endif
-#endif
+
+#else
 
 #ifndef CLEAR_CONTAINER
@@ -153,4 +154,7 @@
 while (0)
 #endif
+
+#endif
+
 
 inline
