Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 286)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 289)
@@ -14,7 +14,7 @@
 #	filename ../data/soda/soda5.dat
 #	viewcells ../data/atlanta/atlanta_viewcells_large.x3d
-#viewcells ../data/atlanta/atlanta_viewcells_large2.x3d
-	viewcells ../data/vienna/viewcells-25-sel.x3d
-#	viewcells ../data/vienna/viewcells-25.x3d
+#	viewcells ../data/atlanta/atlanta_viewcells_large2.x3d
+#	viewcells ../data/vienna/viewcells-25-sel.x3d
+	viewcells ../data/vienna/viewcells-25.x3d
 #	viewcells ../data/vienna/viewcells-large-sel.x3d
 }
@@ -70,11 +70,11 @@
 	splitPlaneStrategy combined
 #       constructionMethod rays
-#	constructionMethod viewCells
-	constructionMethod sceneGeometry
+	constructionMethod viewCells
+#	constructionMethod sceneGeometry
 	maxCandidates 25
 	maxViewCells 999999
 	Termination {
-		maxPolygons 3
-		maxDepth 30
+		maxPolygons 0
+		maxDepth 100
 	}
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 286)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.h	(revision 289)
@@ -15,5 +15,7 @@
 class Intersectable;
 
-/** Class representing a general planar polygon in 3d.
+//typedef Vertex3 Vector3;
+
+/** Class representing a planar convex polygon in 3d.
 */
 class Polygon3
@@ -36,7 +38,6 @@
 		@param front the front polygon
 		@param back the back polygon
-		@param splits number of splits
 	*/
-	void Split(Plane3 *partition, Polygon3 *front, Polygon3 *back, int &splits);
+	void Split(Plane3 *partition, Polygon3 *front, Polygon3 *back);
 
 	enum {BACK_SIDE, FRONT_SIDE, SPLIT, COINCIDENT};
@@ -59,6 +60,9 @@
 	 */
 	Vector3 Center() const;
+	/** Checks if the polygon is valid, i.e., not degenerated.
+		@returns true if polygon is valid.
+	*/
+	bool CheckValid() const; 
 
-		
 	/// vertices are connected in counterclockwise order.
 	VertexContainer mVertices;
@@ -77,6 +81,5 @@
 	VertexContainer::const_iterator it;
 
-	s << setprecision(6) << "Polygon:\n";
-	
+	//s << setprecision(6) << "Polygon:\n";
 	for (it = A.mVertices.begin(); it != A.mVertices.end(); ++it)
 		s << *it << endl;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 286)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 289)
@@ -182,12 +182,14 @@
 		@param frontPolys returns the polygons in the front of the split plane
 		@param backPolys returns the polygons in the back of the split plane
-		@param splits number of splits
-		@returns split polygon if there is a polygon coincident to the split plane, NULL otherwise
-	*/
-	Polygon3 *SplitPolygons(PolygonContainer *polys, 
-							PolygonContainer *frontPolys, 
-						    PolygonContainer *backPolys, 
-							int &splits, 
-							bool storePolys = false);
+		@param coincident returns the polygons coincident to the split plane
+		@param splits returns the splits number of splits	
+		@param storePolys if the polygons should be stored in the node
+	*/
+	void SplitPolygons(PolygonContainer *polys, 
+					   PolygonContainer *frontPolys, 
+					   PolygonContainer *backPolys, 
+					   PolygonContainer *coincident, 
+					   int &splits, 
+					   bool storePolys = false);
 
 	/** Stores polygon in node or discards them according to storePolys.
@@ -195,5 +197,5 @@
 		@param storePolys if the polygons should be stored or discarded
 	*/
-	void ProcessPolygon(Polygon3 *poly, const bool storePolys);
+	void ProcessPolygon(Polygon3 **poly, const bool storePolys);
 
 	friend ostream &operator<<(ostream &s, const BspInterior &A)
@@ -204,5 +206,4 @@
 protected:	
 	
-
 	/// Splitting plane corresponding to this node
 	Plane3 mPlane;
@@ -258,12 +259,12 @@
 		/// current depth
 		int mDepth;
-		/// the polygon that drove the split plane computation
-		Polygon3 *mSplitPoly;
+		/// the view cell associated with this subdivsion
+		ViewCell *mViewCell;
 		/// if the node is an inside or outside node with respect to the parent plane
 		//bool mIsInside;
 		BspTraversalData() {}
 		
-		BspTraversalData(BspNode *node, PolygonContainer *polys, const int depth, Polygon3 *splitPoly): 
-		mNode(node), mPolygons(polys), mDepth(depth), mSplitPoly(splitPoly) {}
+		BspTraversalData(BspNode *node, PolygonContainer *polys, const int depth, ViewCell *viewCell): 
+		mNode(node), mPolygons(polys), mDepth(depth), mViewCell(viewCell) {}
     };
 
@@ -282,5 +283,8 @@
   
 	/** Constructs tree using the given list of view cells.
-	    A pointer to the appropriate view cell is stored within each leaf. 
+	    For this type of construction we filter all view cells down the 
+		tree. If there is no polygon left, the last split plane
+ 	    decides inside or outside of the viewcell. A pointer to the 
+		appropriate view cell is stored within each leaf. 
 		Many leafs can point to the same viewcell.
 	*/
@@ -322,5 +326,5 @@
 	bool Export(const string filename);
 
-static bool displayDebug;
+	//static bool displayDebug;
 protected:
 	
@@ -360,15 +364,20 @@
 	Plane3 SelectPlane(PolygonContainer *polys) const;
 
-	/** Filters next viewcell down the tree and inserts it into the appropriate leaves
+	/** Filters next view cell down the tree and inserts it into the appropriate leaves
 		(i.e., possibly more than one leaf).
 	*/
-	//void InsertViewCell(ViewCell *viewCell);
-	
+	void InsertViewCell(ViewCell *viewCell);
+	/** Inserts polygons down the tree. The polygons are filtered until a leaf is reached,
+		then further subdivided.
+		@param viewCellContainer if not null, a new viewcell is created and stored in the container
+	*/
+	void InsertPolygons(PolygonContainer *polys, ViewCellContainer *viewCells = NULL);
+
 	/** Subdivide leaf.
 		@param leaf the leaf to be subdivided
 		@param polys the input polygons
-		@param frontPolys the polygons of the front child node as a result from splitting
-		@param backPolys the polygons of the back child node as a result from splitting
-		@param splitPoly polygon that is coincident to the split plane, NULL if no such polygon
+		@param frontPolys returns the polygons in the front of the split plane
+		@param backPolys returns the polygons in the back of the split plane
+		@param coincident returns the polygons coincident to the split plane
 		@returns the root of the subdivision
 	*/
@@ -376,5 +385,6 @@
 						 	   PolygonContainer *polys, 
 							   PolygonContainer *frontPolys, 
-							   PolygonContainer *backPolys, Polygon3 **splitPoly);
+							   PolygonContainer *backPolys, 
+							   PolygonContainer *coincident);
 
 	/** Filters polygons down the tree.
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 286)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 289)
@@ -33,6 +33,6 @@
 const int FACTOR_LEAST_SPLITS = 1;
 
-int counter = 0;
-bool BspTree::displayDebug = false;
+//int counter = 0;
+//bool BspTree::displayDebug = false;
 /****************************************************************/
 /*                  class BspNode implementation                */
@@ -88,6 +88,4 @@
 	}
 	else CLEAR_CONTAINER(*polys);
-
-	delete polys;
 }
 
@@ -136,20 +134,22 @@
 }
 
-void BspInterior::ProcessPolygon(Polygon3 *poly, const bool storePolys)
+void BspInterior::ProcessPolygon(Polygon3 **poly, const bool storePolys)
 {
 	if (storePolys) 
-		GetPolygons()->push_back(poly);
+		GetPolygons()->push_back(*poly);
 	else
-		delete poly;
-}
-
-Polygon3 *BspInterior::SplitPolygons(PolygonContainer *polys, 
-									PolygonContainer *frontPolys, 
-									PolygonContainer *backPolys, 
-									int &splits, bool storePolys)
+		DEL_PTR(*poly);
+}
+
+void BspInterior::SplitPolygons(PolygonContainer *polys, 
+								PolygonContainer *frontPolys, 
+								PolygonContainer *backPolys, 
+								PolygonContainer *coincident,
+								int &splits, 
+								bool storePolys)
 {
 	Polygon3 *splitPoly = NULL;
 #ifdef _Debug
-	if (BspTree::displayDebug)Debug << "Splitting polygons of node " << this << " with plane " << mPlane << endl;
+	Debug << "Splitting polygons of node " << this << " with plane " << mPlane << endl;
 #endif
 	while (!polys->empty())
@@ -158,5 +158,5 @@
 		polys->pop_back();
 
-		//if (BspTree::displayDebug) Debug << "New polygon with plane: " << poly->GetSupportingPlane() << "\n";
+		//Debug << "New polygon with plane: " << poly->GetSupportingPlane() << "\n";
 
 		// test if split is neccessary
@@ -170,15 +170,6 @@
 			case Polygon3::COINCIDENT:
 				//Debug << "coincident" << endl;	
-				// same surface normal
-				if (DotProd(mPlane.mNormal, poly->GetSupportingPlane().mNormal) > 0)
-				{
-					if (!splitPoly) // store the split polygon if there is none
-						splitPoly = poly;
-					else //  discard it otherwise
-						ProcessPolygon(poly, storePolys);
-
-					break;
-				}							
-				
+				coincident->push_back(poly);
+				break;			
 			case Polygon3::FRONT_SIDE:	
 				//Debug << "front" << endl;
@@ -192,15 +183,27 @@
 				front_piece = new Polygon3(poly->mParent);
 				back_piece = new Polygon3(poly->mParent);
-
+Debug << "*************\n";
+Debug << "initial poly\n" << *poly << endl;
 				//-- split polygon
-				poly->Split(&mPlane, front_piece, back_piece, splits);
-
-				frontPolys->push_back(front_piece);
-				backPolys->push_back(back_piece);
-
+				poly->Split(&mPlane, front_piece, back_piece);
+				++ splits;
+			
+				//Debug << "poly\n" << *poly << "split front piece not valid\n" << *front_piece << endl;
+				//Debug << "poly\n" << *poly << "split back piece not valid\n" << *back_piece << endl;
+
+				if (front_piece->CheckValid())
+					frontPolys->push_back(front_piece);
+				else
+					DEL_PTR(front_piece);
+				
+				//if (back_piece->CheckValid())
+					backPolys->push_back(back_piece);
+				//else
+				//	DEL_PTR(back_piece);
+Debug << "*************\n";
 #ifdef _DEBUG
 				Debug << "split " << *poly << endl << *front_piece << endl << *back_piece << endl;
 #endif
-				ProcessPolygon(poly, storePolys);
+				ProcessPolygon(&poly, storePolys);
 				
 				break;
@@ -210,8 +213,5 @@
 		}
 	}
-	//if (BspTree::displayDebug) Debug << "inside: " << inside << endl;
-	
-	delete polys; // contains nothing
-	return splitPoly;
+	//Debug << "inside: " << inside << endl;
 }
 
@@ -357,9 +357,6 @@
 }
 
-
-/*void BspTree::InsertViewCell(ViewCell *viewCell)
-{	
-	std::stack<BspTraversalData> tStack;
-	
+void BspTree::InsertViewCell(ViewCell *viewCell)
+{
 	PolygonContainer *polys = new PolygonContainer();
 
@@ -368,8 +365,15 @@
 	mBox.Include(viewCell->GetBox()); // add to BSP aabb
 
-	 // traverse tree or create new one
+	InsertPolygons(polys);
+}
+
+void BspTree::InsertPolygons(PolygonContainer *polys, ViewCellContainer *viewCells)
+{	
+	std::stack<BspTraversalData> tStack;
+		
+	// traverse tree or create new one
 	BspNode *firstNode = mRoot ? mRoot : new BspLeaf();
 
-	tStack.push(BspTraversalData(firstNode, polys, 0, true));
+	tStack.push(BspTraversalData(firstNode, polys, 0, NULL));
 
 	while (!tStack.empty())
@@ -388,16 +392,21 @@
 				PolygonContainer *frontPolys = new PolygonContainer();
 				PolygonContainer *backPolys = new PolygonContainer();
-				Polygon3 *coincident = NULL;
+				PolygonContainer coincident;
 
 				int splits = 0;
 		
 				// split viecell polygons with respect to split plane
-				bool inside = interior->SplitPolygons(tData.mPolygons, 
-													  frontPolys, 
-													  backPolys,
-													  coincident,
-													  splits, 
-													  mStorePolys);
+				interior->SplitPolygons(tData.mPolygons, 
+										frontPolys, 
+										backPolys,
+										&coincident,
+										splits, 
+										mStorePolys);
 				
+				// get view cell associated with the split polygon
+				ViewCell *viewCell = (coincident.size() > 0) ? 
+					dynamic_cast<ViewCell *>(coincident.front()->mParent) : NULL;
+				interior->ProcessPolygons(&coincident, mStorePolys);
+
 				//Debug << "split node on level " << tData.mDepth << " bk: " << backPolys->size() << " frnt: " << frontPolys->size() << endl;
 				mStat.splits += splits;
@@ -405,18 +414,16 @@
 				// push the children on the stack
 				tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, NULL));
-				tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, coincident));
-			
+				tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, viewCell));
 			}
-			else // stop traversal
-			{
-				DEL_PTR(tData.mPolygons);
-			}
+
+			// cleanup
+			DEL_PTR(tData.mPolygons);
 		}
 		else // reached leaf => subdivide current viewcell
 		{
 			if (tData.mPolygons->size() > 0)
-				Debug << "WARNING (should not come here): polygon size: " << (int)tData.mPolygons->size() << " inside: " << tData.mIsInside  << endl;
-
-			BspNode *root = Subdivide(tStack, tData, viewCell);		
+				Debug << "Subdividing further: polygon size: " << (int)tData.mPolygons->size() << ", view cell: " << tData.mViewCell << endl;
+
+			BspNode *root = Subdivide(tStack, tData, viewCells);		
 
 			if (!mRoot) // tree empty => new root
@@ -424,5 +431,5 @@
 		}
 	}
-}*/
+}
 
 void BspTree::InitTree(int maxPolygons, int maxDepth)
@@ -448,5 +455,8 @@
 		poly->mParent = parent; // set parent intersectable
 		polys.push_back(poly);
-		//if (displayDebug)Debug << *poly << endl;
+
+		if (!poly->CheckValid())
+			Debug << "Input polygon not valid: " << *poly << endl;
+
 		++ polysNum;
 	}
@@ -504,10 +514,4 @@
 void BspTree::Construct(const ViewCellContainer &viewCells)
 {
-	//-- Construct tree using the given viewcells
-	
-	/* for this type of construction we filter all viewcells down the 
-	 * tree. If there is no polygon left, the last split plane
-	 * decides inside or outside of the viewcell.
-    */
 	InitTree(sTermMaxPolygons, sTermMaxDepth);
 
@@ -592,42 +596,54 @@
 		}
 		//-- add viewcell stored in split polygon
-		else if (tData.mSplitPoly && tData.mSplitPoly->mParent)
+		else if (tData.mViewCell)
 		{
 			if (leaf->GetViewCell())
 				Debug << "ERROR: leaf already has view cell " << endl;//leaf->mViewCellIdx << endl;
 
-			//leaf->mViewCellIdx = counter;Debug << "insert view cell" << endl;
-
-			leaf->SetViewCell(dynamic_cast<ViewCell *>(tData.mSplitPoly->mParent));
-
-			// discard split polygon
-			tData.mNode->GetParent()->ProcessPolygon(tData.mSplitPoly, mStorePolys);
-		}
-	
-		// add or delete remaining polygons
+			//leaf->mViewCellIdx = counter;
+			Debug << "insert view cell" << endl;
+
+			leaf->SetViewCell(dynamic_cast<ViewCell *>(tData.mViewCell));
+		}
+	
+		// remaining polygons are discarded or added to node
 		tData.mNode->ProcessPolygons(tData.mPolygons, mStorePolys);
-				
+		DEL_PTR(tData.mPolygons);
+
 		return tData.mNode;
 	}
 
-	// discard the split polygon (not needed if traversal continues)
-	if (tData.mSplitPoly)
-		tData.mNode->GetParent()->ProcessPolygon(tData.mSplitPoly, mStorePolys);
-
-	//-- create new subdivided node
+	//-- continue subdivision
 	PolygonContainer *backPolys = new PolygonContainer();
 	PolygonContainer *frontPolys = new PolygonContainer();
-	Polygon3 *splitPoly = NULL;
-	
+	PolygonContainer coincident;
+	
+	// create new interior node and two leaf nodes
 	BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode),
 										  tData.mPolygons,
 										  frontPolys,
 										  backPolys, 
-										  &splitPoly);
+										  &coincident);
+
+	if (coincident.size() == 0) 
+	{
+		Debug << "size is zero at depth " << tData.mDepth << ", #back polys: " << (int)backPolys->size() << ", #front polys: " << (int)frontPolys->size() << endl;
+		if (frontPolys) Debug << "front poly: " << *frontPolys->back() << endl;
+	}
+	//Debug << "coincident size: " << coincident.size() << endl;
+
+	// get view cell associated with the first split polygon
+	ViewCell *viewCell = (coincident.size() > 0) ? 
+					dynamic_cast<ViewCell *>(coincident.front()->mParent) : NULL;
+	interior->ProcessPolygons(&coincident, mStorePolys);
 
 	// push the children on the stack
-	// inside information is only propagated with the back leaf
+	// split polygon is only needed in the back leaf
 	tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, NULL));
-	tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, splitPoly));
+	tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, viewCell));
+
+	// cleanup
+	DEL_PTR(tData.mNode);
+	DEL_PTR(tData.mPolygons);
 
 	return interior;
@@ -638,5 +654,6 @@
 									PolygonContainer *polys, 
 									PolygonContainer *frontPolys,
-									PolygonContainer *backPolys, Polygon3 **splitPoly)
+									PolygonContainer *backPolys, 
+									PolygonContainer *coincident)
 {
 	mStat.nodes += 2;
@@ -651,6 +668,6 @@
 	// split polygon according to current plane
 	int splits = 0;
-		
-	*splitPoly = interior->SplitPolygons(polys, frontPolys, backPolys, splits, mStorePolys);
+	
+	interior->SplitPolygons(polys, frontPolys, backPolys, coincident, splits, mStorePolys);
 	
  	mStat.splits += splits;
@@ -666,9 +683,6 @@
 
 	// and setup child links
-	//interior->SetupChildLinks(new BspLeaf(interior), new BspLeaf(interior, leaf->mViewCell));
 	interior->SetupChildLinks(new BspLeaf(interior), new BspLeaf(interior));
 	
-	delete leaf; // leaf not member of tree anymore
-
 	return interior;
 }
@@ -1038,6 +1052,4 @@
 	{
 		exporter->ExportBspTree(*this);
-		delete exporter;
-
 		return true;
 	}	
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Plane3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Plane3.h	(revision 270)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Plane3.h	(revision 289)
@@ -44,5 +44,5 @@
   {
     const Vector3 v = b - a; // line from A to B
-    float dv = DotProd(mNormal, v);
+    float dv = DotProd(v, mNormal);
     
     if (signum(dv) == 0)
@@ -50,5 +50,5 @@
 		if (coplanar) 
 			(*coplanar) = true;	
-		Debug << "signum is zero" << endl;
+	
 		return a;
 	}
@@ -63,5 +63,5 @@
     
     //return a - Distance(a) * b / dv + Distance(a) * a / dv; // NOTE: gives better precision than calclulating a + u * v
-    return a + (u * v);
+    return a + u * v;
   }
   
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 286)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 289)
@@ -42,21 +42,20 @@
   {
 	  if (vcFilename != "")
-	  {
           p->LoadViewCells(vcFilename);
-		  
-		  Exporter *exporter = Exporter::GetExporter("viewcells.x3d");
-		  if (exporter) 
-		  {	  exporter->ExportViewCells(&p->mViewCells);
-			  delete exporter;  
-		  }
-	  }
 	  else
 		  p->GenerateViewCells();
+
+	  Exporter *exporter = Exporter::GetExporter("viewcells.x3d");
+	  if (exporter) 
+	  {	
+          exporter->ExportViewCells(&p->mViewCells); // export view cells
+		  delete exporter;
+	  }
+	  Debug << "Viewcells loaded / generated. Number of view cells: " << p->mViewCells.size() << endl;
   }
 
   p->BuildBspTree();
   p->BspTreeStatistics(Debug);
-  Debug << "Number of view cells: " << p->mViewCells.size() << endl;
-  p->Export(filename + "-bsptree.x3d", false, false, true);
+  p->Export("vc_bsptree.x3d", false, false, true);
 
 #endif
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 265)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 289)
@@ -352,5 +352,5 @@
   Mesh *mesh = new Mesh;
   // add 6 vertices of the box
-  int index = mesh->mVertices.size();
+  int index = (int)mesh->mVertices.size();
   for (int i=0; i < 8; i++) {
     Vector3 v;
@@ -397,43 +397,63 @@
 	ViewCellContainer mFoundViewCells;
 
-	while (!tStack.empty()) 
-	{
-		BspNode *node = tStack.top();
+	if (tree.StorePolys())
+	{
+		while (!tStack.empty()) 
+		{
+            BspNode *node = tStack.top();
     
-		tStack.pop();
-	
-		if (tree.StorePolys()) // extract the polygons
+			tStack.pop();
+	
+			if (tree.StorePolys()) // extract the polygons
+			{
+				PolygonContainer::const_iterator it;
+				PolygonContainer::const_iterator it_end = node->GetPolygons()->end();
+
+				for (it = node->GetPolygons()->begin(); it != it_end; ++ it)
+					ExportPolygon(*it);
+			}
+
+			if (!node->IsLeaf()) 
+			{
+				BspInterior *interior = dynamic_cast<BspInterior *>(node);
+      
+				tStack.push(interior->GetFront());
+				tStack.push(interior->GetBack());
+
+			}
+		}
+	}
+	else // export view cells
+	{
+		while (!tStack.empty()) 
 		{
-			PolygonContainer::const_iterator it;
-			PolygonContainer::const_iterator it_end = node->GetPolygons()->end();
-
-			for (it = node->GetPolygons()->begin(); it != it_end; ++ it)
-				ExportPolygon(*it);
+            BspNode *node = tStack.top();
+    
+			tStack.pop();
+	
+			if (node->IsLeaf()) 
+			{
+				ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell();
+				if (viewCell)
+					mFoundViewCells.push_back(viewCell);
+			}
+			else
+			{
+				BspInterior *interior = dynamic_cast<BspInterior *>(node);
+      
+				tStack.push(interior->GetFront());
+				tStack.push(interior->GetBack());
+			}
 		}
 
-		if (!node->IsLeaf()) 
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-      
-			tStack.push(interior->GetFront());
-			tStack.push(interior->GetBack());
-
-		}
-		else if (!tree.StorePolys())
-		{
-			ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell();
-			
-			if (viewCell)
-				mFoundViewCells.push_back(viewCell);
-		}
-	}
-	
-	if (!tree.StorePolys())
-	{
-		//move consecutive duplicates past the end; store new end
+		Debug << "Number of view cells with dublicates: " << (int)mFoundViewCells.size() << endl;
+
+        //-- erase dublicates
+		sort(mFoundViewCells.begin(), mFoundViewCells.end());
 		ViewCellContainer::iterator new_end = unique(mFoundViewCells.begin(), mFoundViewCells.end());
-		// delete all elements past new_end 
 		mFoundViewCells.erase(new_end, mFoundViewCells.end());
 		ExportViewCells(&mFoundViewCells);
+
+		Debug << "Number of view cells after erasing dublicates: " << (int)mFoundViewCells.size() << endl;
 	}
 
@@ -458,5 +478,5 @@
     AxisAlignedBox3 box = tree.GetBox(node);
     // add 6 vertices of the box
-    int index = mesh->mVertices.size();
+    int index = (int)mesh->mVertices.size();
     for (int i=0; i < 8; i++) {
       Vector3 v;
@@ -513,5 +533,5 @@
       
       // add 6 vertices of the box
-      int index = mesh->mVertices.size();
+      int index = (int)mesh->mVertices.size();
       for (int i=0; i < 8; i++) {
 	Vector3 v;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 286)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 289)
@@ -6,4 +6,5 @@
 // tolerance value for side relation
 #define SIDE_TOLERANCE 0.002f // TODO: Test different values
+#define SIDE_TOLERANCE_SQRD 0.000004f
 
 Polygon3::Polygon3(): mMaterial(NULL), mParent(NULL)
@@ -38,17 +39,19 @@
 }
 
-void Polygon3::Split(Plane3 *partition, Polygon3 *front, Polygon3 *back, int &splits)
-{
-	splits = 0;
-	Vector3 ptA = mVertices[mVertices.size() - 1];
+void Polygon3::Split(Plane3 *partition, Polygon3 *front, Polygon3 *back)
+{
+	Vector3 ptA = mVertices.back();
 	
 	int sideA = partition->Side(ptA, SIDE_TOLERANCE);
 	
 	VertexContainer::const_iterator it;
+	bool foundSplit = false;
+
+	Vector3 prevSplitPt(ptA);
 
 	// find line - plane intersections
 	for (it = mVertices.begin(); it != mVertices.end(); ++ it)
 	{
-		Vector3 ptB = (*it);
+		Vector3 ptB = *it;
 		int sideB = partition->Side(ptB, SIDE_TOLERANCE);
 	
@@ -60,10 +63,14 @@
 				//-- plane - line intersection
 				Vector3 splitPt = partition->FindIntersection(ptA, ptB);
-			
-				// add vertex to both polygons
-				front->mVertices.push_back(splitPt);
-				back->mVertices.push_back(splitPt);
-			
-				++ splits;
+				Debug << "front split pt " << splitPt << " ptA " << ptA << " ptB " << ptB << " side " << sideB << endl;
+				if (!foundSplit || (SqrDistance(splitPt, prevSplitPt) > SIDE_TOLERANCE_SQRD))
+				{
+					// add vertex to both polygons
+					front->mVertices.push_back(splitPt);
+					back->mVertices.push_back(splitPt);
+
+					foundSplit = true;
+					prevSplitPt = splitPt;
+				}
 			}
 			front->mVertices.push_back(ptB);
@@ -75,10 +82,15 @@
 				//-- plane - line intersection
 				Vector3 splitPt = partition->FindIntersection(ptA, ptB);
-			
-				// add vertex to both polygons
-				front->mVertices.push_back(splitPt);
-				back->mVertices.push_back(splitPt);
-
-				++ splits;
+			//	if (foundSplit) Debug << "back split pt " << splitPt << " prev " << prevSplitPt << endl;
+				if (!foundSplit || (SqrDistance(splitPt, prevSplitPt) > SIDE_TOLERANCE_SQRD))
+				{
+					//Debug << "add back split vertex " << splitPt << endl;
+					// add vertex to both polygons
+					front->mVertices.push_back(splitPt);
+					back->mVertices.push_back(splitPt);
+
+					foundSplit = true;
+					prevSplitPt = splitPt;
+				}//else Debug << "reject back split vertex " << splitPt << endl;	
 			}
 			back->mVertices.push_back(ptB);
@@ -120,5 +132,5 @@
 	{
 		int side = plane.Side(*it, SIDE_TOLERANCE);
-		if (BspTree::displayDebug) Debug << "side: " << side << " " << plane.Distance(*it) << endl;
+		//Debug << "side: " << side << " " << plane.Distance(*it) << endl;
 
 		if (side > 0)
@@ -134,5 +146,11 @@
 		// 3 vertices enough to decide coincident
 		else if (((++ count) >= 3) && !onFrontSide && !onBackSide) 
-			return COINCIDENT;
+		{
+			// Decide if plane and surface normal are same
+			if (DotProd(plane.mNormal, GetSupportingPlane().mNormal) > 0)
+				return COINCIDENT;
+			else 
+				return FRONT_SIDE;
+		}
 	}
 
@@ -159,5 +177,5 @@
 		sum += mVertices[i];
 	
-	return sum/i;
+	return sum/(float)i;
 }
 
@@ -172,2 +190,23 @@
 	}
 }
+
+bool Polygon3::CheckValid() const
+{
+	if (mVertices.size() < 3)
+		return false;
+
+	Vector3 vtx = mVertices.back();
+	VertexContainer::const_iterator it, it_end = mVertices.end();
+
+	for (it = mVertices.begin(); it != it_end; ++it)
+	{
+		if (!(SqrDistance(vtx, *it) > SIDE_TOLERANCE_SQRD))
+		{
+			Debug << "Malformed vertices:\n" << *this << endl;
+			return false;
+		}
+		vtx = *it;
+	}
+	
+	return true;
+}
