Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1884)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1891)
@@ -435,5 +435,5 @@
   Randomize(0);
 
-  if (1) {
+  if (0) {
 	Exporter *exporter = Exporter::GetExporter("samples.wrl");
     exporter->SetFilled();
@@ -501,4 +501,5 @@
   char *curr = buff;
   mUseRssTree = false;
+
   while (1) {
 	char *e = strchr(curr,'+');
@@ -542,4 +543,6 @@
   mMixtureDistribution->Init();
   bool oldGenerator = false;
+
+  const int batch = 100000;
   
   if (mLoadInitialSamples) {
@@ -579,5 +582,4 @@
 	  
 	} else {
-	  const int batch = 1000;
 	  for (int i=0; i < mInitialSamples; i+=batch) {
 		rays.clear();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorFactory.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorFactory.cpp	(revision 1486)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorFactory.cpp	(revision 1891)
@@ -6,4 +6,5 @@
 #include "RenderSampler.h"
 #include "GvsPreprocessor.h"
+#include "CombinedPreprocessor.h"
 
 
@@ -17,5 +18,10 @@
 		return new VssPreprocessor();
 	}
-	
+
+	if (preprocessorType == "combined")
+	{
+		return new CombinedPreprocessor();
+	}
+
 	if (preprocessorType == "rss")
 	{
Index: GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1884)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1891)
@@ -48,5 +48,6 @@
 #	type sampling
 #	type vss
-	type rss
+#	type rss
+	type combined
 #	type render
 	detectEmptyViewSpace true
@@ -88,14 +89,15 @@
 }
 
+
 RssPreprocessor {
 
 #	distributions rss+spatial+object_direction
-	distributions object_direction+spatial
+	distributions rss+object_direction+spatial+object+direction
 #	distributions object_direction
 
-	samplesPerPass 1000
+	samplesPerPass 200000
 	initialSamples 2000000
 	vssSamples 50000000
-	vssSamplesPerPass 2000000
+	vssSamplesPerPass 500000
 	useImportanceSampling true
 
@@ -133,5 +135,5 @@
  	maxCostRatio 1.0
 	maxRayContribution 1.0
-	maxRays		1000000
+	maxRays		10000000
 	maxTotalMemory	400
 	maxStaticMemory	200
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1888)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1891)
@@ -73,9 +73,11 @@
 	int mRays;
  	float mContribution;
-	float mTime;
-	float mRatio;
 
   int mTotalRays;
   float mTotalContribution;
+
+  float mTime;
+	float mRatio;
+
 protected:
 
@@ -159,5 +161,5 @@
   SpatialBoxBasedDistribution(Preprocessor &preprocessor):
 	SamplingStrategy(preprocessor){
-	mType = DIRECTION_BOX_BASED_DISTRIBUTION;
+	mType = SPATIAL_BOX_BASED_DISTRIBUTION;
   }
   
@@ -172,5 +174,5 @@
 	 ViewSpaceBorderBasedDistribution(Preprocessor &preprocessor):
 	   SamplingStrategy(preprocessor){
-	   mType = SPATIAL_BOX_BASED_DISTRIBUTION;
+	   mType = VIEWSPACE_BORDER_BASED_DISTRIBUTION;
 	 }
 	 
@@ -185,5 +187,5 @@
 	 ReverseViewSpaceBorderBasedDistribution(Preprocessor &preprocessor):
 	   SamplingStrategy(preprocessor){
-	   mType = SPATIAL_BOX_BASED_DISTRIBUTION;
+	   mType = REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION;
 	 }
 	 
@@ -199,5 +201,8 @@
  public:
   ViewCellBorderBasedDistribution(Preprocessor &preprocessor):
-	SamplingStrategy(preprocessor) {}
+	SamplingStrategy(preprocessor) {
+	mType = VIEWCELL_BORDER_BASED_DISTRIBUTION;
+
+  }
   
   virtual bool GenerateSample(SimpleRay &ray);
@@ -261,4 +266,8 @@
   UpdateRatios();
 
+  // construct distribution mixyure from a string describing the required distributions
+  bool
+  Construct(char *str);
+
   
 };
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1889)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1891)
@@ -30,6 +30,4 @@
 
 #define KD_PVS_AREA (1e-5f)
-
-
 
 namespace GtpVisibilityPreprocessor {
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1884)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1891)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: st 13. XII 00:50:24 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: st 13. XII 23:09:08 2006
 # Project:  preprocessor.pro
 # Template: app
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1884)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1891)
@@ -29,4 +29,5 @@
 #include "SceneGraph.h"
 #include "SamplingStrategy.h"
+#include "ViewCellsManager.h"
 
 
@@ -2733,5 +2734,5 @@
 // if small very high importance of the last sample
 // if 1.0f then weighs = 1 1/2 1/3 1/4
-float passSampleWeightDecay = 1.0f;
+float passSampleWeightDecay = 2.0f;
 //float passSampleWeightDecay = 1000.0f;
 
@@ -2740,6 +2741,10 @@
 {
   int passDiff = mCurrentPass - pass;
+  if (passDiff < 0) {
+	cerr<<"Error: passdif < 0"<<passDiff<<endl;
+	exit(1);
+  }
   float weight;
-  if (0) 
+  if (1) 
 	weight = 1.0f/(passDiff + passSampleWeightDecay);
   else 
@@ -2788,5 +2793,5 @@
 RssTree::ComputeImportance(RssTreeLeaf *leaf) 
 {
-#if 1
+#if 0
   if (leaf->mTotalRays)
 	leaf->mImportance = leaf->mTotalContribution / leaf->mTotalRays;
@@ -2856,12 +2861,13 @@
 	
 	if (sumWeights != 0.0f) {
+#if 1
 	  leaf->mImportance =
-			sqr(((weightAbsContributions*sumContributions +
-						(1.0f - weightAbsContributions)*sumRelContributions)/sumWeights));
-	  
-	  //	  leaf->mImportance =
-	  //		(weightAbsContributions*maxContribution +
-	  //		 (1.0f - weightAbsContributions)*maxRelContribution)/sumWeights;
-	  
+		pow(((weightAbsContributions*sumContributions +
+			  (1.0f - weightAbsContributions)*sumRelContributions)/sumWeights), 3);
+#else 
+	  leaf->mImportance =
+		(weightAbsContributions*maxContribution +
+		 (1.0f - weightAbsContributions)*maxRelContribution)/sumWeights;
+#endif
 	} else
 	  leaf->mImportance = 0.0f;
@@ -2877,5 +2883,5 @@
 RssTreeNode::GetImportance()  const
 {
-  //  return sqr(mImportance);
+  // return mImportance*mImportance;
   return mImportance;
 }
@@ -3120,14 +3126,24 @@
   float r[5];
 
-  if (mRssTree == NULL)
-	return false;
-  
   mHalton.GetNext(5, r);
 
-  SimpleRayContainer rays;
-  mRssTree->GenerateRay(r, rays);
-  ray = rays[0];
-  
-  return false;
+  if (mRssTree == NULL) {
+	// use direction based distribution
+	Vector3 origin, direction;
+	mPreprocessor.mViewCellsManager->GetViewPoint(origin, Vector3(r[0], r[1], r[2]));
+	
+	direction = UniformRandomVector(r[3], r[4]);
+
+	const float pdf = 1.0f;
+	ray = SimpleRay(origin, direction, RSS_BASED_DISTRIBUTION, pdf);
+	
+  } else {
+	
+	SimpleRayContainer rays;
+	mRssTree->GenerateRay(r, rays);
+	ray = rays[0];
+  }
+  
+  return true;
 }
 
@@ -3141,5 +3157,4 @@
 	/// compute view cell contribution of rays if view cells manager already constructed
 	//  mViewCellsManager->ComputeSampleContributions(mVssRays, true, false);
-	
 	mRssTree->Construct(mPreprocessor.mObjects, vssRays);
 	mRssTree->stat.Print(mPreprocessor.mStats);
@@ -3147,4 +3162,5 @@
 	
   } else {
+	mRssTree->SetPass(mPass);
 	Debug<<"Adding rays...\n"<<flush;
 	mRssTree->AddRays(vssRays);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/CombinedPreprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/CombinedPreprocessor.h	(revision 1891)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/CombinedPreprocessor.h	(revision 1891)
@@ -0,0 +1,37 @@
+#ifndef _CombinedPreprocessor_H__
+#define _CombinedPreprocessor_H__
+
+#include <fstream>
+using namespace std;
+
+#include "Preprocessor.h"
+#include "VssRay.h"
+
+namespace GtpVisibilityPreprocessor {
+
+  class Exporter;
+  class MixtureDistribution;
+  
+/** Sampling based visibility preprocessing. The implementation is based on heuristical
+    sampling of view space 
+	*/
+class CombinedPreprocessor : public Preprocessor {
+public:
+  
+  CombinedPreprocessor();
+  virtual ~CombinedPreprocessor() {}
+  
+  virtual bool ComputeVisibility();
+  
+protected:
+  MixtureDistribution *mMixtureDistribution;
+  
+  int mTotalSamples;
+  int mSamplesPerPass;
+  int mSamplesPerEvaluation;
+  
+};
+
+}
+
+#endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/CombinedPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/CombinedPreprocessor.cpp	(revision 1891)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/CombinedPreprocessor.cpp	(revision 1891)
@@ -0,0 +1,99 @@
+#include "SceneGraph.h"
+#include "KdTree.h"
+#include "X3dExporter.h"
+#include "Environment.h"
+#include "Polygon3.h"
+#include "VssRay.h"
+#include "RssTree.h"
+#include "ViewCellsManager.h"
+#include "RenderSimulator.h"
+#include "GlRenderer.h"
+#include "SamplingStrategy.h"
+#include "PreprocessorThread.h"
+#include "CombinedPreprocessor.h"
+
+
+namespace GtpVisibilityPreprocessor {
+
+const bool pruneInvalidRays = false;
+
+  
+  CombinedPreprocessor::CombinedPreprocessor():
+	Preprocessor()
+  {
+	// this should increase coherence of the samples
+	Environment::GetSingleton()->GetIntValue("RssPreprocessor.vssSamples", mTotalSamples);
+	Environment::GetSingleton()->GetIntValue("RssPreprocessor.samplesPerPass", mSamplesPerPass);
+	Environment::GetSingleton()->GetIntValue("RssPreprocessor.vssSamplesPerPass",
+											 mSamplesPerEvaluation);
+	
+	
+	//  Environment::GetSingleton()->GetBoolValue("RssPreprocessor.Export.rays", mExportRays);
+	//  Environment::GetSingleton()->GetIntValue("RssPreprocessor.Export.numRays", mExportNumRays);
+  }
+  
+
+bool
+CombinedPreprocessor::ComputeVisibility()
+{
+  
+  Debug << "Preprocessor type: combined" << endl;
+  cout<<"Combined Preprocessor started\n"<<flush;
+  
+  // if not already loaded, construct view cells from file
+  if (!mLoadViewCells) {
+	// construct view cells using it's own set of samples
+	mViewCellsManager->Construct(this);
+	
+	//-- several visualizations and statistics
+	Debug << "view cells construction finished: " << endl;
+	mViewCellsManager->PrintStatistics(Debug);
+  }
+  
+  
+  // now decode distribution string
+  char buff[1024];
+  Environment::GetSingleton()->GetStringValue("RssPreprocessor.distributions",
+											  buff);
+  
+
+  mMixtureDistribution = new MixtureDistribution(*this);
+  mMixtureDistribution->Construct(buff);
+  
+  SimpleRayContainer rays;
+  VssRayContainer vssRays;
+
+  int lastEvaluation = 0;
+  int totalVssRays = 0;
+  mPass = 0;
+  
+  long startTime = GetTime();
+  for (int i=0; i < mTotalSamples; i += mSamplesPerPass, mPass++) {
+
+	if (i - lastEvaluation >= mSamplesPerEvaluation) {
+	  mStats <<
+		"#Pass\n" <<mPass<<endl<<
+		"#Time\n" << TimeDiff(startTime, GetTime())<<endl<<
+		"#TotalSamples\n" <<i<<endl<<
+		"#RssSamples\n" <<totalVssRays<<endl;
+	  vssRays.PrintStatistics(mStats);
+	  mViewCellsManager->PrintPvsStatistics(mStats);
+	  lastEvaluation = i;
+	}
+	
+	cout<<"Progress : "<<(100.0f*i)/mTotalSamples<<"%"<<endl;
+	rays.clear();
+	vssRays.clear();
+	
+	mMixtureDistribution->GenerateSamples(mSamplesPerPass, rays);
+	
+	CastRays(rays, vssRays, true, pruneInvalidRays);
+	totalVssRays += vssRays.size();
+	
+	mMixtureDistribution->ComputeContributions(vssRays);
+
+  }
+  
+}
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro	(revision 1883)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro	(revision 1891)
@@ -109,5 +109,7 @@
 InternalRayCaster.cpp IntelRayCaster.cpp \
 RayCaster.cpp PreprocessorFactory.cpp GvsPreprocessor.cpp \
-Trackball.cpp ObjExporter.cpp SubdivisionCandidate.cpp QtGlViewer.cpp Mailable.cpp
+Trackball.cpp ObjExporter.cpp SubdivisionCandidate.cpp QtGlViewer.cpp \
+Mailable.cpp \
+CombinedPreprocessor.cpp
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1888)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1891)
@@ -5,5 +5,5 @@
 #include "ViewCellsManager.h"
 #include "AxisAlignedBox3.h"
-
+#include "RssTree.h"
 
 namespace GtpVisibilityPreprocessor {
@@ -475,7 +475,7 @@
   for (int i=0; i < mDistributions.size(); i++) {
 	// small non-zero value
-	mDistributions[i]->mRays = 1;
+	mDistributions[i]->mTotalRays = 0;
 	// unit contribution per ray
-	mDistributions[i]->mContribution = 1.0f;
+	mDistributions[i]->mTotalContribution = 0.0f;
   }
   UpdateRatios();
@@ -490,8 +490,8 @@
 
   // pickup a distribution
-  for (int i=0; i < mDistributions.size(); i++)
+  for (int i=0; i < mDistributions.size()-1; i++)
 	if (r < mDistributions[i]->mRatio)
 	  break;
-  
+
   return mDistributions[i]->GenerateSample(ray);
 }
@@ -505,18 +505,29 @@
   VssRayContainer::iterator it = vssRays.begin();
 
+  for (i=0; i < mDistributions.size(); i++) {
+	mDistributions[i]->mContribution = 0;
+	mDistributions[i]->mRays = 0;
+  }
+
   for(; it != vssRays.end(); ++it) {
 	VssRay *ray = *it;
-	for (i=0; i < mDistributions.size()-1; i++)
+	for (i=0; i < mDistributions.size()-1; i++) {
 	  if (mDistributions[i]->mType == ray->mDistribution)
 		break;
+	}
+ 
 	float contribution =
-	  mPreprocessor.mViewCellsManager->ComputeSampleContributions(vssRays, true, false);
+	  mPreprocessor.mViewCellsManager->ComputeSampleContribution(*ray, true, false);
 	mDistributions[i]->mContribution += contribution;
 	mDistributions[i]->mRays ++;
+
+	mDistributions[i]->mTotalContribution += contribution;
+	mDistributions[i]->mTotalRays ++;
   }
 
   // now update the distributions with all the rays
-  for (i=0; i < mDistributions.size(); i++)
+  for (i=0; i < mDistributions.size(); i++) {
 	mDistributions[i]->Update(vssRays);
+  }
   
   
@@ -531,11 +542,27 @@
   int i;
   for (i=0; i < mDistributions.size(); i++) {
-	float importance = mDistributions[i]->mContribution/mDistributions[i]->mRays;
+	cout<<i<<": c="<<mDistributions[i]->mContribution<<
+	  " rays="<<mDistributions[i]->mRays<<endl;
+	float importance = 0.0f;
+	if (mDistributions[i]->mRays != 0) {
+	  importance = pow(mDistributions[i]->mContribution/mDistributions[i]->mRays, 3);
+	}
+	if (importance < Limits::Small)
+	  importance = Limits::Small;
 	mDistributions[i]->mRatio = importance;
 	sum += importance;
   }
-  
+
+  const float minratio = 0.05f;
+  float threshold = minratio*sum;
+  for (i=0; i < mDistributions.size(); i++) {
+	if (mDistributions[i]->mRatio < threshold) {
+	  sum += threshold - mDistributions[i]->mRatio;
+	  mDistributions[i]->mRatio = threshold;
+	}
+  }
   
   mDistributions[0]->mRatio /= sum;
+	
   for (i=1; i < mDistributions.size(); i++) {
 	float r = mDistributions[i]->mRatio / sum;
@@ -548,5 +575,53 @@
   cout<<endl;
 }
-}
-
-
+
+
+
+bool
+MixtureDistribution::Construct(char *str)
+{
+  char *curr = str;
+
+  while (1) {
+	char *e = strchr(curr,'+');
+	if (e!=NULL) {
+	  *e=0;
+	}
+	
+	if (strcmp(curr, "rss")==0) {
+	  mDistributions.push_back(new RssBasedDistribution(mPreprocessor));
+	} else
+	  if (strcmp(curr, "object")==0) {
+		mDistributions.push_back(new ObjectBasedDistribution(mPreprocessor));
+	  } else
+		if (strcmp(curr, "spatial")==0) {
+		  mDistributions.push_back(new SpatialBoxBasedDistribution(mPreprocessor));
+		} else
+		  if (strcmp(curr, "global")==0) {
+			mDistributions.push_back(new GlobalLinesDistribution(mPreprocessor));
+		  } else
+			if (strcmp(curr, "direction")==0) {
+			  mDistributions.push_back(new DirectionBasedDistribution(mPreprocessor));
+			} else
+			  if (strcmp(curr, "object_direction")==0) {
+				mDistributions.push_back(new ObjectDirectionBasedDistribution(mPreprocessor));
+			  } else
+				if (strcmp(curr, "reverse_object")==0) {
+				  mDistributions.push_back(new ReverseObjectBasedDistribution(mPreprocessor));
+				} else
+				  if (strcmp(curr, "reverse_viewspace_border")==0) {
+					mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(mPreprocessor));
+				  } 
+	
+	if (e==NULL)
+	  break;
+	curr = e+1;
+  }
+
+  Init();
+  return true;
+}
+
+}
+
+
