Index: /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1643)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1649)
@@ -2527,4 +2527,9 @@
 					"-1");
 
+	RegisterOption("Hierarchy.Termination.maxMemory",
+					optFloat,
+					"hierarchy_construction_max_memory=",
+					"1");
+
 	RegisterOption("Hierarchy.Construction.useMultiLevel",
 					optBool,
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1642)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1649)
@@ -42,5 +42,5 @@
 class Exporter;
 
-
+#define COUNT_ORIGIN_OBJECTS 1
 
 /** View space / object space hierarchy statistics.
@@ -376,5 +376,5 @@
 	/** After the suddivision has ended, do some final tasks.
 	*/
-	void FinishObjectSpaceSubdivision(const ObjectContainer &objects) const;
+	void FinishObjectSpaceSubdivision(const ObjectContainer &objects, const bool removeRayRefs = true) const;
 
 	/** Returns depth of object space subdivision.
@@ -487,4 +487,6 @@
 	/// maximum number of leaves
 	int mTermMaxLeaves;
+	/// Maximal allowed memory consumption.
+	float mTermMaxMemory;
 
 	////////////////////
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1643)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1649)
@@ -25,5 +25,5 @@
 #define PROBABILIY_IS_BV_VOLUME 1
 #define USE_FIXEDPOINT_T 0
-#define COUNT_ORIGIN_OBJECTS 0
+//#define COUNT_ORIGIN_OBJECTS 0
 
 int BvhNode::sMailId = 10000; //2147483647;
@@ -1069,5 +1069,5 @@
 	const float ratio = newRenderCost / oldRenderCost;
 
-#ifdef _DEBUG
+//#ifdef _DEBUG
 	Debug << "\n§§§§ bvh eval const decrease §§§§" << endl
 		  << "back pvs: " << (int)objectsBack.size() << " front pvs: " << (int)objectsFront.size() << " total pvs: " << nTotalObjects << endl 
@@ -1075,5 +1075,5 @@
 		  << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl
 		  << "render cost decrease: " << oldRenderCost / viewSpaceVol - newRenderCost / viewSpaceVol << endl;
-#endif
+//#endif
 
 	return ratio;
@@ -1326,6 +1326,6 @@
 			}
 		}
-
-		if (COUNT_ORIGIN_OBJECTS && ray->mOriginObject)
+#if COUNT_ORIGIN_OBJECTS
+		if (ray->mOriginObject)
 		{
 			ray->mOriginObject->mVssRays.push_back(ray);
@@ -1337,4 +1337,5 @@
 			}
 		}
+#endif
 	}
 
@@ -1509,5 +1510,4 @@
 		for (vit = tmpViewCells.begin(); vit != vit_end; ++ vit)
 		{
-			//VspViewCell *vc = dynamic_cast<VspViewCell *>(*vit);
 			ViewCell *vc = *vit;
 
@@ -1883,5 +1883,5 @@
 
 	PrintSubdivisionStats(*oSubdivisionCandidate);
-
+	
 	return oSubdivisionCandidate;
 }
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1640)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1649)
@@ -27,5 +27,5 @@
 
 // should not count origin object for sampling because it disturbs heuristics
-#define SAMPLE_ORIGIN_OBJECTS 0
+#define SAMPLE_ORIGIN_OBJECTS 1
 
 // $$JB HACK
@@ -1914,13 +1914,11 @@
 
 			if (ray.mTerminationObject) 
-			  {			
-				
-
-			  if (viewcell->GetPvs().GetSampleContribution(obj,
-														   ray.mPdf,
-														   contribution))
+			{			
+				if (viewcell->GetPvs().GetSampleContribution(obj,
+					ray.mPdf,
+					contribution))
 				{
-				  ++ ray.mPvsContribution;
-				  ray.mRelativePvsContribution += contribution;
+					++ ray.mPvsContribution;
+					ray.mRelativePvsContribution += contribution;
 				}
 			}
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1640)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1649)
@@ -28,5 +28,5 @@
 
 #define USE_FIXEDPOINT_T 0
-#define COUNT_ORIGIN_OBJECTS 0
+
 
 /////////////
@@ -1031,5 +1031,5 @@
 			sc += contribution;
 		}
-
+#if COUNT_ORIGIN_OBJECTS
 		obj = ray->mOriginObject;
 
@@ -1046,5 +1046,5 @@
 			sc += contribution;
 		}
-
+#endif
 		if (madeContrib)
 		{
@@ -1167,5 +1167,7 @@
 		
 		pvsSize += PrepareHeuristics(*ray, true);
+#if COUNT_ORIGIN_OBJECTS
 		pvsSize += PrepareHeuristics(*ray, false);
+#endif
 	}
 
@@ -1240,11 +1242,17 @@
 	if (ci.type == SortableEntry::ERayMin)
 	{
+#if COUNT_ORIGIN_OBJECTS
 		pvsLeft += EvalMinEventContribution(*ray, true);
+#else
 		pvsLeft += EvalMinEventContribution(*ray, false);
+#endif
 	}
 	else // eval changes in pvs causes by max event 
 	{
+#if COUNT_ORIGIN_OBJECTS
 		pvsRight -= EvalMaxEventContribution(*ray, true);
+#else
 		pvsRight -= EvalMaxEventContribution(*ray, false);
+#endif
 	}
 }
@@ -2206,7 +2214,9 @@
 	{
 		VssRay *ray = (*rit).mRay;
-
+#if COUNT_ORIGIN_OBJECTS
 		pvsSize += EvalContributionToPvs(*ray, true);
+#else
 		pvsSize += EvalContributionToPvs(*ray, false);
+#endif
 	}
 	
@@ -2283,7 +2293,9 @@
 	{
 		VssRay *ray = (*rit).mRay;
-
+#if COUNT_ORIGIN_OBJECTS
 		pvsSize += EvalPvsEntriesContribution(*ray, true);
+#else
 		pvsSize += EvalPvsEntriesContribution(*ray, false);
+#endif
 	}
 
@@ -2489,7 +2501,5 @@
 				++ hits;
 			}
-#if 0
-			leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0)));
-#endif
+
 			// get the next node from the stack
 			if (tStack.empty())
Index: /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1643)
+++ /GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1649)
@@ -112,5 +112,4 @@
 		"Hierarchy.Construction.minStepsOfSameType", mMinStepsOfSameType);
 	
-
 	char subdivisionStatsLog[100];
 	Environment::GetSingleton()->GetStringValue("Hierarchy.subdivisionStats", subdivisionStatsLog);
@@ -119,4 +118,7 @@
 	Environment::GetSingleton()->GetBoolValue(
 		"Hierarchy.Construction.recomputeSplitPlaneOnRepair", mRecomputeSplitPlaneOnRepair);
+
+	Environment::GetSingleton()->GetFloatValue(
+		"Hierarchy.Termination.maxMemory", mTermMaxMemory);
 
 	Debug << "******** Hierachy Manager Options ***********" << endl;
@@ -129,4 +131,5 @@
 	Debug << "recompute split plane on repair: " << mRecomputeSplitPlaneOnRepair << endl;
 	Debug << "minimal number of steps from same type: " << mMinStepsOfSameType << endl;
+	Debug << "maximal allowed memory: " << mTermMaxMemory << endl;
 
 	switch (mConstructionType)
@@ -233,7 +236,7 @@
 void HierarchyManager::EvalSubdivisionStats()
 {
-	// TODO
-	const float objectSpaceMem = GetObjectSpaceMemUsage();
-	const float viewSpaceMem = mVspTree->GetMemUsage();
+	// question: should I also add the mem usage of the hierarchies?
+	const float objectSpaceMem = 0;//GetObjectSpaceMemUsage();
+	const float viewSpaceMem = 0;//mVspTree->GetMemUsage();
 	
 	// calculate cost in MB
@@ -274,10 +277,11 @@
 		(0
 		|| (mHierarchyStats.Leaves() >= mTermMaxLeaves) 
+		|| (mHierarchyStats.mMemory >= mTermMaxMemory)
+		|| candidate->GlobalTerminationCriteriaMet()
+		//|| (mHierarchyStats.mRenderCostDecrease < mMinRenderCostDecrease)
 		//|| (mHierarchyStats.mGlobalCostMisses >= mTermGlobalCostMissTolerance)
-		|| (candidate->GlobalTerminationCriteriaMet())
-		//|| (mHierarchyStats.mRenderCostDecrease < mMinRenderCostDecrease)
 		);
 
-#if _DEBUG
+//#if _DEBUG
 	if (terminationCriteriaMet)
 	{
@@ -285,6 +289,7 @@
 		Debug << "leaves: " << mHierarchyStats.Leaves() << " " << mTermMaxLeaves << endl;
 		Debug << "cost misses: " << mHierarchyStats.mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
-	}
-#endif
+		Debug << "memory: " << mHierarchyStats.mMemory << " " << mTermMaxMemory << endl;
+	}
+//#endif
 
 	return terminationCriteriaMet;
@@ -466,5 +471,5 @@
 	mVspTree->mVspStats.Stop();
 
-	FinishObjectSpaceSubdivision(objects);
+	FinishObjectSpaceSubdivision(objects, !mUseMultiLevelConstruction);
 }
 
@@ -534,5 +539,6 @@
 	mHierarchyStats.Stop();
 	mVspTree->mVspStats.Stop();
-	FinishObjectSpaceSubdivision(objects);
+	
+	FinishObjectSpaceSubdivision(objects, !mUseMultiLevelConstruction);
 }
 
@@ -551,4 +557,6 @@
 
 	mHierarchyStats.mTotalCost = mVspTree->mTotalCost;
+	mHierarchyStats.mPvsEntries = mVspTree->EvalPvsEntriesSize(*viewSpaceRays);
+
 	cout << "\nreseting cost for vsp, new total cost: " << mHierarchyStats.mTotalCost << endl;
 
@@ -650,5 +658,4 @@
 {
 	const bool terminationCriteriaMet = GlobalTerminationCriteriaMet(sc);
-
 	const bool success = sc->Apply(splitQueue, terminationCriteriaMet);
 
@@ -842,10 +849,8 @@
 	{
 		SubdivisionCandidate *sc = NextSubdivisionCandidate(mTQueue);    
-		cout << "p=" << sc->GetPriority() << " ";
-
+		
 		////////
 		//-- subdivide leaf node of either type
         ApplySubdivisionCandidate(sc, mTQueue, repairQueue);
-	//cout << "\nhere45 " << sc->GetPriority() << " " << sc->GetRenderCostDecrease() << " " << mObjectSpaceSubdivisionType << " " << mViewSpaceSubdivisionType << endl;
 		
 		DEL_PTR(sc);
@@ -904,13 +909,14 @@
 			cout << "\nreseting bv hierarchy" << endl;
 			Debug << "old bv hierarchy:\n " << mBvHierarchy->mBvhStats << endl;
-
+			
 			mBvHierarchy->Initialise(objects);
-
+	
 			// rather use this: remove previous nodes and add the two new ones
 			//mHierarchyStats.mNodes -= mBvHierarchy->mBvhStats.nodes + 2;
 			mHierarchyStats.mNodes = 2;
 
+			//firstCandidate = mBvHierarchy->PrepareConstruction(sampleRays, objects);
 			firstCandidate = mBvHierarchy->Reset(sampleRays, objects);
-		
+
 			mHierarchyStats.mTotalCost = mBvHierarchy->mTotalCost;
 			mHierarchyStats.mRenderCostDecrease = 0;
@@ -918,9 +924,10 @@
 			// bug!! pvs entries cab be much higher at this stage
 			// (if view space was already subdivided)
-			mHierarchyStats.mPvsEntries = 1;
+			mHierarchyStats.mPvsEntries = mBvHierarchy->CountViewCells(objects);
 			mHierarchyStats.mMemory = sizeof(PvsData) + sizeof(Intersectable *) / (1024.0f * 1024.0f);
 
 			// evaluate stats before first subdivision
 			EvalSubdivisionStats();
+			cout << "finished bv hierarchy preparation" << endl;
 		}
 		break;
@@ -941,19 +948,19 @@
 																  AxisAlignedBox3 *forcedViewSpace)
 {
-	ViewCellsManager *vc = mVspTree->mViewCellsManager;
+	ViewCellsManager *vm = mVspTree->mViewCellsManager;
 
 	// HACK: rather not destroy vsp tree
 	DEL_PTR(mVspTree);
 	mVspTree = new VspTree();
+
 	mVspTree->mHierarchyManager = this;
+	mVspTree->mViewCellsManager = vm;
 
 	mVspTree->Initialise(sampleRays, forcedViewSpace);
 	
-	SubdivisionCandidate *vsc = 
-		PrepareViewSpaceSubdivision(sampleRays, objects);
+	SubdivisionCandidate *vsc = PrepareViewSpaceSubdivision(sampleRays, objects);
 	
 	mHierarchyStats.mNodes = 2;
-	// bug!! pvs entries could be much higher at this stage
-	mHierarchyStats.mPvsEntries = 1;
+	
 	mHierarchyStats.mRenderCostDecrease = 0;
 
@@ -993,5 +1000,5 @@
 	mTQueue.Push(osc);
 
-	//////////////////////////7
+	//////////////////////////
 
 
@@ -1021,5 +1028,4 @@
 
 		cout << "iteration " << i << " of " << limit << " finished" << endl;
-
 		mSubdivisionStats.close();
 
@@ -1030,8 +1036,10 @@
 		mSubdivisionStats.open(subdivisionStatsLog);
 
+
 		/////////////////
 		// subdivide view space with respect to the objects
 
-		SubdivisionCandidate *vspVc = ResetViewSpaceSubdivision(sampleRays, objects, forcedViewSpace);
+		SubdivisionCandidate *vspVc = 
+			ResetViewSpaceSubdivision(sampleRays, objects, forcedViewSpace);
 		mTQueue.Push(vspVc);
 
@@ -1043,5 +1051,4 @@
 
 		cout << "iteration " << i << " of " << limit << " finished" << endl;
-
 		mSubdivisionStats.close();
 
@@ -1065,20 +1072,4 @@
 	//mObjectSpaceSubdivisionType = mSavedObjectSpaceSubdivisionType;
 
-	// set the number of leaves 'evaluated' from the previous methods
-	// we go for the same numbers, but we try to optimize both
-	// subdivisions
-	switch (mObjectSpaceSubdivisionType)
-	{
-	case BV_BASED_OBJ_SUBDIV:
-		mBvHierarchy->mTermMaxLeaves = mBvHierarchy->mBvhStats.Leaves();
-		break;
-	case KD_BASED_OBJ_SUBDIV:
-		mOspTree->mTermMaxLeaves = mOspTree->mOspStats.Leaves();
-	default:
-		break;
-	}
-	
-	mVspTree->mMaxViewCells = mVspTree->mVspStats.Leaves();
-
 	const long startTime = GetTime();
 	const int limit = mNumMultiLevels;
@@ -1088,4 +1079,21 @@
 
 	int steps = 0;
+
+	int maxViewSpaceLeaves = mVspTree->mVspStats.Leaves();
+	int maxObjectSpaceLeaves;
+	
+	// set the number of leaves 'evaluated' from the previous methods
+	// we go for the same numbers, but we try to optimize both subdivisions
+	switch (mObjectSpaceSubdivisionType)
+	{
+	case BV_BASED_OBJ_SUBDIV:
+		maxObjectSpaceLeaves = mBvHierarchy->mBvhStats.Leaves();
+		break;
+	case KD_BASED_OBJ_SUBDIV:
+		maxObjectSpaceLeaves = mOspTree->mOspStats.Leaves();
+	default:
+		maxObjectSpaceLeaves = 0;
+		break;
+	}
 
 	// This method subdivides view space / object space 
@@ -1103,4 +1111,8 @@
 		SubdivisionCandidate *ospVc = 
 			ResetObjectSpaceSubdivision(sampleRays, objects);
+	
+		// set the number of leaves 'evaluated' from the previous methods
+		// we go for the same numbers, but we try to optimize both subdivisions
+		mBvHierarchy->mTermMaxLeaves = maxObjectSpaceLeaves;
 		mTQueue.Push(ospVc);
 
@@ -1109,5 +1121,4 @@
 
 		cout << "iteration " << steps << " of " << limit << " finished" << endl;
-
 		mSubdivisionStats.close();
 
@@ -1123,4 +1134,6 @@
 		SubdivisionCandidate *vspVc = 
 			ResetViewSpaceSubdivision(sampleRays, objects, forcedViewSpace);
+
+		mVspTree->mMaxViewCells = maxViewSpaceLeaves;
 		mTQueue.Push(vspVc);
 
@@ -1129,5 +1142,4 @@
 
 		cout << "iteration " << steps << " of " << limit << " finished" << endl;
-
 		mSubdivisionStats.close();
 
@@ -1440,5 +1452,5 @@
 
 
-void HierarchyManager::FinishObjectSpaceSubdivision(const ObjectContainer &objects) const
+void HierarchyManager::FinishObjectSpaceSubdivision(const ObjectContainer &objects, const bool removeRayRefs) const
 {
 	switch (mObjectSpaceSubdivisionType)
@@ -1452,5 +1464,6 @@
 		{
 			mBvHierarchy->mBvhStats.Stop();
-			RemoveRayRefs(objects);
+			if (removeRayRefs)
+				RemoveRayRefs(objects);
 			break;
 		}
