Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 580)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 581)
@@ -22,5 +22,5 @@
 	bool operator() (T v1, T v2) const
 	{
-		return (v1->GetTimeStamp() > v2->GetTimeStamp());
+		return (v1->GetTimeStamp() < v2->GetTimeStamp());
 	}
 };
@@ -220,4 +220,5 @@
 
 
+
 /************************************************************************/
 /*                class ViewCellInterior implementation                 */
@@ -471,10 +472,8 @@
 	//-- use priority queue to merge leaf pairs
 
-	while (!mMergeQueue.empty() && (realNumViewCells > mMergeMinViewCells) &&
-		   (mMergeQueue.top().GetRenderCost() < mMergeMaxCostRatio * totalCost))
+	while (!mMergeQueue.empty() && (realNumViewCells > mMergeMinViewCells))
 	{
 		//-- reset merge queue if the ratio of current expected cost / real expected cost
 		//   too small or after a given number of merges
-		if(0)
 		if ((mergedPerPass > maxMergesPerPass) ||
 			(avgCostMaxDeviation > mAvgRenderCost / realAvgRenderCost))
@@ -611,5 +610,8 @@
 	if ((int)viewCells.size() > 1)
 	{
+		Debug << "here888" << endl;
 		ViewCellInterior *root = new ViewCellInterior();
+
+		root->SetTimeStamp(mergeStats.merged + 1);
 
 		ViewCellContainer::const_iterator it, it_end = viewCells.end();
@@ -621,7 +623,9 @@
 	else if ((int)viewCells.size() == 1)
 	{
+		Debug << "here555" << endl;
 		mRoot = viewCells[0];
 	}
 
+	// TODO delete because makes no sense here
 	mergeStats.expectedRenderCost = realExpectedCost;
 	mergeStats.deviation = mDeviation;
@@ -640,4 +644,10 @@
 	//TODO: should return sample contributions?
 	return mergeStats.merged;
+}
+
+
+ViewCell *ViewCellsTree::GetRoot()
+{
+	return mRoot;
 }
 
@@ -1217,18 +1227,110 @@
 {
 	stack<ViewCell *> tstack;
-
-
-}
-
-
-void  ViewCellsTree::CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells)
+	
+	while (!tstack.empty())
+	{
+		ViewCell *viewCell = tstack.top();
+		tstack.pop();
+
+		if (viewCell->IsLeaf())
+		{
+			
+		}
+		else
+		{
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell);			
+			ComputeCommonPvs(interior);
+		}
+	}
+}
+
+
+void ViewCellsTree::CollectBestViewCellSet(ViewCellContainer &viewCells, 
+										   const int numViewCells)
 {
 	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;
+			viewCells.push_back(vc);
+		}
+		else if (viewCells.size() + tqueue.size() < numViewCells)
+		{	Debug << "here4" << endl;
+			ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(vc);
+
+			ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
+
+			for (it = interior->mChildren.begin(); it != it_end; ++ it)
+			{
+				tqueue.push(*it);
+			}
+		}
+	}
+}
+	
+
+void ViewCellsTree::ComputeCommonPvs(ViewCellInterior *interior)
+{
+	Intersectable::NewMail();
+
+	ViewCellContainer::const_iterator cit, cit_end = interior->mChildren.end();
+
+	ObjectPvsMap::const_iterator oit;
+
+	// mail all objects in the leaf sets
+	for (cit = interior->mChildren.begin(); cit != cit_end; ++ cit)
+	{
+		ViewCell *vc = *cit;
+
+		ObjectPvsMap::const_iterator oit_end = vc->GetPvs().mEntries.end();
+
+		for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+		{
+			if (!(*oit).first->Mailed())
+				(*oit).first->Mail();
+			
+			(*oit).first->IncMail();
+		}
+	}
+
+	interior->GetPvs().mEntries.clear();
+    cit_end = interior->mChildren.end();
+	
+	// only the objects which are present in all leaf pvs 
+	// should remain in the parent pvs
+
+	for (cit = interior->mChildren.begin(); cit != cit_end; ++ cit)
+	{
+		ViewCell *vc = *cit;
+
+		ObjectPvsMap::const_iterator oit_end = vc->GetPvs().mEntries.end();
+
+		for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+		{
+			if ((*oit).first->Mailed((int)interior->mChildren.size()))
+			{	
+				interior->GetPvs().AddSample((*oit).first, (*oit).second.mSumPdf);
+				//(*oit)->remove();
+			}
+		}
+	}
+
+	// delete all the objects from the leaf sets which were moved
+	// to parent pvs
+	ObjectPvsMap::const_iterator oit_end = interior->GetPvs().mEntries.end();
+
+	for (oit = interior->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+	{
+		for (cit = interior->mChildren.begin(); cit != cit_end; ++ cit)
+		{
+			(*cit)->GetPvs().RemoveSample((*oit).first, Limits::Infinity);
+		}
 	}
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 573)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 581)
@@ -112,4 +112,5 @@
 };
 
+
 template <typename T>
 int Pvs<T>::Diff(const Pvs<T> &b)
@@ -134,7 +135,4 @@
 
 	mEntries = a.mEntries;
-	// todo: copy all elements instead of inserting
-	//for (it = a.mEntries.begin(); it != a.mEntries.end(); ++ it)
-	//	mEntries.insert(*it);
 	
 	for (it = b.mEntries.begin(); it != b.mEntries.end(); ++ it)
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 580)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 581)
@@ -339,8 +339,15 @@
 	ViewCellsTree *GetViewCellsTree();
 
-	virtual void CollectMergeCandidates(const VssRayContainer &rays, vector<MergeCandidate> &candidates) = 0;
-
+	virtual void CollectMergeCandidates(const VssRayContainer &rays, 
+										vector<MergeCandidate> &candidates) = 0;
+
+	
 
 protected:
+
+	/**
+		if the view cells tree was already constructed or not.
+	*/
+	bool ViewCellsTreeConstructed() const;
 
 	int CastPassSamples(const int samplesPerPass, 
@@ -421,4 +428,6 @@
 	int mMinPvsSize;
 	float mMaxPvsRatio;
+
+	int mNumActiveViewCells;
 
 	ViewCellsStatistics mViewCellsStats;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 580)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 581)
@@ -1206,4 +1206,8 @@
 			"bspTree");
 
+	RegisterOption("ViewCells.active",
+					optInt,
+					"1000");
+
 	RegisterOption("ViewCells.Construction.samples",
 					optInt,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 580)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 581)
@@ -293,4 +293,8 @@
 	void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
 
+	/** Root of view cells tree.
+	*/
+	ViewCell *GetRoot();
+
 protected:
 
@@ -350,6 +354,4 @@
 							   const int numNewViewCells);
 
-
-
 	/** merge queue must be reset after some time because expected value
 		may not be valid.
@@ -360,4 +362,6 @@
 	*/
 	int UpdateMergedViewCells(ViewCellContainer &viewCells);
+
+	void ComputeCommonPvs(ViewCellInterior *interior);
 
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 580)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 581)
@@ -53,8 +53,8 @@
 
 	environment->GetIntValue("ViewCells.Construction.samplesPerPass", mSamplesPerPass);
-
 	environment->GetBoolValue("ViewCells.exportToFile", mExportViewCells);
-
 	environment->GetBoolValue("ViewCells.PostProcess.useRaysForMerge", mUseRaysForMerge);
+	
+	environment->GetIntValue("ViewCells.active", mNumActiveViewCells);
 
 	mMinPvsSize = emptyViewCells ? 1 : 0;
@@ -234,4 +234,10 @@
 
   return true;
+}
+
+
+bool ViewCellsManager::ViewCellsTreeConstructed() const
+{
+	return mViewCellsTree->GetRoot();
 }
 
@@ -684,4 +690,5 @@
 }
 
+
 int ViewCellsManager::GetMinPvsSize() const
 {
@@ -2066,5 +2073,15 @@
 void VspBspViewCellsManager::CollectViewCells()
 {
-	mVspBspTree->CollectViewCells(mViewCells, true);
+	// view cells tree constructed
+	if (!ViewCellsTreeConstructed())
+	{
+		mVspBspTree->CollectViewCells(mViewCells, true);
+	}
+	else 
+	{
+		// we can use the view cells tree hierarchy to get the right set
+		mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells);
+	}
+
 }
 
