Index: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1108)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1121)
@@ -222,7 +222,10 @@
 	tStack.push(pair<BspNode *, BspNodeGeometry *>(tree.GetRoot(), geom));
 
+	// color code pvs
 	if (maxPvs)
+	{
 		mUseForcedMaterial = true;
-	
+	}
+
 	while (!tStack.empty()) 
 	{
@@ -647,33 +650,4 @@
 	 delete mesh;
 	 return true;
-}
-
-
-bool VrmlExporter::ExportOspTree(const OspTree &ospTree)
-{
-	vector<KdLeaf *> leaves;
-	ospTree.CollectLeaves(leaves);
-
-	mUseForcedMaterial = true;
-
-	vector<KdLeaf *>::const_iterator it, it_end = leaves.end();
-
-	Material white; 
-	white.mDiffuseColor.r = 1;
-	white.mDiffuseColor.g = 1;
-	white.mDiffuseColor.b = 1;
-
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		SetWireframe();
-		SetForcedMaterial(white);
-		ExportBox(ospTree.GetBBox(*it));
-
-		SetFilled();
-		SetForcedMaterial(RandomMaterial());
-		ExportGeometry((*it)->mObjects);	
-	}
-
-	return true;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 1084)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 1121)
@@ -51,4 +51,5 @@
 	*/
 	float GetArea() const;
+
 	/** Returns volume of this node geometry.
 	*/
@@ -215,11 +216,11 @@
 	}
 
-	int Nodes() const {return nodes;}
+	int Nodes() const { return nodes; }
 	int Interior() const { return nodes / 2; }
 	int Leaves() const { return (nodes / 2) + 1; }
 	
 	// TODO: computation wrong
-	double AvgDepth() const { return accumDepth / (double)Leaves();}; 
-	double AvgRays() const { return accumRays / (double)Leaves();}; 
+	double AvgDepth() const { return accumDepth / (double)Leaves(); }
+	double AvgRays() const { return accumRays / (double)Leaves(); }
 
 	void Reset() 
@@ -304,12 +305,14 @@
 	bool IsSibling(BspNode *n) const;
 
-	/** returns depth of the node.
+	/** Returns depth of the node.
 	*/
 	int GetDepth() const;
 
-	/** returns true if the whole subtree is valid
+	/** Returns true if the whole subtree is valid
 	*/
 	bool TreeValid() const;
 
+	/** Sets the valid flag for the subtree with this node as root.
+	*/
 	void SetTreeValid(const bool v);
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1074)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1121)
@@ -559,5 +559,4 @@
 									   const ViewCellContainer &viewCells);
   
-
 	/** Creates clip plane for visualization.
 	*/
@@ -656,4 +655,6 @@
 	/// if pvs should be exported with view cells
 	bool mExportPvs;
+
+	bool mCountKdPvs;
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1121)
@@ -2054,5 +2054,5 @@
 	RegisterOption("VspBspTree.Construction.renderCostDecreaseWeight",
 			optFloat,
-			"vsp_bsp_post_process_render_cost_decrease_weight=",
+			"vsp_bsp_construction_render_cost_decrease_weight=",
 			"0.99");
 
@@ -2098,4 +2098,10 @@
 					"vsp_construction_samples=",
 					"10000");
+
+	
+	RegisterOption("VspTree.Construction.renderCostDecreaseWeight",
+			optFloat,
+			"vsp_construction_render_cost_decrease_weight=",
+			"0.99");
 
 	RegisterOption("VspTree.Termination.maxDepth",
@@ -2282,5 +2288,4 @@
 		"false");
 
-
 	RegisterOption("OspTree.subdivisionStats",
 					optString,
@@ -2293,4 +2298,13 @@
 					"0.01");
 
+	RegisterOption("OspTree.Construction.renderCostDecreaseWeight",
+			optFloat,
+			"osp_construction_render_cost_decrease_weight=",
+			"0.99");
+
+	RegisterOption("OspTree.Evaluation.countKdPvs",
+		optBool,
+		"osp_evaluation_count_kd_pvs=",
+		"false");
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1121)
@@ -70,5 +70,5 @@
 
   virtual bool
-  ExportOspTree(const OspTree &tree) = 0;
+  ExportOspTree(const OspTree &tree, const int maxPvs);// = 0;
 
 //    virtual bool
Index: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h	(revision 1121)
@@ -60,6 +60,5 @@
 				 );
 
-  bool
-  ExportOspTree(const OspTree &tree);
+  // bool ExportOspTree(const OspTree &tree);
 
   bool ExportBspTree(const BspTree &tree);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 1121)
@@ -1292,27 +1292,4 @@
 
 
-bool X3dExporter::ExportOspTree(const OspTree &ospTree)
-{
-	vector<KdLeaf *> leaves;
-	ospTree.CollectLeaves(leaves);
-
-	mUseForcedMaterial = true;
-
-	vector<KdLeaf *>::const_iterator it, it_end = leaves.end();
-
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		SetWireframe();
-		ExportBox(ospTree.GetBBox(*it));
-
-		SetForcedMaterial(RandomMaterial());
-
-		ExportGeometry((*it)->mObjects);	
-	}
-
-	return true;
-}
-
-
-}
-
+}
+
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1111)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1121)
@@ -22,5 +22,5 @@
 
 #define USE_FIXEDPOINT_T 0
-#define COUNT_OBJECTS 1
+#define COUNT_OBJECTS 0
 
 //-- static members
@@ -50,5 +50,5 @@
 void VspTreeStatistics::Print(ostream &app) const
 {
-	app << "===== VspTree statistics ===============\n";
+	app << "=========== VspTree statistics ===============\n";
 
 	app << setprecision(4);
@@ -99,5 +99,5 @@
 	//app << "#N_PVS: " << pvs << endl;
 
-	app << "===== END OF VspTree statistics ==========\n";
+	app << "========== END OF VspTree statistics ==========\n";
 }
 
@@ -352,4 +352,5 @@
 	//-- partition criteria
 	Environment::GetSingleton()->GetFloatValue("VspTree.Construction.epsilon", mEpsilon);
+	Environment::GetSingleton()->GetFloatValue("VspTree.Construction.renderCostDecreaseWeight", mRenderCostDecreaseWeight);
 
 	// if only the driving axis is used for axis aligned split
@@ -392,5 +393,6 @@
 	Debug << "use cost heuristics: " << mUseCostHeuristics << endl;
 	Debug << "subdivision stats log: " << subdivisionStatsLog << endl;
-	
+	Debug << "render cost decrease weight: " << mRenderCostDecreaseWeight << endl;
+
 	Debug << "circulating axis: " << mCirculatingAxis << endl;
 	Debug << "minband: " << mMinBand << endl;
@@ -598,5 +600,5 @@
 		tBackData.mMaxCostMisses = maxCostMisses;
 			
-		
+	
 		if (1)
 		{
@@ -620,5 +622,5 @@
 		}
 
-	
+
 		//-- evaluate new split candidates for global greedy cost heuristics
 		VspSplitCandidate *frontCandidate = new VspSplitCandidate(tFrontData);
@@ -630,5 +632,7 @@
 		tQueue.Push(frontCandidate);
 		tQueue.Push(backCandidate);
-
+		
+		// delete old view cell
+		delete tData.mNode->GetViewCell();
 		// delete old leaf node
 		DEL_PTR(tData.mNode);
@@ -747,4 +751,7 @@
 		parent->ReplaceChildLink(leaf, interior);
 		interior->SetParent(parent);
+
+		// remove "parent" view cell from pvs of all objects (traverse trough rays)
+		RemoveParentViewCellReferences(tData.mNode->GetViewCell());
 	}
 	else // new root
@@ -770,13 +777,10 @@
 	CreateViewCell(backData);
 
-	// TODO: 
+	
 	// create front and back view cell
-	// remove "parent" view cell from pvs of all objects (traverse trough rays)
 	// add front and back view cell to "Potentially Visbilie View Cells" 
 	// of the objects in front and back pvs
-	RemoveParentViewCellReferences(tData.mNode->GetViewCell());
 	AddViewCellReferences(frontLeaf->GetViewCell());
 	AddViewCellReferences(backLeaf->GetViewCell());
-
 
 	interior->mTimeStamp = mTimeStamp ++;
@@ -1144,24 +1148,24 @@
 void VspTree::AddContriToPvs(KdLeaf *leaf, int &pvs) const
 {
-	if (!leaf->Mailed())
-	{
-		leaf->Mail();
-
-		// add objects without those which are part of several kd leaves
-		pvs += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
-
-		//-- handle objects of several kd leaves separately
-		ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
-
-		for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
-		{
-			Intersectable *object = *oit;
-
-			// object not previously in left pvs
-			if (!object->Mailed())
-			{
-				object->Mail();
-				++ pvs;
-			}
+	if (leaf->Mailed())
+		return;
+	
+	leaf->Mail();
+
+	// add objects without those which are part of several kd leaves
+	pvs += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
+
+	//-- handle objects of several kd leaves separately
+	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
+
+	for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *object = *oit;
+
+		// object not previously in left pvs
+		if (!object->Mailed())
+		{
+			object->Mail();
+			++ pvs;
 		}
 	}					
@@ -1513,5 +1517,5 @@
 	// take render cost of node into account 
 	// otherwise danger of being stuck in a local minimum!!
-	const float factor = 0.99f;
+	const float factor = mRenderCostDecreaseWeight;
 
 	const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume();
@@ -2554,6 +2558,4 @@
 
 
-
-
 int VspTree::ComputeBoxIntersections(const AxisAlignedBox3 &box,
 									 ViewCellContainer &viewCells) const
@@ -2606,4 +2608,36 @@
 
 
+
+void VspTree::CollectDirtyCandidates(VspSplitCandidate *sc, 
+									 vector<SplitCandidate *> &dirtyList)
+{
+	VspLeaf *node = sc->mParentData.mNode;
+	
+    ViewCellLeaf *vc = node->GetViewCell();
+		
+	ObjectPvsMap::const_iterator oit, oit_end = vc->GetPvs().mEntries.end();
+
+	KdLeaf::NewMail();
+
+	for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = (*oit).first;
+
+		set<KdLeaf *>::const_iterator kit, kit_end = obj->mKdLeaves.end();
+
+		for (kit = obj->mKdLeaves.begin(); kit != kit_end; ++ kit)
+		{
+			KdLeaf *leaf = *kit;
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				dirtyList.push_back(leaf->mSplitCandidate);
+			}
+		}
+	}
+}
+
+
 /*****************************************************************/
 /*                class OspTree implementation                   */
@@ -2655,7 +2689,6 @@
 
 	Environment::GetSingleton()->GetFloatValue("OspTree.Construction.splitBorder", mSplitBorder);
-	//mSplitBorder = 0.1f;
-
-
+	Environment::GetSingleton()->GetFloatValue("OspTree.Construction.renderCostDecreaseWeight", mRenderCostDecreaseWeight);
+	
 	//-- debug output
 
@@ -2679,4 +2712,5 @@
 	
 	Debug << "split borders: " << mSplitBorder << endl;
+	Debug << "render cost decrease weight: " << mRenderCostDecreaseWeight << endl;
 
 
@@ -2761,8 +2795,8 @@
 		const AxisAlignedBox3 box = (*mi)->GetBox();
 		
-		if (box.Max(axis) > position) 
+		if (box.Max(axis) > position + mEpsilon) 
 			++ objectsFront;
     
-		if (box.Min(axis) < position)
+		if (box.Min(axis) < position - mEpsilon)
 			++ objectsBack;
 	}
@@ -2843,5 +2877,4 @@
 		// delete old leaf node
 		DEL_PTR(tData.mNode);
-		DEL_PTR(tData.mNode->mViewCell);
 	}
 
@@ -2892,5 +2925,4 @@
 {
 	// matt: TODO
-	Debug << "here888 " << mTermMaxLeaves << " " << mOspStats.Leaves() << endl;
 	return (
 		(mOspStats.Leaves() >= mTermMaxLeaves)
@@ -2952,5 +2984,5 @@
 									   int &objectsBack)
 {
-	
+	// sort so we can use a sweep
 	SortSplitCandidates(node, axis);
   
@@ -2984,11 +3016,17 @@
 
 	float sum = (float)pvsSize * sizeBox;
+float dummy1 = 0;
+float dummy2 = 0;
 
 	vector<SortableEntry>::const_iterator ci, ci_end = mSplitCandidates->end();
-
+cout << "***********" << endl;
 	//-- traverse through visibility events
 	for (ci = mSplitCandidates->begin(); ci != ci_end; ++ ci)
 	{
+		int pvslold = pvsl;
 		EvalPvsIncr(*ci, pvsl, pvsr);
+
+		cout << "incr: " << ci->mObject->mViewCellPvs.GetSize() << " obj id " 
+			 << ci->mObject->GetId() << endl;
 
 		// Note: sufficient to compare size of bounding boxes of front and back side?
@@ -2997,5 +3035,6 @@
 			sum = pvsl * ((*ci).value - minBox) + pvsr * (maxBox - (*ci).value);
 
-			//Debug  << "pos=" << (*ci).value << "\t pvs=(" <<  pvsl << "," << pvsr << ")" << "\t cost= " << sum << endl;
+			cout << "pos=" << (*ci).value << "\t pvs=(" <<  pvsl << "," 
+				 << pvsr << ")" << "\t cost= " << sum << endl;
 
 			if (sum < minSum)
@@ -3012,6 +3051,5 @@
 	}
 	
-	
-	// -- compute cost
+	//-- compute cost
 
 	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
@@ -3035,15 +3073,17 @@
 	
 	//if (axis != 1)
-	Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox)
-	      <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl;
+	Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" 
+		  << position << " t=" << (position - minBox) / (maxBox - minBox)
+	      << "\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl;
 
 	return ratio;
 }
 
+
 void OspTree::SortSplitCandidates(KdLeaf *node, const int axis)
 {
 	mSplitCandidates->clear();
 
-	int requestedSize = 2*(int)node->mObjects.size();
+	int requestedSize = 2 * (int)node->mObjects.size();
 	
 	// creates a sorted split candidates array
@@ -3074,5 +3114,4 @@
 	stable_sort(mSplitCandidates->begin(), mSplitCandidates->end());
 }
-
 
 
@@ -3085,4 +3124,10 @@
 	return object->mViewCellPvs.GetSize();
 #endif
+}
+
+
+const OspTreeStatistics &OspTree::GetStatistics() const
+{
+	return mOspStats;
 }
 
@@ -3124,4 +3169,6 @@
 			break;
 	}
+
+	cout << "pvs left: " << pvsLeft << " pvs right " << pvsRight << endl;
 }
 
@@ -3241,6 +3288,9 @@
 float OspTree::EvalViewCellPvsIncr(Intersectable *object) const
 {
-	// TODO		
+#if COUNT_OBJECTS	
 	return 1;
+#else
+	return (float)object->mViewCellPvs.GetSize();
+#endif
 }
 
@@ -3276,4 +3326,5 @@
 		const float pvsIncr = EvalViewCellPvsIncr(obj);
 		totalPvs += pvsIncr;
+		cout << "totalpvs " << totalPvs << " incr " << pvsIncr << endl;
 
 		if (box.Max(candidatePlane.mAxis) > candidatePlane.mPosition)
@@ -3310,13 +3361,13 @@
 	const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack;
 
-	Debug << "old: " << oldRenderCost << " new: " << newRenderCost << " decrease: " << oldRenderCost - newRenderCost << endl;
+	Debug << "old: " << oldRenderCost << " new: " << newRenderCost << " decrease: " 
+		<< oldRenderCost - newRenderCost << endl;
 	const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume();
 	
 	// take render cost of node into account 
 	// otherwise danger of being stuck in a local minimum!!
-	const float factor = 0.99f;
+	const float factor = mRenderCostDecreaseWeight;
 
 	const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume();
-
 	return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost;
 }
@@ -3429,4 +3480,72 @@
 
 
+void OspTree::CollectViewCells(KdLeaf *leaf, ViewCellContainer &viewCells)
+{
+	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
+
+	ViewCell::NewMail();
+
+	// loop through all object and collect view cell pvs of this node
+	for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = *oit;
+
+		ViewCellPvsMap::const_iterator vit, vit_end = obj->mViewCellPvs.mEntries.end();
+
+		for (vit = obj->mViewCellPvs.mEntries.begin(); vit != vit_end; ++ vit)
+		{
+            ViewCell *vc = (*vit).first;
+
+			if (!vc->Mailed())
+			{
+				vc->Mail();
+				viewCells.push_back(vc);
+			}
+		}
+	}
+
+}
+
+
+void OspTree::CollectDirtyCandidates(OspSplitCandidate *sc, 
+									 vector<SplitCandidate *> &dirtyList)
+{
+	KdLeaf *node = sc->mParentData.mNode;
+
+	ObjectContainer::const_iterator oit, oit_end = node->mObjects.end();
+
+	ViewCellContainer viewCells;
+
+	CollectViewCells(node, viewCells);
+
+	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+
+	// through split candidates corresponding to view cell pvs of this
+	// node into dirty list
+	for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+	{
+		VspViewCell *vc = dynamic_cast<VspViewCell *>(*vit);
+
+		VspLeaf *leaf = vc->mLeaf;
+		dirtyList.push_back(leaf->GetSplitCandidate());
+	}
+}
+
+
+int OspTree::ComputePvsSize(const ObjectContainer &objects) const
+{
+	int pvsSize = 0;
+
+	ObjectContainer::const_iterator oit, oit_end = objects.end();
+
+	for (oit = objects.begin(); oit != oit_end; ++ oit)
+	{
+		pvsSize += (*oit)->mViewCellPvs.GetSize();
+	}
+
+	return pvsSize;
+}
+
+
 /********************************************************************/
 /*               class HierarchyManager implementation              */
@@ -3445,5 +3564,5 @@
 	SplitCandidate *splitCandidate = mTQueue.Top();
 
-	Debug << "next candidate: " << splitCandidate->Type()
+	cout << "next candidate: " << splitCandidate->Type()
 		<< ", priority: " << splitCandidate->GetPriority() << endl;
 
@@ -3454,10 +3573,9 @@
 
 
-void HierarchyManager::PrepareConstruction(const VssRayContainer &sampleRays,
-										   const ObjectContainer &objects,
-										   AxisAlignedBox3 *forcedViewSpace,
-										   RayInfoContainer &rays)
-{
-	mVspTree.PrepareConstruction(sampleRays, forcedViewSpace);
+void HierarchyManager::ProcessRays(const VssRayContainer &sampleRays,
+								   RayInfoContainer &rays,
+								   ObjectContainer &sampledObjects)
+{
+	VssRayContainer::const_iterator rit, rit_end = sampleRays.end();
 
 	long startTime = GetTime();
@@ -3467,14 +3585,11 @@
 	Intersectable::NewMail();
 
-	VssRayContainer::const_iterator rit, rit_end = sampleRays.end();
-
-	//-- store rays
+	//-- store rays and objects
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
 	{
 		VssRay *ray = *rit;
-
 		float minT, maxT;
-
 		static Ray hray;
+
 		hray.Init(*ray);
 		
@@ -3489,11 +3604,38 @@
 			rays.push_back(RayInfo(ray, minT / len, maxT / len));
 		}
+
+		// store objects
+		if (ray->mTerminationObject && !ray->mTerminationObject->Mailed())
+		{
+			ray->mTerminationObject->Mail();
+			sampledObjects.push_back(ray->mTerminationObject);
+		}
+
+		if (ray->mOriginObject && !ray->mOriginObject->Mailed())
+		{
+			ray->mOriginObject->Mail();
+			sampledObjects.push_back(ray->mOriginObject);
+		}
 	}
 
 	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-
-
-	int pvsSize = mVspTree.ComputePvsSize(rays);
-
+}
+
+
+void HierarchyManager::PrepareVsp(const VssRayContainer &sampleRays,
+								  AxisAlignedBox3 *forcedViewSpace,
+								  RayInfoContainer &rays)
+{
+	// prepare bounding box
+	mVspTree.PrepareConstruction(sampleRays, forcedViewSpace);
+
+	// get clipped rays
+	ObjectContainer sampledObjects;
+	ProcessRays(sampleRays, rays, sampledObjects);
+
+	//const int pvsSize = mVspTree.ComputePvsSize(rays);
+	const int pvsSize = (int)sampledObjects.size();
+
+	cout <<  "here450 pvs size: " << pvsSize << endl;
 	// -- prepare view space partition
 
@@ -3507,5 +3649,4 @@
 									0,
 									&rays,
-									//(int)objects.size(),
 									pvsSize,	
 									prop,
@@ -3513,4 +3654,20 @@
 
 
+	// create first view cell
+	mVspTree.CreateViewCell(vData);
+		
+	// add first view cell to all the objects view cell pvs
+	ObjectPvsMap::const_iterator oit, 
+		oit_end = leaf->GetViewCell()->GetPvs().mEntries.end();
+
+	cout << "here23 " << leaf->GetViewCell()->GetPvs().mEntries.size();
+
+	for (oit = leaf->GetViewCell()->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = (*oit).first;
+		cout << "obj: " << obj->GetId() << endl;
+		obj->mViewCellPvs.AddSample(leaf->GetViewCell(), 1);
+	}
+
 	// compute first split candidate
 	VspTree::VspSplitCandidate *splitCandidate = new VspTree::VspSplitCandidate(vData);
@@ -3518,8 +3675,10 @@
 
 	mTQueue.Push(splitCandidate);
-
-
-	//-- object space partition
-
+}
+
+
+void HierarchyManager::PrepareOsp(const ObjectContainer &objects,										  
+								  AxisAlignedBox3 *forcedViewSpace)
+{
 	mOspTree.PrepareConstruction(objects, forcedViewSpace);
 
@@ -3530,5 +3689,9 @@
 	mOspTree.mRoot = kdleaf;
 	
-
+	// TODO matt: this is something different than pvs size.
+	const int pvsSize = mOspTree.ComputePvsSize(objects);
+	const float prop = mOspTree.mBoundingBox.GetVolume();
+
+	cout <<  "here40 pvs size: " << pvsSize << endl;
 	// first osp traversal data
 	OspTree::OspTraversalData oData(kdleaf,
@@ -3542,8 +3705,19 @@
 
 	// compute first split candidate
-	OspTree::OspSplitCandidate *oSplitCandidate = new OspTree::OspSplitCandidate(oData);
+	OspTree::OspSplitCandidate *oSplitCandidate = 
+		new OspTree::OspSplitCandidate(oData);
     mOspTree.EvalSplitCandidate(*oSplitCandidate);
 
-	mTQueue.Push(splitCandidate);
+	mTQueue.Push(oSplitCandidate);
+}
+
+
+void HierarchyManager::PrepareConstruction(const VssRayContainer &sampleRays,
+										   const ObjectContainer &objects,
+										   AxisAlignedBox3 *forcedViewSpace,
+										   RayInfoContainer &rays)
+{
+	PrepareVsp(sampleRays, forcedViewSpace, rays);
+	PrepareOsp(objects, forcedViewSpace);
 }
 
@@ -3561,65 +3735,8 @@
 {
 	RayInfoContainer *rays = new RayInfoContainer();
-
-	mVspTree.PrepareConstruction(sampleRays, forcedViewSpace);
+	PrepareVsp(sampleRays, forcedViewSpace, *rays);
 
 	long startTime = GetTime();
-
-	cout << "storing rays ... ";
-
-	Intersectable::NewMail();
-
-	VssRayContainer::const_iterator rit, rit_end = sampleRays.end();
-
-	//-- store rays
-	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
-	{
-		VssRay *ray = *rit;
-
-		float minT, maxT;
-
-		static Ray hray;
-		hray.Init(*ray);
-		
-		// TODO: not very efficient to implictly cast between rays types
-		if (mVspTree.GetBoundingBox().GetRaySegment(hray, minT, maxT))
-		{
-			float len = ray->Length();
-
-			if (!len)
-				len = Limits::Small;
-
-			rays->push_back(RayInfo(ray, minT / len, maxT / len));
-		}
-	}
-
-	cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
-
-	const int pvsSize = mVspTree.ComputePvsSize(*rays);
-
-
-	// -- prepare view space partition
-
-	// add first candidate for view space partition
-	VspLeaf *vspleaf = new VspLeaf();
-
-	mVspTree.mRoot = vspleaf;
-	const float prop = mVspTree.mBoundingBox.GetVolume();
-
-	// first vsp traversal data
-	VspTree::VspTraversalData vData(vspleaf,
-									0,
-									rays,
-									pvsSize,	
-									prop,
-									mVspTree.mBoundingBox);
-
-
-	//-- compute first split candidate
-	VspTree::VspSplitCandidate *splitCandidate = new VspTree::VspSplitCandidate(vData);
-    mVspTree.EvalSplitCandidate(*splitCandidate);
-
-	mTQueue.Push(splitCandidate);
-
+	cout << "starting vsp contruction ... " << endl;
 	int i = 0;
 
@@ -3631,9 +3748,9 @@
 			GlobalTerminationCriteriaMet(splitCandidate);
 
-		//cout << "vsp nodes: " << i ++ << endl;
+		cout << "vsp nodes: " << i ++ << endl;
 
 		// cost ratio of cost decrease / totalCost
 		const float costRatio = splitCandidate->GetPriority() / mTotalCost;
-		//Debug << "cost ratio: " << costRatio << endl;
+		//cout << "cost ratio: " << costRatio << endl;
 
 		if (costRatio < mTermMinGlobalCostRatio)
@@ -3646,6 +3763,7 @@
 			dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate);
 
+	
 		VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet);
-	
+
 		DEL_PTR(splitCandidate);
 	}
@@ -3654,32 +3772,9 @@
 	mVspTree.mVspStats.Stop();
 	
-	Debug << "object space" << endl;
+	startTime = GetTime();
+	cout << "starting osp contruction ... " << endl;
 
 	//-- object space partition
-
-	mOspTree.PrepareConstruction(objects, forcedViewSpace);
-
-	// add first candidate for view space partition
-	KdLeaf *leaf = new KdLeaf(NULL, 0);
-	leaf->mObjects = objects;
-
-	mOspTree.mRoot = leaf;
-	
-
-	//-- first osp traversal data
-	OspTree::OspTraversalData oData(leaf,
-									0,
-									pvsSize,
-									prop,
-									mOspTree.mBoundingBox);
-
-		
-	mOspTree.ProcessLeafObjects(leaf, NULL);
-
-	// compute first split candidate
-	OspTree::OspSplitCandidate *oSplitCandidate = new OspTree::OspSplitCandidate(oData);
-    mOspTree.EvalSplitCandidate(*oSplitCandidate);
-
-	mTQueue.Push(oSplitCandidate);
+    PrepareOsp(objects, forcedViewSpace);
 
 	i = 0;
@@ -3733,13 +3828,13 @@
 	while (!FinishedConstruction())
 	{
-		SplitCandidate *splitCandidate = NextSplitCandidate();
-	    
+		mCurrentCandidate = NextSplitCandidate();
+	   
 		const bool globalTerminationCriteriaMet = 
-			GlobalTerminationCriteriaMet(splitCandidate);
+			GlobalTerminationCriteriaMet(mCurrentCandidate);
 
 		cout << "view cells: " << i ++ << endl;
 
 		// cost ratio of cost decrease / totalCost
-		const float costRatio = splitCandidate->GetPriority() / mTotalCost;
+		const float costRatio = mCurrentCandidate->GetPriority() / mTotalCost;
 		//Debug << "cost ratio: " << costRatio << endl;
 
@@ -3750,8 +3845,8 @@
 
 		// we have either a object space or view space split
-		if (splitCandidate->Type() == SplitCandidate::VIEW_SPACE)
+		if (mCurrentCandidate->Type() == SplitCandidate::VIEW_SPACE)
 		{
 			VspTree::VspSplitCandidate *sc = 
-				dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate);
+				dynamic_cast<VspTree::VspSplitCandidate *>(mCurrentCandidate);
 
 			VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet);
@@ -3760,10 +3855,13 @@
 		{			
 			OspTree::OspSplitCandidate *sc = 
-				dynamic_cast<OspTree::OspSplitCandidate *>(splitCandidate);
+				dynamic_cast<OspTree::OspSplitCandidate *>(mCurrentCandidate);
 
 			KdNode *r = mOspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet);
 		}
 
-		DEL_PTR(splitCandidate);
+		// reevaluate affected candidates
+		RepairQueue();
+
+		DEL_PTR(mCurrentCandidate);
 	}
 
@@ -3780,5 +3878,25 @@
 
 
-void HierarchyManager::RepairQueue(const vector<SplitCandidate *> &dirtyList)
+void HierarchyManager::CollectDirtyCandidates(vector<SplitCandidate *> &dirtyList)
+{	
+	// we have either a object space or view space split
+	if (mCurrentCandidate->Type() == SplitCandidate::VIEW_SPACE)
+	{
+		VspTree::VspSplitCandidate *sc = 
+			dynamic_cast<VspTree::VspSplitCandidate *>(mCurrentCandidate);
+
+		mVspTree.CollectDirtyCandidates(sc, dirtyList);
+	}
+	else // object space split
+	{			
+		OspTree::OspSplitCandidate *sc = 
+			dynamic_cast<OspTree::OspSplitCandidate *>(mCurrentCandidate);
+
+		mOspTree.CollectDirtyCandidates(sc, dirtyList);
+	}
+}
+
+
+void HierarchyManager::RepairQueue()
 {
 	// TODO
@@ -3799,4 +3917,9 @@
 	// split candidate
 
+	// collect list of "dirty" candidates
+	vector<SplitCandidate *> dirtyList;
+	CollectDirtyCandidates(dirtyList);
+	
+	//-- reevaluate the dirty list
 	vector<SplitCandidate *>::const_iterator sit, sit_end = dirtyList.end();
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h	(revision 1121)
@@ -47,6 +47,5 @@
   ExportKdTree(const KdTree &tree);
 
-  bool
-  ExportOspTree(const OspTree &tree);
+  //bool ExportOspTree(const OspTree &tree);
 
   bool
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1121)
@@ -99,4 +99,5 @@
 	Environment::GetSingleton()->GetBoolValue("ViewCells.exportBboxesForPvs", mExportBboxesForPvs);
 	Environment::GetSingleton()->GetBoolValue("ViewCells.exportPvs", mExportPvs);
+	Environment::GetSingleton()->GetBoolValue("ViewCells.Evaluation.countKdPvs", mCountKdPvs);
 
 	char buf[100];
@@ -212,5 +213,6 @@
 	Debug << "export bounding boxes: " << mExportBboxesForPvs << endl;
 	Debug << "export pvs for view cells: " << mExportPvs << endl;
-
+	Debug << "count kd pvs: " << mCountKdPvs << endl;
+	
 	Debug << endl;
 }
@@ -783,5 +785,5 @@
 	sort(viewCells.begin(), viewCells.end(), ViewCell::SmallerPvs);
 
-	maxPvs = mViewCellsTree->GetPvsSize(viewCells.back());
+	maxPvs = mViewCellsTree->GetPvsSize(viewCells.back(), mCountKdPvs);
 	minVal = 0;
 
@@ -791,5 +793,6 @@
 	maxVal = max(histoMaxVal, maxPvs);
 		
-	Debug << "histogram minpvssize: " << minVal << " maxpvssize: " << maxVal << " real maxpvs " << maxPvs << endl;
+	Debug << "histogram minpvssize: " << minVal << " maxpvssize: " << maxVal 
+		<< " real maxpvs " << maxPvs << endl;
 
 	int histoIntervals;
@@ -826,5 +829,5 @@
 
 		while ((i < (int)viewCells.size()) && 
-			   (mViewCellsTree->GetPvsSize(viewCells[i]) < currentPvs))
+			   (mViewCellsTree->GetPvsSize(viewCells[i], mCountKdPvs) < currentPvs))
 		{
 			volDif += viewCells[i]->GetVolume();
@@ -837,5 +840,6 @@
 		
 		if (0 && (i < (int)viewCells.size()))
-			Debug << "new pvs size increase: " << mViewCellsTree->GetPvsSize(viewCells[i]) << " " << currentPvs << endl;
+			Debug << "new pvs size increase: " << mViewCellsTree->GetPvsSize(viewCells[i], mCountKdPvs) 
+			<< " " << currentPvs << endl;
 	
 		const float volRatioDif = volDif / totalVol;
@@ -1685,31 +1689,32 @@
 void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
 {
-  // update pvs of view cells tree if necessary
-  UpdatePvs();
-  
-  ViewCellContainer::const_iterator it = mViewCells.begin();
-  
-  stat.viewcells = 0;
-  stat.minPvs = 100000000;
-  stat.maxPvs = 0;
-  stat.avgPvs = 0.0f;
-  
-  for (; it != mViewCells.end(); ++ it) 
-	{
-	  ViewCell *viewcell = *it;
-	  
-	  const int pvsSize = mViewCellsTree->GetPvsSize(viewcell);
-	  
-	  if (pvsSize < stat.minPvs)
-		stat.minPvs = pvsSize;
-	  if (pvsSize > stat.maxPvs)
-		stat.maxPvs = pvsSize;
-	  stat.avgPvs += pvsSize;
-	  
-	  ++ stat.viewcells;
-	}
-  
-  if (stat.viewcells)
-	stat.avgPvs/=stat.viewcells;
+	// update pvs of view cells tree if necessary
+	UpdatePvs();
+
+	ViewCellContainer::const_iterator it = mViewCells.begin();
+
+	stat.viewcells = 0;
+	stat.minPvs = 100000000;
+	stat.maxPvs = 0;
+	stat.avgPvs = 0.0f;
+
+	for (; it != mViewCells.end(); ++ it) 
+	{
+		ViewCell *viewcell = *it;
+
+		const int pvsSize = mViewCellsTree->GetPvsSize(viewcell, mCountKdPvs);
+
+		if (pvsSize < stat.minPvs)
+			stat.minPvs = pvsSize;
+		if (pvsSize > stat.maxPvs)
+			stat.maxPvs = pvsSize;
+
+		stat.avgPvs += pvsSize;
+
+		++ stat.viewcells;
+	}
+
+	if (stat.viewcells)
+		stat.avgPvs/=stat.viewcells;
 }
 
@@ -1949,5 +1954,5 @@
 float ViewCellsManager::GetRendercost(ViewCell *viewCell) const
 {
-	return mViewCellsTree->GetPvsSize(viewCell);
+	return mViewCellsTree->GetPvsSize(viewCell, mCountKdPvs);
 }
 
@@ -2399,5 +2404,9 @@
 		{
 			if (mCurrentViewCellsStats.maxPvs)
-				importance = (float)mViewCellsTree->GetPvsSize(vc) / (float)mCurrentViewCellsStats.maxPvs;
+			{
+				importance = 
+					(float)mViewCellsTree->GetPvsSize(vc, mCountKdPvs) / 
+					(float)mCurrentViewCellsStats.maxPvs;
+			}
 		}
 		break;
@@ -2633,6 +2642,6 @@
 	Debug << "\nView cells after merge:\n" << mCurrentViewCellsStats << endl;
 
-
-	int savedColorCode  = mColorCode;
+	// save color code
+	const int savedColorCode = mColorCode;
 	
 	//BspLeaf::NewMail();
@@ -2685,7 +2694,6 @@
 		cout << "finished" << endl;
 	}
-
-	
-	// only for testing
+	
+	// only for debugging: test valitidy
 	TestSubdivision();
 
@@ -4379,5 +4387,5 @@
 		Exporter *exporter = Exporter::GetExporter(s);
 		
-		Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl;
+		Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc, mCountKdPvs) << endl;
 
 		//-- export the sample rays
@@ -5311,5 +5319,9 @@
 
 			exporter->SetWireframe();
-			exporter->ExportOspTree(*mOspTree);
+	
+			const int savedColorCode = mColorCode;
+			const int maxPvs = 200;//mOspTree.GetStatistics().maxPvs;
+
+			exporter->ExportOspTree(*mOspTree, mColorCode == 0 ? 0 : maxPvs);
 
 			delete exporter;
@@ -5368,5 +5380,5 @@
 		Exporter *exporter = Exporter::GetExporter(s);
 		
-		Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl;
+		Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc, mCountKdPvs) << endl;
 
 		//-- export the sample rays
@@ -5440,4 +5452,5 @@
 
 		//-- export view cell geometry
+
 		exporter->SetWireframe();
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.cpp	(revision 863)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.cpp	(revision 1121)
@@ -1,5 +1,7 @@
-
 #include "X3dExporter.h"
 #include "VrmlExporter.h"
+#include "VspOspTree.h"
+#include "KdTree.h"
+
 
 namespace GtpVisibilityPreprocessor {
@@ -26,3 +28,47 @@
 }
 
+
+bool Exporter::ExportOspTree(const OspTree &ospTree, const int maxPvs)
+{
+	vector<KdLeaf *> leaves;
+	ospTree.CollectLeaves(leaves);
+
+	mUseForcedMaterial = true;
+
+	vector<KdLeaf *>::const_iterator it, it_end = leaves.end();
+
+	Material white; 
+	white.mDiffuseColor.r = 1;
+	white.mDiffuseColor.g = 1;
+	white.mDiffuseColor.b = 1;
+	
+	for (it = leaves.begin(); it != it_end; ++ it)
+	{
+		KdLeaf *leaf = *it;
+
+		SetWireframe();
+		SetForcedMaterial(white);
+		ExportBox(ospTree.GetBBox(leaf));
+
+		SetFilled();
+
+		if (maxPvs) // color code pvs
+		{
+			mForcedMaterial.mDiffuseColor.b = 1.0f;
+  			const float importance = (float)ospTree.ComputePvsSize(leaf->mObjects) / (float)maxPvs;
+
+			mForcedMaterial.mDiffuseColor.r = importance;
+			mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
+		}
+		else
+		{
+			SetForcedMaterial(RandomMaterial());
+		}
+
+		ExportGeometry(leaf->mObjects);	
+	}
+
+	return true;
 }
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1027)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1121)
@@ -7,5 +7,5 @@
 #include "Mesh.h"
 #include "Intersectable.h"
-#include "MeshKdTree.h"
+#include "KdTree.h"
 #include "Triangle3.h"
 #include "common.h"
@@ -29,5 +29,6 @@
 
 
-typedef priority_queue<ViewCell *, vector<ViewCell *>, myless<vector<ViewCell *>::value_type> > TraversalQueue;
+typedef priority_queue<ViewCell *, vector<ViewCell *>, 
+					   myless<vector<ViewCell *>::value_type> > TraversalQueue;
 
 int ViewCell::sMailId = 21843194198;
@@ -257,5 +258,4 @@
 	return result;
 }
-
 
 
@@ -1675,5 +1675,46 @@
 
 
-int ViewCellsTree::GetPvsSize(ViewCell *vc) const
+int ViewCellsTree::CountKdPvs(const ViewCellLeaf *vc) const
+{
+	ObjectPvsMap::const_iterator oit, oit_end = vc->GetPvs().mEntries.end();
+
+	int pvsSize = 0;
+
+	Intersectable::NewMail();
+
+	for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *obj = (*oit).first;
+
+		set<KdLeaf *>::const_iterator kit, kit_end = obj->mKdLeaves.end();
+
+		for (kit = obj->mKdLeaves.begin(); kit != kit_end; ++ kit)
+		{
+			KdLeaf *leaf = *kit;
+
+			pvsSize += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
+
+			//-- handle objects of several kd leaves separately
+			ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
+
+			for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
+			{
+				Intersectable *object = *oit;
+
+				// object not previously in left pvs
+				if (!object->Mailed())
+				{
+					object->Mail();
+					++ pvsSize;
+				}
+			}		
+		}
+	}
+
+	return pvsSize;
+}
+
+
+int ViewCellsTree::GetPvsSize(ViewCell *vc, const bool countKdPvs) const
 {
 	int pvsSize = 0;
@@ -1691,5 +1732,8 @@
 			if (vc->IsLeaf())
 			{
-				pvsSize = vc->GetPvs().GetSize();
+				if (countKdPvs)
+					pvsSize = vc->GetPvs().GetSize();
+				else
+					pvsSize = CountKdPvs(dynamic_cast<ViewCellLeaf *>(vc));
 				break;
 			}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1110)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1121)
@@ -429,4 +429,9 @@
 	void SetViewCell(ViewCellLeaf *viewCell);
 
+	SplitCandidate *GetSplitCandidate() const 
+	{ return mSplitCandidate; }
+
+public:
+
 	/// Rays piercing this leaf.
 	VssRayContainer mVssRays;
@@ -439,5 +444,8 @@
 
 protected:
-	
+
+	/// pointer to a split plane candidate splitting this leaf
+	SplitCandidate *mSplitCandidate;
+
 	/// if NULL this does not correspond to feasible viewcell
 	ViewCellLeaf *mViewCell;
@@ -986,7 +994,12 @@
 	float GetMemUsage() const;
 
-	void ProcessViewCellObjects(ViewCell *parent, ViewCell *front, ViewCell *back) const;
+	void ProcessViewCellObjects(ViewCell *parent, 
+		ViewCell *front, 
+		ViewCell *back) const;
 
 	void CreateViewCell(VspTraversalData &tData);
+
+	void CollectDirtyCandidates(VspSplitCandidate *sc, 
+		vector<SplitCandidate *> &dirtyList);
 
 protected:
@@ -1077,4 +1090,7 @@
 	/// number of currenly generated view cells
 	int mCreatedViewCells;
+
+	/// weight between  render cost decrease and node render cost
+	float mRenderCostDecreaseWeight;
 };
 
@@ -1224,7 +1240,7 @@
 	~OspTree();
 
-	/** Returns BSP Tree statistics.
-	*/
-	const KdTreeStatistics &GetStatistics() const; 
+	/** Returns tree statistics.
+	*/
+	const OspTreeStatistics &GetStatistics() const; 
   
 	/** Returns bounding box of the specified node.
@@ -1310,4 +1326,11 @@
 	int ComputeBoxIntersections(const AxisAlignedBox3 &box, 
 								ViewCellContainer &viewCells) const;
+
+
+	/** Compute "pvs size of this object container
+		@ note bot relly pvs size just weighted sum of object taking their
+		appearances in pvss into account
+	*/
+	int ComputePvsSize(const ObjectContainer &objects) const;
 
 
@@ -1470,8 +1493,4 @@
 					 float &totalPvs) const;
 	
-	/** Computes PVS size induced by the rays.
-	*/
-	int ComputePvsSize(const RayInfoContainer &rays) const;
-
 	/** Returns true if tree can be terminated.
 	*/
@@ -1535,8 +1554,16 @@
 		AxisAlignedBox3 *forcedBoundingBox);
 
+	void CollectDirtyCandidates(OspSplitCandidate *sc,
+		vector<SplitCandidate *> &dirtyList);
+
+	void CollectViewCells(KdLeaf *leaf, 
+		ViewCellContainer &viewCells);
 
 protected:
 
+	/// The view cells manager
 	ViewCellsManager *mViewCellsManager;
+
+	/// candidates for placing split planes during cost heuristics
 	vector<SortableEntry> *mSplitCandidates;
 
@@ -1544,4 +1571,5 @@
 	KdNode *mRoot;
 		
+	/// Statistics for the object space partition
 	OspTreeStatistics mOspStats;
 	
@@ -1568,4 +1596,5 @@
 
 	//-- global criteria
+
 	float mTermMinGlobalCostRatio;
 	int mTermGlobalCostMissTolerance;
@@ -1609,4 +1638,7 @@
 	/// represents min and max band for sweep
 	float mSplitBorder;
+
+	/// weight between  render cost decrease and node render cost
+	float mRenderCostDecreaseWeight;
 };
 
@@ -1656,4 +1688,5 @@
 					const ObjectContainer &objects,
 					AxisAlignedBox3 *forcedViewSpace);
+
 public:
 	VspTree &mVspTree;
@@ -1670,11 +1703,29 @@
 
 	bool FinishedConstruction();
+
 	SplitCandidate *NextSplitCandidate();
 
-	void RepairQueue(const vector<SplitCandidate *> &dirtyList);
+	void RepairQueue();
+
+	void CollectDirtyCandidates(vector<SplitCandidate *> &dirtyList);
+
+	void PrepareVsp(const VssRayContainer &sampleRays,
+		AxisAlignedBox3 *forcedViewSpace,
+		RayInfoContainer &rays);
+
+	void PrepareOsp(const ObjectContainer &objects, AxisAlignedBox3 *forcedViewSpace);
+
+	void ProcessRays(const VssRayContainer &sampleRays,
+		RayInfoContainer &rays,
+		ObjectContainer &sampledObjects);
+
+
+protected:
 
 	AxisAlignedBox3 mBoundingBox;
 
 	SplitQueue mTQueue;
+
+	SplitCandidate *mCurrentCandidate;
 
 	//-- global criteria
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1010)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1121)
@@ -350,6 +350,6 @@
 };
 
-/**
-	Leaf of the view cell hierarchy corresponding to a leaf in a spatial hierarchy.
+/** Leaf of the view cell hierarchy corresponding 
+	to a leaf in a spatial hierarchy.
 */
 template<typename T>
@@ -420,9 +420,7 @@
 	void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
 
-
 	/** Get costs resulting from each merge step. 
 	*/
 	void GetCostFunction(vector<float> &costFunction);
-
   
 	/** Returns optimal set of view cells for a given number of view cells.
@@ -442,5 +440,6 @@
 	/** Returns pvs size of view cell.
 	*/
-	int GetPvsSize(ViewCell *vc) const;
+	//int GetPvsSize(ViewCell *vc) const;
+	int GetPvsSize(ViewCell *vc, const bool countKdPvs = false) const;
 
 	/** Returns actual number of object in this pvs and the children.
@@ -502,4 +501,8 @@
 	*/
 	void ResetPvs();
+
+	/** Counts pvs of the view cell taking the kd cells into account.
+	*/
+	int CountKdPvs(const ViewCellLeaf *vc) const;
 
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1112)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 1121)
@@ -163,4 +163,5 @@
 };
   
+class SplitCandidate;
   
 /** Implementation of the kd-tree leaf node */
@@ -209,4 +210,5 @@
   /// pvs of view cells seeing this node.
   // ViewCellPvs mViewCellPvs;
+  SplitCandidate *mSplitCandidate;
 
   /** pointer to view cell.
