Index: trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.h	(revision 372)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.h	(revision 387)
@@ -26,8 +26,12 @@
   bool Export(const string filename);
   
-  int CollectObjects(ObjectContainer *instances);
-
+  int
+	CollectObjects(ObjectContainer *instances);
+	
   int
 	AssignObjectIds();
+
+	void
+	GetStatistics(int &intersectables, int &faces) const;
 
 protected:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h	(revision 376)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/AxisAlignedBox3.h	(revision 387)
@@ -54,5 +54,9 @@
     return  mMax[axis];
   }
-  
+
+	float Size(const int axis) const {
+    return  Max(axis) - Min(axis);
+  }
+
   // Read-only const access tomMin and max vectors using references
   const Vector3& Min() const { return mMin;}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h	(revision 386)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.h	(revision 387)
@@ -469,7 +469,7 @@
 				leafb->rays.size()*b.bbox.GetVolume();
 #endif
-#if 0
+#if 1
 			return
-				leafa->mPvsSize*a.bbox.GetVolume()*
+				leafa->mPvsSize*a.bbox.GetVolume()
 				<
 				leafb->mPvsSize*b.bbox.GetVolume();
@@ -481,5 +481,5 @@
 				leafb->mPvsSize;
 #endif
-#if 1
+#if 0
 			return
 				leafa->mPvsSize/(leafa->rays.size()+1)
@@ -487,5 +487,5 @@
 				leafb->mPvsSize/(leafb->rays.size()+1);
 #endif
-#if o
+#if 0
 			return
 				leafa->mPvsSize*leafa->rays.size()
@@ -754,4 +754,11 @@
 	EvalLeafPvs(VssTreeLeaf *leaf);
 
+	int
+	GetRootPvsSize() const {
+		return GetPvsSize(root, bbox);
+	}
+	
+	int
+	GetPvsSize(VssTreeNode *node, const AxisAlignedBox3 &box) const;
 	
 };
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h	(revision 372)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Mesh.h	(revision 387)
@@ -192,4 +192,6 @@
   virtual float IntersectionComplexity() {  return (float)mMesh->mFaces.size(); }
 
+	virtual int NumberOfFaces() const {  return mMesh->mFaces.size(); }
+
   virtual int Type() const { return MESH_INSTANCE; }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp	(revision 339)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SceneGraph.cpp	(revision 387)
@@ -77,2 +77,28 @@
   return id;
 }
+
+void
+SceneGraph::GetStatistics(int &intersectables, int &faces) const
+{
+  stack<SceneGraphNode *> nodeStack;
+  
+  nodeStack.push(mRoot);
+  faces = 0;
+	intersectables = 0;
+  while (!nodeStack.empty()) {
+    SceneGraphNode *node = nodeStack.top();
+    nodeStack.pop();
+		
+    ObjectContainer::const_iterator mi = node->mGeometry.begin();
+    for (; mi != node->mGeometry.end(); mi++) {
+			intersectables++;
+			faces += (*mi)->NumberOfFaces();
+		}
+    
+    SceneGraphNodeContainer::iterator ni = node->mChildren.begin();
+    for (; ni != node->mChildren.end(); ni++) {
+      nodeStack.push(*ni);
+    }
+  }
+	
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 372)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 387)
@@ -92,4 +92,23 @@
 }
 
+int
+SplitFilenames(const string str,
+							 vector<string> &filenames)
+{
+	int pos = 0;
+
+	while(1) {
+		int npos = str.find(';', pos);
+		
+		if (npos < 0 || npos - pos < 1)
+			break;
+		filenames.push_back(string(str, pos, npos - pos));
+		pos = npos + 1;
+	}
+	
+	filenames.push_back(string(str, pos, str.size() - pos));
+	return filenames.size();
+}
+
 bool
 Preprocessor::LoadScene(const string filename)
@@ -101,18 +120,49 @@
   
   Parser *parser;
-
-  if (strstr(filename.c_str(), ".x3d"))
-    parser = new X3dParser;
-  else
-    parser = new UnigraphicsParser;
-
-  bool result = parser->ParseFile(filename, &mSceneGraph->mRoot);
-
-	
-	
-  delete parser;
-
-	if (result)
+	vector<string> filenames;
+	int files = SplitFilenames(filename, filenames);
+	cout<<files<<endl;
+	bool result = false;
+	if (files == 1) {
+		
+		if (strstr(filename.c_str(), ".x3d"))
+			parser = new X3dParser;
+		else
+			parser = new UnigraphicsParser;
+
+		cout<<filename<<endl;
+		result = parser->ParseFile(filename, &mSceneGraph->mRoot);
+
+		delete parser;
+
+	} else {
+		// root for different files
+		mSceneGraph->mRoot = new SceneGraphNode;
+		for (int i= 0; i < filenames.size(); i++) {
+			if (strstr(filenames[i].c_str(), ".x3d"))
+				parser = new X3dParser;
+			else
+				parser = new UnigraphicsParser;
+			
+			SceneGraphNode *node;
+			if (parser->ParseFile(filenames[i], &node)) {
+				mSceneGraph->mRoot->mChildren.push_back(node);
+				// at least one file parsed
+				result = true;
+			}
+			delete parser;
+		}
+	}
+	
+
+	if (result) {
 		mSceneGraph->AssignObjectIds();
+		int intersectables, faces;
+		mSceneGraph->GetStatistics(intersectables, faces);
+		cout<<filename<<" parsed successfully."<<endl;
+		cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<intersectables<<endl;
+		cout<<"#NUM_FACES (Total numner of faces)\n"<<faces<<endl;
+	}
+
 	
   return result;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp	(revision 386)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssTree.cpp	(revision 387)
@@ -272,9 +272,12 @@
 			ri++)
 		if ((*ri).mRay->IsActive()) {
-			Intersectable *object = (*ri).mRay->mOriginObject;
+			Intersectable *object;
+#if BIDIRECTIONAL_RAY
+			object = (*ri).mRay->mOriginObject;
 			if (object && !object->Mailed()) {
 				pvsSize++;
 				object->Mail();
 			}
+#endif
 			object = (*ri).mRay->mTerminationObject;
 			if (object && !object->Mailed()) {
@@ -365,57 +368,13 @@
 	
   if (splitType == ESplitRegular) {
-		int sRaysBack, sRaysFront;
-		int dRaysBack, dRaysFront;
-		int sPvsBack, sPvsFront;
-		int dPvsBack, dPvsFront;
-		
-		
-		int sAxis = box.Size().DrivingAxis();
-		float sPosition = (box.Min()[sAxis] + box.Max()[sAxis])*0.5f;
-		float sCostRatio = EvalCostRatio(leaf,
-																		 sAxis,
-																		 sPosition,
-																		 sRaysBack,
-																		 sRaysFront,
-																		 sPvsBack,
-																		 sPvsFront
+		costRatio = BestCostRatioRegular(leaf,
+																		 axis,
+																		 position,
+																		 raysBack,
+																		 raysFront,
+																		 pvsBack,
+																		 pvsFront
 																		 );
-		//		cout<<"srays back="<<sRaysBack<<" rays front="<<sRaysFront<<" pvs back="<<sPvsBack<<
-		//			" pvs front="<<sPvsFront<<endl;
-
-		AxisAlignedBox3 dirBox = GetDirBBox(leaf);
-		int dAxis = dirBox.Size().DrivingAxis();
-		float dPosition = (dirBox.Min()[dAxis] + dirBox.Max()[dAxis])*0.5f;
-		float dCostRatio = EvalCostRatio(leaf,
-																		 dAxis+3,
-																		 dPosition,
-																		 dRaysBack,
-																		 dRaysFront,
-																		 dPvsBack,
-																		 dPvsFront
-																		 );
-		
-		//		cout<<"drays back="<<dRaysBack<<" rays front="<<dRaysFront<<" pvs back="<<dPvsBack<<
-		//			" pvs front="<<dPvsFront<<endl;
-
-		if (sCostRatio < dCostRatio) {
-			costRatio = sCostRatio;
-			axis = sAxis;
-			position = sPosition;
-			raysBack = sRaysBack;
-			raysFront = sRaysFront;
-			pvsBack = sPvsBack;
-			pvsFront = sPvsFront;
-			
-		} else {
-			costRatio = dCostRatio;
-			axis = dAxis+3;
-			position = dPosition;
-			raysBack = dRaysBack;
-			raysFront = dRaysFront;
-			pvsBack = dPvsBack;
-			pvsFront = dPvsFront;
-		}
-		
+
 	} else {
     if (splitType == ESplitHeuristic)
@@ -487,5 +446,4 @@
 				// determine the side of this ray with respect to the plane
 				int side = (*ri).ComputeRayIntersection(axis, position, (*ri).mRay->mT);
-				
 				//				(*ri).mRay->mSide = side;
 				
@@ -496,9 +454,5 @@
 					raysFront++;
 				
-#if BIDIRECTIONAL_RAY
-				AddObject2Pvs((*ri).mRay->mOriginObject, side, pvsBack, pvsFront);
-#endif
 				AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
-
       }
 		
@@ -536,8 +490,4 @@
 
 				//				(*ri).mRay->mSide = side;
-
-#if BIDIRECTIONAL_RAY
-				AddObject2Pvs((*ri).mRay->mOriginObject, side, pvsBack, pvsFront);
-#endif
 				AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
 
@@ -551,5 +501,7 @@
 		
 		//		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
-		float sum = pvsBack*(position - minBox) + pvsFront*(maxBox - position);
+		float sum =
+			pvsBack*(position - minBox) +
+			pvsFront*(maxBox - position);
 		//		float sum = pvsBack + pvsFront;
 		newCost = ct_div_ci + sum/sizeBox;
@@ -566,5 +518,5 @@
 float
 VssTree::BestCostRatioRegular(
-															VssTreeLeaf *node,
+															VssTreeLeaf *leaf,
 															int &axis,
 															float &position,
@@ -573,14 +525,59 @@
 															int &pvsBack,
 															int &pvsFront
-															
 															)
 {
-	
-	return 0;
+	int nRaysBack[6], nRaysFront[6];
+	int nPvsBack[6], nPvsFront[6];
+	float nPosition[6];
+	float nCostRatio[6];
+	int bestAxis = -1;
+	
+	AxisAlignedBox3 sBox = GetBBox(leaf);
+	AxisAlignedBox3 dBox = GetDirBBox(leaf);
+	// int sAxis = box.Size().DrivingAxis();
+	int sAxis = sBox.Size().DrivingAxis();
+	int dAxis = dBox.Size().DrivingAxis() + 3;
+
+	bool onlyDrivingAxis = true; 
+
+	for (axis = 0; axis < 6; axis++) {
+		if (!onlyDrivingAxis || axis == sAxis || axis == dAxis) {
+			if (axis < 3)
+				nPosition[axis] = (sBox.Min()[axis] + sBox.Max()[axis])*0.5f;
+			else
+				nPosition[axis] = (dBox.Min()[axis-3] + dBox.Max()[axis-3])*0.5f;
+			
+			nCostRatio[axis] = EvalCostRatio(leaf,
+																			 axis,
+																			 nPosition[axis],
+																			 nRaysBack[axis],
+																			 nRaysFront[axis],
+																			 nPvsBack[axis],
+																			 nPvsFront[axis]
+																			 );
+			
+			if ( bestAxis == -1)
+				bestAxis = axis;
+			else
+				if ( nCostRatio[axis] < nCostRatio[bestAxis] )
+					bestAxis = axis;
+		}
+	}
+
+	axis = bestAxis;
+	position = nPosition[bestAxis];
+
+	raysBack = nRaysBack[bestAxis];
+	raysFront = nRaysFront[bestAxis];
+
+	pvsBack = nPvsBack[bestAxis];
+	pvsFront = nPvsFront[bestAxis];
+	
+	return nCostRatio[bestAxis];
 }
 
 float
 VssTree::BestCostRatioHeuristic(
-																VssTreeLeaf *node,
+																VssTreeLeaf *leaf,
 																int &axis,
 																float &position,
@@ -591,48 +588,78 @@
 																)
 {
-	AxisAlignedBox3 box = GetBBox(node);
-	AxisAlignedBox3 dirBox = GetDirBBox(node);
-
+	AxisAlignedBox3 box = GetBBox(leaf);
+	//	AxisAlignedBox3 dirBox = GetDirBBox(node);
+	
 	axis = box.Size().DrivingAxis();
-	
-	SortSplitCandidates(node, axis);
-  
-  // go through the lists, count the number of objects left and right
-  // and evaluate the following cost funcion:
-  // C = ct_div_ci  + (ql*rl + qr*rr)/queries
-
-  int rl=0, rr=node->rays.size();
-	
-  float minBox = box.Min(axis);
-  float maxBox = box.Max(axis);
-  float sizeBox = maxBox - minBox;
-  
-  float minBand = minBox + 0.1*(maxBox - minBox);
-  float maxBand = minBox + 0.9*(maxBox - minBox);
-  
-  float sum = rr*sizeBox;
-  float minSum = 1e20;
-  
-  for(vector<SortableEntry>::const_iterator ci = splitCandidates->begin();
-      ci < splitCandidates->end();
-      ci++) {
-    
-    switch ((*ci).type) {
-    case SortableEntry::ERayMin:
-      rl++;
-      break;
-    case SortableEntry::ERayMax:
-      rr--;
-      break;
-    }
-		
-    if ((*ci).value > minBand && (*ci).value < maxBand) {
-      
-      sum = rl*((*ci).value - minBox) + rr*(maxBox - (*ci).value);
-      
-      //      cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl;
-      //      cout<<"cost= "<<sum<<endl;
-      
-      if (sum < minSum) {
+		
+	SortSplitCandidates(leaf, axis);
+  
+	// go through the lists, count the number of objects left and right
+	// and evaluate the following cost funcion:
+	// C = ct_div_ci  + (ql*rl + qr*rr)/queries
+	
+	int rl=0, rr = leaf->rays.size();
+	int pl=0, pr = leaf->mPvsSize;
+	float minBox = box.Min(axis);
+	float maxBox = box.Max(axis);
+	float sizeBox = maxBox - minBox;
+	
+	float minBand = minBox + 0.1*(maxBox - minBox);
+	float maxBand = minBox + 0.9*(maxBox - minBox);
+	
+	float sum = rr*sizeBox;
+	float minSum = 1e20;
+	
+	Intersectable::NewMail();
+	// set all object as belonging to the fron pvs
+	for(VssTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
+			ri != leaf->rays.end();
+			ri++)
+		if ((*ri).mRay->IsActive()) {
+			Intersectable *object = (*ri).mRay->mTerminationObject;
+			if (object)
+				if (!object->Mailed()) {
+					object->Mail();
+					object->mCounter = 1;
+				} else
+					object->mCounter++;
+		}
+	
+	Intersectable::NewMail();
+	
+	for(vector<SortableEntry>::const_iterator ci = splitCandidates->begin();
+			ci < splitCandidates->end();
+			ci++) {
+		VssRay *ray;
+		switch ((*ci).type) {
+		case SortableEntry::ERayMin: {
+			rl++;
+			ray = (VssRay *) (*ci).data;
+			Intersectable *object = ray->mTerminationObject;
+			if (object && !object->Mailed()) {
+				object->Mail();
+				pl++;
+			}
+			break;
+		}
+		case SortableEntry::ERayMax: {
+			rr--;
+			ray = (VssRay *) (*ci).data;
+			Intersectable *object = ray->mTerminationObject;
+			if (object) {
+				if (--object->mCounter == 0)
+					pr--;
+			}
+			break;
+		}
+		}
+		if ((*ci).value > minBand && (*ci).value < maxBand) {
+			
+			sum = pl*((*ci).value - minBox) + pr*(maxBox - (*ci).value);
+			
+			//      cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl;
+			//      cout<<"cost= "<<sum<<endl;
+			
+			if (sum < minSum) {
 				minSum = sum;
 				position = (*ci).value;
@@ -641,9 +668,12 @@
 				raysFront = rr;
 				
+				pvsBack = pl;
+				pvsFront = pr;
+				
       }
     }
   }
   
-  float oldCost = node->rays.size();
+  float oldCost = leaf->mPvsSize;
   float newCost = ct_div_ci + minSum/sizeBox;
   float ratio = newCost/oldCost;
@@ -652,5 +682,4 @@
   //  cout<<"costRatio="<<ratio<<" pos="<<position<<" t="<<(position - minBox)/(maxBox - minBox)
   //      <<"\t q=("<<queriesBack<<","<<queriesFront<<")\t r=("<<raysBack<<","<<raysFront<<")"<<endl;
-
 	return ratio;
 }
@@ -1290,2 +1319,55 @@
   return totalRayCount - rayCount;
 }
+
+
+int
+VssTree::GetPvsSize(VssTreeNode *node, const AxisAlignedBox3 &box) const
+{
+	stack<VssTreeNode *> tstack;
+  tstack.push(root);
+
+	Intersectable::NewMail();
+	int pvsSize = 0;
+	
+  while (!tstack.empty()) {
+    VssTreeNode *node = tstack.top();
+    tstack.pop();
+    
+ 
+    if (node->IsLeaf()) {
+			VssTreeLeaf *leaf = (VssTreeLeaf *)node;
+			for(VssTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
+					ri != leaf->rays.end();
+					ri++)
+				if ((*ri).mRay->IsActive()) {
+					Intersectable *object;
+#if BIDIRECTIONAL_RAY
+					object = (*ri).mRay->mOriginObject;
+					if (object && !object->Mailed()) {
+						pvsSize++;
+						object->Mail();
+					}
+#endif
+					object = (*ri).mRay->mTerminationObject;
+					if (object && !object->Mailed()) {
+						pvsSize++;
+						object->Mail();
+					}
+				}
+		} else {
+			VssTreeInterior *in = (VssTreeInterior *)node;
+			if (in->axis < 3) {
+				if (box.Max(in->axis) >= in->position )
+					tstack.push(in->front);
+				
+				if (box.Min(in->axis) <= in->position )
+					tstack.push(in->back);
+			} else {
+				// both nodes for directional splits
+				tstack.push(in->front);
+				tstack.push(in->back);
+			}
+		}
+	}
+	return pvsSize;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 386)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VssPreprocessor.cpp	(revision 387)
@@ -76,6 +76,8 @@
 	
 	if (mKdTree->CastRay(ray)) {
+		
 		objectB = ray.intersections[0].mObject;
 	  pointB = ray.Extrap(ray.intersections[0].mT);
+
 	} else {
 		objectB = NULL;
@@ -92,21 +94,30 @@
 	VssRay *vssRay  = NULL;
 
-	if (objectA) {
-		vssRay = new VssRay(pointB,
-												pointA,
-												objectB,
-												objectA);
-		mVssRays.push_back(vssRay);
-		hits ++;
-	}
-	
-	if (objectB) {
-		vssRay = new VssRay(pointA,
-												pointB,
-												objectA,
-												objectB);
-		mVssRays.push_back(vssRay);
-		hits ++;
-
+	bool validSample = true;
+	if (detectEmptyViewSpace) {
+		if (Distance(pointA, pointB) <
+				Distance(viewPoint, pointA) + Distance(viewPoint, pointB) - Limits::Small) {
+			validSample = false;
+		}
+	}
+	
+	if (validSample) {
+		if (objectA) {
+			vssRay = new VssRay(pointB,
+													pointA,
+													objectB,
+													objectA);
+			mVssRays.push_back(vssRay);
+			hits ++;
+		}
+		
+		if (objectB) {
+			vssRay = new VssRay(pointA,
+													pointB,
+													objectA,
+													objectB);
+			mVssRays.push_back(vssRay);
+			hits ++;
+		}
 	}
 	
@@ -122,5 +133,5 @@
 	if (viewSpaceBox)
 		box =*viewSpaceBox;
-	else
+	else 
 		box = mKdTree->GetBox();
 	
@@ -146,5 +157,4 @@
   
   mSceneGraph->CollectObjects(&mObjects);
-	cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<mObjects.size()<<endl;
 	
   long startTime = GetTime();
@@ -155,7 +165,15 @@
 
 	AxisAlignedBox3 box = mKdTree->GetBox();
-	box.Enlarge(box.Size()*-Vector3(0.45, 0.45, 0.45));
-
-	bool useViewSpaceBox = false;
+
+	
+	if (1)
+		box.Enlarge(box.Size()*-Vector3(0.45, 0.45, 0.45));
+	else {
+		// sample city like heights
+		box.SetMin(1, box.Min(1) + box.Size(1)*0.1);
+		box.SetMax(1, box.Min(1) + box.Size(1)*0.2);
+	}
+	
+	bool useViewSpaceBox = true;
 	if (useViewSpaceBox)
 		viewSpaceBox = &box;
@@ -243,4 +261,5 @@
 	vssTree->Construct(mVssRays, viewSpaceBox);
 
+	cout<<"VssTree root PVS size = "<<vssTree->GetRootPvsSize()<<endl;
 	
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 386)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 387)
@@ -52,5 +52,5 @@
 
   p->LoadScene(filename);
-
+	
   p->BuildKdTree();
   p->KdTreeStatistics(cout);
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h	(revision 382)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Intersectable.h	(revision 387)
@@ -17,4 +17,7 @@
 	int mId;
 
+	// universal counter
+	int mCounter;
+	
 	// object based pvs
 	KdPvs mKdPvs;
@@ -51,5 +54,7 @@
   virtual float IntersectionComplexity() = 0;
   
-  virtual int Type() const = 0;
+	virtual int NumberOfFaces() const = 0;
+
+	virtual int Type() const = 0;
 
   virtual int GetRandomSurfacePoint(Vector3 &point, Vector3 &normal) = 0;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 386)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/default.env	(revision 387)
@@ -9,9 +9,11 @@
 #	filename vienna.x3d
 # filename ../data/vienna/vienna-simple.x3d
-# filename ../data/vienna/vienna-buildings.x3d
+#filename ../data/vienna/vienna-buildings.x3d
+#filename ../data/vienna/vienna-buildings.x3d;../data/vienna/vienna-roofs.x3d
+#;../data/vienna/vienna-plane.x3d
 # filename ../data/vienna/viewcells-25-sel.x3d
-filename ../data/atlanta/atlanta2.x3d
+# filename ../data/atlanta/atlanta2.x3d
 # filename ../data/soda/soda.dat
-# filename ../data/soda/soda5.dat
+filename ../data/soda/soda5.dat
 }
 
@@ -22,5 +24,5 @@
 
 VssPreprocessor {
-	totalSamples 1000000
+	totalSamples 100000
 	samplesPerPass  50000
 }
