Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 191)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 240)
@@ -5,4 +5,5 @@
 
 class KdNode;
+class BspNode;
 class Ray;
 
@@ -17,4 +18,15 @@
 };
 
+/** Superclass for all types of PVS data.
+*/
+class Pvs {
+public:
+	Pvs(): mSamples(0) {}
+	int mSamples;
+
+	virtual int Compress() = 0;
+	virtual int GetSize() = 0;
+};
+
 struct KdPvsData {
   int mVisibleSamples;
@@ -26,10 +38,10 @@
 
 
-class KdPvs {
+class KdPvs: public Pvs {
 public:
-  int mSamples;
+ 
   KdPvsMap mEntries;
   
-  KdPvs():mSamples(0),mEntries() {}
+  KdPvs():mEntries() {}
   
   KdPvsData *Find(KdNode *node);
@@ -44,5 +56,39 @@
 };
 
+struct LtBspNode
+{
+  bool operator()(const BspNode *a,
+		  const BspNode *b) const
+  {
+	  return a < b;
+  }
+};
 
+struct BspPvsData {
+  int mVisibleSamples;
+  BspPvsData() {}
+  BspPvsData(const int samples): mVisibleSamples(samples) {}
+};
+
+typedef std::map<BspNode *, BspPvsData, LtBspNode> BspPvsMap;
+
+class BspPvs: public Pvs 
+{
+public:
+	BspPvs(): mEntries() {}
+
+	BspPvsMap mEntries;
+ 
+	BspPvsData *Find(BspNode *node);
+	int AddNodeSample(BspNode *node);
+	
+	int Compress() {return 0;}
+	
+	int GetSize() {return mEntries.size();}
+	
+	void GetData(const int index,
+				 BspNode *&node,
+				 BspPvsData &data);
+};
 
 #endif
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 239)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 240)
@@ -230,4 +230,7 @@
 	void Construct(const ObjectContainer &objects);
 
+	int BspTree::CollectLeafPvs();
+
+	void CollectLeaves(vector<BspLeaf *> &leaves);
 
 protected:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 239)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 240)
@@ -11,5 +11,5 @@
 #include <iomanip>
 
-#define INITIAL_TEST_VAL 999999// unreachable high initial value for heuristic evaluation
+#define INITIAL_COST 999999// unreachable high initial cost for heuristic evaluation
 
 int BspTree::sTermMaxPolygons = 10;
@@ -452,5 +452,5 @@
 Plane3 BspTree::SelectPlaneHeuristics(PolygonContainer *polygons, int maxTests) const
 {
-	int bestValue = INITIAL_TEST_VAL;
+	int lowestCost = INITIAL_COST;
 	Plane3 *bestPlane = NULL;
 	
@@ -463,11 +463,11 @@
 		
 		// evaluate current candidate
-		int candidateValue = EvalSplitPlane(polygons, candidatePlane);
+		int candidateCost = EvalSplitPlane(polygons, candidatePlane);
 			
-		if (candidateValue < bestValue)
+		if (candidateCost < lowestCost)
 		{
 			bestPlane = &candidatePlane;
-			bestValue = candidateValue;
-			//Debug << "new plane value " << bestValue << endl;
+			lowestCost = candidateCost;
+			//Debug << "new plane cost " << lowestCost << endl;
 		}
 	}
@@ -593,4 +593,79 @@
 }
 
+void BspTree::CollectLeaves(vector<BspLeaf *> &leaves)
+{
+	stack<BspNode *> nodeStack;
+	nodeStack.push(mRoot);
+ 
+	while (!nodeStack.empty()) 
+	{
+		BspNode *node = nodeStack.top();
+    
+		nodeStack.pop();
+    
+		if (node->IsLeaf()) 
+		{
+			BspLeaf *leaf = (BspLeaf *)node;
+			
+			leaves.push_back(leaf);
+		} else 
+		{
+			BspInterior *interior = dynamic_cast<BspInterior *>(node);
+			nodeStack.push(interior->GetBack());
+			nodeStack.push(interior->GetFront());
+		}
+	}
+}
+
+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();
+					
+				// 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;
+}
+
 void BspTree::EvaluateLeafStats(const BspTraversalData &data)
 {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.cpp	(revision 191)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.cpp	(revision 240)
@@ -42,2 +42,47 @@
   data = (*i).second;
 }
+
+BspPvsData *BspPvs::Find(BspNode *node)
+{
+	BspPvsMap::iterator i = mEntries.find(node);
+	
+	if (i != mEntries.end()) 
+	{
+		//    cout<<node<<" "<<(*i).first<<" "<<(*i).second.mVisibleSamples<<endl;
+		return &(*i).second;
+	} 
+	else
+	  return NULL;
+}
+
+// TODO: Get common ancestor for bsp and kd tree (HierarchyNode)
+int BspPvs::AddNodeSample(BspNode *node)
+{
+  int result;
+  
+  BspPvsData *data = Find(node);
+
+  if (data) 
+  {
+	  data->mVisibleSamples ++;
+	  result = 0;
+  } 
+  else 
+  {
+	  mEntries[node] = BspPvsData(1);
+	  result = 1;
+  }
+
+  return  result;
+}
+
+
+void BspPvs::GetData(const int index, BspNode *&node, BspPvsData &data)
+{
+	BspPvsMap::iterator i = mEntries.begin();
+  
+	for (int k = 0; k!=index && i != mEntries.end(); i++, k++);
+
+	node = (*i).first;
+	data = (*i).second;
+}
