Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.h	(revision 1138)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.h	(revision 1138)
@@ -0,0 +1,62 @@
+#ifndef __KDINTERSECTABLE_H
+#define __KDINTERSECTABLE_H
+
+#include "AxisAlignedBox3.h"
+#include "Intersectable.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+struct VssRayContainer;
+class KdNode;
+
+/**
+	Wrapper for Kd nodes for use in a PVS.
+*/
+class KdIntersectable: public Intersectable
+{
+public:
+	KdIntersectable(KdNode *node);
+
+	/** Returns 'mesh' associated with this instance. 
+	*/
+	KdNode *GetNode() const;
+
+	/** See get.
+	*/
+	void SetNode(KdNode *node);
+
+
+	//-- inherited functions from Intersectable
+
+	AxisAlignedBox3 GetBox() const;
+	
+	int CastRay(Ray &ray);
+	
+	bool IsConvex() const;
+	bool IsWatertight() const;
+	float IntersectionComplexity();
+  
+	int NumberOfFaces() const;
+	int Type() const;
+
+	int GetRandomSurfacePoint(GtpVisibilityPreprocessor::Vector3 &point, 
+							  GtpVisibilityPreprocessor::Vector3 &normal);
+
+	int GetRandomVisibleSurfacePoint(GtpVisibilityPreprocessor::Vector3 &point,
+									 GtpVisibilityPreprocessor::Vector3 &normal,
+									 const GtpVisibilityPreprocessor::Vector3 &viewpoint,
+									 const int maxTries);
+  
+	ostream &Describe(ostream &s);
+	
+
+protected:
+	
+	KdNode *mNode;
+};
+
+
+}
+
+#endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.cpp	(revision 1138)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdIntersectable.cpp	(revision 1138)
@@ -0,0 +1,89 @@
+#include "KdIntersectable.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+
+KdIntersectable::KdIntersectable(KdNode *node):
+Intersectable(), mNode(node)
+{
+}
+
+
+void KdIntersectable::SetNode(KdNode *node)
+{
+	mNode = node;
+}
+
+
+KdNode *KdIntersectable::GetNode() const
+{ 
+	return mNode; 
+}
+	
+
+AxisAlignedBox3 KdIntersectable::GetBox() const
+{	// TODO matt
+	return AxisAlignedBox3();
+}
+
+
+int KdIntersectable::CastRay(Ray &ray)
+{	// TODO matt
+	return 0;
+}
+	
+
+bool KdIntersectable::IsConvex() const
+{
+	return true;
+}
+
+
+bool KdIntersectable::IsWatertight() const
+{
+	return true;
+}
+
+
+float KdIntersectable::IntersectionComplexity()
+{
+	return 1.0f;
+}
+
+
+int KdIntersectable::NumberOfFaces() const
+{
+	return 0;
+}
+
+
+int KdIntersectable::Type() const
+{
+	return Intersectable::KD_INTERSECTABLE;
+}
+
+
+int KdIntersectable::GetRandomSurfacePoint(Vector3 &point,
+										   Vector3 &normal)
+{
+	return 0;
+}
+
+
+int KdIntersectable::GetRandomVisibleSurfacePoint(Vector3 &point,
+												  Vector3 &normal,
+												  const Vector3 &viewpoint,
+												  const int maxTries)
+{
+	return 0;
+}
+  
+
+ostream &KdIntersectable::Describe(ostream &s)
+{
+	s << mNode;
+	return s;
+}
+	
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1137)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1138)
@@ -982,50 +982,42 @@
 
 
-int VspTree::PrepareHeuristics(Intersectable *object)
+int VspTree::PrepareHeuristics(KdLeaf *leaf)
 {	
 	int pvsSize = 0;
-	// TODO matt§§
-#if TODO
-	set<KdLeaf *>::const_iterator kit, kit_end = object->mKdLeaves.end();
-
-	for (kit = object->mKdLeaves.begin(); kit != kit_end; ++ kit)
-	{
-		KdLeaf *node = dynamic_cast<KdLeaf *>(*kit);
-
-		if (!node->Mailed())
-		{
-			node->Mail();
-			node->mCounter = 1;
-
-			// add objects without the objects which are in several kd leaves
-			pvsSize += (int)(node->mObjects.size() - node->mMultipleObjects.size());
+	
+	if (!leaf->Mailed())
+	{
+		leaf->Mail();
+		leaf->mCounter = 1;
+
+		// add objects without the objects which are in several kd leaves
+		pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
+	}
+	else
+	{
+		++ leaf->mCounter;
+	}
+
+	//-- the objects belonging to several leaves must be handled seperately
+
+	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
+
+	for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
+	{
+		Intersectable *object = *oit;
+						
+		if (!object->Mailed())
+		{
+			object->Mail();
+			object->mCounter = 1;
+
+			++ pvsSize;
 		}
 		else
 		{
-			++ node->mCounter;
-		}
-
-		//-- the objects belonging to several leaves must be handled seperately
-
-		ObjectContainer::const_iterator oit, oit_end = node->mMultipleObjects.end();
-
-		for (oit = node->mMultipleObjects.begin(); oit != oit_end; ++ oit)
-		{
-			Intersectable *object = *oit;
-						
-			if (!object->Mailed())
-			{
-				object->Mail();
-				object->mCounter = 1;
-
-				++ pvsSize;
-			}
-			else
-			{
-				++ object->mCounter;
-			}
-		}
-	}
-#endif
+			++ object->mCounter;
+		}
+	}
+	
 	return pvsSize;
 }
@@ -1045,5 +1037,6 @@
 	for (ri = rays.begin(); ri != ri_end; ++ ri)
 	{
-		Intersectable *oObject = (*ri).mRay->mOriginObject;
+		VssRay *ray = (*ri).mRay;
+		Intersectable *oObject = ray->mOriginObject;
 
 		if (oObject)
@@ -1064,5 +1057,6 @@
 			else
 			{
-				pvsSize += PrepareHeuristics(oObject);	
+				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+				pvsSize += PrepareHeuristics(leaf);	
 			}	
 		}
@@ -1087,5 +1081,6 @@
 			else
 			{
-				pvsSize += PrepareHeuristics(tObject);	
+				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+				pvsSize += PrepareHeuristics(leaf);	
 			}	
 		}
@@ -1175,23 +1170,15 @@
 		else // per kd node
 		{
-	// TODO matt§§
-#if TODO
-			set<KdLeaf *>::const_iterator kit, kit_end = oObject->mKdLeaves.end();
-
-			for (kit = oObject->mKdLeaves.begin(); kit != kit_end; ++ kit)
-			{
-				KdLeaf *node = dynamic_cast<KdLeaf *>(*kit);
-
-				// add contributions of the kd nodes
-				if (ci.type == SortableEntry::ERayMin)
-				{
-					AddContriToPvs(node, pvsLeft);
-				}
-				else if (ci.type == SortableEntry::ERayMax)
-				{
-					RemoveContriFromPvs(node, pvsRight);
-				}
-			}
-#endif
+			KdLeaf *node = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+
+			// add contributions of the kd nodes
+			if (ci.type == SortableEntry::ERayMin)
+			{
+				AddContriToPvs(node, pvsLeft);
+			}
+			else if (ci.type == SortableEntry::ERayMax)
+			{
+				RemoveContriFromPvs(node, pvsRight);
+			}
 		}
 			
@@ -1219,22 +1206,14 @@
 		else // per kd node
 		{
-			// TODO matt§§
-#if TODO
-			set<KdLeaf *>::const_iterator kit, kit_end = tObject->mKdLeaves.end();
-			
-			for (kit = tObject->mKdLeaves.begin(); kit != kit_end; ++ kit)
-			{
-				KdLeaf *node = dynamic_cast<KdLeaf *>(*kit);
-
-				if (ci.type == SortableEntry::ERayMin)
-				{
-					AddContriToPvs(node, pvsLeft);
-				}
-				else if (ci.type == SortableEntry::ERayMax)
-				{
-					RemoveContriFromPvs(node, pvsRight);
-				}
-			}
-#endif
+			KdLeaf *node = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+
+			if (ci.type == SortableEntry::ERayMin)
+			{
+				AddContriToPvs(node, pvsLeft);
+			}
+			else if (ci.type == SortableEntry::ERayMax)
+			{
+				RemoveContriFromPvs(node, pvsRight);
+			}
 		}
 	}
@@ -2562,30 +2541,31 @@
 									 vector<SplitCandidate *> &dirtyList)
 {
-	VspLeaf *node = sc->mParentData.mNode;
-	
-    ViewCellLeaf *vc = node->GetViewCell();
+	VspTraversalData &tData = sc->mParentData;
+	VspLeaf *node = tData.mNode;
+	
+	KdLeaf::NewMail();
+
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+
+	// add all kd nodes seen by the rays
+	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+	
+		KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+	
+		if (!leaf->Mailed())
+		{
+			leaf->Mail();
+			dirtyList.push_back(leaf->mSplitCandidate);
+		}
 		
-	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;
-	// TODO matt§§
-#if TODO
-		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);
-			}
-		}
-#endif
+		leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+	
+		if (!leaf->Mailed())
+		{
+			leaf->Mail();
+			dirtyList.push_back(leaf->mSplitCandidate);
+		}
 	}
 }
@@ -3014,5 +2994,5 @@
 	SortSplitCandidates(tData, axis, minBand, maxBand);
 
-	float totalVol = PrepareHeuristics(tData.mNode->mObjects);
+	float totalVol = PrepareHeuristics(tData);
 	float voll = 0;
 	float volr = totalVol;
@@ -3227,5 +3207,5 @@
 	ViewCellContainer viewCells;
 
-	mVspTree->GetViewCells(ray);
+	mVspTree->GetViewCells(ray, viewCells);
     
 	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
@@ -3267,5 +3247,5 @@
 			(GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf))
 		{
-            vol += PrepareHeuristics(ray);
+            vol += PrepareHeuristics(tData);
 		}
 	}
@@ -3428,8 +3408,8 @@
 
 float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
-									  const OspTraversalData &data) const
+									  const OspTraversalData &tData) const
 {
 #if 0
-	return (float)-data.mDepth;
+	return (float)-tData.mDepth;
 #endif
 
@@ -3439,5 +3419,5 @@
 
 	// probability that view point lies in back / front node
-	float pOverall = data.mBoundingBox.GetVolume();//data.mProbability;
+	float pOverall = 0;//data.mProbability; // todo matt§: value ok?
 	float pFront = 0;
 	float pBack = 0;
@@ -3447,5 +3427,5 @@
 	ViewCell::NewMail();
 
-	KdLeaf *leaf = data.mNode;
+	KdLeaf *leaf = tData.mNode;
 	ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end();
 
@@ -3482,74 +3462,41 @@
 		if (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)
 		{
-			if (ray->mOrigin[candidatePlane.mAxis] > candidatePlane.mPosition)
-			{
-				// add view cells volume to front	
-				mVspTree->GetViewCells(ray, viewCells);
-
-				ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
-
-				for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+			ViewCellContainer viewCells;		
+			mVspTree->GetViewCells(*ray, viewCells);
+			
+			ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+
+			// add view cells volume to front	
+			for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+			{
+				ViewCell *vc = *vit;
+
+				if (!vc->Mailed())
 				{
-					ViewCell *vc = *vit;
-
-					if (!vit->Mailed())
-					{
-						vit->Mail();
-						volBack += vc->GetVolume();
-					}
+					vc->Mail();
+
+					const float vol = vc->GetVolume();
+					pOverall += vol;
+
+					if (ray->mOrigin[candidatePlane.mAxis] > candidatePlane.mPosition)
+						pFront += vol;
+					else
+						pBack += vol;
 				}
 			}
-			else
-			{// TODO matt§§
-				// add view cells volume to back
-				if (ray->mOrigin[candidatePlane.mAxis] < candidatePlane.mPosition)
-				{
-					// add view cells volume to front	
-					mVspTree->GetViewCells(ray, viewCells);
-
-					ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
-
-					for (vit = viewCells.begin(); vit != vit_end; ++ vit)
-					{
-						ViewCell *vc = *vit;
-	
-						if (!vit->Mailed())
-						{
-							vit->Mail();
-							volBack += vc->GetVolume();
-						}
-					}
-				}
-			}
-		}
-	}
-
-
-
-	AxisAlignedBox3 frontBox;
-	AxisAlignedBox3 backBox;
-
-	data.mBoundingBox.Split(candidatePlane.mAxis, candidatePlane.mPosition, frontBox, backBox);
-
-	pFront = frontBox.GetVolume();
-	pBack = pOverall - pFront;
-		
+		}
+	}
+
 
 	//-- pvs rendering heuristics
-	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
-	const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize();
-
-	//-- only render cost heuristics or combined with standard deviation
-	const float penaltyOld = totalPvs;//EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit);
-    const float penaltyFront = pvsFront;//EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit);
-	const float penaltyBack = pvsBack;//EvalPvsPenalty((int)pvsBack, lowerPvsLimit, upperPvsLimit);
-			
-	Debug << "total pvs: " << totalPvs << " p " << pOverall << endl;
-	const float oldRenderCost = pOverall * penaltyOld;
-	const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack;
-
-	Debug << "old: " << oldRenderCost << " new: " << newRenderCost << " decrease: " 
-		<< oldRenderCost - newRenderCost << endl;
-	const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume();
+	const float oldRenderCost = pOverall * totalPvs;
+	const float newRenderCost = pvsFront * pFront + pvsBack * pBack;
+
+	Debug << "total pvs: " << totalPvs << " p " << pOverall << endl
+		  << "old: " << oldRenderCost << " new: " << newRenderCost << " decrease: " 
+		  << oldRenderCost - newRenderCost << endl;
+
+	// todo matt§§: how to normalize volume??
+	const float renderCostDecrease = (oldRenderCost - newRenderCost);// / mBoundingBox.GetVolume();
 	
 	// take render cost of node into account 
@@ -3557,5 +3504,5 @@
 	const float factor = mRenderCostDecreaseWeight;
 
-	const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume();
+	const float normalizedOldRenderCost = oldRenderCost;// / mBoundingBox.GetVolume();
 	return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost;
 }
@@ -3745,16 +3692,38 @@
 									 vector<SplitCandidate *> &dirtyList)
 {
-	KdLeaf *node = sc->mParentData.mNode;
-
-	ObjectContainer::const_iterator oit, oit_end = node->mObjects.end();
-
+	OspTraversalData &tData = sc->mParentData;
+	KdLeaf *node = tData.mNode;
+	
+	ViewCell::NewMail();
 	ViewCellContainer viewCells;
-
-	CollectViewCells(node, viewCells);
-
+	ViewCellContainer tmpViewCells;
+
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+
+	// find all view cells associated with the rays, add them to view cells
+	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+		mVspTree->GetViewCells(*ray, tmpViewCells);
+
+		ViewCellContainer::const_iterator vit, vit_end = tmpViewCells.end();
+
+		for (vit = tmpViewCells.begin(); vit != vit_end; ++ vit)
+		{
+			VspViewCell *vc = dynamic_cast<VspViewCell *>(*vit);
+
+			if (!vc->Mailed())
+			{
+				vc->Mail();
+				viewCells.push_back(vc);
+			}
+		}
+	}
+
+
+	// split candidates holding this view cells 
+	// are thrown into dirty list
 	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)
 	{
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1135)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1138)
@@ -5465,6 +5465,6 @@
 
 		if (1)
-		{	//-- export pvs
-
+		{	
+			//-- export pvs
 			ObjectPvsMap::const_iterator oit,
 				oit_end = pvs.mEntries.end();
@@ -5482,5 +5482,5 @@
 			for (oit = pvs.mEntries.begin(); oit != oit_end; ++ oit)
 			{	
-				// exportŽ"original" pvs
+				// export "original" pvs
 				Intersectable *obj = (*oit).first;
 
@@ -5490,21 +5490,14 @@
 					obj->Mail();
 				}					
-	// TODO matt§§
-#if TODO
-				// collect kd leaves
-				//KdLeaf =
-				set<KdLeaf *>::const_iterator kdit, kdit_end = obj->mKdLeaves.end();
-
-				for (kdit = obj->mKdLeaves.begin(); kdit != kdit_end; ++ kdit)
+				
+				// TODO matt§§
+				// export kd pvs
+				KdLeaf *kdleaf = 0;
+
+				if (!kdleaf->Mailed())
 				{
-					KdLeaf *kdleaf = *kdit;
-
-					if (!kdleaf->Mailed())
-					{
-						kdleaf->Mail();
-						kdLeaves.push_back(kdleaf);
-					}
+					kdleaf->Mail();
+					kdLeaves.push_back(kdleaf);
 				}
-#endif
 			}
 
@@ -5522,8 +5515,5 @@
 
 				//-- export kd node
-				/*exporter->SetWireframe();
-				exporter->ExportBox(mKdTree->GetBox(kdleaf));
-				exporter->SetFilled();*/
-
+				
 				ObjectContainer::const_iterator oit, oit_end = kdleaf->mObjects.end();
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1137)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1138)
@@ -927,5 +927,5 @@
 	int PrepareHeuristics(const RayInfoContainer &rays);
 
-	int PrepareHeuristics(Intersectable *object);
+	int PrepareHeuristics(KdLeaf *leaf);
 
 	/** Subdivides the rays into front and back rays according to the split plane.
