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

Revision 878, 16.1 KB checked in by bittner, 18 years ago (diff)

mesh inntersection bug fixed

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