Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 256)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 260)
@@ -76,2 +76,12 @@
 	}
 }
+
+ViewCell *ViewCell::Convert2ViewCell(Face *face, float scale)
+{
+	// TODO: delete mesh
+	Mesh *mesh = new Mesh();
+	mesh->mFaces.push_back(face);
+    
+
+	return new ViewCell(mesh);
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 182)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 260)
@@ -374,2 +374,326 @@
 
 
+
+/***********************************************************
+ *         class X3dViewCellsParser implemenation          *
+ ***********************************************************/
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Constructors and Destructor
+// ---------------------------------------------------------------------------
+X3dViewCellsParser::X3dViewCellsParser(ViewCellContainer *viewCells) :
+  mElementCount(0)
+  , mAttrCount(0)
+  , mCharacterCount(0)
+  , mSpaceCount(0)
+  , mViewCells(viewCells)
+{
+}
+
+X3dViewCellsParser::~X3dViewCellsParser()
+{
+}
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
+// ---------------------------------------------------------------------------
+void X3dViewCellsParser::endElement(const XMLCh* const name)
+{
+  StrX lname(name);
+  string element(lname.LocalForm());
+  if (element == "Shape")
+    EndShape();
+}
+
+void
+X3dViewCellsParser::EndShape()
+{
+}
+
+void
+X3dViewCellsParser::StartIndexedFaceSet(
+				      AttributeList&  attributes)
+{
+	int len = attributes.getLength();
+	int i;
+	VertexIndexContainer vertices;
+
+	for (i=0; i < len; i++) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+	    
+		if (attrName == "coordIndex") 
+		{
+			StrX attrValue(attributes.getValue(i));
+			
+			// handle coordIndex
+			vertices.clear();
+			const char *ptr = attrValue.LocalForm();
+			char *endptr;
+		
+			while(1)
+			{
+				int index = strtol(ptr, &endptr, 10);
+				
+				if (ptr == endptr || index == -1) 
+				{
+					if (vertices.size() > 2) 
+					{
+						// the base of all view cells is a triangle.
+						Face *face = new Face(vertices);
+						
+						mViewCells->push_back(ViewCell::Convert2ViewCell(face));						
+					}
+					vertices.clear();
+					
+					if (ptr == endptr)
+						break;
+				} 
+				else 
+				{
+					vertices.push_back(index);
+				}
+	            
+				ptr = endptr;
+			}
+		}
+	}
+}
+
+
+void
+X3dViewCellsParser::StartCoordinate(
+				  AttributeList&  attributes)
+{
+	int len = attributes.getLength();
+	
+	VertexContainer vertices;
+
+	for (int i=0; i < len; i++) 
+	{
+		string attrName(StrX(attributes.getName(i)).LocalForm());
+		
+		if (attrName == "point") 
+		{
+			StrX attrValue(attributes.getValue(i));
+			
+			const char *ptr = attrValue.LocalForm();
+			
+			char *endptr;
+			
+			while (1) 
+			{
+				float x = strtod(ptr, &endptr);
+                
+				if (ptr == endptr)
+					break;
+				ptr = endptr;
+				
+				float y = strtod(ptr, &endptr);
+
+				
+				if (ptr == endptr)
+					break;
+				ptr = endptr;
+
+				float z = strtod(ptr, &endptr);
+
+				if (ptr == endptr)
+					break;
+
+				ptr = endptr;
+				if (*ptr == ',')
+					ptr++;
+
+				Vector3 v(x, y, z);
+				vertices.push_back(v);
+			}
+			mCurrentMesh->mVertices = vertices;
+		}
+	}
+}
+
+
+void
+X3dViewCellsParser::startElement(const XMLCh* const name,
+			       AttributeList&  attributes)
+{
+  StrX lname(name);
+  string element(lname.LocalForm());
+  
+  if (element == "IndexedFaceSet") {
+    // create a new mesh node in the scene graph
+    StartIndexedFaceSet(attributes);
+  }
+
+  if (element == "Shape") {
+    cout<<"+";
+    mCurrentMesh = new Mesh;
+  }
+  
+  if (element == "Coordinate") {
+    if (mCurrentMesh)
+      StartCoordinate(attributes);
+  }
+  
+  if (element == "Material") {
+    StartMaterial(attributes);
+  }
+
+  mElementCount++;
+  mAttrCount += attributes.getLength();
+}
+
+void
+X3dViewCellsParser::characters(const XMLCh* const chars,
+			     const unsigned int length)
+{
+  mCharacterCount += length;
+}
+
+void
+X3dViewCellsParser::ignorableWhitespace(const XMLCh* const chars,
+				      const unsigned int length)
+{
+  mSpaceCount += length;
+}
+
+void
+X3dViewCellsParser::resetDocument()
+{
+  mAttrCount = 0;
+  mCharacterCount = 0;
+  mElementCount = 0;
+  mSpaceCount = 0;
+}
+
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
+// ---------------------------------------------------------------------------
+void
+X3dViewCellsParser::error(const SAXParseException& e)
+{
+  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
+			    << ", line " << e.getLineNumber()
+			    << ", char " << e.getColumnNumber()
+			    << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
+}
+
+void
+X3dViewCellsParser::fatalError(const SAXParseException& e)
+{
+  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
+			    << ", line " << e.getLineNumber()
+			    << ", char " << e.getColumnNumber()
+			    << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
+}
+
+void
+X3dViewCellsParser::warning(const SAXParseException& e)
+{
+  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
+			    << ", line " << e.getLineNumber()
+			    << ", char " << e.getColumnNumber()
+			    << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
+}
+
+
+bool
+X3dParser::ParseFile(const string filename,
+		     SceneGraphNode **root)
+{
+  // Initialize the XML4C system
+  try {
+    XMLPlatformUtils::Initialize();
+  }
+  
+  catch (const XMLException& toCatch)
+    {
+      XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
+				<< StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
+      return false;
+    }
+  
+  
+  //
+  //  Create a SAX parser object. Then, according to what we were told on
+  //  the command line, set the options.
+  //
+  SAXParser* parser = new SAXParser;
+  parser->setValidationScheme(valScheme);
+  parser->setDoNamespaces(doNamespaces);
+  parser->setDoSchema(doSchema);
+  parser->setValidationSchemaFullChecking(schemaFullChecking);
+  
+
+  //
+  //  Create our SAX handler object and install it on the parser, as the
+  //  document and error handler. We are responsible for cleaning them
+  //  up, but since its just stack based here, there's nothing special
+  //  to do.
+  //
+  *root = new SceneGraphNode;
+  X3dViewCellsParser handler(*root);
+  parser->setDocumentHandler(&handler);
+  parser->setErrorHandler(&handler);
+  
+  unsigned long duration;
+  int errorCount = 0;
+  // create a faux scope so that 'src' destructor is called before
+  // XMLPlatformUtils::Terminate
+  {
+    //
+    //  Kick off the parse and catch any exceptions. Create a standard
+    //  input input source and tell the parser to parse from that.
+    //
+    //    StdInInputSource src;
+    try
+      {
+	const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
+	parser->parse(filename.c_str());
+	const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
+	duration = endMillis - startMillis;
+	errorCount = parser->getErrorCount();
+      }
+    catch (const OutOfMemoryException&)
+      {
+	XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
+	errorCount = 2;
+	return false;
+      }
+    catch (const XMLException& e)
+      {
+	XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
+				  << StrX(e.getMessage())
+				  << "\n" << XERCES_STD_QUALIFIER endl;
+	errorCount = 1;
+	return false;
+      }
+
+    
+    // Print out the stats that we collected and time taken
+    if (!errorCount) {
+      XERCES_STD_QUALIFIER cout << filename << ": " << duration << " ms ("
+				<< handler.GetElementCount() << " elems, "
+				<< handler.GetAttrCount() << " attrs, "
+				<< handler.GetSpaceCount() << " spaces, "
+				<< handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
+    }
+  }
+  
+  //
+  //  Delete the parser itself.  Must be done prior to calling Terminate, below.
+  //
+  delete parser;
+  
+  XMLPlatformUtils::Terminate();
+  
+  if (errorCount > 0)
+    return false;
+  else
+    return true;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 240)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Pvs.h	(revision 260)
@@ -85,5 +85,5 @@
 	int Compress() {return 0;}
 	
-	int GetSize() {return mEntries.size();}
+	int GetSize() {return (int)mEntries.size();}
 	
 	void GetData(const int index,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 242)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 260)
@@ -13,5 +13,5 @@
 class Polygon3;
 class AxisAlignedBox3;
-
+class Ray;
 
 //namespace GtpVisibilityPreprocessor {
@@ -19,5 +19,6 @@
 /** Container storing a soup of polygons used during BSP tree construction
 */
-typedef std::vector<Polygon3 *> PolygonContainer;
+typedef vector<Polygon3 *> PolygonContainer;
+typedef vector<Ray *> RayContainer;
 
 struct BspRayTraversalData 
@@ -125,8 +126,12 @@
 	void SetParent(BspInterior *parent);
 
+	PolygonContainer *GetPolygons();
+
 protected:
 
 	/// parent of this node
 	BspInterior *mParent;
+
+	PolygonContainer mPolygons;
 };
 
@@ -158,5 +163,5 @@
 	*/
 	void SplitPolygons(PolygonContainer *polys, PolygonContainer *frontPolys, 
-					   PolygonContainer *backPolys, int &splits);
+					   PolygonContainer *backPolys, int &splits, bool storePolys = false);
 
 	friend ostream &operator<<(ostream &s, const BspInterior &A)
@@ -180,12 +185,24 @@
 class BspLeaf : public BspNode 
 {
+	friend BspTree;
+
 public:
 	BspLeaf(ViewCell *viewCell = NULL);
 
-	/** @return true since it is an interior node */
+	/** @return true since it is an interior node 
+	*/
 	bool IsLeaf() const;
+	/** Returns pointer from view cell.
+	*/
 	ViewCell *GetViewCell();
+	/** Sets pointer to view cell.
+	*/
+	void SetViewCell(ViewCell *viewCell);
 
 protected:
+
+	/** Helper function used to add remaining polygons to leaf.
+	*/
+	void AddPolygons(PolygonContainer *polys);
 
 	/// polygonal representation of this viewcell
@@ -222,5 +239,5 @@
 
 	/// BSP tree construction type
-	enum {VIEWCELLS, SCENE_GEOMETRY};
+	enum {VIEWCELLS, SCENE_GEOMETRY, RAYS};
 
 	/** Default constructor creating an empty tree.
@@ -232,15 +249,24 @@
 	const BspTreeStatistics &GetStatistics() const; 
   
-	/** Constructs tree using the given list of viewcells.
-	    A pointer to the appropriate viewcell is stored within each leaf. 
+	/** Constructs tree using the given list of view cells.
+	    A pointer to the appropriate view cell is stored within each leaf. 
 		Many leafs can point to the same viewcell.
 	*/
 	void Construct(const ViewCellContainer &viewCells);
-	/** Constructs tree using the given list of objects. Each leaf is taken as viewcell.
-	    No objects are treated as viewcells explicitly.
+
+	/** Constructs tree using the given list of objects. 
+	    Note that the objects are not taken as view cells, but the view cells are
+		constructed from the subdivision: Each leaf is taken as one viewcell;
 
 		@param objects list of objects
-	*/
-	void Construct(const ObjectContainer &objects);
+		@returns list of view cells.
+	*/
+	ViewCellContainer *Construct(const ObjectContainer &objects);
+
+	/** Constructs tree using the given number of rays
+	    @param objects list of objects
+		@returns list of view cells.
+	*/
+	ViewCellContainer *Construct(const RayContainer &rays);
 
 	int CollectLeafPvs();
@@ -255,7 +281,23 @@
 	*/
 	BspNode *GetRoot() const;
+
+	/** If the view cell polygons are stored in the nodes.
+	*/
+	bool StorePolys() const;
 
 protected:
 	
+	/** Initialises BSP tree.
+		@param maxPolygons the maximal polygon count before termination of 
+		subdivision
+		@param maxDepth the maximal depth before termination of 
+		subdivision
+	*/
+	void InitTree(int maxPolygons, int maxDepth);
+
+	/** Constructs the tree from the given list of polygons.
+	*/
+	void Construct(PolygonContainer *polys);
+
 	/** Evaluates plane classification with respect to the plane's 
 		contribution for a balanced tree.
@@ -301,8 +343,10 @@
 		@param backPolys the polygons of the back child node as a result from splitting
 	*/
-	BspNode *SubdivideNode(BspLeaf *leaf, BspInterior *parent, 
-							PolygonContainer *polys, const int depth, 
-							ViewCell *viewCell,
-							PolygonContainer *frontPolys, PolygonContainer *backPolys);
+	BspNode *SubdivideNode(BspLeaf *leaf, 
+						   BspInterior *parent, 
+						   PolygonContainer *polys, 
+						   const int depth, 
+						   PolygonContainer *frontPolys, 
+						   PolygonContainer *backPolys);
 
 	/** Filters polygons down the tree.
@@ -321,8 +365,14 @@
 	Plane3 SelectPlaneHeuristics(PolygonContainer *polygons, int maxTests) const;
 
-	/** Extracts the meshes of the objects and copies them into the mesh. Also calculcates the bounding box of the tree.
+	/** Extracts the meshes of the objects and copies them into the mesh. 
+		Adds object aabb to the aabb of the tree.
 		@param maxPolys the maximal number of objects to be stored as polygons
 	*/
 	void Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects);
+	/** Extracts the meshes of the view cells and copies them into the mesh. 
+		Adds view cell aabb to the aabb of the tree.
+		@param maxPolys the maximal number of objects to be stored as polygons
+	*/
+	void Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects);
 
 	/** Add this mesh as polygons to polygon container.
@@ -353,4 +403,10 @@
 	/// box around the whole view domain
 	AxisAlignedBox3 mBox;
+
+		/// if view cell calculation is incremential
+	bool mIsIncremential;
+
+	/// if polygons should be stored in the tree
+	bool mStorePolys;
 
 public:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 238)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 260)
@@ -1066,5 +1066,10 @@
 		 optString,
 		 "-scene_filename=",
-		 "soda.x3d");
+		 "atlanta2.x3d");
+
+  RegisterOption("Scene.viewcells",
+		 optString,
+		 "-viewcells_filename=",
+		 "atlanta_viewcells_large.x3d");
 
   RegisterOption("Unigraphics.meshGrouping",
@@ -1179,5 +1184,5 @@
 	  optInt,
 	  "-bsp_max_viewcells=",
-	  "100");
+	  "9999");
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 258)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 260)
@@ -45,4 +45,9 @@
 }
 
+PolygonContainer *BspNode::GetPolygons()
+{
+	return &mPolygons;
+}
+
 /****************************************************************/
 /*              class BspInterior implementation                */
@@ -94,5 +99,5 @@
 								PolygonContainer *frontPolys, 
 								PolygonContainer *backPolys, 
-								int &splits)
+								int &splits, bool storePolys)
 {
 	while (!polys->empty())
@@ -110,4 +115,14 @@
 		{
 			case Polygon3::COINCIDENT:
+				// same sides => discard
+				if (DotProd(poly->GetSupportingPlane().mNormal, mPlane.mNormal) > 0) 
+				{
+					if (storePolys)
+						mPolygons.push_back(poly);
+					else
+						DEL_PTR(poly);
+				}
+				else
+					backPolys->push_back(poly);
 				break; // TODO: compare normals
 			case Polygon3::FRONT_SIDE:
@@ -127,16 +142,20 @@
 				backPolys->push_back(back_piece);
 				
+				if (storePolys)
+					mPolygons.push_back(poly);
+				else
+					DEL_PTR(poly);
 #ifdef _DEBUG
-				//				Debug << "split " << poly << endl << front << endl << back << endl;
+				Debug << "split " << poly << endl << front << endl << back << endl;
 #endif
-				// don't need polygon anymore
-				DEL_PTR(poly);
-
 				break;
 			default:
-				Debug << "SHOULD NEVER COME HERE\n";
+                Debug << "SHOULD NEVER COME HERE\n";
 				break;
 		}
 	}
+
+	// contains nothing
+	delete polys;
 }
 
@@ -154,4 +173,9 @@
 }
 
+void BspLeaf::SetViewCell(ViewCell *viewCell)
+{
+	mViewCell = viewCell;
+}
+
 bool BspLeaf::IsLeaf() const 
 { 
@@ -159,10 +183,22 @@
 }
 
-
+void BspLeaf::AddPolygons(PolygonContainer *polys)
+{
+	while (!polys->empty())
+	{
+		mPolygons.push_back(polys->back());
+		polys->pop_back();
+	}
+}
 /****************************************************************/
 /*                  class BspTree implementation                */
 /****************************************************************/
 
-BspTree::BspTree(): mTermMaxPolygons(0), mTermMaxDepth(0), mRoot(NULL)
+BspTree::BspTree(): 
+mTermMaxPolygons(0), 
+mTermMaxDepth(0), 
+mRoot(NULL), 
+mIsIncremential(false),
+mStorePolys(false)
 {
 	Randomize(); // initialise random generator for heuristics
@@ -243,4 +279,8 @@
 	    tStack.pop();
 	
+		/// if we store
+		if (mStorePolys)
+			Polygon3::DeletePolygons(&node->mPolygons);
+
 		if (!node->IsLeaf())
 		{
@@ -248,7 +288,4 @@
 
 			// push the children on the stack (there are always two children)
-			interior->GetBack()->mParent = NULL;
-			interior->GetFront()->mParent = NULL;
-
 			tStack.push(interior->GetBack());
 			tStack.push(interior->GetFront());
@@ -268,5 +305,5 @@
 	// copy polygon information to guide the split process
 	AddMesh2Polygons(viewCell->GetMesh(), polys);
-	mBox.Include(viewCell->GetBox()); // also add to BSP root box
+	mBox.Include(viewCell->GetBox()); // add to BSP aabb
 
 	BspNode *firstNode = mRoot ? mRoot : new BspLeaf(); // traverse tree or create new one
@@ -292,24 +329,30 @@
 			// split viecell polygons with respect to split plane
 			interior->SplitPolygons(tData.mPolygons, frontPolys, backPolys, splits);
+
 			mStat.splits += splits;
 
 			// push the children on the stack
-			if (frontPolys->size() > 0) // if polygons on this side of bsp tree
+			if (frontPolys->size() > 0) // if polygons on front side of bsp tree
+			{
 				tStack.push(BspTraversalData(interior->GetFront(), interior->GetParent(), 
 							frontPolys, tData.mDepth + 1));
-			else
+			}
+			else // front side polygons empty
 				delete frontPolys;
 
-			if (backPolys->size() > 0) // if polygons on this side of bsp tree
+			if (backPolys->size() > 0) // if polygons on backc side of bsp tree
+			{
 				tStack.push(BspTraversalData(interior->GetBack(), interior->GetParent(), 
 							backPolys, tData.mDepth + 1));
-			else
+			}
+			else // back side polygons empty
 				delete backPolys;
 		}
 		else // reached leaf => subdivide current viewcell
 		{
-			BspNode *root = Subdivide(tStack, tData, NULL);
-
-			if (!mRoot) // take as root if there is none yet
+			BspNode *root = Subdivide(tStack, tData, viewCell);
+
+            // tree empty => new root
+			if (!mRoot)
 				mRoot = root;				
 		}
@@ -317,20 +360,13 @@
 }
 
-void BspTree::Construct(const ViewCellContainer &viewCells)
-{
-	// for this type of construction we split until no polygons is left
-	mTermMaxPolygons = 0;
-	mTermMaxDepth = sTermMaxDepth;
-
+void BspTree::InitTree(int maxPolygons, int maxDepth)
+{
+	mTermMaxPolygons = maxPolygons;
+	mTermMaxDepth = maxDepth;
 	mStat.nodes = 1;
-
-	// insert all viewcells
-	ViewCellContainer::const_iterator it;
-
-	for (it = viewCells.begin(); it != viewCells.end(); ++ it)
-	{
-		InsertViewCell(*it);
-	}
-}
+	mBox.Initialize(); 	// initialise bsp tree bounding box
+}
+
+
 
 void BspTree::AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys)
@@ -346,20 +382,28 @@
 }
 
-void BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects)
-{
-	ObjectContainer::const_iterator it, it_end = objects.end();
-
-	int limit = (maxObjects > 0) ? Min((int)objects.size(), maxObjects) : (int)objects.size();
-	
-	// initialise bounding box
-	mBox.Initialize();
+void BspTree::Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects)
+{
+	int limit = (maxObjects > 0) ? Min((int)viewCells.size(), maxObjects) : (int)viewCells.size();
   
 	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
+			AddMesh2Polygons(viewCells[i]->GetMesh(), polys);
+		}
+	}
+}
+
+void BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects)
+{
+	int limit = (maxObjects > 0) ? Min((int)objects.size(), maxObjects) : (int)objects.size();
+  
+	for (int i = 0; i < limit; ++i)
+	{
 		Intersectable *object = objects[i];//*it;
 		Mesh *mesh = NULL;
 
-		// extract the meshes
-		switch (object->Type())
+		switch (object->Type()) // extract the meshes
 		{
 		case Intersectable::MESH_INSTANCE:
@@ -376,28 +420,77 @@
         if (mesh) // copy the mesh data to polygons
 		{
-			mBox.Include(object->GetBox()); // also add to BSP root box
+			mBox.Include(object->GetBox()); // add to BSP tree aabb
 			AddMesh2Polygons(mesh, polys);
 		}
 	}
 
-	Debug << "Number of polygons: " << polys.size() << ", BSP root box: " << mBox << endl;
-}
-
-void BspTree::Construct(const ObjectContainer &objects)
-{
+	Debug << "Number of polygons: " << (int)polys.size() << ", BSP root box: " << mBox << endl;
+}
+
+void BspTree::Construct(const ViewCellContainer &viewCells)
+{
+	//-- Construct tree using the given viewcells
+	
+	/* for this type of construction we filter all viewcells down the 
+	 * tree until there is no polygon left. The split of the last polygon 
+	 * decides inside or outside of the viewcell.
+    */
+	const int maxPolygons = 0;
+	const int maxDepth = 99999;
+	InitTree(maxPolygons, maxDepth);
+	
+
+	// tree is completely constructed before 
+	// view cells are not inserted one after another => better tree behaviour
+	if (!mIsIncremential)
+	{
+		// copy view cell meshes into one big polygon soup
+		PolygonContainer *polys = new PolygonContainer();
+		Copy2PolygonSoup(viewCells, *polys, sMaxCandidates);
+
+		// construct tree from viewcell polygons
+		Construct(polys);
+	}
+
+	// insert all viewcells
+	ViewCellContainer::const_iterator it;
+
+	for (it = viewCells.begin(); it != viewCells.end(); ++ it)
+	{
+		InsertViewCell(*it);
+	}
+}
+
+
+ViewCellContainer *BspTree::Construct(const ObjectContainer &objects)
+{
+#ifdef _DEBUG
 	Debug << "Constructing tree using object container\n";
-
-	mTermMaxPolygons = sTermMaxPolygons;
-	mTermMaxDepth = sTermMaxDepth;
-
-	mStat.nodes = 1;
-
+#endif
+	// take termination criteria from globals
+	InitTree(mTermMaxPolygons, mTermMaxDepth);
+
+	PolygonContainer *polys = new PolygonContainer();
+	
+	// copy mesh instance polygons into one big polygon soup
+	Copy2PolygonSoup(objects, *polys, sMaxCandidates);
+
+	// construct tree from polygon soup
+	Construct(polys);
+
+	return NULL;// TODO
+}
+
+ViewCellContainer *BspTree::Construct(const RayContainer &rays)
+{
+	// TODO
+	return NULL;
+}
+
+void BspTree::Construct(PolygonContainer *polys)
+{
 	std::stack<BspTraversalData> tStack;
-	PolygonContainer *polys = new PolygonContainer();
-	
-	// copy mesh instance polygons into one big polygon soup
-	Copy2PolygonSoup(objects, *polys, 100);
-
-	BspTraversalData tData(new BspLeaf(), mRoot->GetParent(), polys, 0); // new root corresponding to unbounded space
+	// new root corresponding to unbounded space
+	BspTraversalData tData(new BspLeaf(), mRoot->GetParent(), polys, 0);
 
 	tStack.push(tData);
@@ -411,10 +504,13 @@
 		BspNode *root = Subdivide(tStack, tData);
 
-		if (!mRoot)
+		if (!mRoot) // empty tree => new root
 			mRoot = root;
 	}
 }
 
-BspNode * BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, ViewCell *viewCell)
+
+BspNode * BspTree::Subdivide(BspTraversalStack &tStack, 
+							 BspTraversalData &tData, 
+							 ViewCell *viewCell)
 {
 	PolygonContainer *backPolys = new PolygonContainer();
@@ -425,5 +521,4 @@
 								  tData.mPolygons,
 								  tData.mDepth,
-								  viewCell,
 								  frontPolys,
 								  backPolys);
@@ -440,8 +535,64 @@
 	{
 		EvaluateLeafStats(tData);
-		// don't need to store polygon information => delete polygons
-		Polygon3::DeletePolygons(tData.mPolygons);
-	}
-
+
+		// add view cell if in positive halfspace
+		if (!tData.mParent || (node == tData.mParent->GetFront()))
+			dynamic_cast<BspLeaf *>(node)->SetViewCell(viewCell);
+	}
+
+	return node;
+}
+
+BspNode *BspTree::SubdivideNode(BspLeaf *leaf, 
+								BspInterior *parent, 
+								PolygonContainer *polys, 
+								const int depth, 
+								PolygonContainer *frontPolys, 
+								PolygonContainer *backPolys)
+{
+	// terminate traversal
+	if ((polys->size() <= mTermMaxPolygons) || (depth >= mTermMaxDepth))
+	{
+		// add or delete remaining polygons
+		if (mStorePolys)
+			leaf->AddPolygons(polys);
+		else
+			Polygon3::DeletePolygons(polys);
+
+		delete polys;
+
+		return leaf;
+	}
+
+	 mStat.nodes += 2;
+
+	// add the new nodes to the tree + select subdivision plane
+	BspInterior *node = new BspInterior(SelectPlane(polys)); 
+
+#ifdef _DEBUG
+	Debug << node << endl;
+#endif
+	// split polygon according to current plane
+	int splits = 0;
+		
+	node->SplitPolygons(polys, frontPolys, backPolys, splits, mStorePolys);
+	
+ 	mStat.splits += splits;
+
+	// two new leaves
+	BspLeaf *back = new BspLeaf();
+	BspLeaf *front = new BspLeaf();
+
+	// replace a link from node's parent
+	if (parent)
+	{
+		parent->ReplaceChildLink(leaf, node);
+	}
+
+	// and setup child links
+	node->SetupChildLinks(back, front);
+
+	delete leaf; // leaf not member of tree anymore
+	
 	return node;
 }
@@ -455,4 +606,5 @@
 	}
 	
+	// use heuristics to find appropriate plane
 	return SelectPlaneHeuristics(polygons, sMaxCandidates);
 }
@@ -511,4 +663,5 @@
 int BspTree::EvalForBalancedTree(const int classification)
 {
+	// there should be roughly the same number of front and back polygons
 	if (classification == Polygon3::FRONT_SIDE)
 		return 1;
@@ -527,51 +680,4 @@
 }
 
-BspNode *BspTree::SubdivideNode(BspLeaf *leaf, 
-								BspInterior *parent, 
-								PolygonContainer *polys, 
-								const int depth, 
-								ViewCell *viewCell,
-								PolygonContainer *frontPolys, 
-								PolygonContainer *backPolys)
-{
-	// terminate traversal
-	if ((polys->size() <= mTermMaxPolygons) || (depth >= mTermMaxDepth))
-	{
-		return leaf;
-	}
-
-	 mStat.nodes += 2;
-
-	// add the new nodes to the tree + select subdivision plane
-	BspInterior *node = new BspInterior(SelectPlane(polys)); 
-
-#ifdef _DEBUG
-	Debug << node << endl;
-#endif
-	// split polygon according to current plane
-	int splits = 0;
-	int polySize = polys->size();
-	
-	node->SplitPolygons(polys, frontPolys, backPolys, splits);
-	
- 	mStat.splits += splits;
-
-	// two new leaves
-	BspLeaf *back = new BspLeaf();
-	BspLeaf *front = new BspLeaf(viewCell);
-
-	// replace a link from node's parent
-	if (parent)
-	{
-		parent->ReplaceChildLink(leaf, node);
-	}
-
-	// and setup child links
-	node->SetupChildLinks(back, front);
-
-	DEL_PTR(leaf); // leaf not member of tree anymore
-
-	return node;
-}
 
 void BspTree::ParseEnvironment()
@@ -648,5 +754,5 @@
 			if (!viewcell->Mailed()) 
 			{
-				viewcell->Mail();
+				viewcell->Mail(); // what does mail mean?
 					
 				// add this node to pvs of all nodes it can see
@@ -686,4 +792,8 @@
 }
 
+bool BspTree::StorePolys() const
+{
+	return mStorePolys;
+}
 void BspTree::EvaluateLeafStats(const BspTraversalData &data)
 {
@@ -696,5 +806,5 @@
 	}
 
-	// record maximal depth
+	// store maximal depth
 	if (data.mDepth > mStat.maxDepth)
 		mStat.maxDepth = data.mDepth;
@@ -732,7 +842,5 @@
 	BspNode *farChild;
 	
-	float position;
-	
-	while (1) // endless loop
+	while (1)
 	{
 		if (!node->IsLeaf()) 
@@ -781,4 +889,5 @@
 			// find intersection with plane between ray origin and exit point
 			extp = splitPlane->FindIntersection(ray.GetLoc(), extp, &maxt);
+
 		} else // compute intersections with objects in leaf
 		{
@@ -816,7 +925,7 @@
 			tStack.pop();
 		}
-
-		return hits;
-	}
+	}
+
+	return hits;
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 239)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 260)
@@ -51,4 +51,6 @@
 								ViewCellContainer &viewCells, 
 								const int maxViewCells);
+
+	static ViewCell *Convert2ViewCell(Face *face);
 protected:
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp	(revision 176)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp	(revision 260)
@@ -50,4 +50,2 @@
   return number;
 }
-
-
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polytope.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polytope.h	(revision 260)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polytope.h	(revision 260)
@@ -0,0 +1,47 @@
+#ifndef _Polytope_h__
+#define _Polytope_h__
+
+#include "Containers.h"
+
+class Hyperplane;
+
+/** Contains a list of hyperplanes
+*/
+typedef vector<Hyperplane *> HyperplaneContainer;
+
+/** Class representing a polyhedron in 5d projected space.
+*/
+class Polyhedron
+{
+public:
+	Polyhedron() {}
+
+	/** Adds plane to polyhedron equations
+	*/
+	void AddPlane(Hyperplane *plane) {mHyperPlanes.push_back(plane);}
+	/** Returns true if polyhedron is bounded.
+	*/
+	virtual bool IsBounded();
+
+protected:
+
+	/// the hyperplanes define the polyhedron
+	HyperplaneContainer mHyperPlanes;
+};
+
+/** Class representing a polytope (i.e., a bounded polyhedron) in 5d projected space.
+*/
+class Polytope: public Polyhedron
+{
+public:
+	Polytope(const Polyhedron &boundedPoly);
+
+    /** Split polytope into 2 polytopes front and back.
+		@param plane the split plane
+	*/
+	void Split(Hyperplane *plane, Polytope *front, Polytope *back);
+
+	virtual bool IsBounded() {return true;}
+};
+
+#endif // Polytope
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 242)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 260)
@@ -79,4 +79,6 @@
 	else if (strcmp(constructionMethodStr, "sceneGeometry") == 0)
 		constructionMethod = BspTree::SCENE_GEOMETRY;
+	else if (strcmp(constructionMethodStr, "rays") == 0)
+		constructionMethod = BspTree::RAYS;
 	else 
 	{
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.h	(revision 242)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.h	(revision 260)
@@ -47,5 +47,5 @@
   
   virtual void 
-	ExportPolygon(Polygon3 *poly);
+  ExportPolygon(Polygon3 *poly);
 
   virtual bool
@@ -61,5 +61,6 @@
   ExportMesh(Mesh *mesh);
 
-  virtual void ExportViewCell(ViewCell *viewCell);
+  virtual void 
+  ExportViewCell(ViewCell *viewCell);
 
 protected:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polytope.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polytope.cpp	(revision 260)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polytope.cpp	(revision 260)
@@ -0,0 +1,23 @@
+#include "Polytope.h"
+
+/************************************************
+ *         class Polyhedron implementation      *
+ ***********************************************/
+
+bool Polyhedron::IsBounded()
+{
+	return true;
+}
+
+/************************************************
+ *         class Polytope implementation        *
+ ***********************************************/
+
+Polytope::Polytope(const Polyhedron &boundedPoly)
+{
+}
+
+void Polytope::Split(Hyperplane *plane, Polytope *front, Polytope *back)
+{
+}
+
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 242)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 260)
@@ -31,5 +31,8 @@
   p->BuildKdTree();
   p->KdTreeStatistics(cout);
+
 #ifdef TEST_BSP_VIEWCELLS
+  environment->GetStringValue("Scene.viewcells", buff);
+
   p->GenerateViewcells();
   p->BspTreeStatistics(Debug);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 242)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 260)
@@ -7,5 +7,5 @@
 #include "ViewCellBsp.h"
 #include "ViewCell.h"
-#include "Polygon3.h";
+#include "Polygon3.h"
 
 
@@ -296,8 +296,8 @@
 	Mesh *mesh = new Mesh;
 
-	AxisAlignedBox3 box = tree.GetBoundingBox();
-	ExportBox(box);
-
-  	while (!tStack.empty()) 
+	//AxisAlignedBox3 box = tree.GetBoundingBox();
+	//ExportBox(box);
+	 
+	while (!tStack.empty()) 
 	{
 		BspNode *node = tStack.top();
@@ -305,4 +305,13 @@
 		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()) 
 		{
@@ -311,16 +320,15 @@
 			tStack.push(interior->GetFront());
 			tStack.push(interior->GetBack());
+
 		}
 		else
 		{
 			BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
-			// NOTE: could also export polygons to see if splits work
-			if (leaf->GetViewCell())
+			// export view cell geometry
+			if (!tree.StorePolys() && leaf->GetViewCell())
 				ExportViewCell(leaf->GetViewCell());
 		}
   }
   
-  ExportMesh(mesh);
-  delete mesh;
   return true;
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 256)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp	(revision 260)
@@ -35,10 +35,8 @@
 void Polygon3::DeletePolygons(PolygonContainer *polys)
 {
-	// don't need to store polygon information => delete polygons
 	while(!polys->empty())
 	{
-		Polygon3 *poly = polys->back();
+		DEL_PTR(polys->back());
 		polys->pop_back();
-		DEL_PTR(poly);
 	}
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h	(revision 170)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h	(revision 260)
@@ -3,5 +3,5 @@
 
 #include "Parser.h"
-
+#include "ViewCells.h"
 
 class X3dParser : public Parser
@@ -11,5 +11,5 @@
   
   bool ParseFile(const string filename, SceneGraphNode **root);
-  
+  bool ParseViewCells(const string filename, ViewCellContainer *viewCells);
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParserXerces.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParserXerces.h	(revision 180)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParserXerces.h	(revision 260)
@@ -105,4 +105,93 @@
 };
 
+/** Parser handlers for view cell x3d files.
+*/
+class X3dViewCellsParseHandlers : public HandlerBase
+{
+public:
+  // -----------------------------------------------------------------------
+  //  Constructors and Destructor
+  // -----------------------------------------------------------------------
+  X3dViewCellsParseHandlers(ViewCellContainer *mViewCells;);
+  ~X3dViewCellsParseHandlers();
+  
+  
+  // -----------------------------------------------------------------------
+  //  Getter methods
+  // -----------------------------------------------------------------------
+  unsigned int GetElementCount()
+  {
+    return mElementCount;
+  }
+  
+  unsigned int GetAttrCount()
+  {
+    return mAttrCount;
+  }
+  
+  unsigned int GetCharacterCount()
+  {
+    return mCharacterCount;
+  }
+  
+  unsigned int GetSpaceCount()
+  {
+    return mSpaceCount;
+  }
+
+
+  // -----------------------------------------------------------------------
+  //  Handlers for the SAX DocumentHandler interface
+  // -----------------------------------------------------------------------
+  void endElement(const XMLCh* const name);
+  void startElement(const XMLCh* const name, AttributeList& attributes);
+  void characters(const XMLCh* const chars, const unsigned int length);
+  void ignorableWhitespace(const XMLCh* const chars, const unsigned int length);
+  void resetDocument();
+
+  ViewCellContainer *mViewCells;
+  
+  // Handlers for X3D
+  void
+  StartIndexedFaceSet(
+		      AttributeList&  attributes);
+  
+  void
+  EndShape();
+
+  void
+  StartCoordinate(
+		  AttributeList&  attributes);
+
+  void
+  StartMaterial(
+		AttributeList&  attributes);
+  
+  
+  // -----------------------------------------------------------------------
+  //  Handlers for the SAX ErrorHandler interface
+  // -----------------------------------------------------------------------
+  void warning(const SAXParseException& exc);
+  void error(const SAXParseException& exc);
+  void fatalError(const SAXParseException& exc);
+  
+  
+private:
+  // -----------------------------------------------------------------------
+  //  Private data members
+  //
+  //  fAttrCount
+  //  fCharacterCount
+  //  fElementCount
+  //  fSpaceCount
+  //      These are just counters that are run upwards based on the input
+  //      from the document handlers.
+  // -----------------------------------------------------------------------
+  unsigned int    mAttrCount;
+  unsigned int    mCharacterCount;
+  unsigned int    mElementCount;
+  unsigned int    mSpaceCount;
+};
+
 
 // ---------------------------------------------------------------------------
