Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1577)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1580)
@@ -26,5 +26,6 @@
 #define COUNT_ORIGIN_OBJECTS 1
 
-///////////
+
+//////////////
 //-- static members
 
@@ -383,6 +384,5 @@
 
         cout << "Extracting polygons from rays ... ";
-
-		long startTime = GetTime();
+		const long startTime = GetTime();
 
         VssRayContainer::const_iterator rit, rit_end = sampleRays.end();
@@ -422,5 +422,5 @@
 						{
 							// TODO
-							cout << "here5" << endl;
+							cout << "not implemented yet" << endl;
 						}
 					default:
@@ -1384,4 +1384,5 @@
 	SortSubdivisionCandidates(usedRays, axis, minBand, maxBand);
 
+	//////////////////
 	// go through the lists, count the number of objects left and right
 	// and evaluate the following cost funcion:
@@ -1396,5 +1397,4 @@
 	float sum = (float)pvsSize * sizeBox;
 	float minSum = 1e20f;
-
 	
 	// if no border can be found, take mid split
@@ -1406,5 +1406,4 @@
 
 	Intersectable::NewMail();
-
    	RayInfoContainer::const_iterator ri, ri_end = usedRays.end();
 
@@ -1443,5 +1442,4 @@
 
 	Intersectable::NewMail();
-
 	vector<SortableEntry>::const_iterator ci, ci_end = mLocalSubdivisionCandidates->end();
 
@@ -1454,5 +1452,4 @@
 		Intersectable *tObject = ray->mTerminationObject;
 		
-
 		switch ((*ci).type)
 		{
@@ -2115,6 +2112,8 @@
 		AddObjToPvs(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs);
 
-		if (COUNT_ORIGIN_OBJECTS) 
+		if (COUNT_ORIGIN_OBJECTS)
+		{
 			AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs);
+		}
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1576)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1580)
@@ -517,4 +517,6 @@
 		@param exportPvs if the pvs should also be exported
 		@param exportRays if sample rays should be exported as well
+		@param maxRays maximum number of rays to export
+		@param prefix the prefix for the output file
 		@param visRays additional rays
 	*/
@@ -530,4 +532,8 @@
 		VssRayContainer *visRays = NULL) = NULL;
 
+	
+	void ViewCellsManager::ResetPvs();
+
+
 protected:
 
@@ -577,5 +583,5 @@
 	void EvaluateViewCellsStats();
 
-
+	
 	///////////////////////
 	//-- helper functions for view cell visualization
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1576)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1580)
@@ -245,5 +245,7 @@
 	void RunConstruction(const bool repairQueue);
 		
-	bool ApplySubdivisionCandidate(SubdivisionCandidate *sc);
+	/** Evaluates the subdivision candidate and executes the split.
+	*/
+	bool ApplySubdivisionCandidate(SubdivisionCandidate *sc, const bool repairQueue);
 
 	bool FinishedConstruction() const;
@@ -251,9 +253,16 @@
 	SubdivisionCandidate *NextSubdivisionCandidate();
 
+	/** Repairs the dirty entries of the candidate queue.
+	*/
 	void RepairQueue();
 
+	/** Collect the list of dirty candidates after the current subdivision candidate
+		split.
+	*/
 	void CollectDirtyCandidates(vector<SubdivisionCandidate *> &dirtyList);
 
-	void EvalSubdivisionStats(const SubdivisionCandidate &tData);
+	/** Evaluate subdivision stats for log.
+	*/
+	void EvalSubdivisionStats(const float renderCostDecr);
 
 	void AddSubdivisionStats(
@@ -328,49 +337,75 @@
 
 	enum {SEQUENTIAL, INTERLEAVED};
-	
+	/// type of hierarchy construction
+	int mConstructionType;
+
+	/// Type of object space partition
 	int mObjectSpaceSubdivisionType;
+	/// Type of view space partition
     int mViewSpaceSubdivisionType;
 
-	/// the original osp type
+	////////////
+	//-- helper variables
+	
+	// the original osp type
 	int mSavedObjectSpaceSubdivisionType;
+	// the original vsp type
 	int mSavedViewSpaceSubdivisionType;
-
-	int mConstructionType;
-
+	/// the current subdivision candidate
+	SubdivisionCandidate *mCurrentCandidate;
+
+	///////////////////
+
+
+	///////////////////
+	// Hierarchies
+
+	/// view space hierarchy
 	VspTree *mVspTree;
+	/// object space partition kd tree
 	OspTree *mOspTree;
+	/// bounding volume hierarchy
 	BvHierarchy *mBvHierarchy;
 
-	AxisAlignedBox3 mBoundingBox;
-
+	//////////////////////
+	
+
+	/// the traversal queue
 	SplitQueue mTQueue;
-
-	SubdivisionCandidate *mCurrentCandidate;
-
-	////////
+	
+
+	//////////
 	//-- global termination criteria
 
+	/// the mininal acceptable cost ratio for a split
 	float mTermMinGlobalCostRatio;
+	/// the threshold for global cost miss tolerance
 	int mTermGlobalCostMissTolerance;
-	
+	/// maximum number of leaves
+	int mTermMaxLeaves;
+
 	////////////////////
 
 	/// keeps track of cost during subdivision
 	float mTotalCost;
-
-	int mTotalPvsEntries;
+	/// statistics about the hierarchy
 	HierarchyStatistics mHierarchyStats;
 
 	int mMinDepthForObjectSpaceSubdivion;
 	int mMinDepthForViewSpaceSubdivion;
-
-	int mTermMaxLeaves;
+	
 	ofstream mSubdivisionStats;
 
+	/// if the queue should be repaired after a subdivision steps
 	bool mRepairQueue;
 
 	bool mStartWithObjectSpace;
-
+	/** if multi level construction method should be used
+		where we iterate over both hierarchies until we
+		converge to the optimum.
+	*/
 	bool mUseMultiLevelConstruction;
+	/// number of iteration steps for multilevel approach	
+	int mNumMultiLevels;
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1577)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1580)
@@ -174,4 +174,6 @@
 	ReadEnvironment();
 	mSubdivisionCandidates = new SortableEntryContainer;
+	for (int i = 0; i < 3; ++ i)
+		mSortedObjects[i] = NULL;
 }
 
@@ -189,4 +191,8 @@
 	DEL_PTR(mSubdivisionCandidates);
 
+	for (int i = 0; i < 3; ++ i)
+	{
+		DEL_PTR(mSortedObjects[i]);
+	}
 	mSubdivisionStats.close();
 }
@@ -1004,5 +1010,6 @@
 {
 	//-- insert object queries
-	ObjectContainer *objects = mUseGlobalSorting ? tData.mSortedObjects[axis] : &tData.mNode->mObjects;
+	ObjectContainer *objects = 
+		mUseGlobalSorting ? tData.mSortedObjects[axis] : &tData.mNode->mObjects;
 
 	CreateLocalSubdivisionCandidates(*objects, &mSubdivisionCandidates, !mUseGlobalSorting, axis);
@@ -1042,5 +1049,5 @@
 
 	if (sort)
-	{
+	{	// no presorted candidate list
 		stable_sort((*subdivisionCandidates)->begin(), (*subdivisionCandidates)->end());
 	}
@@ -1154,5 +1161,5 @@
 	}
 	
-	////////////////////////////////////////////
+	////////////////////////////////////
 	//-- evaluate split cost for all three axis
 	
@@ -1179,5 +1186,6 @@
 				else
 				{
-					//-- use surface area heuristic because view cells not constructed yet				
+					//////////////////
+					//-- view cells not constructed yet	=> use surface area heuristic			
 					nCostRatio[axis] =
 						EvalSah(
@@ -1210,5 +1218,5 @@
 	}
 
-	/////////////////////////////////////
+    ////////////////
 	//-- assign values
 
@@ -1242,5 +1250,5 @@
 		}
 
-		if (1 && ray->mOriginObject)
+		if (COUNT_ORIGIN_OBJECTS && ray->mOriginObject)
 		{
 			ray->mOriginObject->mVssRays.push_back(ray);
@@ -1298,17 +1306,19 @@
 
 float BvHierarchy::EvalRenderCost(const ObjectContainer &objects) const
-{
-	if (mHierarchyManager->GetViewSpaceSubdivisionType() == HierarchyManager::NO_VIEWSPACE_SUBDIV)
-	{
+{	
+	if (mHierarchyManager->GetViewSpaceSubdivisionType() == 
+		HierarchyManager::NO_VIEWSPACE_SUBDIV)
+	{
+		////////////////
+		//-- surface area heuristics
+
 		if (objects.empty())
 			return 0.0f;
 
-		////////////////
-		//-- surface area heuristics
-
 		const AxisAlignedBox3 box = EvalBoundingBox(objects);
 		const float area = box.SurfaceArea();
-
-		return (float)objects.size() * area / mViewCellsManager->GetViewSpaceBox().SurfaceArea();
+		const float viewSpaceArea = mViewCellsManager->GetViewSpaceBox().SurfaceArea();
+
+		return (float)objects.size() * area / viewSpaceArea;
 	}
 	else
@@ -1771,5 +1781,5 @@
 	if (mUseGlobalSorting)
 	{
-		CreateInitialSortedObjectList(oData);
+		AssignInitialSortedObjectList(oData);
 	}
 	
@@ -1793,25 +1803,28 @@
 
 
-void BvHierarchy::CreateInitialSortedObjectList(BvhTraversalData &tData)
-{
-	SortableEntryContainer *sortedObjects = new SortableEntryContainer();
-
+void BvHierarchy::AssignInitialSortedObjectList(BvhTraversalData &tData)
+{
 	// we sort the objects as a preprocess so they don't have
 	// to be sorted for each split
 	for (int i = 0; i < 3; ++ i)
 	{
-		CreateLocalSubdivisionCandidates(tData.mNode->mObjects, &sortedObjects, true, i);
-			
+		// create new objects
+		if (!mSortedObjects[i])
+		{
+			mSortedObjects[i] = new SortableEntryContainer();
+			CreateLocalSubdivisionCandidates(tData.mNode->mObjects, &mSortedObjects[i], true, i);
+		}
+
+		// copy list into traversal data list
 		tData.mSortedObjects[i] = new ObjectContainer();
-		tData.mSortedObjects[i]->reserve((int)sortedObjects->size());
-
-		SortableEntryContainer::const_iterator oit, oit_end = sortedObjects->end();
-		for (oit = sortedObjects->begin(); oit != oit_end; ++ oit)
+		tData.mSortedObjects[i]->reserve((int)mSortedObjects[i]->size());
+
+		SortableEntryContainer::const_iterator oit, oit_end = mSortedObjects[i]->end();
+
+		for (oit = mSortedObjects[i]->begin(); oit != oit_end; ++ oit)
 		{
 			tData.mSortedObjects[i]->push_back((*oit).mObject);
 		}
 	}
-
-	delete sortedObjects;
 }
 
@@ -1885,4 +1898,7 @@
 	BvhTraversalData oData(bvhLeaf, 0, prop, nRays);
 
+	AssignInitialSortedObjectList(oData);
+	
+
 	///////////////////
 	//-- add first candidate for object space partition	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1576)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1580)
@@ -35,5 +35,5 @@
 // HACK
 const static bool SAMPLE_AFTER_SUBDIVISION = true;
-const static bool CLAMP_TO_BOX = false;
+const static bool CLAMP_TO_BOX = true;
 
 template <typename T> class myless
@@ -814,4 +814,17 @@
 	// potentially visible objects
 	return vc->AddPvsSample(obj, pdf, contribution);
+}
+
+
+void ViewCellsManager::ResetPvs()
+{
+	if (ViewCellsTreeConstructed())
+	{
+		mViewCellsTree->ResetPvs();
+	}
+	else
+	{
+		cout << "view cells tree not constructed" << endl;
+	}
 }
 
@@ -1841,5 +1854,5 @@
 
 			if (ray.mTerminationObject) 
-			{
+			{			
 				if (viewcell->GetPvs().GetSampleContribution(
 							ray.mTerminationObject,
@@ -2932,7 +2945,8 @@
 				if (p < raysOut)
 				{
-					cout << "here42 " << (int)(*rit)->mFlags << endl;
 					if ((*rit)->mFlags & VssRay::BorderSample)
+					{
 						vcRays.push_back(*rit);
+					}
 					else if ((*rit)->mFlags & VssRay::ReverseSample)
 						vcRays2.push_back(*rit);
@@ -5309,22 +5323,25 @@
 	stream << "<VisibilitySolution>" << endl;
 
-
-	///////////////
-	//-- export bounding boxes
-	//-- The bounding boxes are used to identify 
-	//-- the objects in the rendering engine
-
-	stream << "<BoundingBoxes>" << endl;
-	ObjectContainer::const_iterator oit, oit_end = objects.end();
-
-	for (oit = objects.begin(); oit != oit_end; ++ oit)
-	{
+	if (exportPvs) 
+	{
+        ///////////////
+		//-- export bounding boxes
+		//-- The bounding boxes are used to identify 
+		//-- the objects in the rendering engine
+
+		stream << "<BoundingBoxes>" << endl;
+		ObjectContainer::const_iterator oit, oit_end = objects.end();
+        
+		for (oit = objects.begin(); oit != oit_end; ++ oit)
+		{
 			const AxisAlignedBox3 box = (*oit)->GetBox();
 			stream << "<BoundingBox" << " id=\"" << (*oit)->GetId() << "\""
-				   << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\""
-				   << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl;
-	}
-	stream << "</BoundingBoxes>" << endl;
-
+				<< " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\""
+				
+				<< " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl;
+		}
+		
+		stream << "</BoundingBoxes>" << endl;
+	}
 
 	//////////////////////////
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1576)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1580)
@@ -13,4 +13,5 @@
 #include "AxisAlignedBox3.h"
 #include "IntersectableWrapper.h"
+
 
 
@@ -789,7 +790,7 @@
 	float EvalViewCellsVolume(const ObjectContainer &objects) const;
 
-	/** Creates initial list of sorted objects.
-	*/
-	void CreateInitialSortedObjectList(BvhTraversalData &tData);
+	/** Assigns or newly creates initial list of sorted objects.
+	*/
+	void AssignInitialSortedObjectList(BvhTraversalData &tData);
 
 	/** Assigns sorted objects to front and back data.
@@ -844,8 +845,8 @@
 	//-- global termination criteria
 
+	/// the minimal accepted global cost ratio
 	float mTermMinGlobalCostRatio;
+	//// number of accepted misses of the global cost ratio
 	int mTermGlobalCostMissTolerance;
-	
-
 	/// maximal number of view cells
 	int mTermMaxLeaves;
@@ -882,6 +883,8 @@
 	/// stores the kd node intersectables used for pvs
 	BvhIntersectableMap mBvhIntersectables;
-
+	/// if the objects should be sorted in one global step
 	bool mUseGlobalSorting;
+
+	SortableEntryContainer *mSortedObjects[3];
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1577)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1580)
@@ -829,8 +829,12 @@
 	
 	AxisAlignedPlane candidatePlane = splitCandidate.mSplitPlane;
-	RayInfoContainer::const_iterator rit, 
-		rit_end = splitCandidate.mParentData.mRays->end();
-
-	// this is the main ray classification loop!
+	
+	Intersectable::NewMail(3);
+	KdLeaf::NewMail(3);
+	BvhLeaf::NewMail(3);
+
+	RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end();
+
+    // this is the main ray classification loop!
 	for(rit = splitCandidate.mParentData.mRays->begin(); rit != rit_end; ++ rit)
 	{
@@ -849,5 +853,6 @@
 #endif
 	}
-	
+	//cout << "pvs entries: " << fPvsSize << " " << bPvsSize << " " << oldPvsSize << endl;
+
 	return (int)(fPvsSize + bPvsSize - oldPvsSize);
 }
@@ -1495,6 +1500,6 @@
 										  candidatePlane.mPosition, t);
 
-		// evaluate contribution of ray endpoint to front and back pvs
-		// with respect to the classification
+		// evaluate contribution of ray endpoint to front 
+		// and back pvs with respect to the classification
 		UpdateContributionsToPvs(*ray, true, cf, pvsFront, pvsBack, totalPvs);	
 #if COUNT_ORIGIN_OBJECTS
@@ -1657,5 +1662,5 @@
 	if (!leaf) return;
 	const int renderCost = countEntries ? 1 : (int)leaf->mObjects.size();
-
+	
 	// leaf in no pvs => new
 	if (!leaf->Mailed() && !leaf->Mailed(1) && !leaf->Mailed(2))
@@ -3124,5 +3129,5 @@
 		{
 			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
-			UpdateContributionsToPvs(leaf, cf, pvsFront, pvsBack, totalPvs, true);	        
+			UpdateContributionsToPvs(leaf, cf, pvsFront, pvsBack, totalPvs, true);
 			break;
 		}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1579)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1580)
@@ -129,4 +129,5 @@
 	char internKdTree[100];
 	Environment::GetSingleton()->GetStringValue("Preprocessor.kdTreeFilename", internKdTree);
+	//string internKdTree = ReplaceSuffic(filename, ".x3d", ".kd");
 
 	//-- initialize external ray casters
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1528)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.cpp	(revision 1580)
@@ -73,5 +73,5 @@
 	mFlags = 0;
 	Vector3 dir = GetDir();
-
+//mFlags |= BorderSample;
 #define BIDIRECTIONAL_RAY 0
 #if BIDIRECTIONAL_RAY
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1576)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 1580)
@@ -67,5 +67,5 @@
 		// set flag for visualization
 		newRay->mFlags |= VssRay::ReverseSample;
-		cout << "here9444 " << (int) newRay->mFlags << " " << newRay << endl;
+		
 		// ray is not pushed into the queue => can delete ray
 		if (!HandleRay(newRay))
@@ -81,5 +81,4 @@
 bool GvsPreprocessor::HandleRay(VssRay *vssRay)
 {
-	cout << "x " << (int)vssRay->mFlags;
 	const bool storeRaysForViz = true;
 	mViewCellsManager->ComputeSampleContribution(*vssRay, true, storeRaysForViz);
@@ -88,4 +87,5 @@
 	if (vssRay->mPvsContribution > 0)
 	{
+		// add new ray to ray queue
 		mRayQueue.push(vssRay);
 
@@ -96,8 +96,5 @@
 			{
 				VssRay *nray = new VssRay(*vssRay);
-				nray->mFlags = vssRay->mFlags;
-				(*vit)->mVssRays.push_back(nray);
-nray->mFlags = 10;
-				cout << "\nhere58 " << (int)nray->mFlags << "  " << (int)vssRay->mFlags << endl;
+				(*vit)->mVssRays.push_back(nray);				
 			}
 		}
@@ -205,5 +202,8 @@
 		
 		if (!newRay) return 0;
-newRay->mFlags |= VssRay::BorderSample;
+
+		newRay->mFlags |= VssRay::BorderSample;
+
+		// add new ray to queue
 		const bool enqueued = HandleRay(newRay);
 		
@@ -267,4 +267,11 @@
 	CastRays(simpleRays, vssRays, false, false);
 
+	// set flags
+	VssRayContainer::const_iterator rit, rit_end = vssRays.end();
+	for (rit = vssRays.begin(); rit != rit_end; ++ rit)
+	{cout << "z";
+		(*rit)->mFlags |= VssRay::BorderSample;
+		//(*rit)->mOriginObject = currentRay.mTerminationObject;
+	}
 	// add to ray queue
 	EnqueueRays(vssRays);
@@ -273,12 +280,6 @@
 	int castRays = (int)vssRays.size();
 
-	VssRayContainer::const_iterator rit, rit_end = vssRays.end();
-	for (rit = vssRays.begin(); rit != rit_end; ++ rit)
-	{
-		(*rit)->mFlags |= VssRay::BorderSample;
-		cout << "here390 " << (int) (*rit)->mFlags << endl;
-	}
-
-#if 1
+
+#if 0
     // recursivly subdivide each edge
 	for (int i = 0; i < n; ++ i)
@@ -347,5 +348,5 @@
 {	
 	const long startTime = GetTime();
-
+//cout << "here8"<<endl;
 	// generate simple rays
 	SimpleRayContainer simpleRays;
@@ -433,4 +434,6 @@
 		/// construct the view cells from the scratch
 		ConstructViewCells();
+		// reset pvs already gathered during view cells construction
+		mViewCellsManager->ResetPvs();
 		cout << "finished view cell construction" << endl;
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1577)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1580)
@@ -58,4 +58,5 @@
 	mVspTree->mHierarchyManager = this;
 	
+	mViewSpaceSubdivisionType = KD_BASED_VIEWSPACE_SUBDIV;
 	ParseEnvironment();
 }
@@ -72,4 +73,5 @@
 	mVspTree->mHierarchyManager = this;
 
+	mViewSpaceSubdivisionType = KD_BASED_VIEWSPACE_SUBDIV;
 	ParseEnvironment();
 }
@@ -78,9 +80,4 @@
 void HierarchyManager::ParseEnvironment()
 {
-	char subdivisionStatsLog[100];
-	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", 
-		subdivisionStatsLog);
-	mSubdivisionStats.open(subdivisionStatsLog);
-
 	Environment::GetSingleton()->GetFloatValue(
 		"Hierarchy.Termination.minGlobalCostRatio", mTermMinGlobalCostRatio);
@@ -109,5 +106,7 @@
 		"Hierarchy.Construction.useMultiLevel", mUseMultiLevelConstruction);
 
-	 mUseMultiLevelConstruction;
+	Environment::GetSingleton()->GetIntValue(
+		"Hierarchy.Construction.levels", mNumMultiLevels);
+
 	Debug << "******** Hierachy Manager Parameters ***********" << endl;
 	Debug << "max leaves: " << mTermMaxLeaves << endl;
@@ -117,4 +116,5 @@
 	Debug << "min depth for object space subdivision: " << mMinDepthForObjectSpaceSubdivion << endl;
 	Debug << "repair queue: " << mRepairQueue << endl;
+	Debug << "number of multilevels: " << mNumMultiLevels << endl;
 	Debug << endl;
 }
@@ -198,12 +198,10 @@
 
 
-void HierarchyManager::EvalSubdivisionStats(const SubdivisionCandidate &tData)
-{
-	const float costDecr = tData.GetRenderCostDecrease();
-cout << "here44 " << mHierarchyStats.pvsEntries << endl;
+void HierarchyManager::EvalSubdivisionStats(const float renderCostDecr)
+{
+	//cout << "pvs entries " << mHierarchyStats.pvsEntries << endl;
 	AddSubdivisionStats(mHierarchyStats.Leaves(),
-						costDecr,
+						renderCostDecr,
 						mTotalCost,
-						//mPvsEntries
 						mHierarchyStats.pvsEntries
 						);
@@ -253,4 +251,9 @@
 	else
 	{
+		char subdivisionStatsLog[100];
+		Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", 
+		subdivisionStatsLog);
+		mSubdivisionStats.open(subdivisionStatsLog);
+
 		ConstructInterleaved(sampleRays, objects, forcedViewSpace);
 	}
@@ -267,4 +270,5 @@
 
 	mTotalCost = (float)objects.size();
+	EvalSubdivisionStats(0);
 	Debug << "setting total cost to " << mTotalCost << endl;
 
@@ -315,7 +319,7 @@
 {
 	cout << "\nstarting view space hierarchy construction ... " << endl;
-	 // hack: reset global cost misses
+	// hack: reset global cost misses
 	mHierarchyStats.mGlobalCostMisses = 0;
-
+	
 	RayInfoContainer *viewSpaceRays = new RayInfoContainer();
 	SubdivisionCandidate *vsc = 
@@ -346,6 +350,5 @@
 
 void HierarchyManager::PrepareBvHierarchy(const VssRayContainer &sampleRays,
-										  const ObjectContainer &objects) 
-
+										  const ObjectContainer &objects)
 {
 	const long startTime = GetTime();
@@ -387,5 +390,5 @@
 
 
-bool HierarchyManager::ApplySubdivisionCandidate(SubdivisionCandidate *sc)
+bool HierarchyManager::ApplySubdivisionCandidate(SubdivisionCandidate *sc, const bool repairQueue)
 {
 	const bool globalTerminationCriteriaMet = GlobalTerminationCriteriaMet(sc);
@@ -406,27 +409,52 @@
 	}
 
-	if (vspSplit)
-	{
-		VspNode *n = mVspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
-
-		if (n->IsLeaf()) // local or global termination criteria failed
-			return false;
-	}
-	else
-	{
-		if (mObjectSpaceSubdivisionType == KD_BASED_OBJ_SUBDIV)
-		{
-			KdNode *n = mOspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
-			// local or global termination criteria failed
-			if (n->IsLeaf()) 
-				return false;
-		}
-		else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV)
-		{
-			BvhNode *n = mBvHierarchy->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
-			// local or global termination criteria failed
-			if (n->IsLeaf())
-				return false;
-		}
+	bool success;
+	switch (sc->Type())
+	{
+	case SubdivisionCandidate::VIEW_SPACE:
+		{
+			VspNode *n = mVspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
+			success = !n->IsLeaf(); // local or global termination criteria failed?
+		}
+		break;
+	case SubdivisionCandidate::OBJECT_SPACE:
+		{
+			if (mObjectSpaceSubdivisionType == KD_BASED_OBJ_SUBDIV)
+			{
+				KdNode *n = mOspTree->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
+				// local or global termination criteria failed
+				success = !n->IsLeaf();
+			}
+			else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV)
+			{
+				BvhNode *n = mBvHierarchy->Subdivide(mTQueue, sc, globalTerminationCriteriaMet);
+				// local or global termination criteria failed
+				success = !n->IsLeaf();					
+			}
+		}
+		break;
+	default:
+		break;
+	}
+
+	cout << sc->Type() << " ";
+		
+	// update stats
+	mHierarchyStats.nodes += 2;
+	
+	const int pvsEntries = sc->GetPvsEntriesIncr();
+	mHierarchyStats.pvsEntries += pvsEntries;
+	
+	//cout << "pvs entries: " << pvsEntries << " " << mHierarchyStats.pvsEntries << endl;
+	mHierarchyStats.memory += 0; // TODO
+	
+	// subdivision successful
+	EvalSubdivisionStats(sc->GetRenderCostDecrease());
+		
+	// reevaluate candidates affected by the split for view space splits, 
+	// this would be object space splits and other way round
+	if (repairQueue) 
+	{	
+		RepairQueue();
 	}
 
@@ -507,25 +535,6 @@
 		//-- subdivide leaf node
 
-		if (ApplySubdivisionCandidate(mCurrentCandidate))
-		{
-			cout << mCurrentCandidate->Type() << " ";
-		
-			// update stats
-			mHierarchyStats.nodes += 2;
-			const int pvsEntries = mCurrentCandidate->GetPvsEntriesIncr();
-			mHierarchyStats.pvsEntries += pvsEntries;
-			cout << "pvs entries: " << pvsEntries << " " << mHierarchyStats.pvsEntries << endl;
-			mHierarchyStats.memory += 0; // TODO
-			// subdivision successful
-			EvalSubdivisionStats(*mCurrentCandidate);
-		
-			// reevaluate candidates affected by the split for view space splits, 
-			// this would be object space splits and other way round
-			if (repairQueue) 
-			{	
-				RepairQueue();
-			}
-		}
-
+		ApplySubdivisionCandidate(mCurrentCandidate, repairQueue);
+				
 		// we use objects for evaluating vsp tree construction until 
 		// a certain depth once a certain depth existiert ...
@@ -569,29 +578,13 @@
 {
 	int i = 0;
+	// main loop
 	while (!FinishedConstruction())
 	{
 		mCurrentCandidate = NextSubdivisionCandidate();    
 			
-		///////////////////
+		///////
 		//-- subdivide leaf node
 
-		if (ApplySubdivisionCandidate(mCurrentCandidate))
-		{
-			cout << mCurrentCandidate->Type() << " ";
-			if (0) cout << "subdividing candidate " << ++ i << " of type " 
-						<< mCurrentCandidate->Type() << endl;
-			mHierarchyStats.nodes += 2;
-
-			// subdivision successful
-			EvalSubdivisionStats(*mCurrentCandidate);
-		
-			// reevaluate candidates affected by the split for view space splits, 
-			// this would be object space splits and other way round
-			if (repairQueue) 
-			{
-				RepairQueue();
-			}
-		}
-
+		ApplySubdivisionCandidate(mCurrentCandidate, repairQueue);
 		DEL_PTR(mCurrentCandidate);
 	}
@@ -601,5 +594,5 @@
 void HierarchyManager::ResetObjectSpaceSubdivision(const VssRayContainer &sampleRays, 
 												   const ObjectContainer &objects)
-{
+{	
 #if 0	
 		DEL_PTR(mBvHierarchy);
@@ -609,6 +602,7 @@
 		PrepareObjectSpaceSubdivision(sampleRays, objects);
 		return;
-#endif
-
+#else
+	
+	// no object space subdivision yet
 	if (!ObjectSpaceSubdivisionConstructed())
 	{
@@ -616,13 +610,22 @@
 	}
 
+	// object space partition constructed => reconstruct
 	switch (mObjectSpaceSubdivisionType)
 	{
 	case BV_BASED_OBJ_SUBDIV:
-		cout << "\nreseting bv hierarchy" << endl;
-        Debug << "old bv hierarchy:\n " << mBvHierarchy->mBvhStats << endl;
-	
-		mHierarchyStats.nodes -= mBvHierarchy->mBvhStats.nodes;
-		mTQueue.Push(mBvHierarchy->Reset(sampleRays, objects));
-		mTotalCost = mBvHierarchy->mTotalCost;
+		{
+			cout << "\nreseting bv hierarchy" << endl;
+			Debug << "old bv hierarchy:\n " << mBvHierarchy->mBvhStats << endl;
+	
+			SubdivisionCandidate *firstCandidate = 
+				mBvHierarchy->Reset(sampleRays, objects);
+
+			mTQueue.Push(firstCandidate);
+			mTotalCost = mBvHierarchy->mTotalCost;
+
+			mHierarchyStats.nodes = 2;
+			mHierarchyStats.pvsEntries = 0;
+			EvalSubdivisionStats(0);
+		}
 		break;
 
@@ -633,4 +636,5 @@
 		break;
 	}
+#endif
 }
 
@@ -639,10 +643,17 @@
 												 const ObjectContainer &objects)
 {
-	DEL_PTR(mBvHierarchy);
-	mBvHierarchy = new BvHierarchy();
-	mBvHierarchy->mHierarchyManager = this;
+	ViewCellsManager *vc = mVspTree->mViewCellsManager;
+
+	DEL_PTR(mVspTree);
+	mVspTree = new VspTree();
+	mVspTree->mHierarchyManager = this;
+	mVspTree->mViewCellsManager = vc;
 
 	PrepareViewSpaceSubdivision(sampleRays, objects);
-	return;
+	
+	mHierarchyStats.nodes = 2;
+	mHierarchyStats.pvsEntries = 0;
+	EvalSubdivisionStats(0);
+
 }
 
@@ -665,9 +676,14 @@
 	mVspTree->ComputeBoundingBox(sampleRays, forcedViewSpace);
 
-	// use sah for evaluating object space construction for the first run
+	// use sah for evaluating osp tree construction 
+	// in the first iteration of the subdivision
+	
 	mSavedViewSpaceSubdivisionType = mViewSpaceSubdivisionType;
 	mViewSpaceSubdivisionType = NO_VIEWSPACE_SUBDIV;
-	
-	const int limit = 4;
+
+	mSavedObjectSpaceSubdivisionType = mObjectSpaceSubdivisionType;
+	//mObjectSpaceSubdivisionType = NO_OBJ_SUBDIV;
+
+	const int limit = mNumMultiLevels;
 	int i = 0;
 
@@ -678,25 +694,40 @@
 	while (1)
 	{
-       	// first run object space subdivision
+		char subdivisionStatsLog[100];
+		sprintf(subdivisionStatsLog, "tests/i3d/subdivision-%04d.log", i);
+		mSubdivisionStats.open(subdivisionStatsLog);
+
+		// fsubdivide object space first
 		ResetObjectSpaceSubdivision(sampleRays, objects);
-
 		// process object space candidates
 		RunConstruction(false);
 
-		if ((++ i) >= limit)
+		// object space subdivision constructed
+		mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;
+
+		cout << "iteration " << i << " of " << limit << " finished" << endl;
+
+		mSubdivisionStats.close();
+		if ((i ++) >= limit)
 			break;
 
+		sprintf(subdivisionStatsLog, "tests/i3d/subdivision-%04d.log", i);
+		mSubdivisionStats.open(subdivisionStatsLog);
+
 		/////////////////
-		// do view space subdivison with respect to the object space partition
+		// subdivide view space with respect to the objects
+
 		ResetViewSpaceSubdivision(sampleRays, objects);
-
 		// process view space candidates
 		RunConstruction(false);
+		// view space subdivision constructed
 		mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType;
-		
-		if ((++ i) >= limit)
+	
+		cout << "iteration " << i << " of " << limit << " finished" << endl;
+
+		mSubdivisionStats.close();
+
+		if ((i ++) >= limit)
 			break;
-
-		cout << "iteration " << i << " of " << limit << " finished" << endl;
 	}
 	
@@ -729,5 +760,5 @@
 		return mBvHierarchy && mBvHierarchy->GetRoot();
 	default:
-        return false;
+		return false;
 	}
 }
@@ -808,5 +839,5 @@
 
 	// collect list of "dirty" candidates
-	long startTime = GetTime();
+	const long startTime = GetTime();
    
 	vector<SubdivisionCandidate *> dirtyList;
@@ -827,22 +858,18 @@
 		sc->EvalPriority(); // reevaluate
 		
-		/*
+#ifdef _DEBUG
 		Debug << "candidate " << sc << " reevaluated\n" 
 			  << "render cost decrease diff " <<  rcd - sc->GetRenderCostDecrease()
-			  << " old: " << rcd << " new " << sc->GetRenderCostDecrease() << endl;*/
-		if (0)
-		{
-			const float rcDiff =  rcd - sc->GetRenderCostDecrease();
-			mTotalCost += rcDiff;
-		}
+			  << " old: " << rcd << " new " << sc->GetRenderCostDecrease() << endl;
+#endif	
 		mTQueue.Push(sc); // reinsert
+		cout << ".";
 	}
 
 	long endTime = GetTime();
 	Real timeDiff = TimeDiff(startTime, endTime);
-
 	mHierarchyStats.repairTime += timeDiff;
 
-	if (0) cout << "finished in " << timeDiff * 1e-3f << " secs" << endl;
+	if (1) cout << "repaired in " << timeDiff * 1e-3f << " secs" << endl;
 }
 
@@ -864,5 +891,5 @@
 	SubdivisionCandidateContainer::const_iterator sit, sit_end = mCandidateBuffer.end();
     for (sit = mCandidateBuffer.begin(); sit != sit_end; ++ sit)
-	{cout << ":";
+	{
 		mTQueue.Push(*sit);
 	}
