Index: trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 350)
+++ trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env	(revision 352)
@@ -9,7 +9,7 @@
 #	filename vienna.x3d
 #	filename ../data/vienna/vienna-simple.x3d
-#	filename ../data/vienna/vienna-buildings.x3d
+	filename ../data/vienna/vienna-buildings.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
@@ -76,7 +76,7 @@
 BspTree {
 	Construction {
-		input fromRays
+	#	input fromRays
 	#	input fromViewCells
-	#	input fromSceneGeometry
+		input fromSceneGeometry
 		samples 150000
 		sideTolerance 0.005
@@ -114,5 +114,7 @@
 	
 	#splitPlaneStrategy 384
-	splitPlaneStrategy 130
+	#splitPlaneStrategy 130
+	
+	splitPlaneStrategy 66
 	
 	maxCandidates 80
@@ -120,10 +122,10 @@
 	Termination {
 		# autopartition
-		maxRays 30
-		maxPolygons 0
+		maxRays -1
+		maxPolygons 250
 		maxDepth 100
 		
-		#axis aligned split
-		maxPolysForAxisAligned 200
+		# axis aligned splits
+		maxPolysForAxisAligned 400
 		maxCostRatio 0.9
 		ct_div_ci 0.5
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 338)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 352)
@@ -5,9 +5,9 @@
 #include "Triangle3.h"
 
-ViewCell::ViewCell(): MeshInstance(NULL)
+ViewCell::ViewCell(): MeshInstance(NULL), mPiercingRays(0)
 {
 }
 
-ViewCell::ViewCell(Mesh *mesh): MeshInstance(mesh)
+ViewCell::ViewCell(Mesh *mesh): MeshInstance(mesh), mPiercingRays(0)
 {
 }
@@ -80,4 +80,50 @@
 }
 
+ViewCell *ViewCell::MergeViewCells(const ViewCell &front, const ViewCell &back)
+{
+	/*stable_sort(front.mPiercingRays.begin(), front.mPiercingRays.end());
+	stable_sort(back.mPiercingRays.begin(), back.mPiercingRays.end());
+
+	ViewCell *vc = front.Merge(back);
+
+	if (vc)
+		return vc;
+
+	return back.Merge(front);*/return NULL;
+}
+
+ViewCell *ViewCell::Merge(const ViewCell &other) const
+{
+	//-- compute set differences
+	const float minDif = 10;
+
+	RayContainer diff;
+
+	set_difference(mPiercingRays.begin(), mPiercingRays.end(), 
+				   other.mPiercingRays.begin(), other.mPiercingRays.end(),
+				   diff.begin());
+
+	if (diff.size() < minDif)
+	{
+		ViewCell *vc = new ViewCell();
+
+		RayContainer::const_iterator it, it_end = other.mPiercingRays.end();
+
+		for (it = other.mPiercingRays.begin(); it != it_end; ++ it)
+			vc->mPiercingRays.push_back(*it);
+
+		while (!diff.empty())
+		{
+			vc->mPiercingRays.push_back(diff.back());
+			diff.pop_back();
+		}
+
+		return vc;
+	}
+
+	return NULL;
+}
+
+
 void ViewCell::AddPassingRay(const Ray &ray, const int contributions)
 {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 350)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 352)
@@ -221,8 +221,10 @@
 		@param sampleContributions the number contributions of the sampels
 		@param contributingSampels the number of contributing rays
+		@param storeRays if ray set should be stored in view cell
 	*/
 	void BspLeaf::GenerateViewCell(const RayContainer &rays, 
 							   int &sampleContributions,
-							   int &contributingSamples);
+							   int &contributingSamples,
+							   const bool storeRays = false);
 
 protected:
@@ -230,5 +232,4 @@
 	/// if NULL this does not correspond to feasible viewcell
 	ViewCell *mViewCell;
-	RayContainer mPiercingRays;
 };
 
@@ -377,7 +378,7 @@
 	};
 
-	BspNode *MergeNodes(BspInterior *node);
-
-	bool MergeNecessary(BspLeaf *front, BspLeaf *back) const;
+	/** Merges view cells of leafs.
+	*/
+	void MergeLeafs(BspLeaf *front, BspLeaf *back) const;
 
 	/** Evaluates tree stats in the BSP tree leafs.
@@ -584,6 +585,4 @@
 				  RayContainer &backRays);
 
-	void MergeLeafs(BspLeaf *front, BspLeaf *back);
-
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 351)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 352)
@@ -220,5 +220,5 @@
 				//-- inherit rays from parent polygon
 				poly->InheritRays(*front_piece, *back_piece);
-				Debug << "p: " << poly->mPiercingRays.size() << " f: " << front_piece->mPiercingRays.size() << " b: " << back_piece->mPiercingRays.size() << endl;
+				//Debug << "p: " << poly->mPiercingRays.size() << " f: " << front_piece->mPiercingRays.size() << " b: " << back_piece->mPiercingRays.size() << endl;
 				
 				// check if polygons still valid 
@@ -250,19 +250,19 @@
 /*                  class BspLeaf implementation                */
 /****************************************************************/
-BspLeaf::BspLeaf(): mViewCell(NULL), mPiercingRays(0)
+BspLeaf::BspLeaf(): mViewCell(NULL)
 {
 }
 
 BspLeaf::BspLeaf(ViewCell *viewCell): 
-mViewCell(viewCell), mPiercingRays(0)
+mViewCell(viewCell)
 {
 }
 
 BspLeaf::BspLeaf(BspInterior *parent): 
-BspNode(parent), mViewCell(NULL), mPiercingRays(0)
+BspNode(parent), mViewCell(NULL)
 {}
 
 BspLeaf::BspLeaf(BspInterior *parent, ViewCell *viewCell): 
-BspNode(parent), mViewCell(viewCell), mPiercingRays(0)
+BspNode(parent), mViewCell(viewCell)
 {
 }
@@ -285,5 +285,6 @@
 void BspLeaf::GenerateViewCell(const RayContainer &rays, 
 							   int &sampleContributions,
-							   int &contributingSamples)
+							   int &contributingSamples,
+							   const bool storeRays)
 {
 	sampleContributions = 0;
@@ -311,4 +312,7 @@
 			++ contributingSamples;
 		}
+
+		if (storeRays)
+			mViewCell->mPiercingRays.push_back(*it);
 	}
 }
@@ -694,13 +698,4 @@
 		leaf->ProcessPolygons(tData.mPolygons, sStoreSplitPolys);
 		DEL_PTR(tData.mPolygons);
-		
-		if (mStorePiercingRays)
-		{
-			RayContainer::const_iterator it, it_end = tData.mRays->end();
-			for (it = tData.mRays->begin(); it != it_end; ++ it)
-			{
-				leaf->mPiercingRays.push_back(*it);
-			}
-		}
 		DEL_PTR(tData.mRays);
 
@@ -1580,5 +1575,5 @@
 	nodeStack.push(mRoot);
 
-	BspLeaf *rightLeaf = NULL;
+	BspLeaf *storedLeaf = NULL;
 
 	while (!nodeStack.empty()) 
@@ -1591,6 +1586,9 @@
 			BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
 
-			if (rightLeaf && MergeNecessary(leaf, rightLeaf))
-				MergeLeafs(leaf, rightLeaf);
+			if (storedLeaf)
+				MergeLeafs(leaf, storedLeaf);
+
+			// store current leaf
+			storedLeaf = leaf;
 		}
 		else 
@@ -1605,26 +1603,18 @@
 }
 
-bool BspTree::MergeNecessary(BspLeaf *front, BspLeaf *back) const
-{
-	if ((front->mPiercingRays.size() < 2) ||
-		(back->mPiercingRays.size() < 2))
-		return true;
-	//else if ((Raydiff(front, back) > 100) ||
-	//		   (Raydiff(back, front) > 100))return true;
-
-	return false;
-}
-
-void BspTree::MergeLeafs(BspLeaf *front, BspLeaf *back)
+void BspTree::MergeLeafs(BspLeaf *front, BspLeaf *back) const
 {
 	//std::merge(front->mPvs.mEntries.begin(), back->mPvs.mEntries.begin());
-	ViewCell *viewCell = new ViewCell();
-	viewCell->GetPvs().Merge(front->mViewCell->GetPvs(), back->mViewCell->GetPvs());
-
-	DEL_PTR(front->mViewCell);
-	DEL_PTR(back->mViewCell);
-
-	front->SetViewCell(viewCell);
-	back->SetViewCell(viewCell);
+	ViewCell *viewCell = ViewCell::MergeViewCells(*front->mViewCell, *back->mViewCell);
+	//viewCell->GetPvs().Merge(front->mViewCell->GetPvs(), back->mViewCell->GetPvs());
+
+	if (viewCell)
+	{
+		DEL_PTR(front->mViewCell);
+		DEL_PTR(back->mViewCell);
+
+		front->SetViewCell(viewCell);
+		back->SetViewCell(viewCell);
+	}
 }
 
@@ -1688,2 +1678,40 @@
 	return splits;
 }
+
+int BspTree::FindNeighbors(KdNode *n, vector<BspNode *> &neighbors, bool onlyUnmailed)
+{
+	stack<BspNode *> nodeStack;
+	nodeStack.push(mRoot);
+
+	AxisAlignedBox3 box = GetBox(n);
+
+	while (!nodeStack.empty()) 
+	{
+		BspNode *node = nodeStack.top();
+		nodeStack.pop();
+
+		if (node->IsLeaf()) 
+		{
+			if (node != n && (!onlyUnmailed || !node->Mailed())) 
+				neighbors.push_back(node);
+		} 
+		else 
+		{
+			KdInterior *interior = (KdInterior *)node;
+			
+			if (interior->mPosition > box.Max(interior->mAxis))
+				nodeStack.push(interior->mBack);
+			else
+				if (interior->mPosition < box.Min(interior->mAxis))
+					nodeStack.push(interior->mFront);
+				else 
+				{
+					// random decision
+					nodeStack.push(interior->mBack);
+					nodeStack.push(interior->mFront);
+				}
+		}
+	
+	}
+	return neighbors.size();
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 311)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 352)
@@ -37,4 +37,9 @@
 								const int maxViewCells);
 
+	
+	/** Adds a passing ray to the passing ray container.
+	*/
+	void AddPassingRay(const Ray &ray, const int contributions);	
+
 	/** Constructs view cell from base triangle. The ViewCell is extruded along the normal vector.
 		@param the base triangle
@@ -43,12 +48,22 @@
 	static ViewCell *ExtrudeViewCell(const Triangle3 &baseTri, const float height);
 
-	void AddPassingRay(const Ray &ray, const int contributions);	
+	/** Merges two view cells based on some criteria
+		@returns new view cell if merge was success. NULL if merge failed.
+	*/
+	static ViewCell *MergeViewCells(const ViewCell &front, const ViewCell &back);
 
-	static bool ParseEnvironment();
 
-	/** Ray set description of the rays passing through this node */
+	/// Ray set description of the rays passing through this node.	
 	PassingRaySet mPassingRays;
 
+	/// Rays piercing this view cell.
+	RayContainer mPiercingRays;
+
 protected:
+	
+	/** Merges view cell with other view cell if certain criteria are met.
+		@note because of performance issues the precondition is that the piercing rays are ordered.
+	*/
+	ViewCell *Merge(const ViewCell &other) const;
 
 	/// the potentially visible objects
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 350)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 352)
@@ -742,5 +742,5 @@
 
 		// export scene geometry
-		if (1)
+		if (0)
 		{
 			Material m;//= RandomMaterial();
