source: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp @ 1201

Revision 1201, 19.0 KB checked in by mattausch, 18 years ago (diff)

added loader for osp trees

Line 
1#include "SceneGraph.h"
2#include "Exporter.h"
3#include "UnigraphicsParser.h"
4#include "X3dParser.h"
5#include "Preprocessor.h"
6#include "ViewCell.h"
7#include "Environment.h"
8#include "ViewCellsManager.h"
9#include "ViewCellBsp.h"
10#include "VspBspTree.h"
11#include "RenderSimulator.h"
12#include "GlRenderer.h"
13#include "PlyParser.h"
14#include "SamplingStrategy.h"
15#include "VspOspTree.h"
16
17
18
19namespace GtpVisibilityPreprocessor {
20
21const static bool ADDITIONAL_GEOMETRY_HACK = false;
22
23//Preprocessor *preprocessor;
24
25
26// HACK: Artificially modify scene to watch rendercost changes
27static void AddGeometry(SceneGraph *scene)
28{
29        scene->mRoot->UpdateBox();
30
31        AxisAlignedBox3 sceneBox = scene->GetBox();
32
33        int n = 200;
34
35        if (0){
36        // form grid of boxes
37        for (int i = 0; i < n; ++ i)
38        {
39                for (int j = 0; j < n; ++ j)
40                {
41                        const Vector3 scale2((float)j * 0.8f / n + 0.1f,  0.05f, (float)i * 0.8f  / (float)n + 0.1f);
42               
43                        const Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
44               
45                        const Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
46                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
47                        Mesh *mesh = CreateMeshFromBox(box);
48
49                        mesh->Preprocess();
50               
51                        MeshInstance *mi = new MeshInstance(mesh);
52                        scene->mRoot->mGeometry.push_back(mi);
53                }
54        }
55
56        for (int i = 0; i < n; ++ i)
57        {
58                for (int j = 0; j < n; ++ j)
59                {
60                        const Vector3 scale2(0.15f, (float)j * 0.8f / n + 0.1f, (float)i * 0.8f  / (float)n + 0.1f);
61               
62                        Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
63               
64                        Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
65                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
66                        Mesh *mesh = CreateMeshFromBox(box);
67
68                        mesh->Preprocess();
69               
70                        MeshInstance *mi = new MeshInstance(mesh);
71                        scene->mRoot->mGeometry.push_back(mi);
72                }
73        }
74
75        for (int i = 0; i < n; ++ i)
76        {
77                const Vector3 scale2(2, 0.2f, (float)i * 0.8f  / (float)n + 0.1f);
78               
79                Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
80               
81                //Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
82                Vector3 boxSize = sceneBox.Size() * Vector3(0.005f, 0.02f, 0.005f);
83
84                AxisAlignedBox3 box(pt2 + 0.1f, pt2 + boxSize);
85                Mesh *mesh = CreateMeshFromBox(box);
86
87                mesh->Preprocess();
88               
89                MeshInstance *mi = new MeshInstance(mesh);
90                scene->mRoot->mGeometry.push_back(mi);
91        }
92       
93        scene->mRoot->UpdateBox();
94        }
95       
96        // plane separating view space regions
97        if (1)
98        {
99                const Vector3 scale(1.0f, 0.0, 0);
100
101                Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
102
103                Plane3 cuttingPlane(Vector3(1, 0, 0), pt);
104                Mesh *planeMesh = new Mesh();
105               
106                Polygon3 *poly = sceneBox.CrossSection(cuttingPlane);
107                IncludePolyInMesh(*poly, *planeMesh);
108               
109                planeMesh->Preprocess();
110               
111                MeshInstance *planeMi = new MeshInstance(planeMesh);
112                scene->mRoot->mGeometry.push_back(planeMi);
113        }       
114}
115
116
117Preprocessor::Preprocessor():
118mKdTree(NULL),
119mBspTree(NULL),
120mVspBspTree(NULL),
121mViewCellsManager(NULL),
122mRenderSimulator(NULL)
123{
124        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
125 
126        // renderer will be constructed when the scene graph and viewcell manager will be known
127        renderer = NULL;
128 
129        Environment::GetSingleton()->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
130        Environment::GetSingleton()->GetBoolValue("Preprocessor.loadPolygonsAsMeshes", mLoadPolygonsAsMeshes);
131        Environment::GetSingleton()->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
132        Environment::GetSingleton()->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
133        Environment::GetSingleton()->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
134        Environment::GetSingleton()->GetBoolValue("Preprocessor.exportVisibility", mExportVisibility );
135
136        char buffer[256];
137        Environment::GetSingleton()->GetStringValue("Preprocessor.visibilityFile",  buffer);
138        mVisibilityFileName = buffer;
139        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilityFilter", mApplyVisibilityFilter );
140        Environment::GetSingleton()->GetBoolValue("Preprocessor.applyVisibilitySpatialFilter",
141                                                          mApplyVisibilitySpatialFilter );
142        Environment::GetSingleton()->GetFloatValue("Preprocessor.visibilityFilterWidth", mVisibilityFilterWidth);
143
144        Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
145        Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
146}
147
148
149Preprocessor::~Preprocessor()
150{
151  cout << "cleaning up" << endl;
152
153  cout << "Deleting view cells manager ... \n";
154  DEL_PTR(mViewCellsManager);
155  cout << "done.\n";
156
157  cout << "Deleting bsp tree ... \n";
158  DEL_PTR(mBspTree);
159  cout << "done.\n";
160
161  cout << "Deleting kd tree...\n";
162  DEL_PTR(mKdTree);
163  cout << "done.\n";
164 
165  cout << "Deleting vsp tree...\n";
166  DEL_PTR(mVspTree);
167  cout << "done.\n";
168
169  cout << "Deleting osp tree...\n";
170  DEL_PTR(mOspTree);
171  cout << "done.\n";
172
173  cout << "Deleting vspbsp tree...\n";
174  DEL_PTR(mVspBspTree);
175  cout << "done.\n";
176
177   cout << "Deleting scene graph...\n";
178  DEL_PTR(mSceneGraph);
179  cout << "done.\n";
180
181  DEL_PTR(mRenderSimulator);
182  DEL_PTR(renderer);
183}
184
185int
186SplitFilenames(const string str, vector<string> &filenames)
187{
188        int pos = 0;
189
190        while(1) {
191                int npos = (int)str.find(';', pos);
192               
193                if (npos < 0 || npos - pos < 1)
194                        break;
195                filenames.push_back(string(str, pos, npos - pos));
196                pos = npos + 1;
197        }
198       
199        filenames.push_back(string(str, pos, str.size() - pos));
200        return (int)filenames.size();
201}
202
203
204bool
205Preprocessor::LoadScene(const string filename)
206{
207        // use leaf nodes of the original spatial hierarchy as occludees
208        mSceneGraph = new SceneGraph;
209 
210        Parser *parser;
211        vector<string> filenames;
212        int files = SplitFilenames(filename, filenames);
213        cout << "number of input files: " << files << endl;
214        bool result = false;
215        if (files == 1) {
216               
217                if (strstr(filename.c_str(), ".x3d"))
218                  parser = new X3dParser;
219                else
220                  if (strstr(filename.c_str(), ".ply") || strstr(filename.c_str(), ".plb"))
221                        parser = new PlyParser;
222                  else
223                        parser = new UnigraphicsParser;
224
225                cout<<filename<<endl;
226                result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
227
228                delete parser;
229
230        } else {
231                // root for different files
232                mSceneGraph->mRoot = new SceneGraphNode;
233                for (int i= 0; i < filenames.size(); i++) {
234                        if (strstr(filenames[i].c_str(), ".x3d"))
235                                parser = new X3dParser;
236                        else
237                                parser = new UnigraphicsParser;
238                       
239                        SceneGraphNode *node;
240                        if (parser->ParseFile(filenames[i], &node)) {
241                                mSceneGraph->mRoot->mChildren.push_back(node);
242                                // at least one file parsed
243                                result = true;
244                        }
245                        delete parser;
246                }
247        }
248       
249
250        if (result)
251        {
252                // HACK
253                if (ADDITIONAL_GEOMETRY_HACK)
254                        AddGeometry(mSceneGraph);
255               
256                mSceneGraph->AssignObjectIds();
257       
258                int intersectables, faces;
259                mSceneGraph->GetStatistics(intersectables, faces);
260       
261                cout<<filename<<" parsed successfully."<<endl;
262                cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<intersectables<<endl;
263                cout<<"#NUM_FACES (Total numner of faces)\n"<<faces<<endl;
264                mSceneGraph->CollectObjects(&mObjects);
265                mSceneGraph->mRoot->UpdateBox();
266
267                if (0)
268                {
269                        Exporter *exporter = Exporter::GetExporter("testload.x3d");
270
271                        if (exporter)
272                        {
273                                exporter->ExportGeometry(mObjects);
274                                delete exporter;
275                        }
276                }
277        }
278       
279       
280        return result;
281}
282
283bool
284Preprocessor::ExportPreprocessedData(const string filename)
285{
286 
287  mViewCellsManager->ExportViewCells(filename, true, mObjects);
288 
289  return true;
290}
291
292bool
293Preprocessor::PostProcessVisibility()
294{
295 
296  if (mApplyVisibilityFilter || mApplyVisibilitySpatialFilter) {
297        cout<<"Applying visibility filter ...";
298        cout<<"filter width = " << mVisibilityFilterWidth << endl;
299       
300        if (!mViewCellsManager)
301          return false;
302       
303        mViewCellsManager->ApplyFilter(mKdTree,
304                                                                   mApplyVisibilityFilter ? mVisibilityFilterWidth : -1.0f,
305                                                                   mApplyVisibilitySpatialFilter ? mVisibilityFilterWidth : -1.0f);
306        cout << "done." << endl;
307  }
308 
309  // export the preprocessed information to a file
310  if (mExportVisibility)
311        ExportPreprocessedData(mVisibilityFileName);
312 
313  return true;
314}
315
316
317bool
318Preprocessor::BuildKdTree()
319{
320  mKdTree = new KdTree;
321  // add mesh instances of the scene graph to the root of the tree
322  KdLeaf *root = (KdLeaf *)mKdTree->GetRoot();
323  mSceneGraph->CollectObjects(&root->mObjects);
324 
325  long startTime = GetTime();
326
327  cout << "building kd tree ... " << endl;
328  mKdTree->Construct();
329  cout << "construction finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs " << endl;
330  return true;
331}
332
333void
334Preprocessor::KdTreeStatistics(ostream &s)
335{
336  s<<mKdTree->GetStatistics();
337}
338
339void
340Preprocessor::BspTreeStatistics(ostream &s)
341{
342        s << mBspTree->GetStatistics();
343}
344
345bool
346Preprocessor::Export( const string filename,
347                                          const bool scene,
348                                          const bool kdtree,
349                                          const bool bsptree
350                                          )
351{
352  Exporter *exporter = Exporter::GetExporter(filename);
353       
354  if (exporter) {
355    if (scene)
356      exporter->ExportScene(mSceneGraph->mRoot);
357
358    if (kdtree) {
359      exporter->SetWireframe();
360      exporter->ExportKdTree(*mKdTree);
361    }
362
363        if (bsptree) {
364                //exporter->SetWireframe();
365                exporter->ExportBspTree(*mBspTree);
366        }
367
368    delete exporter;
369    return true;
370  }
371
372  return false;
373}
374
375
376bool Preprocessor::PrepareViewCells()
377{
378        //-- parse view cells construction method
379        Environment::GetSingleton()->GetBoolValue("ViewCells.loadFromFile", mLoadViewCells);
380        char buf[100];
381       
382        if (mLoadViewCells)
383        {       
384                Environment::GetSingleton()->GetStringValue("ViewCells.filename", buf);
385                mViewCellsManager = ViewCellsManager::LoadViewCells(buf, &mObjects, true);
386        }
387        else
388        {
389                //-- parse type of view cell container
390                Environment::GetSingleton()->GetStringValue("ViewCells.type", buf);             
391            mViewCellsManager = CreateViewCellsManager(buf);
392
393                // default view space is the extent of the scene
394                mViewCellsManager->SetViewSpaceBox(mSceneGraph->GetBox());
395
396
397        }
398       
399        //-- parameters for render heuristics evaluation
400        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
401
402        Environment::GetSingleton()->GetFloatValue("Simulation.objRenderCost",objRenderCost);
403        Environment::GetSingleton()->GetFloatValue("Simulation.vcOverhead", vcOverhead);
404        Environment::GetSingleton()->GetFloatValue("Simulation.moveSpeed", moveSpeed);
405       
406        mRenderSimulator =
407                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
408
409        mViewCellsManager->SetRenderer(mRenderSimulator);
410
411
412        if (mUseGlRenderer || mUseGlDebugger)
413        {
414                // NOTE: render texture should be power of 2 and square
415                // renderer must be initialised
416                // $$matt
417//              renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
418                //              renderer->makeCurrent();
419               
420        }
421       
422        return true;
423}
424
425
426ViewCellsManager *Preprocessor::CreateViewCellsManager(const char *name)
427{
428        if (strcmp(name, "kdTree") == 0)
429        {
430                mViewCellsManager = new KdViewCellsManager(mKdTree);
431        }
432        else if (strcmp(name, "bspTree") == 0)
433        {
434                Debug << "view cell type: Bsp" << endl;
435
436                mBspTree = new BspTree();
437                mViewCellsManager = new BspViewCellsManager(mBspTree);
438        }
439        else if (strcmp(name, "vspBspTree") == 0)
440        {
441                Debug << "view cell type: VspBsp" << endl;
442
443                mVspBspTree = new VspBspTree();
444                mViewCellsManager = new VspBspViewCellsManager(mVspBspTree);
445        }
446        else if (strcmp(name, "vspOspTree") == 0)
447        {
448                mVspTree = new VspTree();
449                mOspTree = new OspTree();
450               
451                // HACK for testing if per kd evaluation works!!
452                mOspTree = new OspTree(*mKdTree);
453
454                mViewCellsManager = new VspOspViewCellsManager(mVspTree, mOspTree);
455        }
456        else if (strcmp(name, "sceneDependent") == 0)
457        {
458                Debug << "view cell type: Bsp" << endl;
459
460                //TODO
461                mBspTree = new BspTree();
462                mViewCellsManager = new BspViewCellsManager(mBspTree);
463        }
464        else
465        {
466                cerr << "Wrong view cells type " << name << "!!!" << endl;
467                exit(1);
468        }
469
470        return mViewCellsManager;
471}
472
473
474// use ascii format to store rays
475#define USE_ASCII 0
476
477
478static inline bool ilt(Intersectable *obj1, Intersectable *obj2)
479{
480        return obj1->mId < obj2->mId;
481}
482
483
484bool Preprocessor::LoadKdTree()
485{
486        return true;
487}
488
489bool Preprocessor::ExportKdTree()
490{
491        return true;
492}
493
494
495bool Preprocessor::LoadSamples(VssRayContainer &samples,
496                                                           ObjectContainer &objects) const
497{
498        std::stable_sort(objects.begin(), objects.end(), ilt);
499        char fileName[100];
500        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
501       
502    Vector3 origin, termination;
503        // HACK: needed only for lower_bound algorithm to find the
504        // intersected objects
505        MeshInstance sObj(NULL);
506        MeshInstance tObj(NULL);
507
508#if USE_ASCII
509        ifstream samplesIn(fileName);
510        if (!samplesIn.is_open())
511                return false;
512
513        string buf;
514        while (!(getline(samplesIn, buf)).eof())
515        {
516                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
517                           &origin.x, &origin.y, &origin.z,
518                           &termination.x, &termination.y, &termination.z,
519                           &(sObj.mId), &(tObj.mId));
520               
521                Intersectable *sourceObj = NULL;
522                Intersectable *termObj = NULL;
523               
524                if (sObj.mId >= 0)
525                {
526                        ObjectContainer::iterator oit =
527                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
528                        sourceObj = *oit;
529                }
530               
531                if (tObj.mId >= 0)
532                {
533                        ObjectContainer::iterator oit =
534                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
535                        termObj = *oit;
536                }
537
538                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
539        }
540#else
541        ifstream samplesIn(fileName, ios::binary);
542        if (!samplesIn.is_open())
543                return false;
544
545        while (1)
546        {
547                 samplesIn.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
548                 samplesIn.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
549                 samplesIn.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
550                 samplesIn.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
551               
552                 if (samplesIn.eof())
553                        break;
554
555                Intersectable *sourceObj = NULL;
556                Intersectable *termObj = NULL;
557               
558                if (sObj.mId >= 0)
559                {
560                        ObjectContainer::iterator oit =
561                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
562                        sourceObj = *oit;
563                }
564               
565                if (tObj.mId >= 0)
566                {
567                        ObjectContainer::iterator oit =
568                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
569                        termObj = *oit;
570                }
571
572                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
573        }
574
575#endif
576        samplesIn.close();
577
578        return true;
579}
580
581
582bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
583{
584        char fileName[100];
585        Environment::GetSingleton()->GetStringValue("Preprocessor.samplesFilename", fileName);
586       
587
588        VssRayContainer::const_iterator it, it_end = samples.end();
589       
590#if USE_ASCII
591        ofstream samplesOut(fileName);
592        if (!samplesOut.is_open())
593                return false;
594
595        for (it = samples.begin(); it != it_end; ++ it)
596        {
597                VssRay *ray = *it;
598                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
599                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
600
601                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
602                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
603                                   << sourceid << " " << termid << "\n";
604        }
605#else
606        ofstream samplesOut(fileName, ios::binary);
607        if (!samplesOut.is_open())
608                return false;
609
610        for (it = samples.begin(); it != it_end; ++ it)
611        {       
612                VssRay *ray = *it;
613                Vector3 origin(ray->GetOrigin());
614                Vector3 termination(ray->GetTermination());
615               
616                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
617                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;               
618
619                samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
620                samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
621                samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
622                samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
623    }
624#endif
625        samplesOut.close();
626
627        return true;
628}
629
630#if 0 // matt: implemented interface samplestrategy
631bool
632Preprocessor::GenerateRays(
633                                                   const int number,
634                                                   const int sampleType,
635                                                   SimpleRayContainer &rays
636                                                   )
637{
638  Vector3 origin, direction;
639  int startSize = (int)rays.size();
640  for (int i=0; (int)rays.size() - startSize  < number; i ++) {
641        // now get the direction
642        switch (sampleType) {
643        case OBJECT_BASED_DISTRIBUTION: {
644          mViewCellsManager->GetViewPoint(origin);
645          Vector3 point;
646          Vector3 normal;
647          int i = RandomValue(0, mObjects.size() - 1);
648          Intersectable *object = mObjects[i];
649          object->GetRandomSurfacePoint(point, normal);
650          direction = point - origin;
651        }
652          break;
653        case OBJECT_DIRECTION_BASED_DISTRIBUTION: {
654          int i = RandomValue(0, mObjects.size() - 1);
655          Intersectable *object = mObjects[i];
656          Vector3 normal;
657          object->GetRandomSurfacePoint(origin, normal);
658          direction = UniformRandomVector(normal);
659          origin += 0.1f*direction;
660        }
661          break;
662        case DIRECTION_BASED_DISTRIBUTION:
663          mViewCellsManager->GetViewPoint(origin);
664          direction = UniformRandomVector();
665          break;
666        case DIRECTION_BOX_BASED_DISTRIBUTION: {
667          mViewCellsManager->GetViewPoint(origin);
668          float alpha = RandomValue(0.0f, 2*M_PI);
669          float beta = RandomValue(-M_PI/2, M_PI/2);
670          direction = VssRay::GetDirection(alpha, beta);
671          break;
672        }
673        case SPATIAL_BOX_BASED_DISTRIBUTION:
674          mViewCellsManager->GetViewPoint(origin);
675          direction = mKdTree->GetBox().GetRandomPoint() - origin;
676          break;
677        default:
678          // unsuported distribution type
679          return false;
680        }
681        // $$ jb the pdf is yet not correct for all sampling methods!
682        float pdf = 1.0f;
683        float c = Magnitude(direction);
684        if (c > Limits::Small) {
685          direction*=1.0f/c;
686          rays.AddRay(SimpleRay(origin, direction, pdf));
687        }
688  }
689  return true;
690}
691#endif
692bool Preprocessor::GenerateRays(const int number,
693                                                                const int sampleType,
694                                                                SimpleRayContainer &rays)
695{
696        Vector3 origin, direction;
697       
698        const int startSize = (int)rays.size();
699        SamplingStrategy *strategy = GenerateSamplingStrategy(sampleType);
700
701        if (!strategy)
702                return false;
703
704        for (int i=0; (int)rays.size() - startSize < number; ++ i)
705        {
706                SimpleRay newRay;
707                bool success = strategy->GenerateSample(newRay);
708
709                if (success)
710                        rays.AddRay(newRay);
711        }
712
713        delete strategy;
714
715    return true;
716}
717
718
719SamplingStrategy *Preprocessor::GenerateSamplingStrategy(const int strategyId) const
720{
721        switch (strategyId)
722        {
723        case OBJECT_BASED_DISTRIBUTION:
724                return new ObjectBasedDistribution(*this);
725        case OBJECT_DIRECTION_BASED_DISTRIBUTION:
726                return new ObjectDirectionBasedDistribution(*this);
727        case DIRECTION_BASED_DISTRIBUTION:
728                return new DirectionBasedDistribution(*this);
729        case DIRECTION_BOX_BASED_DISTRIBUTION:
730                return new DirectionBoxBasedDistribution(*this);
731        case SPATIAL_BOX_BASED_DISTRIBUTION:
732                return new SpatialBoxBasedDistribution(*this);
733        //case OBJECTS_INTERIOR_DISTRIBUTION:
734        //      return new ObjectsInteriorDistribution(*this);
735        default: // no valid strategy
736                return NULL;
737        }
738        // should never come here
739        return NULL;
740}
741
742
743}
Note: See TracBrowser for help on using the repository browser.