Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.cpp	(revision 170)
@@ -1,4 +1,275 @@
+// ---------------------------------------------------------------------------
+//  Includes for all the program files to see
+// ---------------------------------------------------------------------------
+#include <string.h>
+#include <stdlib.h>
+#include <iostream>
+using namespace std;
+#include <xercesc/util/PlatformUtils.hpp>
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <xercesc/framework/StdInInputSource.hpp>
+#include <xercesc/parsers/SAXParser.hpp>
+#include <xercesc/util/OutOfMemoryException.hpp>
+
+// ---------------------------------------------------------------------------
+//  Includes
+// ---------------------------------------------------------------------------
+#include <xercesc/sax/AttributeList.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax/SAXException.hpp>
 
 #include "X3dParser.h"
+
+#include "X3dParserXerces.h"
+#include "Mesh.h"
+#include "SceneGraph.h"
+
+
+
+// ---------------------------------------------------------------------------
+//  Local data
+//
+//  doNamespaces
+//      Indicates whether namespace processing should be enabled or not.
+//      The default is no, but -n overrides that.
+//
+//  doSchema
+//      Indicates whether schema processing should be enabled or not.
+//      The default is no, but -s overrides that.
+//
+//  schemaFullChecking
+//      Indicates whether full schema constraint checking should be enabled or not.
+//      The default is no, but -s overrides that.
+//
+//  valScheme
+//      Indicates what validation scheme to use. It defaults to 'auto', but
+//      can be set via the -v= command.
+// ---------------------------------------------------------------------------
+static bool     doNamespaces       = false;
+static bool     doSchema           = false;
+static bool     schemaFullChecking = false;
+static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
+
+
+
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Constructors and Destructor
+// ---------------------------------------------------------------------------
+X3dParseHandlers::X3dParseHandlers(SceneGraphNode *root) :
+  fElementCount(0)
+  , fAttrCount(0)
+  , fCharacterCount(0)
+  , fSpaceCount(0)
+{
+  currentNode = root;
+}
+
+X3dParseHandlers::~X3dParseHandlers()
+{
+}
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
+// ---------------------------------------------------------------------------
+void X3dParseHandlers::endElement(const XMLCh* const name)
+{
+  StrX lname(name);
+  string element(lname.localForm());
+  if (element == "Shape")
+    EndShape();
+}
+
+void
+X3dParseHandlers::EndShape()
+{
+  currentMesh->Preprocess();
+  // make an instance of this mesh
+  MeshInstance *mi = new MeshInstance(currentMesh);
+  currentNode->mGeometry.push_back(mi); 
+  currentMesh = NULL;
+}
+
+void
+X3dParseHandlers::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) {
+	    Face *face = new Face(vertices);
+	    currentMesh->mFaces.push_back(face);
+	  }
+	  vertices.clear();
+	  if (ptr == endptr)
+	    break;
+	} else {
+	  vertices.push_back(index);
+	}
+	ptr = endptr;
+      }
+    }
+  }
+}
+
+void
+X3dParseHandlers::StartMaterial(
+				AttributeList&  attributes)
+{
+  int len = attributes.getLength();
+  int i;
+  if (!currentMesh->mMaterial)
+    currentMesh->mMaterial = new Material;
+  for (i=0; i < len; i++) {
+    string attrName(StrX(attributes.getName(i)).localForm());
+    StrX attrValue(attributes.getValue(i));
+    const char *ptr = attrValue.localForm();
+    if (attrName == "diffuseColor") {
+      float r, g, b;
+      if (sscanf(ptr, "%f %f %f", &r, &g, &b) == 3)
+	currentMesh->mMaterial->mDiffuseColor = RgbColor(r, g, b);
+    }
+  }
+}
+
+void
+X3dParseHandlers::StartCoordinate(
+				  AttributeList&  attributes)
+{
+  int len = attributes.getLength();
+  int i;
+  VertexContainer vertices;
+  for (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);
+      }
+      currentMesh->mVertices = vertices;
+    }
+  }
+}
+
+
+void
+X3dParseHandlers::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<<"+";
+    currentMesh = new Mesh;
+  }
+  
+  if (element == "Coordinate") {
+    if (currentMesh)
+      StartCoordinate(attributes);
+  }
+  
+  if (element == "Material") {
+    StartMaterial(attributes);
+  }
+
+  fElementCount++;
+  fAttrCount += attributes.getLength();
+}
+
+void
+X3dParseHandlers::characters(const XMLCh* const chars,
+			     const unsigned int length)
+{
+  fCharacterCount += length;
+}
+
+void
+X3dParseHandlers::ignorableWhitespace(const XMLCh* const chars,
+				      const unsigned int length)
+{
+  fSpaceCount += length;
+}
+
+void
+X3dParseHandlers::resetDocument()
+{
+  fAttrCount = 0;
+  fCharacterCount = 0;
+  fElementCount = 0;
+  fSpaceCount = 0;
+}
+
+
+
+// ---------------------------------------------------------------------------
+//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
+// ---------------------------------------------------------------------------
+void
+X3dParseHandlers::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
+X3dParseHandlers::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
+X3dParseHandlers::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;
+}
 
 
@@ -7,122 +278,94 @@
 		     SceneGraphNode **root)
 {
-  
-  
-  
-}
-
-  
-namespace X3DTK {
-namespace MESH {
-
-MyStructureComputer::MyStructureComputer()
-{
-  setGraphTraversal(new DFSGraphTraversal());
-	setComponentVisitor(new MyStructureComputerCoreVisitor());
-      }
-      
-      MyStructureComputer::~MyStructureComputer()
+  // 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;
+  X3dParseHandlers 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
       {
-	Singleton<MyStructureComputerStateVariables>::removeInstance();
-      }
-      
-      MySimpleMesh *MyStructureComputer::compute(SFNode N)
+	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&)
       {
-	Singleton<MyStructureComputerStateVariables>::getInstance()->init();
-	traverse(N);
-	Singleton<MyStructureComputerStateVariables>::getInstance()->finish();
-	
-	return Singleton<MyStructureComputerStateVariables>::getInstance()->getMesh();
-      }
-      
-      
-      MyStructureComputerCoreVisitor::MyStructureComputerCoreVisitor()
+	XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
+	errorCount = 2;
+	return false;
+      }
+    catch (const XMLException& e)
       {
-	// Enter functions.
-	define(Recorder<Mesh>::getEnterFunction(&MyStructureComputerCoreVisitor::enterMesh));
-	define(Recorder<Transform>::getEnterFunction(&MyStructureComputerCoreVisitor::enterTransform));
-	// Leave function.
-	define(Recorder<X3DGroupingNode>::getLeaveFunction(&MyStructureComputerCoreVisitor::leaveX3DGroupingNode));
-      }
-      
-      void MyStructureComputerCoreVisitor::enterMesh(Mesh *M)
-      {
-	// StateVariables assignation.
-	MyStructureComputerStateVariables *stateVariables = Singleton<MyStructureComputerStateVariables>::getInstance();
-	
-	SFMatrix34f T = stateVariables->getMatrix();
-
-  // Beginning a new Mesh by memorizing the current vertex index.
-  stateVariables->beginNewMesh();
-
-  // filling the vertices.
-  for (Mesh::MFVertex::const_iterator v = M->getVertices().begin(); v != M->getVertices().end(); ++v)
-  {
-    SFPoint3f P = T*(*v)->data().getPoint();
-    stateVariables->addVertex(P.x, P.y, P.z);
-  }
-  
-  // filling the faces.
-  for (Mesh::MFFace::const_iterator
-	 f = M->getFaces().begin(); f != M->getFaces().end(); ++f)
-  {
-    const SFFace::MFEdge &edges = (*f)->getEdges();
-    list<unsigned int> indexList;
-    for (SFFace::MFEdge::const_iterator e = edges.begin(); e != edges.end(); ++e)
-      indexList.push_back((*e)->getFromVertex()->getIndex());
+	XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
+				  << StrX(e.getMessage())
+				  << "\n" << XERCES_STD_QUALIFIER endl;
+	errorCount = 1;
+	return false;
+      }
     
-    stateVariables->addFace(indexList);
-  }
-}
-
-void MyStructureComputerCoreVisitor::enterTransform(Transform *T)
-{
-  Singleton<MyStructureComputerStateVariables>::getInstance()->pushMatrix(T->getTransform());
-}
-
-void MyStructureComputerCoreVisitor::leaveX3DGroupingNode(X3DGroupingNode *)
-{
-  Singleton<MyStructureComputerStateVariables>::getInstance()->popMatrix();
-}
-
-: StateVariables(), _mesh(0), _decal(0)
-{
-}
-
-void MyStructureComputerStateVariables::init()
-{
-  _mesh = new MySimpleMesh();
-  _matrixStack.push_front(SFMatrix34f::identity);
-}
-
-void MyStructureComputerStateVariables::finish()
-{
-  _matrixStack.clear();
-}
-
-void MyStructureComputerStateVariables::beginNewMesh()
-{
-  _decal = _mesh->getVertexArray().size();
-}
-
-void MyStructureComputerStateVariables::addFace(const Face &face)
-{
-  //  MyFace decalFace = face;
-  //  for (MyFace::iterator it = decalFace.begin(); it != decalFace.end(); ++it)
-  //    *it = _decal + *it;
-    
-  //  _mesh->addFace(decalFace);
-};
-
-void MyStructureComputerStateVariables::pushMatrix(const SFMatrix34f &transformation)
-{
-  _matrixStack.push_front(_matrixStack.front()*transformation);
-}
-
-void MyStructureComputerStateVariables::popMatrix()
-{
-  _matrixStack.pop_front();
-}
-
-}
-
+    // 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/KdTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.h	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.h	(revision 170)
@@ -449,5 +449,5 @@
   float mCt_div_ci;
   int mSplitMethod;
-
+  bool mSahUseFaces;
   /// root of the tree
   KdNode *mRoot;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 170)
@@ -3,6 +3,8 @@
 #include "Parser.h"
 #include "UnigraphicsParser.h"
+#include "X3dParser.h"
 #include "Environment.h"
 #include "Camera.h"
+#include "MeshKdTree.h"
 
 #define USE_EXE_PATH false
@@ -15,27 +17,37 @@
   environment = new Environment;
   environment->Parse(argc, argv, USE_EXE_PATH);
+  MeshKdTree::ParseEnvironment();
   
   Preprocessor *p =
     new SamplingPreprocessor();
 
-  p->LoadScene("soda.dat");
+  char buff[128];
+  environment->GetStringValue("Scene.filename", buff);
+  string filename(buff);
+
+  p->LoadScene(filename);
   p->BuildKdTree();
   p->KdTreeStatistics(cout);
 
   //  p->mSceneGraph->Export("soda.x3d");
-  p->Export("soda.x3d", true, false);
-  p->Export("soda-kdtree.x3d", false, true);
-
+  if (1) {
+    p->Export(filename + "-out.x3d", true, false);
+    p->Export(filename + "-kdtree.x3d", false, true);
+  }
+  
   //  p->LoadViewcells("viewcells.wrl");
   p->ComputeVisibility();
   p->ExportPreprocessedData("scene.vis");
+  
+  if (1) {
+    Camera camera;
+    camera.LookAtBox(p->mKdTree->GetBox());
+    camera.SnapImage("camera.png", p->mKdTree);
+    
+    camera.LookInBox(p->mKdTree->GetBox());
+    camera.SetPosition(camera.mPosition - Vector3(0,100,0));
+    camera.SnapImage("camera2.png", p->mKdTree);
+  }
 
-  Camera camera;
-  camera.LookAtBox(p->mKdTree->GetBox());
-  camera.SnapImage("camera.png", p->mKdTree);
-
-  camera.LookInBox(p->mKdTree->GetBox());
-  camera.SetPosition(camera.mPosition - Vector3(0,100,0));
-  camera.SnapImage("camera2.png", p->mKdTree);
   
   return 0;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h	(revision 170)
@@ -63,4 +63,12 @@
     mMax += v;
     mMin -= v;
+  }
+
+  void SetMin(const Vector3 &v) {
+    mMin = v;
+  }
+
+  void SetMax(const Vector3 &v) {
+    mMax = v;
   }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 163)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 170)
@@ -3,4 +3,12 @@
 # Jiri Bittner 2003
 #############################################################################
+
+Scene {
+
+#	filename atlanta2.x3d
+	filename soda.dat
+
+}
+
 Limits {
 
@@ -11,17 +19,31 @@
 
 Unigraphics {
-		meshGrouping 1
+		meshGrouping 1000
 }
 
 KdTree {
+	sahUseFaces true
 	Termination {
-		minCost 6
+		minCost 2
 		maxDepth 18
-		maxCostRatio 1.5
-		ct_div_ci 1
+		maxCostRatio 0.9
+		ct_div_ci 0.5
 	}
 
 #	splitMethod spatialMedian
 	splitMethod SAH
-	splitBorder 0.1
+	splitBorder 0.01
 }
+
+MeshKdTree {
+	Termination {
+		minCost 4
+		maxDepth 18
+		maxCostRatio 0.9
+		ct_div_ci 0.5
+	}
+
+#	splitMethod spatialMedian
+	splitMethod SAH
+	splitBorder 0.01
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h	(revision 170)
@@ -12,4 +12,5 @@
 
 class MeshInstance;
+class MeshKdTree;
 
 /// default vertex container for Mesh
@@ -18,5 +19,4 @@
 /// vertex index container
 typedef std::vector<int> VertexIndexContainer;
-
 
 
@@ -54,5 +54,5 @@
 
   /// Default constructor
-  Mesh():mVertices(), mFaces(), mMaterial(NULL) {}
+  Mesh():mVertices(), mFaces(), mMaterial(NULL), mKdTree(NULL) {}
   
   /// Constructor with container preallocation
@@ -65,5 +65,5 @@
     mFaces.reserve(faces);
   }
-
+  
   ~Mesh() {
     for (int i=0; i < mFaces.size(); i++)
@@ -75,5 +75,5 @@
     mFaces.push_back(face);
   }
-
+  
   void Preprocess();
 
@@ -86,10 +86,12 @@
   /** Patches forming the mesh */
   FaceContainer mFaces;
-
+  
   /** Global mesh material */
   Material *mMaterial;
-
+  
   /** true if the mesh is a convex mesh */
   bool mIsConvex;
+
+  MeshKdTree *mKdTree;
   
   int
@@ -99,5 +101,21 @@
 	  );
 
+  int
+  CastRayToSelectedFaces(
+			 Ray &ray,
+			 const vector<int> &faces,
+			 MeshInstance *instance
+			 );
 
+  int
+  CastRayToFace(
+		const int faceIndex,
+		Ray &ray,
+		float &nearestT,
+		int &nearestFace,
+		MeshInstance *instance
+		);
+
+  
   int
   RayFaceIntersection(const int faceIndex,
@@ -106,7 +124,9 @@
 		      const float nearestT
 		      );
-
+  
   Plane3 GetFacePlane(const int faceIndex);
 
+  AxisAlignedBox3 GetFaceBox(const int faceIndex);
+  
 };
 
@@ -139,4 +159,10 @@
 	  );
   
+  virtual int
+  CastRay(
+	  Ray &ray,
+	  const vector<int> &faces
+	  );
+
 
 };
Index: trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro	(revision 163)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/preprocessor.pro	(revision 170)
@@ -5,5 +5,8 @@
 
 #win32:INCLUDEPATH += c:/STLport-4.6.2/stlport
-INCLUDEPATH += ../src ../support/X3DToolKit/include  ../support/zlib/include ../support/boost
+
+INCLUDEPATH += ../src ../support/xerces/include  ../support/zlib/include ../support/boost
+
+win32:LIBPATH += ../support/expat/lib ../support/xerces/lib
 
 #win32:LIBPATH += c:/STLport-4.6.2/lib
@@ -17,8 +20,10 @@
 # DEPENDPATH	= ../../include
 
+win32:LIBS += xerces-c_2.lib
+
 # Input
 HEADERS += 
 
-	
+
 SOURCES += \
 Preprocessor.cpp SamplingPreprocessor.cpp ExactPreprocessor.cpp \
@@ -26,7 +31,5 @@
 UnigraphicsParser.cpp X3dExporter.cpp SceneGraph.cpp Material.cpp \
 Matrix4x4.cpp Vector3.cpp AxisAlignedBox3.cpp Ray.cpp main.cpp Mesh.cpp \
-Exporter.cpp Camera.cpp
-
-#X3dParser.cpp
+Exporter.cpp Camera.cpp X3dParser.cpp MeshKdTree.cpp
 
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 170)
@@ -1063,4 +1063,9 @@
 
 
+  RegisterOption("Scene.filename",
+		 optString,
+		 "-scene_filename=",
+		 "soda.x3d");
+
   RegisterOption("Unigraphics.meshGrouping",
 		 optInt,
@@ -1099,36 +1104,41 @@
 		 "0.1");
 
-  
-  RegisterOption("IFS.loadKDtree", optBool, NULL, "true");
-  RegisterOption("IFS.kdtree", optBool, NULL, "true");
-  RegisterOption("IFS.KDTree.minCost", optFloat, NULL, "20");
-  RegisterOption("IFS.KDTree.maxDepth", optInt, NULL, "12");
-  RegisterOption("IFS.KDTree.ct_div_ci", optFloat, NULL, "1");
-  RegisterOption("IFS.KDTree.tries", optFloat, NULL, "3");
-  RegisterOption("IFS.KDTree.minCostImprovement", optFloat, NULL, "1.0");
-  
-  RegisterOption("IFS.KDTree.buildCostCoef", optFloat, NULL, "2");
-
-  RegisterOption("IFS.optimizeBuffers", optBool, NULL, "true");
-  RegisterOption("IFS.strips", optBool, NULL, "false");
-  RegisterOption("IFS.stripsRemap", optBool, NULL, "false");
-  RegisterOption("IFS.loadStrips", optBool,
-		 "loadStrips", "true");
-
-  RegisterOption("World.loadTextures", optBool,
-		 "loadTextures",
-		 "true" );
-
-  RegisterOption("World.loadTransparentTextures", optBool,
-		 "loadTransparentTextures",
-		 "true" );
-
-  RegisterOption("World.loadLightmaps", optBool,
-		 "loadLightmaps",
-		 "true" );
-
-  RegisterOption("World.loadImages", optBool,
-		 "loadImages",
-		 "true" );
+
+  RegisterOption("KdTree.sahUseFaces",
+		 optBool,
+		 "-kd_sah_use_faces=",
+		 "true");
+
+
+  RegisterOption("MeshKdTree.Termination.minCost",
+		 optInt,
+		 "-kd_term_min_cost=",
+		 "10");
+  
+  RegisterOption("MeshKdTree.Termination.maxDepth",
+		 optInt,
+		 "-kd_term_max_depth=",
+		 "20");
+
+  RegisterOption("MeshKdTree.Termination.maxCostRatio",
+		 optFloat,
+		 "-kd_term_max_cost_ratio=",
+		 "1.5");
+
+  RegisterOption("MeshKdTree.Termination.ct_div_ci",
+		 optFloat,
+		 "-kd_term_ct_div_ci=",
+		 "1.0");
+
+  RegisterOption("MeshKdTree.splitMethod",
+		 optString,
+		 "-kd_split_method=",
+		 "spatialMedian");
+
+  RegisterOption("MeshKdTree.splitBorder",
+		 optFloat,
+		 "-kd_split_border=",
+		 "0.1");
+
   
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h	(revision 165)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Exporter.h	(revision 170)
@@ -23,4 +23,5 @@
   {
   }
+  virtual ~Exporter() {}
   
   virtual bool ExportScene(SceneGraphNode *node) = 0;
@@ -44,4 +45,5 @@
   GetExporter(const string filename);
 
+  
 };
  
Index: trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp	(revision 165)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/KdTree.cpp	(revision 170)
@@ -25,4 +25,6 @@
   environment->GetFloatValue("KdTree.Termination.ct_div_ci", mCt_div_ci);
   environment->GetFloatValue("KdTree.splitBorder", mSplitBorder);
+
+  environment->GetBoolValue("KdTree.sahUseFaces", mSahUseFaces);
 
   char splitType[64];
@@ -42,6 +44,5 @@
 	exit(1);
       }
-
-  splitCandidates = new vector<SortableEntry>;
+  splitCandidates = NULL;
 }
 
@@ -49,4 +50,7 @@
 KdTree::Construct()
 {
+  if (!splitCandidates)
+    splitCandidates = new vector<SortableEntry>;
+
   // first construct a leaf that will get subdivide
   KdLeaf *leaf = (KdLeaf *) mRoot;
@@ -63,8 +67,9 @@
   }
 
-  cout <<"box:"<< mBox<<endl;
-
-  
+  cout <<"KdTree Root Box:"<< mBox<<endl;
   mRoot = Subdivide(TraversalData(leaf, mBox, 0));
+
+  // remove the allocated array
+  delete splitCandidates;
 
   return true;
@@ -131,5 +136,5 @@
   //  cerr<<"\n OBJECTS="<<leaf->mObjects.size()<<endl;
   return
-    (leaf->mObjects.size() < mTermMinCost) ||
+    (leaf->mObjects.size() <= mTermMinCost) ||
     (leaf->mDepth >= mTermMaxDepth);
   
@@ -424,12 +429,24 @@
   // C = ct_div_ci  + (ol + or)/queries
 
+  int totalFaces = 0;
+  vector<SortableEntry>::const_iterator ci;
+
+  for(ci = splitCandidates->begin();
+      ci < splitCandidates->end();
+      ci++) 
+    if ((*ci).type == SortableEntry::MESH_MIN) {
+      Mesh *mesh = ((MeshInstance *)(*ci).data)->GetMesh();
+      totalFaces += mesh->mFaces.size();
+    }
+
+  int facesLeft = 0;
+  int facesRight = totalFaces;
+
   int objectsLeft = 0, objectsRight = node->mObjects.size();
-
+  
   float minBox = box.Min(axis);
   float maxBox = box.Max(axis);
   float boxArea = box.SurfaceArea();
   
-  
-  
   float minBand = minBox + mSplitBorder*(maxBox - minBox);
   float maxBand = minBox + (1.0f - mSplitBorder)*(maxBox - minBox);
@@ -437,14 +454,16 @@
   float minSum = 1e20;
   
-  for(vector<SortableEntry>::const_iterator ci = splitCandidates->begin();
+  for(ci = splitCandidates->begin();
       ci < splitCandidates->end();
       ci++) {
-    
+    Mesh *mesh = ((MeshInstance *)(*ci).data)->GetMesh();
     switch ((*ci).type) {
     case SortableEntry::MESH_MIN:
       objectsLeft++;
+      facesLeft += mesh->mFaces.size();
       break;
     case SortableEntry::MESH_MAX:
       objectsRight--;
+      facesRight -= mesh->mFaces.size();
       break;
     }
@@ -456,5 +475,9 @@
       rbox.SetMin(axis, (*ci).value);
 
-      float sum = objectsLeft*lbox.SurfaceArea() + objectsRight*rbox.SurfaceArea();
+      float sum;
+      if (mSahUseFaces)
+	sum = facesLeft*lbox.SurfaceArea() + facesRight*rbox.SurfaceArea();
+      else
+	sum = objectsLeft*lbox.SurfaceArea() + objectsRight*rbox.SurfaceArea();
       
       //      cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl;
@@ -471,8 +494,8 @@
   }
   
-  float oldCost = node->mObjects.size();
+  float oldCost = mSahUseFaces ? totalFaces : node->mObjects.size();
   float newCost = mCt_div_ci + minSum/boxArea;
   float ratio = newCost/oldCost;
-
+  
 #if 0
   cout<<"===================="<<endl;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dParser.h	(revision 170)
@@ -2,10 +2,6 @@
 #define __X3DPARSER_H
 
-#include "parser.h"
-#include "mesh.h"
+#include "Parser.h"
 
-#include <X3DTK/MESH/scenegraph.h>
-#include <X3DTK/kernel.h>
-#include <X3DTK/MESH/scenegraph.h>
 
 class X3dParser : public Parser
@@ -14,70 +10,8 @@
   X3dParser():Parser() {}
   
-  
   bool ParseFile(const string filename, SceneGraphNode **root);
   
 };
 
-};
-
-
-namespace X3DTK {
-namespace MESH {
-
-class MyStructureComputerStateVariables : public StateVariables
-{
-public:
-  MyStructureComputerStateVariables();
-  
-  void init();
-  void finish();
-  
-  void beginNewMesh();
-  inline void addVertex(float x, float y, float z) {
-    //_mesh->addVertex(x, y, z);
-  };
-
-  void addFace(const Face &face);
-
-  void pushMatrix(const SFMatrix34f &transformation);  
-  void popMatrix();
-  
-inline Mesh *getMesh() const {return _mesh;};  
-  SFMatrix34f getMatrix() const {return _matrixStack.front();};
-  
-private: 
-  Mesh *_mesh;
-  unsigned int _decal;
-  std::list<SFMatrix34f> _matrixStack;
-};
-  
-  // MyStructureComputer processor.
-  
-  class MyStructureComputer : public X3DOnePassProcessor
-  {
-public:
-    MyStructureComputer();
-    virtual ~MyStructureComputer();
-    
-    virtual Mesh *compute(SFNode N);
-  };
-
-  class X3DGroupingNode;
-  class Transform;
-  
-  /// Visitor for the Core component of the MyStructureComputer module.
-  
-  class MyStructureComputerCoreVisitor : public CoreVisitor
-  {
-  public:
-    MyStructureComputerCoreVisitor();
-    
-    static void enterMesh(Mesh *M);
-    static void enterTransform(Transform *T);
-    static void leaveX3DGroupingNode(X3DGroupingNode *N);
-  };
-  
-}
-
 
 #endif
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 162)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 170)
@@ -2,4 +2,5 @@
 #include "Exporter.h"
 #include "UnigraphicsParser.h"
+#include "X3dParser.h"
 #include "Preprocessor.h"
 
@@ -27,5 +28,13 @@
 
   mSceneGraph = new SceneGraph;
-  Parser *parser = new UnigraphicsParser;
+
+  
+  Parser *parser;
+
+  if (strstr(filename.c_str(), ".x3d"))
+    parser = new X3dParser;
+  else
+    parser = new UnigraphicsParser;
+
   bool result = parser->ParseFile(filename, &mSceneGraph->mRoot);
   
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp	(revision 167)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.cpp	(revision 170)
@@ -1,4 +1,5 @@
 #include "Ray.h"
 #include "Mesh.h"
+#include "MeshKdTree.h"
 
 int MeshInstance::mailID = 21843194198;
@@ -15,6 +16,54 @@
   
   mIsConvex = false;
-}
-
+
+  if (mFaces.size() > 2*MeshKdTree::mTermMinCost) {
+    mKdTree = new MeshKdTree(this);
+    MeshKdLeaf *root = (MeshKdLeaf *)mKdTree->GetRoot();
+    for (int i = 0; i < mFaces.size(); i++)
+      root->mFaces.push_back(i);
+    cout<<"KD";
+    mKdTree->Construct();
+  }
+}
+
+AxisAlignedBox3
+Mesh::GetFaceBox(const int faceIndex)
+{
+  Face *face = mFaces[faceIndex];
+  AxisAlignedBox3 box;
+  box.SetMin( mVertices[face->mVertexIndices[0]] );
+  box.SetMax(box.Min());
+  for (int i = 1; i < face->mVertexIndices.size(); i++) {
+    box.Include(mVertices[face->mVertexIndices[i]]);
+  }
+  return box;
+}
+
+int
+Mesh::CastRayToFace(
+		    const int faceIndex,
+		    Ray &ray,
+		    float &nearestT,
+		    int &nearestFace,
+		    MeshInstance *instance
+		    )
+{
+  float t;
+  int hit = 0;
+  if (RayFaceIntersection(faceIndex, ray, t, nearestT) == Ray::INTERSECTION) {
+    switch (ray.GetType()) {
+    case Ray::GLOBAL_RAY:
+      ray.intersections.push_back(Ray::RayIntersection(t, instance, faceIndex));
+      hit++;
+      break;
+    case Ray::LOCAL_RAY:
+      nearestT = t;
+      nearestFace = faceIndex;
+      hit++;
+      break;
+    }
+  }
+  return hit;
+}
 
 int
@@ -24,31 +73,56 @@
 	      )
 {
-  FaceContainer::const_iterator fi;
+  if (mKdTree) {
+    return mKdTree->CastRay(ray, instance);
+  }
+  
   int faceIndex = 0;
   int hits = 0;
   float nearestT = MAX_FLOAT;
-  float nearestFace;
-
+  int nearestFace = -1;
+  
   if (ray.GetType() == Ray::LOCAL_RAY && ray.intersections.size())
     nearestT = ray.intersections[0].mT;
 
-  
   for ( ;
 	faceIndex < mFaces.size();
 	faceIndex++) {
-    float t;
-    if (RayFaceIntersection(faceIndex, ray, t, nearestT) == Ray::INTERSECTION) {
-      switch (ray.GetType()) {
-      case Ray::GLOBAL_RAY:
-	ray.intersections.push_back(Ray::RayIntersection(t, instance, faceIndex));
-	hits++;
-	break;
-      case Ray::LOCAL_RAY:
-	hits++;
-	nearestT = t;
-	nearestFace = faceIndex;
-	break;
-      }
-    }
+    hits += CastRayToFace(faceIndex, ray, nearestT, nearestFace, instance);
+    if (mIsConvex && nearestFace != -1)
+      break;
+  }
+  
+  if ( hits && ray.GetType() == Ray::LOCAL_RAY ) {
+    if (ray.intersections.size())
+      ray.intersections[0] = Ray::RayIntersection(nearestT, instance, nearestFace);
+    else
+      ray.intersections.push_back(Ray::RayIntersection(nearestT, instance, nearestFace));
+  }
+  
+  return hits;
+}
+
+int
+Mesh::CastRayToSelectedFaces(
+			     Ray &ray,
+			     const vector<int> &faces,
+			     MeshInstance *instance
+			     )
+{
+  vector<int>::const_iterator fi;
+  int faceIndex = 0;
+  int hits = 0;
+  float nearestT = MAX_FLOAT;
+  int nearestFace = -1;
+
+  if (ray.GetType() == Ray::LOCAL_RAY && ray.intersections.size())
+    nearestT = ray.intersections[0].mT;
+
+  for ( fi = faces.begin();
+	fi != faces.end();
+	fi++) {
+    hits += CastRayToFace(*fi, ray, nearestT, nearestFace, instance);
+    if (mIsConvex && nearestFace != -1)
+      break;
   }
   
@@ -143,10 +217,12 @@
 
 
-  mVertices[face->mVertexIndices[face->mVertexIndices.size() - 1]].
+  int size = face->mVertexIndices.size();
+
+  mVertices[face->mVertexIndices[size - 1]].
     ExtractVerts(&u1, &v1, paxis );
-
-  if (mIsConvex) {
+  
+  if (0 && size <= 4) {
     // assume a convex face
-    for (i = 0; i < face->mVertexIndices.size(); i++) {
+    for (i = 0; i < size; i++) {
       mVertices[face->mVertexIndices[i]].ExtractVerts(&u2, &v2, paxis);
       // line u1, v1, u2, v2
@@ -164,5 +240,5 @@
   // with a ray originating at the point of intersection and
   // travelling in the positive X direction.
-  for (i = 0; i < face->mVertexIndices.size(); i++) {
+  for (i = 0; i < size; i++) {
     mVertices[face->mVertexIndices[i]].ExtractVerts(&u2, &v2, paxis);
     count += (int_lineseg(u, v, u1, v1, u2, v2) != 0);
@@ -185,4 +261,13 @@
 }
 
+int
+MeshInstance::CastRay(
+		      Ray &ray,
+		      const vector<int> &faces
+		      )
+{
+  return mMesh->CastRayToSelectedFaces(ray, faces, this);
+}
+
 
 Plane3
@@ -206,2 +291,3 @@
   return res;
 }
+
