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

Revision 752, 15.1 KB checked in by mattausch, 18 years ago (diff)

after rendering workshop submissioin
x3dparser can use def - use constructs
implemented improved evaluation (samples are only stored in leaves, only propagate pvs size)

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 "VspKdTree.h"
12#include "RenderSimulator.h"
13#include "GlRenderer.h"
14#include "PlyParser.h"
15
16Preprocessor *preprocessor;
17
18
19static void AddGeometry(SceneGraph *scene)
20{
21        scene->mRoot->UpdateBox();
22
23        AxisAlignedBox3 sceneBox = scene->GetBox();
24
25        int n = 200;
26
27        if (0){
28        // form figure
29        for (int i = 0; i < n; ++ i)
30        {
31                for (int j = 0; j < n; ++ j)
32                {
33                        const Vector3 scale2((float)j * 0.8 / n + 0.1,  0.05, (float)i * 0.8  / (float)n + 0.1);
34               
35                        Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
36               
37                        Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
38                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
39                        Mesh *mesh = CreateBox(box);
40
41                        mesh->Preprocess();
42               
43                        MeshInstance *mi = new MeshInstance(mesh);
44                        scene->mRoot->mGeometry.push_back(mi);
45                }
46        }
47
48        for (int i = 0; i < n; ++ i)
49        {
50                for (int j = 0; j < n; ++ j)
51                {
52                        const Vector3 scale2(0.15, (float)j * 0.8 / n + 0.1, (float)i * 0.8  / (float)n + 0.1);
53               
54                        Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
55               
56                        Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
57                        AxisAlignedBox3 box(pt2, pt2 + boxSize);
58                        Mesh *mesh = CreateBox(box);
59
60                        mesh->Preprocess();
61               
62                        MeshInstance *mi = new MeshInstance(mesh);
63                        scene->mRoot->mGeometry.push_back(mi);
64                }
65        }
66
67        for (int i = 0; i < n; ++ i)
68        {
69                const Vector3 scale2(2, 0.2, (float)i * 0.8  / (float)n + 0.1);
70               
71                Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
72               
73                //Vector3 boxSize = sceneBox.Size() * Vector3(0.0025, 0.01, 0.0025);
74                Vector3 boxSize = sceneBox.Size() * Vector3(0.005, 0.02, 0.005);
75                AxisAlignedBox3 box(pt2 + 0.1, pt2 + boxSize);
76                Mesh *mesh = CreateBox(box);
77
78                mesh->Preprocess();
79               
80                MeshInstance *mi = new MeshInstance(mesh);
81                scene->mRoot->mGeometry.push_back(mi);
82        }
83       
84        scene->mRoot->UpdateBox();
85        }
86// plane separating areas
87if(1)
88{
89const Vector3 scale(1.0, 0.0, 0);
90
91    Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
92
93        Plane3 cuttingPlane(Vector3(1, 0, 0), pt);
94       
95        Mesh *planeMesh = new Mesh();
96       
97        Polygon3 *poly = sceneBox.CrossSection(cuttingPlane);
98
99        poly->AddToMesh(*planeMesh);
100
101        planeMesh->Preprocess();
102
103    MeshInstance *planeMi = new MeshInstance(planeMesh);
104    scene->mRoot->mGeometry.push_back(planeMi);
105}       
106}
107
108
109Preprocessor::Preprocessor():
110mKdTree(NULL),
111mBspTree(NULL),
112mVspKdTree(NULL),
113mVspBspTree(NULL),
114mViewCellsManager(NULL)
115{
116  environment->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
117 
118  // renderer will be constructed when the scene graph and viewcell manager will be known
119  renderer = NULL;
120 
121  environment->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
122  environment->GetBoolValue("Preprocessor.loadPolygonsAsMeshes", mLoadPolygonsAsMeshes);
123  environment->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
124  environment->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
125  environment->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
126 
127  Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
128  Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
129
130}
131
132
133Preprocessor::~Preprocessor()
134{
135  cout << "cleaning up" << endl;
136
137  cout << "Deleting view cells manager ... \n";
138  DEL_PTR(mViewCellsManager);
139  cout << "done.\n";
140
141  cout << "Deleting bsp tree ... \n";
142  DEL_PTR(mBspTree);
143  cout << "done.\n";
144
145  cout<<"Deleting kd tree...\n";
146  DEL_PTR(mKdTree);
147  cout<<"done.\n";
148 
149  cout<<"Deleting vspkd tree...\n";
150  DEL_PTR(mVspKdTree);
151  cout<<"done.\n";
152
153  cout<<"Deleting vspbsp tree...\n";
154  DEL_PTR(mVspBspTree);
155  cout<<"done.\n";
156}
157
158int
159SplitFilenames(const string str, vector<string> &filenames)
160{
161        int pos = 0;
162
163        while(1) {
164                int npos = (int)str.find(';', pos);
165               
166                if (npos < 0 || npos - pos < 1)
167                        break;
168                filenames.push_back(string(str, pos, npos - pos));
169                pos = npos + 1;
170        }
171       
172        filenames.push_back(string(str, pos, str.size() - pos));
173        return (int)filenames.size();
174}
175
176
177bool
178Preprocessor::LoadScene(const string filename)
179{
180        // use leaf nodes of the original spatial hiearrchy as occludees
181        mSceneGraph = new SceneGraph;
182 
183        Parser *parser;
184        vector<string> filenames;
185        int files = SplitFilenames(filename, filenames);
186        cout << "number of input files: " << files << endl;
187        bool result = false;
188        if (files == 1) {
189               
190                if (strstr(filename.c_str(), ".x3d"))
191                  parser = new X3dParser;
192                else
193                  if (strstr(filename.c_str(), ".ply"))
194                        parser = new PlyParser;
195                  else
196                        parser = new UnigraphicsParser;
197
198                cout<<filename<<endl;
199                result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
200
201                delete parser;
202
203        } else {
204                // root for different files
205                mSceneGraph->mRoot = new SceneGraphNode;
206                for (int i= 0; i < filenames.size(); i++) {
207                        if (strstr(filenames[i].c_str(), ".x3d"))
208                                parser = new X3dParser;
209                        else
210                                parser = new UnigraphicsParser;
211                       
212                        SceneGraphNode *node;
213                        if (parser->ParseFile(filenames[i], &node)) {
214                                mSceneGraph->mRoot->mChildren.push_back(node);
215                                // at least one file parsed
216                                result = true;
217                        }
218                        delete parser;
219                }
220        }
221       
222
223        if (result)
224                {
225                // HACK
226                //AddGeometry(mSceneGraph);
227          mSceneGraph->AssignObjectIds();
228               
229          int intersectables, faces;
230          mSceneGraph->GetStatistics(intersectables, faces);
231
232          cout<<filename<<" parsed successfully."<<endl;
233          cout<<"#NUM_OBJECTS (Total numner of objects)\n"<<intersectables<<endl;
234          cout<<"#NUM_FACES (Total numner of faces)\n"<<faces<<endl;
235          mSceneGraph->CollectObjects(&mObjects);
236          mSceneGraph->mRoot->UpdateBox();
237
238         /* Exporter *exporter = Exporter::GetExporter("testload.x3d");
239
240          if (exporter)
241          {
242                  exporter->ExportGeometry(mObjects);
243                  delete exporter;
244          }*/
245
246        }
247       
248       
249        return result;
250}
251
252bool
253Preprocessor::ExportPreprocessedData(const string filename)
254{
255  return false;
256}
257
258bool
259Preprocessor::BuildKdTree()
260{
261  mKdTree = new KdTree;
262  // add mesh instances of the scene graph to the root of the tree
263  KdLeaf *root = (KdLeaf *)mKdTree->GetRoot();
264  mSceneGraph->CollectObjects(&root->mObjects);
265 
266  mKdTree->Construct();
267  return true;
268}
269
270void
271Preprocessor::KdTreeStatistics(ostream &s)
272{
273  s<<mKdTree->GetStatistics();
274}
275
276void
277Preprocessor::BspTreeStatistics(ostream &s)
278{
279        s << mBspTree->GetStatistics();
280}
281
282bool
283Preprocessor::Export( const string filename,
284                                          const bool scene,
285                                          const bool kdtree,
286                                          const bool bsptree
287                                          )
288{
289  Exporter *exporter = Exporter::GetExporter(filename);
290       
291  if (exporter) {
292    if (scene)
293      exporter->ExportScene(mSceneGraph->mRoot);
294
295    if (kdtree) {
296      exporter->SetWireframe();
297      exporter->ExportKdTree(*mKdTree);
298    }
299
300        if (bsptree) {
301                //exporter->SetWireframe();
302                exporter->ExportBspTree(*mBspTree);
303        }
304
305    delete exporter;
306    return true;
307  }
308
309  return false;
310}
311
312
313bool Preprocessor::PrepareViewCells()
314{
315        //-- parse view cells construction method
316        environment->GetBoolValue("ViewCells.loadFromFile", mLoadViewCells);
317        char buf[100];
318       
319        if (mLoadViewCells)
320        {
321                environment->GetStringValue("ViewCells.filename", buf);
322                mViewCellsManager = ViewCellsManager::LoadViewCells(buf, &mObjects);
323        }
324        else
325        {
326                //-- parse type of view cell container
327                char viewCellsStr[64];
328                environment->GetStringValue("ViewCells.type", viewCellsStr);
329            mViewCellsManager = CreateViewCellsManager(viewCellsStr);
330        }
331
332        float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
333
334        environment->GetFloatValue("Simulation.objRenderCost",objRenderCost);
335        environment->GetFloatValue("Simulation.vcOverhead", vcOverhead);
336        environment->GetFloatValue("Simulation.moveSpeed", moveSpeed);
337       
338        mRenderSimulator =
339                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
340
341        mViewCellsManager->SetRenderer(mRenderSimulator);
342
343
344        if (mUseGlRenderer || mUseGlDebugger)
345        {
346                // NOTE: render texture should be power of 2 and square
347                // renderer must be initialised
348                renderer = new GlRendererBuffer(1024, 768, mSceneGraph, mViewCellsManager, mKdTree);
349                //              renderer->makeCurrent();
350               
351        }
352       
353        return true;
354}
355
356
357ViewCellsManager *Preprocessor::CreateViewCellsManager(const char *name)
358{
359        if (strcmp(name, "kdTree") == 0)
360        {
361                mViewCellsManager = new KdViewCellsManager(mKdTree);
362        }
363        else if (strcmp(name, "bspTree") == 0)
364        {
365                Debug << "view cell type: Bsp" << endl;
366
367                mBspTree = new BspTree();
368                mViewCellsManager = new BspViewCellsManager(mBspTree);
369        }
370        else if (strcmp(name, "vspBspTree") == 0)
371        {
372                Debug << "view cell type: VspBsp" << endl;
373
374                mVspBspTree = new VspBspTree();
375                mViewCellsManager = new VspBspViewCellsManager(mVspBspTree);
376        }
377        else if (strcmp(name, "vspKdTree") == 0)
378        {
379                mVspKdTree = new VspKdTree();           
380       
381                mViewCellsManager = new VspKdViewCellsManager(mVspKdTree);
382        }
383        else if (strcmp(name, "sceneDependent") == 0)
384        {
385                //TODO
386                mBspTree = new BspTree();
387
388                Debug << "view cell type: Bsp" << endl;
389               
390                mViewCellsManager = new BspViewCellsManager(mBspTree);
391        }
392        else
393        {
394                cerr << "Wrong view cells type " << name << "!!!" << endl;
395                exit(1);
396        }
397
398        return mViewCellsManager;
399}
400
401
402// use ascii format to store rays
403#define USE_ASCII 0
404
405
406inline bool ilt(Intersectable *obj1, Intersectable *obj2)
407{
408        return obj1->mId < obj2->mId;
409}
410
411
412bool Preprocessor::LoadSamples(VssRayContainer &samples,
413                                                           ObjectContainer &objects) const
414{
415        std::stable_sort(objects.begin(), objects.end(), ilt);
416        char fileName[100];
417        environment->GetStringValue("Preprocessor.samplesFilename", fileName);
418       
419    Vector3 origin, termination;
420        // HACK: needed only for lower_bound algorithm to find the
421        // intersected objects
422        MeshInstance sObj(NULL);
423        MeshInstance tObj(NULL);
424
425#if USE_ASCII
426        ifstream samplesIn(fileName);
427        if (!samplesIn.is_open())
428                return false;
429
430        string buf;
431        while (!(getline(samplesIn, buf)).eof())
432        {
433                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
434                           &origin.x, &origin.y, &origin.z,
435                           &termination.x, &termination.y, &termination.z,
436                           &(sObj.mId), &(tObj.mId));
437               
438                Intersectable *sourceObj = NULL;
439                Intersectable *termObj = NULL;
440               
441                if (sObj.mId >= 0)
442                {
443                        ObjectContainer::iterator oit =
444                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
445                        sourceObj = *oit;
446                }
447               
448                if (tObj.mId >= 0)
449                {
450                        ObjectContainer::iterator oit =
451                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
452                        termObj = *oit;
453                }
454
455                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
456        }
457#else
458        ifstream samplesIn(fileName, ios::binary);
459        if (!samplesIn.is_open())
460                return false;
461
462        while (1)
463        {
464                 samplesIn.read(reinterpret_cast<char *>(&origin), sizeof(Vector3));
465                 samplesIn.read(reinterpret_cast<char *>(&termination), sizeof(Vector3));
466                 samplesIn.read(reinterpret_cast<char *>(&(sObj.mId)), sizeof(int));
467                 samplesIn.read(reinterpret_cast<char *>(&(tObj.mId)), sizeof(int));
468               
469                 if (samplesIn.eof())
470                        break;
471
472                Intersectable *sourceObj = NULL;
473                Intersectable *termObj = NULL;
474               
475                if (sObj.mId >= 0)
476                {
477                        ObjectContainer::iterator oit =
478                                lower_bound(objects.begin(), objects.end(), &sObj, ilt);
479                        sourceObj = *oit;
480                }
481               
482                if (tObj.mId >= 0)
483                {
484                        ObjectContainer::iterator oit =
485                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
486                        termObj = *oit;
487                }
488
489                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
490        }
491
492#endif
493        samplesIn.close();
494
495        return true;
496}
497
498
499bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
500{
501        char fileName[100];
502        environment->GetStringValue("Preprocessor.samplesFilename", fileName);
503       
504
505        VssRayContainer::const_iterator it, it_end = samples.end();
506       
507#if USE_ASCII
508        ofstream samplesOut(fileName);
509        if (!samplesOut.is_open())
510                return false;
511
512        for (it = samples.begin(); it != it_end; ++ it)
513        {
514                VssRay *ray = *it;
515                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
516                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
517
518                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
519                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
520                                   << sourceid << " " << termid << "\n";
521        }
522#else
523        ofstream samplesOut(fileName, ios::binary);
524        if (!samplesOut.is_open())
525                return false;
526
527        for (it = samples.begin(); it != it_end; ++ it)
528        {       
529                VssRay *ray = *it;
530                Vector3 origin(ray->GetOrigin());
531                Vector3 termination(ray->GetTermination());
532               
533                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
534                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;               
535
536                samplesOut.write(reinterpret_cast<char *>(&origin), sizeof(Vector3));
537                samplesOut.write(reinterpret_cast<char *>(&termination), sizeof(Vector3));
538                samplesOut.write(reinterpret_cast<char *>(&sourceid), sizeof(int));
539                samplesOut.write(reinterpret_cast<char *>(&termid), sizeof(int));
540    }
541#endif
542        samplesOut.close();
543        return true;
544}
545
546
547
548bool
549Preprocessor::GenerateRays(
550                                                   const int number,
551                                                   const int sampleType,
552                                                   SimpleRayContainer &rays
553                                                   )
554{
555  Vector3 origin, direction;
556  int startSize = rays.size();
557  for (int i=0; rays.size() - startSize  < number; i++) {
558        // now get the direction
559        switch (sampleType) {
560        case OBJECT_BASED_DISTRIBUTION: {
561          mViewCellsManager->GetViewPoint(origin);
562          Vector3 point;
563          Vector3 normal;
564          int i = RandomValue(0, mObjects.size() - 1);
565          Intersectable *object = mObjects[i];
566          object->GetRandomSurfacePoint(point, normal);
567          direction = point - origin;
568        }
569          break;
570        case OBJECT_DIRECTION_BASED_DISTRIBUTION: {
571          int i = RandomValue(0, mObjects.size() - 1);
572          Intersectable *object = mObjects[i];
573          Vector3 normal;
574          object->GetRandomSurfacePoint(origin, normal);
575          direction = UniformRandomVector(normal);
576          origin += 0.1f*direction;
577        }
578          break;
579        case DIRECTION_BASED_DISTRIBUTION:
580          mViewCellsManager->GetViewPoint(origin);
581          direction = UniformRandomVector();
582          break;
583        case DIRECTION_BOX_BASED_DISTRIBUTION: {
584          mViewCellsManager->GetViewPoint(origin);
585          float alpha = RandomValue(0.0f, 2*M_PI);
586          float beta = RandomValue(-M_PI/2, M_PI/2);
587          direction = VssRay::GetDirection(alpha, beta);
588          break;
589        }
590        case SPATIAL_BOX_BASED_DISTRIBUTION:
591          mViewCellsManager->GetViewPoint(origin);
592          direction = mKdTree->GetBox().GetRandomPoint() - origin;
593          break;
594        default:
595          // unsuported distribution type
596          return false;
597        }
598        // $$ jb the pdf is yet not correct for all sampling methods!
599        float pdf = 1.0f;
600        float c = Magnitude(direction);
601        if (c > Limits::Small) {
602          direction*=1.0f/c;
603          rays.AddRay(SimpleRay(origin, direction, pdf));
604        }
605  }
606  return true;
607}
Note: See TracBrowser for help on using the repository browser.