Index: GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ObjectPvs.h	(revision 2117)
@@ -31,7 +31,5 @@
 		while (pit.HasMoreEntries())
 		{		
-			const ObjectPvsEntry &entry = pit.Next();
-			Intersectable *obj = entry.mObject;
-
+			Intersectable *obj = pit.Next();
 			cout << obj << " ";
 		}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 2117)
@@ -21,5 +21,5 @@
 				Optimization="0"
 				AdditionalIncludeDirectories="..\include;..\src;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\..\..\..\..\NonGTP\Boost"
-				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NO_QT;USE_HASH_PVS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;NO_QT;USE_BIT_PVS"
 				MinimalRebuild="TRUE"
 				BasicRuntimeChecks="3"
@@ -81,5 +81,5 @@
 				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="..\include;..\..\..\..\..\..\NonGTP\Boost;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\MultiLevelRayTracing;Timer"
-				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NO_QT;USE_HASH_PVS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;NO_QT;USE_BIT_PVS"
 				RuntimeLibrary="2"
 				EnableEnhancedInstructionSet="2"
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 2117)
@@ -382,13 +382,10 @@
 
 
-  // resort pvss after a pass of the algorithm
-  void
-  SortViewCellPvs();
-
-  // map the ray intersection objects from triangles to high level objects...
-  void
-  DeterminePvsObjects(
-					  VssRayContainer &rays,
-					  const bool useHitObjects = false);
+	// resort pvss after a pass of the algorithm
+	void  SortViewCellPvs();
+
+	// map the ray intersection objects from triangles to high level objects...
+	void DeterminePvsObjects(VssRayContainer &rays,
+							 const bool useHitObjects = false);
 	
 	/** Sets validity of view cell
@@ -404,7 +401,7 @@
 
 
-	/** set valid viewcells in the range of pvs. sorts the viewcells
-	  according to the pvs and then pickups those in the ranges 
-	  */
+	/** Set valid viewcells in the range of pvs. sorts the viewcells
+		according to the pvs and then pickups those in the ranges 
+	*/
 	void SetValidityPercentage(const float minValid, const float maxValid);
 
@@ -420,16 +417,17 @@
 	*/
 	int GetMinPvsSize() const;
+
 	/** Returns maximal ratio. i.e., currentPVs / maxPvs,
 		where pvs is still considered valid.
 	*/
 	float GetMaxPvsRatio() const;
+
 	/** Exports view cell geometry.
 	*/
-	virtual	void ExportViewCellGeometry(
-		Exporter *exporter,
-		ViewCell *vc,
-		const AxisAlignedBox3 *box,
-		const AxisAlignedPlane *clipPlane = NULL
-		) const = 0;
+	virtual	void ExportViewCellGeometry(Exporter *exporter,
+										ViewCell *vc,
+										const AxisAlignedBox3 *box,
+										const AxisAlignedPlane *clipPlane = NULL
+										) const = 0;
 
 	/** Brings the view cells into their final state, computes meshes and volume.
@@ -446,5 +444,4 @@
 								  float &avgRenderCost);
 
-
 	/** Returns hierarchy of the view cells.
 	*/
@@ -488,5 +485,6 @@
 	/** Evaluautes histogram for a given number of view cells.
 	*/
-	void EvalViewCellHistogramForPvsSize(const string filename, const int nViewCells);
+	void EvalViewCellHistogramForPvsSize(const string filename, 
+										 const int nViewCells);
 
 	void EvalViewCellHistogramForPvsSize(const string filename, 
@@ -500,5 +498,7 @@
 		of the hierarchy.
 	*/
-	void UpdateScalarPvsSize(ViewCell *vc, const float pvsCost, const int entriesInPvs) const;
+	void UpdateScalarPvsSize(ViewCell *vc, 
+							 const float pvsCost, 
+							 const int entriesInPvs) const;
 
 	/** Returns bounding box of a view cell.
@@ -508,9 +508,11 @@
 	/** Exports bounding boxes of objects to file.
 	*/
-	bool ExportBoundingBoxes(const string filename, const ObjectContainer &objects) const;
+	bool ExportBoundingBoxes(const string filename, 
+							 const ObjectContainer &objects) const;
     
 	/** Load the bounding boxes into the container.
 	*/
-	bool LoadBoundingBoxes(const string filename, IndexedBoundingBoxContainer &boxes) const;
+	bool LoadBoundingBoxes(const string filename, 
+						  IndexedBoundingBoxContainer &boxes) const;
 
 	/** Returns true if pvs should be exported together with the view cells.
@@ -523,4 +525,6 @@
 								  const ViewCellContainer &viewCells) const;
 
+	/** Compress the view cells.
+	*/
 	virtual void CompressViewCells();
 
@@ -616,5 +620,6 @@
 	/** Returns the bounding box of filter width.
 	*/
-	AxisAlignedBox3 GetFilterBBox(const Vector3 &viewPoint, const float width) const;
+	AxisAlignedBox3 GetFilterBBox(const Vector3 &viewPoint, 
+								  const float width) const;
 
 	//////////////////////////////////////////////////////////////////
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h	(revision 2117)
@@ -70,8 +70,14 @@
 	}
 
-	PvsEntry<T, S> Next()
+	T Next(S &pdf)
 	{
 		// hack: create new pvs entry
-		return PvsEntry<T, S>(*(mItCurrent) ++, S(0.0));
+		return *(mItCurrent) ++;
+	}
+
+	T Next()
+	{
+		// hack: create new pvs entry
+		return *(mItCurrent) ++;
 	}
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 2115)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 2117)
@@ -729,6 +729,15 @@
 	char buf[100];
 
-	if (mLoadViewCells)
+    if (mLoadViewCells)
 	{	
+		
+#ifdef USE_BIT_PVS
+		// HACK: for kd pvs, set pvs size to maximal number of kd nodes
+		vector<KdLeaf *> leaves;
+		preprocessor->mKdTree->CollectLeaves(leaves);
+
+		ObjectPvs::SetPvsSize((int)leaves.size());
+#endif
+
         Environment::GetSingleton()->GetStringValue("ViewCells.filename", buf);
 		
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2117)
@@ -21,5 +21,5 @@
 				Optimization="0"
 				AdditionalIncludeDirectories="..\include;..\src;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\..\..\..\..\NonGTP\Boost;Timer"
-				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_HASH_PVS"
+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB;USE_BIT_PVS"
 				MinimalRebuild="TRUE"
 				BasicRuntimeChecks="3"
@@ -72,5 +72,5 @@
 				OptimizeForWindowsApplication="TRUE"
 				AdditionalIncludeDirectories="..\include;..\src;..\..\..\..\..\..\NonGTP\Devil\include;..\..\..\..\..\..\NonGTP\Zlib\include;..\..\..\..\..\..\NonGTP\Xerces;..\..\..\..\..\..\NonGTP\Boost;Timer"
-				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_HASH_PVS"
+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB;USE_BIT_PVS"
 				ExceptionHandling="TRUE"
 				RuntimeLibrary="2"
@@ -383,4 +383,7 @@
 			</File>
 			<File
+				RelativePath=".\BitVectorPvs.cpp">
+			</File>
+			<File
 				RelativePath=".\BitVectorPvs.h">
 			</File>
@@ -588,4 +591,10 @@
 			<File
 				RelativePath=".\ObjectPvs.h">
+			</File>
+			<File
+				RelativePath=".\ObjectsParser.cpp">
+			</File>
+			<File
+				RelativePath=".\ObjectsParser.h">
 			</File>
 			<File
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2117)
@@ -681,6 +681,6 @@
 	if (mUseKdPvs)
 	{
-	  KdNode *node = GetPreprocessor()->mKdTree->GetPvsNode(isTermination ?
-															ray.mTermination : ray.mOrigin);
+		KdNode *node = GetPreprocessor()->
+			mKdTree->GetPvsNode(isTermination ?	ray.mTermination : ray.mOrigin);
 	  return GetPreprocessor()->mKdTree->GetOrCreateKdIntersectable(node);
 	}
@@ -1278,5 +1278,8 @@
 
 	ViewCellContainer viewCells;
-	
+
+	cout << "objects size: " << ObjectPvsIterator::sObjects.size() << endl;
+	cout << "pvs size: " <<  ObjectPvs::sPvsSize << endl;
+
 	// $$ JB hack - the collect best viewcells does not work?
 #if 0
@@ -2612,15 +2615,16 @@
 
 
-void
-ViewCellsManager::SortViewCellPvs()
-{
-
-  ViewCellContainer::iterator it, it_end = mViewCells.end();
-  for (it = mViewCells.begin(); it != it_end; ++ it) {
-	ObjectPvs &pvs = (*it)->GetPvs();
-	if (pvs.RequiresResortLog())
-	  pvs.SimpleSort();
-  }
-}
+void ViewCellsManager::SortViewCellPvs()
+{
+	ViewCellContainer::iterator it, it_end = mViewCells.end();
+	
+	for (it = mViewCells.begin(); it != it_end; ++ it) 
+	{
+		ObjectPvs &pvs = (*it)->GetPvs();
+		if (pvs.RequiresResortLog())
+			pvs.SimpleSort();
+	}
+}
+
 
 void ViewCellsManager::ComputeViewCellContribution(ViewCell *viewCell,
@@ -2630,58 +2634,61 @@
 												   const bool addSamplesToPvs)
 {
-  // check if we are outside of view space
-  // $$JB tmp commented to speedup up computations
+	// check if we are outside of view space
+	// $$JB tmp commented to speedup up computations
 #if 0
-  if (!obj || !viewCell->GetValid())
-	return;
+	if (!obj || !viewCell->GetValid())
+		return;
 #endif
-  
-  
-  // if ray not outside of view space
-  float relContribution = 0.0f;
-  float absContribution = 0.0f;
-  bool hasAbsContribution;
-  
-  // todo: maybe not correct for kd node pvs
-  if (addSamplesToPvs) {
-	hasAbsContribution = viewCell->GetPvs().AddSampleDirtyCheck(obj,
-																ray.mPdf);
-	//hasAbsContribution = viewCell->GetPvs().AddSample(obj,ray.mPdf);
-  }
-  else {
-	hasAbsContribution = viewCell->GetPvs().GetSampleContribution(
-																  obj,
-																  ray.mPdf,
-																  relContribution);
-  }
-  
-  // $$ clear the relative contribution as it is currently not correct anyway
-  //  relContribution = 0.0f;
-  
-  if (hasAbsContribution)  {
-	++ ray.mPvsContribution;
-	absContribution = relContribution = 1.0f;
-	if (viewCell->GetPvs().RequiresResort()) 
-		viewCell->GetPvs().SimpleSort();
+
+	// if ray not outside of view space
+	float relContribution = 0.0f;
+	float absContribution = 0.0f;
+	bool hasAbsContribution;
+
+	// todo: maybe not correct for kd node pvs
+	if (addSamplesToPvs) 
+	{
+		hasAbsContribution = viewCell->GetPvs().
+			AddSampleDirtyCheck(obj, ray.mPdf);
+		//hasAbsContribution = viewCell->GetPvs().AddSample(obj,ray.mPdf);
+	}
+	else 
+	{
+		hasAbsContribution = 
+			viewCell->GetPvs().GetSampleContribution(obj,
+			ray.mPdf,
+			relContribution);
+	}
+
+	// $$ clear the relative contribution as it is currently not correct anyway
+	//  relContribution = 0.0f;
+
+	if (hasAbsContribution)  
+	{
+		++ ray.mPvsContribution;
+		absContribution = relContribution = 1.0f;
+
+		if (viewCell->GetPvs().RequiresResort()) 
+			viewCell->GetPvs().SimpleSort();
 
 #if CONTRIBUTION_RELATIVE_TO_PVS_SIZE
-	relContribution /= viewcell->GetPvs().GetSize();
+		relContribution /= viewcell->GetPvs().GetSize();
 #endif
-	
+
 #if DIST_WEIGHTED_CONTRIBUTION 
-	// recalculate the contribution - weight the 1.0f contribution by the sqr distance to the
-	// object-> a new contribution in the proximity of the viewcell has a larger weight!
-	relContribution /= SqrDistance(GetViewCellBox(viewcell).Center(),
-								   ray.mTermination);
-	
+		// recalculate the contribution - weight the 1.0f contribution by the sqr distance to the
+		// object-> a new contribution in the proximity of the viewcell has a larger weight!
+		relContribution /= 
+			SqrDistance(GetViewCellBox(viewcell).Center(), ray.mTermination);
+
 #endif
 	}
-  
+
 #if SUM_RAY_CONTRIBUTIONS || AVG_RAY_CONTRIBUTIONS
-  ray.mRelativePvsContribution += relContribution;
+	ray.mRelativePvsContribution += relContribution;
 #else
-  // recalculate relative contribution - use max of Rel Contribution
-  if (ray.mRelativePvsContribution < relContribution)
-	ray.mRelativePvsContribution = relContribution;
+	// recalculate relative contribution - use max of Rel Contribution
+	if (ray.mRelativePvsContribution < relContribution)
+		ray.mRelativePvsContribution = relContribution;
 #endif
 }
@@ -3287,8 +3294,5 @@
   while (pit.HasMoreEntries())
   {		
-	  ObjectPvsEntry entry = pit.Next();
-  
-	  Intersectable *object = entry.mObject;
-      object->Mail();
+      pit.Next()->Mail();
   }
 
@@ -3301,6 +3305,5 @@
   {		
 	  // now go through the pvs again
-	  ObjectPvsEntry entry = pit2.Next();
-	  Intersectable *object = entry.mObject;
+	  Intersectable *object = pit2.Next();
 
 	  //	Vector3 center = object->GetBox().Center();
@@ -3385,7 +3388,5 @@
 	  while (pit.HasMoreEntries()) 	
 	  {
-		  ObjectPvsEntry entry = pit.Next();
-		  Intersectable *object = entry.mObject;
-		  object->Mail();
+		  pit.Next()->Mail();
 	  }
   }
@@ -3447,8 +3448,9 @@
 	ObjectContainer objects;
 	
+	PvsData pvsData;
+
 	while (pit.HasMoreEntries()) {		
-	  ObjectPvsEntry entry = pit.Next();
+	  Intersectable *object = pit.Next(pvsData);
 	  
-	  Intersectable *object = entry.mObject;
 	  // compute filter size based on the distance and the numebr of samples
 	  AxisAlignedBox3 box = object->GetBox();
@@ -3457,5 +3459,5 @@
 	  float globalRadius = distance*globalC;
 	  
-	  int objectSamples = (int)entry.mData.mSumPdf;
+	  int objectSamples = (int)pvsData.mSumPdf;
 	  float localRadius = MAX_FLOAT;
 	  
@@ -3525,10 +3527,12 @@
   if (!mUseKdPvs)
   {
+	  PvsData pvsData;
+
 	  // copy the base pvs to the new pvs
 	  pit = basePvs.GetIterator();
 	  while (pit.HasMoreEntries()) 
 	  {		
-		  ObjectPvsEntry entry = pit.Next();
-		  pvs.AddSampleDirty(entry.mObject, entry.mData.mSumPdf);
+		  Intersectable *obj = pit.Next(pvsData);
+		  pvs.AddSampleDirty(obj, pvsData.mSumPdf);
 	  }
   }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BitVectorPvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BitVectorPvs.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BitVectorPvs.h	(revision 2117)
@@ -13,7 +13,7 @@
 typedef vector<bool> bit_vector;
 
+
 /** Iterator over a bitvector pvs.
 */
-#if 0
 template<typename T, typename S>
 class BitVectorPvsIterator
@@ -21,9 +21,9 @@
 public:
 	
-	HashPvsIterator<T, S>() {}
-
-	HashPvsIterator<T, S>(const typename HASH_SET::const_iterator &itCurrent,
-						  const typename HASH_SET::const_iterator &itEnd):
-	mItCurrent(itCurrent), mItEnd(itEnd)
+	BitVectorPvsIterator<T, S>(const typename bit_vector::const_iterator &itBegin,
+							   const typename bit_vector::const_iterator &itEnd
+							   //,const int lastElement
+							   ):
+	mItCurrent(itBegin), mItEnd(itEnd), mDistance(0)//, mLastElement
 	{
 	}
@@ -31,20 +31,48 @@
 	bool HasMoreEntries() const 
 	{
-		return (mItCurrent != mItEnd);
-	}
-
-	PvsEntry<T, S> Next()
+		// find next element in bit vector
+		// warning: has to do traversal each time
+		typename bit_vector::const_iterator itNext = mItCurrent;
+
+		for (;(itNext != mItEnd) && !(*itNext); ++ itNext);
+
+		return (itNext != mItEnd);
+	}
+
+	T Next(S &pdf)
+	{
+		return Next();
+	}
+	
+	T Next()
 	{
 		// hack: create new pvs entry
-		return PvsEntry<T, S>(*(mItCurrent) ++, S(0.0));
-	}
-	
+		for (; !(*mItCurrent); ++ mItCurrent, ++ mDistance);
+
+		T sample = sObjects[mDistance];
+
+		++ mDistance;
+		++ mItCurrent;
+
+		return sample;
+	}
+
+	
+	// vector of objects corresponding to pvs entries
+	static vector<T> sObjects;
+
 private:
-	typename HASH_SET::const_iterator mItCurrent;
-	typename HASH_SET::const_iterator mItEnd;
+
+	typename bit_vector::const_iterator mItCurrent;
+	//typename bit_vector::const_iterator mItNext;
+	typename bit_vector::const_iterator mItEnd;
+	
+	// note: store distance explicitly because I 
+	// don't know how efficient
+	// std::distance is on specialisation of vector<bool>
+	int mDistance;
 };
-#endif
-
-#if 0
+
+
 /** Pvs implemented as bitvector
 */
@@ -56,6 +84,5 @@
 public:
 
-	//HashPvs(): mEntries((Intersectable *)100) {};
-	HashPvs() {};
+	BitVectorPvs();
 	//virtual ~HashPvs() {};
 
@@ -92,20 +119,16 @@
 
 	/** Finds sample in PVS.
-		@param checkDirty if dirty part of the pvs should be checked for entry 
-		(warning: linear runtime in dirty part)
-		@returns iterator on the sample if found, else the place where 
-		it would be added in the sorted vector.
-	*/
-	bool Find(T sample, typename HASH_SET::iterator &it);
-
-	typename HashPvsIterator<T, S> GetIterator() const;
+	*/
+	bool Find(T sample);
+
+	typename BitVectorPvsIterator<T, S> GetIterator() const;
 
 	/** Compute continuous PVS difference 
 	*/
-	float GetPvsHomogenity(HashPvs<T, S> &pvs);
-
-	static void Merge(HashPvs<T, S> &mergedPvs, 
-					  const HashPvs<T, S> &a, 
-					  const HashPvs<T, S> &b);
+	float GetPvsHomogenity(BitVectorPvs<T, S> &pvs);
+
+	static void Merge(BitVectorPvs<T, S> &mergedPvs, 
+					  const BitVectorPvs<T, S> &a, 
+					  const BitVectorPvs<T, S> &b);
 
 	static int GetEntrySizeByte(); 
@@ -121,5 +144,5 @@
 	}
 
-	void MergeInPlace(const HashPvs<T, S> &a)
+	void MergeInPlace(const BitVectorPvs<T, S> &a)
 	{
 		cerr << "not implemented yet" << endl;
@@ -133,15 +156,15 @@
 	void Reserve(const int n) 
 	{ 
+		mEntries.reserve(n);
+	}
+
+	/** Sort pvs entries assume that the pvs contains unique entries
+	*/
+	void SimpleSort()
+	{
 		// not necessary
 	}
 
-	/** Sort pvs entries assume that the pvs contains unique entries
-	*/
-	void SimpleSort()
-	{
-		// not necessary
-	}
-
-	int SubtractPvs(const HashPvs<T, S> &pvs)
+	int SubtractPvs(const BitVectorPvs<T, S> &pvs)
 	{
 		cerr << "not yet implemented" << endl;
@@ -151,5 +174,5 @@
 	/** Compute continuous PVS difference 
 	*/
-	void ComputeContinuousPvsDifference(HashPvs<T, S> &pvs, 
+	void ComputeContinuousPvsDifference(BitVectorPvs<T, S> &pvs, 
 										float &pvsReduction,
 										float &pvsEnlargement)
@@ -157,47 +180,77 @@
 		cerr << "not yet implemented" << endl;
 	}
+
+
+	static void SetPvsSize(const int pvsSize) { sPvsSize = pvsSize; };
+	
 protected:
 
 	/// hash table of PVS entries
-	HASH_SET mEntries; 
+	bit_vector mEntries; 
 
 	/// Number of samples used to create the PVS
 	int mSamples;
+
+public:
+	static int sPvsSize;
 };
 
 
 template <typename T, typename S>
-bool HashPvs<T, S>::Find(T sample, typename HASH_SET::iterator &it)
-{
-	it = mEntries.find(sample);
-
-	// already in map
-	return (it != mEntries.end());
-}
-
-
-template <typename T, typename S>
-int HashPvs<T, S>::GetSize() const
-{
-	return (int)mEntries.size();
-}
-
-
-template <typename T, typename S>
-bool HashPvs<T, S>::Empty() const
-{
-	return mEntries.empty();
-}
-
-
-template <typename T, typename S>
-float HashPvs<T, S>::AddSample(T sample, const float pdf)
-{
-	HASH_SET::iterator it;
-
-	if (Find(sample, it))
+BitVectorPvs<T, S>::BitVectorPvs()
+{
+	// initialize bit vector
+	mEntries.reserve(sPvsSize);
+	mEntries.resize(sPvsSize);
+
+	// set pvs entries to false
+	Clear();
+}
+
+
+template <typename T, typename S>
+bool BitVectorPvs<T, S>::Find(T sample)
+{
+	return mEntries[sample->GetId()];
+}
+
+
+template <typename T, typename S>
+int BitVectorPvs<T, S>::GetSize() const
+{
+	int size = 0;
+	bit_vector::const_iterator bit, bit_end = mEntries.end();
+
+	for (bit = mEntries.begin(); bit != bit_end; ++ bit)
+	{
+		if (*bit) ++ size;
+	}
+
+	return size;
+}
+
+
+template <typename T, typename S>
+bool BitVectorPvs<T, S>::Empty() const
+{
+	bit_vector::const_iterator bit, bit_end = mEntries.end();
+
+	for (bit = mEntries.begin(); bit != bit_end; ++ bit)
+	{
+		if (*bit) return false;
+	}
+
+	return true;
+}
+
+
+template <typename T, typename S>
+float BitVectorPvs<T, S>::AddSample(T sample, const float pdf)
+{
+	if (Find(sample))
 		return 0.0f;
 	
-	mEntries.insert(sample);
+	mEntries[sample->GetId()] = true;
+
 	return 1.0f;
 }
@@ -205,27 +258,21 @@
 
 template <typename T, typename S>
-void HashPvs<T, S>::AddSampleDirty(T sample, const float pdf)
-{
-	HASH_SET::iterator it;
-
-	// not yet in map
-	if (!Find(sample, it))
-	{
-		mEntries.insert(sample);	
-	}
-}
-
-
-template <typename T, typename S>
-bool HashPvs<T, S>::AddSampleDirtyCheck(T sample, 
+void BitVectorPvs<T, S>::AddSampleDirty(T sample, const float pdf)
+{
+	if (!Find(sample))
+	{
+		mEntries[sample->GetId()] = true;
+	}
+}
+
+
+template <typename T, typename S>
+bool BitVectorPvs<T, S>::AddSampleDirtyCheck(T sample, 
 										const float pdf)
 {
-	HASH_SET::iterator it;
-
-	// already in map
-	if (Find(sample, it))
+	if (Find(sample))
 		return false;
 	
-	mEntries.insert(sample);
+	mEntries[sample->GetId()] = true;
 	return true;
 }
@@ -233,18 +280,22 @@
 
 template <typename T, typename S>
-void HashPvs<T, S>::Sort()
-{
-}
-
-
-template <typename T, typename S>
-void HashPvs<T, S>::Clear(const bool trim = true)
-{
-	mEntries.clear();
-}
-
-
-template <typename T, typename S>
-bool HashPvs<T, S>::IsDirty() const
+void BitVectorPvs<T, S>::Sort()
+{
+}
+
+
+template <typename T, typename S>
+void BitVectorPvs<T, S>::Clear(const bool trim = true)
+{
+	bit_vector::iterator bit, bit_end = mEntries.end();
+	for (bit = mEntries.begin(); bit != bit_end; ++ bit)
+	{
+		(*bit) = false;
+	}
+}
+
+
+template <typename T, typename S>
+bool BitVectorPvs<T, S>::IsDirty() const
 {
 	return false;
@@ -253,5 +304,5 @@
 
 template <typename T, typename S>
-bool HashPvs<T, S>::RequiresResort() const
+bool BitVectorPvs<T, S>::RequiresResort() const
 {
 	return false;
@@ -260,7 +311,7 @@
 
 template <typename T, typename S>
-typename HashPvsIterator<T, S> HashPvs<T, S>::GetIterator() const
-{
-	HashPvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
+typename BitVectorPvsIterator<T, S> BitVectorPvs<T, S>::GetIterator() const
+{
+	BitVectorPvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
 
 	return pit;
@@ -269,19 +320,19 @@
 
 template <typename T, typename S>
-float HashPvs<T, S>::GetEntrySize()
-{
-	return (float)(sizeof(T)) / float(1024 * 1024);
-}
-
-
-template <typename T, typename S>
-int HashPvs<T, S>::GetEntrySizeByte()
-{
-	return sizeof(T);
-}
-
-
-template <typename T, typename S>
-float HashPvs<T, S>::GetPvsHomogenity(HashPvs<T, S> &pvs) 
+float BitVectorPvs<T, S>::GetEntrySize()
+{
+	return (float)(sizeof(bool)) / float(1024 * 1024);
+}
+
+
+template <typename T, typename S>
+int BitVectorPvs<T, S>::GetEntrySizeByte()
+{
+	return sizeof(bool);
+}
+
+
+template <typename T, typename S>
+float BitVectorPvs<T, S>::GetPvsHomogenity(BitVectorPvs<T, S> &pvs) 
 {
 	float pvsReduction, pvsEnlargement;
@@ -294,10 +345,9 @@
 
 template <typename T, typename S>
-bool HashPvs<T, S>::GetSampleContribution(T sample,
+bool BitVectorPvs<T, S>::GetSampleContribution(T sample,
 									  const float pdf,
 									  float &contribution) 
 {
-	HASH_SET::iterator it;
-	const bool entryFound = Find(sample, it);
+	const bool entryFound = Find(sample);
 
 	if (entryFound)  
@@ -315,14 +365,26 @@
 
 template <typename T, typename S>
-void HashPvs<T, S>::Merge(HashPvs<T, S> &mergedPvs, 
-						  const HashPvs<T, S> &a, 
-						  const HashPvs<T, S> &b)
-{
+void BitVectorPvs<T, S>::Merge(BitVectorPvs<T, S> &mergedPvs, 
+							   const BitVectorPvs<T, S> &a, 
+							   const BitVectorPvs<T, S> &b)
+{
+	bit_vector::iterator bit, bit_end = mergedPvs.mEntries.end();
+	bit_vector::const_iterator bitA =  a.mEntries.begin(), bitB = b.mEntries.begin();
+
+	for (bit = mergedPvs.mEntries.begin(); bit != bit_end; ++ bit, ++ bitA, ++ bitB)
+	{
+        (*bit) = (*bitA) | (*bitB);
+	}
+}
+
+
+template<typename T, typename S>
+int BitVectorPvs<T, S>::sPvsSize = 0;
+
+template<typename T, typename S>
+vector<T> BitVectorPvsIterator<T, S>::sObjects;
+
 }
 
 #endif
 
-}
-
-#endif
-
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 2100)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 2117)
@@ -65,9 +65,9 @@
 	while (pit.HasMoreEntries())
 	{
-		ObjectPvsEntry entry = pit.Next();
-
-		if (!entry.mObject->Mailed())
-		{
-			entry.mObject->Mail();
+		Intersectable *obj = pit.Next();
+
+		if (!obj->Mailed())
+		{
+			obj->Mail();
 			++ count;
 		}
@@ -92,6 +92,5 @@
 	while (pit.HasMoreEntries())
 	{
-		ObjectPvsEntry entry = pit.Next();
-		entry.mObject->Mail();
+		pit.Next()->Mail();
 	}
 
@@ -100,8 +99,5 @@
 	while (pit.HasMoreEntries())
 	{
-		ObjectPvsEntry entry = pit.Next();
-
-		Intersectable *obj = entry.mObject;
-		if (!obj->Mailed())
+		if (!pit.Next()->Mailed())
 			++ pvs;
 	}
@@ -847,7 +843,5 @@
 	while (pit.HasMoreEntries())
 	{
-		ObjectPvsEntry entry = pit.Next();
-
-		Intersectable *obj = entry.mObject;
+		Intersectable *obj = pit.Next();
 
 		obj->Mail();
@@ -859,7 +853,6 @@
 	while (pit2.HasMoreEntries())
 	{
-		ObjectPvsEntry entry = pit2.Next();
-		Intersectable *obj = entry.mObject;
-
+		Intersectable *obj = pit2.Next();
+		
 		// test if object already considered	
 		if (!obj->Mailed())
@@ -1681,7 +1674,5 @@
 		while (pit.HasMoreEntries())
 		{		
-			const ObjectPvsEntry &entry = pit.Next();
-			Intersectable *obj = entry.mObject;
-			obj->Mail();
+			pit.Next()->Mail();
 		}
 	}
@@ -1695,8 +1686,5 @@
 		while (pit.HasMoreEntries())
 		{		
-			const ObjectPvsEntry &entry = pit.Next();
-			Intersectable *obj = entry.mObject;
-
-			obj->IncMail();
+			pit.Next()->IncMail();
 		}
 	}
@@ -1705,4 +1693,6 @@
     interior->GetPvs().Clear(false);
 		
+	PvsData pvsData;
+
 	// only the objects which are present in all leaf pvs 
 	// should remain in the parent pvs
@@ -1716,9 +1706,9 @@
 		while (pit.HasMoreEntries())
 		{		
-			ObjectPvsEntry entry = pit.Next();
-
-			if (entry.mObject->Mailed(mail))
+			Intersectable *obj = pit.Next(pvsData);
+
+			if (obj->Mailed(mail))
 			{	
-				interior->GetPvs().AddSample(entry.mObject, entry.mData.mSumPdf);
+				interior->GetPvs().AddSample(obj, pvsData.mSumPdf);
 			}
 		}
@@ -1733,17 +1723,12 @@
 
 		ObjectPvs newPvs;
-
+		
 		while (pit.HasMoreEntries())
 		{		
-			const ObjectPvsEntry &entry = pit.Next();
-			Intersectable *obj = entry.mObject;
-
-			/*if (obj->Mailed(mail))
-			{
-				vc->GetPvs().RemoveSample(entry.mObject, Limits::Infinity))
-			}*/
+			Intersectable *obj = pit.Next(pvsData);
+
 			if (!obj->Mailed(mail))
 			{
-				newPvs.AddSampleDirty(obj, entry.mData.mSumPdf);
+				newPvs.AddSampleDirty(obj, pvsData.mSumPdf);
 			}
 		}
@@ -1872,6 +1857,5 @@
 		while (oit.HasMoreEntries())
 		{
-			ObjectPvsEntry entry = oit.Next();
-			Intersectable *intersect = entry.mObject;
+			Intersectable *intersect = oit.Next();
 
 			if (!intersect->Mailed())
@@ -2390,6 +2374,5 @@
 	while (it.HasMoreEntries())
 	{
-		ObjectPvsEntry entry = it.Next();
-		Intersectable *obj = entry.mObject;
+		Intersectable *obj = it.Next();
 
 		// hack: just output full pvs
@@ -2408,5 +2391,5 @@
 		else
 		{
-			stream << entry.mObject->GetId() << " ";
+			stream << obj->GetId() << " ";
 		}
 	}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 2117)
@@ -29,7 +29,13 @@
 	}
 
-	const PvsEntry<T, S> &Next()
-	{
-		return *(mItCurrent ++);
+	T Next(S &pdf)
+	{
+		pdf = (*mItCurrent).mData;
+		return (*(mItCurrent ++)).mObject;
+	}
+
+	T Next()
+	{
+		return (*(mItCurrent ++)).mObject;
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/PvsBase.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/PvsBase.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/PvsBase.h	(revision 2117)
@@ -19,6 +19,6 @@
 public:
 
-	PvsEntry() {}
-
+	PvsEntry(): mObject(NULL), mData(0) {}
+	PvsEntry(T sample): mObject(sample), mData(0) {}
 	PvsEntry(T sample, const S &data): mObject(sample), mData(data) {}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 2117)
@@ -1464,7 +1464,15 @@
 	{
 		// not in map => create new entry
-		node->mIntersectable = new KdIntersectable(node, GetBox(node));
-		mKdIntersectables.push_back(node->mIntersectable);
-		node->mIntersectable->SetId((int)mKdIntersectables.size());
+		const int id = (int)mKdIntersectables.size();
+		KdIntersectable *kdObj = new KdIntersectable(node, GetBox(node));;
+		node->mIntersectable = kdObj;
+		
+		mKdIntersectables.push_back(kdObj);
+		kdObj->SetId(id);
+
+#ifdef USE_BIT_PVS
+		// hack: for kd pvs the kd intersecables are the pvs objects
+		ObjectPvsIterator::sObjects.push_back(kdObj);
+#endif
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 2117)
@@ -283,5 +283,4 @@
 		return mPvsCost;
 	}
-
 
 	int GetFilteredPvsSize() const 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h	(revision 2117)
@@ -202,15 +202,16 @@
   }
 
-  /** \sa KdNode::IsLeaf() */
+  /** \sa KdNode::IsLeaf() 
+  */
   virtual bool IsLeaf() const { return true; }
 
 
-  /** pointers to occluders contained in this node */
+  /// pointers to occluders contained in this node
   ObjectContainer mObjects;
 
-  /** Ray set description of the rays passing through this node */
+  /// Ray set description of the rays passing through this node
   PassingRaySet mPassingRays;
 	
-  /** PVS consisting of visible KdTree nodes */
+  /// PVS consisting of visible KdTree nodes
   //KdPvs mKdPvs;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 2117)
@@ -218,9 +218,5 @@
 	}
 
-
-	if (HASH_PVS)
-		Debug << "using hash pvs" << endl;
-	else
-		Debug << "using verbose pvs" << endl;
+	Debug << "using pvs type " << PVS_TYPE << endl;
 
 	/////////////
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GvsPreprocessor.cpp	(revision 2117)
@@ -678,23 +678,4 @@
 		return;
 
-	/*ObjectPvsIterator pit = vc->GetPvs().GetIterator();
-
-	// output PVS of view cell
-	while (pit.HasMoreEntries())
-	{		
-		ObjectPvsEntry entry = pit.Next();
-
-		Intersectable *intersect = entry.mObject;
-		
-		if (intersect->Mailed())
-			continue;
-		
-		intersect->Mail();
-		//m.mDiffuseColor = RgbColor(1, 0, 0);
-		m = RandomMaterial();
-		exporter->SetForcedMaterial(m);
-
-		exporter->ExportIntersectable(intersect);
-	}*/
 	ObjectContainer::const_iterator oit, oit_end = objects.end();
 
@@ -1028,8 +1009,6 @@
 	while (pit.HasMoreEntries())
 	{		
-		ObjectPvsEntry entry = pit.Next();
-
-		Intersectable *intersect = entry.mObject;
-	
+		Intersectable *intersect = pit.Next();
+
 		BvhLeaf *bv = intersect->mBvhLeaf;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/PvsDefinitions.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/PvsDefinitions.h	(revision 2116)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/PvsDefinitions.h	(revision 2117)
@@ -12,5 +12,5 @@
 #include "HashPvs.h"
 
-#define HASH_PVS 1
+#define PVS_TYPE 0
 
 namespace GtpVisibilityPreprocessor {
@@ -19,9 +19,11 @@
 }
 
-#else
+#endif
+
+#ifdef USE_VERBOSE_PVS
 
 #include "Pvs.h"
 
-#define HASH_PVS 0
+#define PVS_TYPE 1
 
 namespace GtpVisibilityPreprocessor {
@@ -29,4 +31,18 @@
 typedef PvsIterator<Intersectable *, PvsData> ObjectPvsIterator;
 }
+#endif
+
+
+#ifdef USE_BIT_PVS
+
+#include "BitVectorPvs.h"
+
+#define PVS_TYPE 2
+
+namespace GtpVisibilityPreprocessor {
+typedef BitVectorPvs<Intersectable *, PvsData> DefaultPvs;
+typedef BitVectorPvsIterator<Intersectable *, PvsData> ObjectPvsIterator;
+}
+
 #endif
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 2094)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 2117)
@@ -1877,10 +1877,10 @@
 	while (pit.HasMoreEntries())
 	{
-		const ObjectPvsEntry &entry = pit.Next();
-
-		if (entry.mObject->Type() != Intersectable::BVH_INTERSECTABLE)
-			cout << "error " << entry.mObject->Type() << endl;
-
-		BvhNode *intersect = static_cast<BvhNode *>(entry.mObject);
+		Intersectable *obj = pit.Next();
+
+		if (obj->Type() != Intersectable::BVH_INTERSECTABLE)
+			cout << "error " << obj->Type() << endl;
+
+		BvhNode *intersect = static_cast<BvhNode *>(obj);
 		BvhNode *activeNode;
 
@@ -1937,7 +1937,6 @@
 			while (pit.HasMoreEntries())
 			{		
-				const ObjectPvsEntry &entry = pit.Next();
-
-				Intersectable *object = entry.mObject;
+				Intersectable *object = pit.Next();
+
 				if (!object->Mailed())
 				{
