Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 1418)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.cpp	(revision 1545)
@@ -17,5 +17,5 @@
 namespace GtpVisibilityPreprocessor {
 
-
+//////////////
 //-- static members
 
@@ -168,12 +168,15 @@
 mRoot(NULL), 
 mUseAreaForPvs(false),
-mGenerateViewCells(true),
-mTimeStamp(1)
+mUsePredefinedViewCells(false),
+mTimeStamp(1),
+mViewCellsTree(NULL),
+ mOutOfBoundsCellPartOfTree(false)
 {
 	Randomize(); // initialise random generator for heuristics
-
-	mOutOfBoundsCell = GetOrCreateOutOfBoundsCell();
-
+	mOutOfBoundsCell = new BspViewCell();
+
+	/////////
 	//-- termination criteria for autopartition
+
 	Environment::GetSingleton()->GetIntValue("BspTree.Termination.maxDepth", mTermMaxDepth);
 	Environment::GetSingleton()->GetIntValue("BspTree.Termination.minPvs", mTermMinPvs);
@@ -184,5 +187,8 @@
 	Environment::GetSingleton()->GetFloatValue("BspTree.Termination.minAccRayLenght", mTermMinAccRayLength);
 
+	
+	/////////
 	//-- factors for bsp tree split plane heuristics
+
 	Environment::GetSingleton()->GetFloatValue("BspTree.Factor.verticalSplits", mVerticalSplitsFactor);
 	Environment::GetSingleton()->GetFloatValue("BspTree.Factor.largestPolyArea", mLargestPolyAreaFactor);
@@ -196,5 +202,8 @@
 	Environment::GetSingleton()->GetFloatValue("BspTree.Termination.ct_div_ci", mCtDivCi);
 
+
+	///////////
 	//-- termination criteria for axis aligned split
+
 	Environment::GetSingleton()->GetFloatValue("BspTree.Termination.AxisAligned.ct_div_ci", mAxisAlignedCtDivCi);
 	Environment::GetSingleton()->GetFloatValue("BspTree.Termination.maxCostRatio", mMaxCostRatio);
@@ -205,5 +214,9 @@
 	Environment::GetSingleton()->GetIntValue("BspTree.Termination.AxisAligned.minObjects", 
 							 mTermMinObjectsForAxisAligned);
+	
+	
+	//////////////
 	//-- partition criteria
+
 	Environment::GetSingleton()->GetIntValue("BspTree.maxPolyCandidates", mMaxPolyCandidates);
 	Environment::GetSingleton()->GetIntValue("BspTree.maxRayCandidates", mMaxRayCandidates);
@@ -219,4 +232,7 @@
 	mSubdivisionStats.open(subdivisionStatsLog);
 
+	/////////////////////7
+
+	Debug << "BSP options: " << endl;
     Debug << "BSP max depth: " << mTermMaxDepth << endl;
 	Debug << "BSP min PVS: " << mTermMinPvs << endl;
@@ -401,12 +417,11 @@
 {
 	DEL_PTR(mRoot);
-
-	// TODO must be deleted if used!!
-	//if (mGenerateViewCells) DEL_PTR(mOutOfBoundsCell);
-}
-
-BspViewCell *BspTree::GetOutOfBoundsCell()
-{
-	return mOutOfBoundsCell;
+	
+	if (!mOutOfBoundsCellPartOfTree)
+	{
+		// out of bounds cell not part of tree =>
+		// delete manually
+		DEL_PTR(mOutOfBoundsCell);
+	}
 }
 
@@ -418,14 +433,7 @@
 
 
-BspViewCell *BspTree::GetOrCreateOutOfBoundsCell()
-{
-	if (!mOutOfBoundsCell)
-	{
-		mOutOfBoundsCell = new BspViewCell();
-		mOutOfBoundsCell->SetId(-1);
-		mOutOfBoundsCell->SetValid(false);
-	}
-
-	return mOutOfBoundsCell;
+void BspTree::SetViewCellsTree(ViewCellsTree *viewCellsTree)
+{
+	mViewCellsTree = viewCellsTree;
 }
 
@@ -433,11 +441,11 @@
 void BspTree::InsertViewCell(ViewCellLeaf *viewCell)
 {
+	// don't generate new view cell, insert this view cell
+	mUsePredefinedViewCells = true;
 	PolygonContainer *polys = new PolygonContainer();
 
-	// don't generate new view cell, insert this one
-	mGenerateViewCells = false;
 	// extract polygons that guide the split process
 	mStat.polys += AddMeshToPolygons(viewCell->GetMesh(), *polys, viewCell);
-	mBox.Include(viewCell->GetBox()); // add to BSP aabb
+	mBbox.Include(viewCell->GetBox()); // add to BSP aabb
 
 	InsertPolygons(polys);
@@ -459,5 +467,5 @@
 								 new BoundedRayContainer(), 
 								 0, 
-								 mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(), 
+								 mUseAreaForPvs ? mBbox.SurfaceArea() : mBbox.GetVolume(), 
 								 new BspNodeGeometry()));
 
@@ -472,4 +480,5 @@
 			BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
 
+			///////////////////
 			//-- filter view cell polygons down the tree until a leaf is reached
 			if (!tData.mPolygons->empty())
@@ -489,6 +498,6 @@
 				
 				// extract view cells associated with the split polygons
-				ViewCellLeaf *frontViewCell = GetOrCreateOutOfBoundsCell();
-				ViewCellLeaf *backViewCell = GetOrCreateOutOfBoundsCell();
+				ViewCellLeaf *frontViewCell = mOutOfBoundsCell;
+				ViewCellLeaf *backViewCell = mOutOfBoundsCell;
 			
 				BspTraversalData frontData(interior->GetFront(), 
@@ -498,5 +507,5 @@
 										   tData.mRays,
 										   tData.mPvs,
-										   mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(), 
+										   mUseAreaForPvs ? mBbox.SurfaceArea() : mBbox.GetVolume(), 
 										   new BspNodeGeometry());
 
@@ -507,8 +516,8 @@
 										  tData.mRays,
 										  tData.mPvs,
-										   mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(), 
+										   mUseAreaForPvs ? mBbox.SurfaceArea() : mBbox.GetVolume(), 
 										  new BspNodeGeometry());
 
-				if (!mGenerateViewCells)
+				if (mUsePredefinedViewCells)
 				{
 					ExtractViewCells(frontData,
@@ -558,5 +567,7 @@
 		}
 		else
+		{
 			DEL_PTR(poly);
+		}
 	}
 	return (int)mesh->mFaces.size();
@@ -572,14 +583,18 @@
   
 	int polysSize = 0;
-
+	cout << "here55 " << mBbox << endl;
+	
+cout << "here99";
 	for (int i = 0; i < limit; ++ i)
-	{
-		if (viewCells[i]->GetMesh()) // copy the mesh data to polygons
-		{
-			mBox.Include(viewCells[i]->GetBox()); // add to BSP tree aabb
-			polysSize += AddMeshToPolygons(viewCells[i]->GetMesh(), polys, viewCells[i]);
-		}
-	}
-
+	{cout << "q";
+	Mesh *mesh = viewCells[i]->GetMesh();
+		if (mesh) 
+		{cout << "w";
+			// copy the mesh into polygons and add to BSP tree aabb
+			mBbox.Include(viewCells[i]->GetBox()); 
+			polysSize += AddMeshToPolygons(mesh, polys, viewCells[i]);
+		}
+	}
+cout << "here155 " << mBbox << endl;
 	return polysSize;
 }
@@ -593,9 +608,8 @@
 	int limit = (maxObjects > 0) ? 
 		Min((int)objects.size(), maxObjects) : (int)objects.size();
-  
+  cout << "here88";
 	for (int i = 0; i < limit; ++i)
-	{
+	{cout << "e";
 		Intersectable *object = objects[i];
-
 		Mesh *mesh = NULL;
 
@@ -616,5 +630,4 @@
 				mesh = new Mesh();
 				mi->GetTransformedMesh(*mesh);
-				
 				break;
 			}
@@ -624,14 +637,17 @@
 		}
 		
-        if (mesh) // copy the mesh data to polygons
-		{
-			if (addToBbox)
-				mBox.Include(object->GetBox()); // add to BSP tree aabb
-				
-			AddMeshToPolygons(mesh, polys, mOutOfBoundsCell);
-
-			// cleanup
-			if (object->Type() == Intersectable::TRANSFORMED_MESH_INSTANCE)
-				DEL_PTR(mesh);
+        if (!mesh) continue;
+		// copy the mesh data to polygons
+		if (addToBbox)
+		{cout << "b";
+			mBbox.Include(object->GetBox()); // add to BSP tree aabb
+		}
+
+		AddMeshToPolygons(mesh, polys, mOutOfBoundsCell);
+
+		// cleanup
+		if (object->Type() == Intersectable::TRANSFORMED_MESH_INSTANCE)
+		{
+			DEL_PTR(mesh);
 		}	
 	}
@@ -640,9 +656,13 @@
 }
 
-
+	
 void BspTree::Construct(const ViewCellContainer &viewCells)
 {
+	cout << "here5500000000" << endl;
+	// construct hierarchy over the given view cells
+	mUsePredefinedViewCells = true;
+
 	mStat.nodes = 1;
-	mBox.Initialize(); 	// initialise bsp tree bounding box
+	mBbox.Initialize(); // initialise bsp tree bounding box
 
  	// copy view cell meshes into one big polygon soup
@@ -650,6 +670,7 @@
 	mStat.polys = AddToPolygonSoup(viewCells, *polys);
 
-	// view cells are given
-	mGenerateViewCells = false;
+	Exporter *expo = Exporter::GetExporter("dummy2.wrl");
+	expo->ExportPolygons(*polys);
+	delete expo;
 	// construct tree from the view cell polygons
 	Construct(polys, new BoundedRayContainer());
@@ -659,10 +680,12 @@
 void BspTree::Construct(const ObjectContainer &objects)
 {
+	// generate new view cells for this type
+	mUsePredefinedViewCells = false;
+
 	mStat.nodes = 1;
-	mBox.Initialize(); 	// initialise bsp tree bounding box
+	mBbox.Initialize(); 	// initialise bsp tree bounding box
 	
 	PolygonContainer *polys = new PolygonContainer();
 
-	mGenerateViewCells = true;
 	// copy mesh instance polygons into one big polygon soup
 	mStat.polys = AddToPolygonSoup(objects, *polys);
@@ -677,5 +700,5 @@
 	// preprocess: throw out polygons coincident to the view space box (not needed)
 	PolygonContainer boxPolys;
-	mBox.ExtractPolys(boxPolys);
+	mBbox.ExtractPolys(boxPolys);
 	vector<Plane3> boxPlanes;
 
@@ -722,13 +745,20 @@
 
 
-
 void BspTree::Construct(const RayContainer &sampleRays,
 						AxisAlignedBox3 *forcedBoundingBox)
 {
+	// generate new view cells for this contruction type
+	mUsePredefinedViewCells = false;
+
     mStat.nodes = 1;
-	mBox.Initialize(); 	// initialise BSP tree bounding box
-	
+
 	if (forcedBoundingBox)
-		mBox = *forcedBoundingBox;
+	{
+		mBbox = *forcedBoundingBox;
+	}
+	else
+	{
+		mBbox.Initialize(); // initialise BSP tree bounding box	
+	}
 
 	PolygonContainer *polys = new PolygonContainer();
@@ -737,16 +767,13 @@
 	RayContainer::const_iterator rit, rit_end = sampleRays.end();
 
-	// generate view cells
-	mGenerateViewCells = true;
-
 	long startTime = GetTime();
-
 	Debug << "**** Extracting polygons from rays ****\n";
 
 	std::map<Face *, Polygon3 *> facePolyMap;
 
-	//-- extract polygons intersected by the rays
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
 	{
+		//////////////
+		//-- extract polygons intersected by the rays
 		Ray *ray = *rit;
 	
@@ -803,6 +830,9 @@
 	// compute bounding box
 	if (!forcedBoundingBox)
-		mBox.Include(*polys);
-
+	{
+		mBbox.Include(*polys);
+	}
+
+	////////////
 	//-- store rays
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
@@ -812,5 +842,5 @@
 
 		float minT, maxT;
-		if (mBox.GetRaySegment(*ray, minT, maxT))
+		if (mBbox.GetRaySegment(*ray, minT, maxT))
 			rays->push_back(new BoundedRay(ray, minT, maxT));
 	}
@@ -833,22 +863,25 @@
 						AxisAlignedBox3 *forcedBoundingBox)
 {
+	// generate new view cells for this construction type
+	mUsePredefinedViewCells = false;
+
     mStat.nodes = 1;
-	mBox.Initialize(); 	// initialise BSP tree bounding box
+	mBbox.Initialize(); 	// initialise BSP tree bounding box
 	
 	if (forcedBoundingBox)
-		mBox = *forcedBoundingBox;
+	{
+		mBbox = *forcedBoundingBox;
+	}
 
 	BoundedRayContainer *rays = new BoundedRayContainer();
 	PolygonContainer *polys = new PolygonContainer();
 	
-	mGenerateViewCells = true;
-
 	// copy mesh instance polygons into one big polygon soup
 	mStat.polys = AddToPolygonSoup(objects, *polys, 0, !forcedBoundingBox);
 
-
+	///////
+	//-- store rays
 	RayContainer::const_iterator rit, rit_end = sampleRays.end();
-
-	//-- store rays
+	
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
 	{
@@ -857,5 +890,5 @@
 
 		float minT, maxT;
-		if (mBox.GetRaySegment(*ray, minT, maxT))
+		if (mBbox.GetRaySegment(*ray, minT, maxT))
 			rays->push_back(new BoundedRay(ray, minT, maxT));
 	}
@@ -870,5 +903,4 @@
 {
 	BspTraversalStack tStack;
-
 	mRoot = new BspLeaf();
 
@@ -880,5 +912,5 @@
 						   polys, 
 						   0, 
-						   GetOrCreateOutOfBoundsCell(), 
+						   mOutOfBoundsCell, 
 						   rays, 
 						   ComputePvsSize(*rays), 
@@ -886,5 +918,5 @@
 						   geom);
 
-	mTotalCost = tData.mPvs * tData.mProbability / mBox.GetVolume();
+	mTotalCost = tData.mPvs * tData.mProbability / mBbox.GetVolume();
 	mTotalPvsSize = tData.mPvs;
 	
@@ -950,5 +982,7 @@
 BspNode *BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData)
 {
-	//-- terminate traversal  
+	////////
+	//-- terminate traversal
+
 	if (TerminationCriteriaMet(tData))		
 	{
@@ -957,13 +991,16 @@
 		BspViewCell *viewCell;
 
-		// generate new view cell for each leaf
-		if (mGenerateViewCells)
-		{
+		if (!mUsePredefinedViewCells)
+		{	// generate new view cell for each leaf
 			viewCell = new BspViewCell();
 		}
 		else
 		{
-			// add view cell to leaf
+			// add predefined view cell to leaf
 			viewCell = dynamic_cast<BspViewCell *>(tData.mViewCell);
+		
+			/// out of bounds cell can be handled as any other cell
+			if (viewCell == mOutOfBoundsCell)
+				mOutOfBoundsCellPartOfTree = true;
 		}
 
@@ -979,5 +1016,8 @@
 			viewCell->SetVolume(probability);
 
-		//-- add pvs
+		
+		///////////
+		//-- add pvs contribution of rays
+
 		if (viewCell != mOutOfBoundsCell)
 		{
@@ -989,9 +1029,10 @@
 		}
 
-		if (1)
-			EvaluateLeafStats(tData);
-		
+		if (1)EvaluateLeafStats(tData);
+		
+
+		////////
 		//-- clean up
-		
+
 		// discard polygons
 		CLEAR_CONTAINER(*tData.mPolygons);
@@ -1006,5 +1047,7 @@
 	}
 
+	///////////
 	//-- continue subdivision
+
 	PolygonContainer coincident;
 	
@@ -1019,5 +1062,4 @@
 		SubdivideNode(tData, tFrontData, tBackData, coincident);
 
-
 	if (1)
 	{
@@ -1028,5 +1070,5 @@
 		float cBack = (float)tBackData.mPvs * tBackData.mProbability;
 
-		float costDecr = (cFront + cBack - cData) / mBox.GetVolume();
+		float costDecr = (cFront + cBack - cData) / mBbox.GetVolume();
 		
 		mTotalCost += costDecr;
@@ -1040,7 +1082,10 @@
 	}
 
-	// extract view cells from coincident polygons according to plane normal
-    // only if front or back polygons are empty
-	if (!mGenerateViewCells)
+	// extract view cells from coincident polygons 
+	// with respect to the orientation of their normal
+    // note: if front or back polygons are empty, 
+	// we get the valid in - out classification for the view cell
+
+	if (mUsePredefinedViewCells)
 	{
    		ExtractViewCells(tFrontData,
@@ -1057,7 +1102,8 @@
 	tStack.push(tBackData);
 
-	// cleanup
+	////////
+	//-- cleanup
+
 	DEL_PTR(tData.mNode);
-
 	DEL_PTR(tData.mPolygons);
 	DEL_PTR(tData.mRays);
@@ -1080,5 +1126,7 @@
 		coincident.begin(), it_end = coincident.end();
 
+	//////////
 	//-- find first view cells in front and back leafs
+
 	for (; !(foundFront && foundBack) && (it != it_end); ++ it)
 	{
@@ -1108,5 +1156,4 @@
 	// select subdivision plane
 	BspInterior *interior = new BspInterior(SelectPlane(leaf, tData)); 
-	
 	
 #ifdef _DEBUG
@@ -1135,5 +1182,5 @@
 									   *backData.mGeometry, 
 									   interior->mPlane,
-									   mBox,
+									   mBbox,
 									   //0.000000000001);
 									   mEpsilon);
@@ -1274,6 +1321,5 @@
 	const float ratio = newCost / oldCost;
 
-
-#if 0
+#ifdef _DEBUG
   Debug << "====================" << endl;
   Debug << "costRatio=" << ratio << " pos=" << position<<" t=" << (position - minBox)/(maxBox - minBox)
@@ -1430,4 +1476,5 @@
 	return Plane3(pt[0], pt[1], pt[2]);
 }
+
 
 Plane3 BspTree::ChooseCandidatePlane3(const BoundedRayContainer &rays) const
@@ -1697,5 +1744,5 @@
 							   geomBack, 
 							   candidatePlane,
-							   mBox,
+							   mBbox,
 							   mEpsilon);
 
@@ -1856,5 +1903,5 @@
 	if (mSplitPlaneStrategy & VERTICAL_AXIS)
 	{
-		Vector3 tinyAxis(0,0,0); tinyAxis[mBox.Size().TinyAxis()] = 1.0f;
+		Vector3 tinyAxis(0,0,0); tinyAxis[mBbox.Size().TinyAxis()] = 1.0f;
 		// we put a penalty on the dot product between the "tiny" vertical axis
 		// and the split plane axis
@@ -1915,5 +1962,5 @@
 AxisAlignedBox3 BspTree::GetBoundingBox() const
 {
-	return mBox;
+	return mBbox;
 }
 
@@ -1972,5 +2019,5 @@
 	float maxt, mint;
 
-	if (!mBox.GetRaySegment(ray, mint, maxt))
+	if (!mBbox.GetRaySegment(ray, mint, maxt))
 		return 0;
 
@@ -2194,4 +2241,14 @@
 		}
 	}
+
+	// also add out of bounds cell
+	if (0 && !mOutOfBoundsCell->Mailed())
+	{
+		mOutOfBoundsCell->Mail();
+		viewCells.push_back(mOutOfBoundsCell);
+	}
+
+	cout << "here555 " << viewCells.size() << endl;
+
 }
 
@@ -2247,5 +2304,4 @@
 		case Ray::COINCIDENT: // TODO: should really discard ray?
 			frontRays.push_back(bRay);
-			//DEL_PTR(bRay);
 			break;
 		case Ray::BACK:
@@ -2322,4 +2378,8 @@
 								BspNodeGeometry &vcGeom) const
 {
+	// if false, cannot construct geometry for interior leaf
+	if (!mViewCellsTree)
+		return;
+
 	ViewCellContainer leaves;
 	mViewCellsTree->CollectLeaves(vc, leaves);
@@ -2364,5 +2424,5 @@
 
 		for (int j = 0; j < 4; ++ j)
-			vertices.push_back(mBox.GetFace(i).mVertices[j]);
+			vertices.push_back(mBbox.GetFace(i).mVertices[j]);
 
 		Polygon3 *poly = new Polygon3(vertices);
@@ -2533,5 +2593,5 @@
 								*bGeom,
 								interior->GetPlane(),
-								mBox,
+								mBbox,
 								//0.0000001f);
 								mEpsilon);
@@ -2807,7 +2867,7 @@
 	Debug << "leaves in queue: " << numLeaves << endl;
 
-
+#if 0
+	//////////
 	//-- collect the leaves which haven't been found by ray casting
-#if 0
 	cout << "finding additional merge candidates using geometry" << endl;
 	vector<BspLeaf *> leaves;
@@ -2822,5 +2882,4 @@
 
 
-
 /***************************************************************/
 /*              BspNodeGeometry Implementation                 */
@@ -3050,4 +3109,5 @@
 bool BspNodeGeometry::Valid() const
 {
+	// geometry is degenerated
 	if (mPolys.size() < 4)
 		return false;
@@ -3294,5 +3354,7 @@
 		int id = -1;
 		if (leaf->GetViewCell() != mOutOfBoundsCell)
+		{
 			id = leaf->GetViewCell()->GetId();
+		}
 
 		stream << "<Leaf viewCellId=\"" << id << "\" />" << endl;
