Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 501)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 503)
@@ -835,4 +835,5 @@
 
 
+/*
 float VspBspTree::EvalCostRatio(const VspBspTraversalData &tData,
 								const AxisAlignedBox3 &box,
@@ -949,5 +950,5 @@
 	return  (mCtDivCi + newCost) / oldCost;
 }
-
+*/
 
 
@@ -1304,5 +1305,7 @@
 
 
-void VspBspTree::CollectLeaves(vector<BspLeaf *> &leaves) const
+void VspBspTree::CollectLeaves(vector<BspLeaf *> &leaves, 
+							   const bool onlyUnmailed,
+							   const int maxPvsSize) const
 {
 	stack<BspNode *> nodeStack;
@@ -1317,7 +1320,9 @@
 		{
 			// test if this leaf is in valid view space
-			if (node->TreeValid())
+			BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
+			if (leaf->TreeValid() && 
+				(!onlyUnmailed || leaf->Mailed()) &&
+				((maxPvsSize < 0) || (leaf->GetViewCell()->GetPvs().GetSize() <= maxPvsSize)))
 			{
-				BspLeaf *leaf = (BspLeaf *)node;
 				leaves.push_back(leaf);
 			}
@@ -1641,12 +1646,5 @@
 
 void VspBspTree::ConstructGeometry(BspNode *n,
-								   BspNodeGeometry &cell) const
-{
-	ConstructGeometry(n, cell.mPolys);
-}
-
-
-void VspBspTree::ConstructGeometry(BspNode *n,
-								   PolygonContainer &cell) const
+								   BspNodeGeometry &geom) const
 {
 	vector<Plane3> halfSpaces;
@@ -1726,5 +1724,5 @@
 
 		if (candidatePolys[i])
-			cell.push_back(candidatePolys[i]);
+			geom.mPolys.push_back(candidatePolys[i]);
 	}
 }
@@ -1732,5 +1730,5 @@
 
 void VspBspTree::ConstructGeometry(BspViewCell *vc, 
-								   PolygonContainer &vcGeom) const
+								   BspNodeGeometry &vcGeom) const
 {
 	vector<BspLeaf *> leaves = vc->mLeaves;
@@ -1745,5 +1743,5 @@
 						   const bool onlyUnmailed) const
 {
-	PolygonContainer geom;
+	BspNodeGeometry geom;
 	ConstructGeometry(n, geom);
 
@@ -1770,5 +1768,5 @@
 				// test all planes of current node if candidate really
 				// is neighbour
-				PolygonContainer neighborCandidate;
+				BspNodeGeometry neighborCandidate;
 				ConstructGeometry(node, neighborCandidate);
 
@@ -1777,5 +1775,5 @@
 				{
 					const int cf =
-						Polygon3::ClassifyPlane(neighborCandidate,
+						Polygon3::ClassifyPlane(neighborCandidate.mPolys,
 												halfSpaces[i],
 												mEpsilon);
@@ -1787,6 +1785,4 @@
 				if (isAdjacent)
 					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
-
-				CLEAR_CONTAINER(neighborCandidate);
 			}
 		}
@@ -1795,5 +1791,5 @@
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
 
-			const int cf = Polygon3::ClassifyPlane(geom,
+			const int cf = Polygon3::ClassifyPlane(geom.mPolys,
 												   interior->GetPlane(),
 												   mEpsilon);
@@ -1813,5 +1809,4 @@
 	}
 
-	CLEAR_CONTAINER(geom);
 	return (int)neighbors.size();
 }
@@ -1837,13 +1832,12 @@
 		{
 			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
 			BspNode *next;
-
-			PolygonContainer geom;
+			BspNodeGeometry geom;
 
 			// todo: not very efficient: constructs full cell everytime
 			ConstructGeometry(interior, geom);
 
-			const int cf = Polygon3::ClassifyPlane(geom, halfspace, mEpsilon);
+			const int cf = 
+				Polygon3::ClassifyPlane(geom.mPolys, halfspace, mEpsilon);
 
 			if (cf == Polygon3::BACK_SIDE)
@@ -2248,10 +2242,6 @@
 
 
-int VspBspTree::CollectMergeCandidates()
-{
-	vector<BspLeaf *> leaves;
-
-	// collect the leaves, e.g., the "voxels" that will build the view cells
-	CollectLeaves(leaves);
+int VspBspTree::CollectMergeCandidates(const vector<BspLeaf *> leaves)
+{
 	BspLeaf::NewMail();
 
@@ -2291,10 +2281,12 @@
 	vector<BspRay *> bspRays;
 
+	long startTime = GetTime();
 	ConstructBspRays(bspRays, rays);
+	Debug << (int)bspRays.size() << " bsp rays constructed in " << TimeDiff(startTime, GetTime()) * 1e-3f << " secs" << endl;
+
 	map<BspLeaf *, vector<BspLeaf*> > neighborMap;
-
 	vector<BspIntersection>::const_iterator iit;
 
-	int leaves = 0;
+	int numLeaves = 0;
 	
 	BspLeaf::NewMail();
@@ -2321,5 +2313,5 @@
 				leaf->mArea * leaf->mPvs->GetSize();
 			
-			++ leaves;
+			++ numLeaves;
 		}
 		
@@ -2345,5 +2337,5 @@
 					leaf->mArea * leaf->mPvs->GetSize();
 
-				++ leaves;
+				++ numLeaves;
 			}
 		
@@ -2379,10 +2371,16 @@
 	Debug << "neighbormap size: " << (int)neighborMap.size() << endl;
 	Debug << "mergequeue: " << (int)mMergeQueue.size() << endl;
-	Debug << "leaves in queue: " << leaves << endl;
+	Debug << "leaves in queue: " << numLeaves << endl;
 	Debug << "overall cost: " << BspMergeCandidate::sOverallCost << endl;
 
 	CLEAR_CONTAINER(bspRays);
 
-	return leaves;
+	//-- collect the leaves which haven't been found by ray casting
+	vector<BspLeaf *> leaves;
+	CollectLeaves(leaves, true, mMaxPvs);
+	Debug << "found " << (int)leaves.size() << " new leaves" << endl;
+	//CollectMergeCandidates(leaves);
+
+	return numLeaves;
 }
 
@@ -2440,5 +2438,9 @@
 		mergeStats.nodes = CollectMergeCandidates(rays);
 	else
-		mergeStats.nodes = CollectMergeCandidates();
+	{
+		vector<BspLeaf *> leaves;
+		CollectLeaves(leaves);
+		mergeStats.nodes = CollectMergeCandidates(leaves);
+	}
 
 	mergeStats.collectTime = TimeDiff(startTime, GetTime());
@@ -2735,4 +2737,138 @@
 }
 
+#define USE_ASCII 0
+bool VspBspTree::WriteVspBspTree()
+{
+	char fileName[100];
+	environment->GetStringValue("VspBspTree.viewCellsFilename", fileName);
+	
+	/*VssRayContainer::const_iterator it, it_end = samples.end();
+	
+#if USE_ASCII
+	ofstream samplesOut(fileName);
+	if (!samplesOut.is_open())
+		return false;
+
+	for (it = samples.begin(); it != it_end; ++ it)
+	{
+		VssRay *ray = *it;
+		int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;		
+		int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;	
+
+		samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " " 
+				   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " " 
+				   << sourceid << " " << termid << "\n";
+	}
+#else
+	ofstream samplesOut(fileName, ios::binary);
+	if (!samplesOut.is_open())
+		return false;
+
+	for (it = samples.begin(); it != it_end; ++ it)
+	{	
+		VssRay *ray = *it;
+		Vector3 origin(ray->GetOrigin());
+		Vector3 termination(ray->GetTermination());
+		
+		int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;		
+		int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;		
+
+		samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
+		samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
+		samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
+		samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
+    }
+#endif
+
+	samplesOut.close();
+	*/
+	return true;
+}
+
+bool VspBspTree::LoadVspBspTree()
+{
+	/*std::stable_sort(objects.begin(), objects.end(), ilt);
+	char fileName[100];
+	environment->GetStringValue("Preprocessor.samplesFilename", fileName);
+	
+    Vector3 origin, termination;
+	// HACK: needed only for lower_bound algorithm to find the 
+	// intersected objects
+	MeshInstance sObj(NULL);
+	MeshInstance tObj(NULL);
+
+#if USE_ASCII
+	ifstream samplesIn(fileName, ios::binary);
+	if (!samplesIn.is_open())
+		return false;
+
+	string buf;
+	while (!(getline(samplesIn, buf)).eof())
+	{
+		sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d", 
+			   &origin.x, &origin.y, &origin.z,
+			   &termination.x, &termination.y, &termination.z, 
+			   &(sObj.mId), &(tObj.mId));
+		
+		Intersectable *sourceObj = NULL;
+		Intersectable *termObj = NULL;
+		
+		if (sObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &sObj, ilt);
+			sourceObj = *oit;
+		}
+		
+		if (tObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &tObj, ilt);
+			termObj = *oit;
+		}
+
+		samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
+	}
+#else
+	ifstream samplesIn(fileName, ios::binary);
+	if (!samplesIn.is_open())
+		return false;
+
+	while (1)
+	{
+		 samplesIn.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
+		 samplesIn.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
+		 samplesIn.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
+		 samplesIn.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
+		
+		 if (samplesIn.eof())
+			break;
+
+		Intersectable *sourceObj = NULL;
+		Intersectable *termObj = NULL;
+		
+		if (sObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &sObj, ilt);
+			sourceObj = *oit;
+		}
+		
+		if (tObj.mId >= 0)
+		{
+			ObjectContainer::iterator oit =
+				lower_bound(objects.begin(), objects.end(), &tObj, ilt);
+			termObj = *oit;
+		}
+
+		samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
+	}
+
+#endif
+	samplesIn.close();
+*/
+	return true;
+}
+
 
 /************************************************************************/
