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

RevLine 
[372]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"
[439]8#include "ViewCellsManager.h"
[445]9#include "ViewCellBsp.h"
10#include "VspBspTree.h"
11#include "VspKdTree.h"
[469]12#include "RenderSimulator.h"
[496]13#include "GlRenderer.h"
[749]14#include "PlyParser.h"
[372]15
[863]16namespace GtpVisibilityPreprocessor {
[860]17
18
[492]19Preprocessor *preprocessor;
20
[750]21
[840]22// HACK
[750]23static void AddGeometry(SceneGraph *scene)
24{
[752]25        scene->mRoot->UpdateBox();
26
[750]27        AxisAlignedBox3 sceneBox = scene->GetBox();
28
29        int n = 200;
30
31        if (0){
[840]32        // form grid of boxes
[750]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               
[840]39                        const Vector3 pt2 = sceneBox.Min() + scale2 * (sceneBox.Max() - sceneBox.Min());
[750]40               
[840]41                        const Vector3 boxSize = sceneBox.Size() * Vector3(0.0025f, 0.01f, 0.0025f);
[750]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       
[840]91        // plane separating view space regions
92        if (1)
93        {
94                const Vector3 scale(1.0, 0.0, 0);
[750]95
[840]96                Vector3 pt = sceneBox.Min() + scale * (sceneBox.Max() - sceneBox.Min());
[750]97
[840]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        }       
[750]109}
110
111
[372]112Preprocessor::Preprocessor():
113mKdTree(NULL),
[409]114mBspTree(NULL),
[422]115mVspKdTree(NULL),
[445]116mVspBspTree(NULL),
[439]117mViewCellsManager(NULL)
[308]118{
[840]119        environment->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
[538]120 
[840]121        // renderer will be constructed when the scene graph and viewcell manager will be known
122        renderer = NULL;
[496]123 
[840]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);
[871]129        environment->GetBoolValue("Preprocessor.exportVisibility", mExportVisibility );
[599]130
[871]131        char buffer[256];
132        environment->GetStringValue("Preprocessor.visibilityFile",  buffer);
133        mVisibilityFileName = buffer;
[878]134        environment->GetBoolValue("Preprocessor.applyVisibilityFilter", mApplyVisibilityFilter );
135        environment->GetFloatValue("Preprocessor.visibilityFilterWidth", mVisibilityFilterWidth);
136
[840]137        Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
138        Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
[372]139}
140
141
142Preprocessor::~Preprocessor()
143{
[752]144  cout << "cleaning up" << endl;
145
146  cout << "Deleting view cells manager ... \n";
[496]147  DEL_PTR(mViewCellsManager);
[752]148  cout << "done.\n";
149
150  cout << "Deleting bsp tree ... \n";
[496]151  DEL_PTR(mBspTree);
[752]152  cout << "done.\n";
153
[840]154  cout << "Deleting kd tree...\n";
[496]155  DEL_PTR(mKdTree);
[840]156  cout << "done.\n";
[752]157 
[840]158  cout << "Deleting vspkd tree...\n";
[496]159  DEL_PTR(mVspKdTree);
[840]160  cout << "done.\n";
[752]161
[840]162  cout << "Deleting vspbsp tree...\n";
[496]163  DEL_PTR(mVspBspTree);
[840]164  cout << "done.\n";
[372]165}
166
[387]167int
[419]168SplitFilenames(const string str, vector<string> &filenames)
[387]169{
170        int pos = 0;
171
172        while(1) {
[469]173                int npos = (int)str.find(';', pos);
[387]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));
[440]182        return (int)filenames.size();
[387]183}
184
[750]185
[372]186bool
187Preprocessor::LoadScene(const string filename)
188{
[508]189        // use leaf nodes of the original spatial hiearrchy as occludees
190        mSceneGraph = new SceneGraph;
[372]191 
[508]192        Parser *parser;
[387]193        vector<string> filenames;
194        int files = SplitFilenames(filename, filenames);
[712]195        cout << "number of input files: " << files << endl;
[387]196        bool result = false;
197        if (files == 1) {
198               
199                if (strstr(filename.c_str(), ".x3d"))
[749]200                  parser = new X3dParser;
[387]201                else
[811]202                  if (strstr(filename.c_str(), ".ply") || strstr(filename.c_str(), ".plb"))
[749]203                        parser = new PlyParser;
204                  else
[387]205                        parser = new UnigraphicsParser;
[372]206
[387]207                cout<<filename<<endl;
[658]208                result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
[372]209
[387]210                delete parser;
[372]211
[387]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        }
[372]230       
231
[752]232        if (result)
233                {
234                // HACK
235                //AddGeometry(mSceneGraph);
[492]236          mSceneGraph->AssignObjectIds();
[752]237               
[492]238          int intersectables, faces;
239          mSceneGraph->GetStatistics(intersectables, faces);
[752]240
[492]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);
[752]245          mSceneGraph->mRoot->UpdateBox();
[658]246
[659]247         /* Exporter *exporter = Exporter::GetExporter("testload.x3d");
[658]248
[659]249          if (exporter)
250          {
251                  exporter->ExportGeometry(mObjects);
252                  delete exporter;
253          }*/
[658]254
[387]255        }
[372]256       
[492]257       
258        return result;
[372]259}
260
261bool
262Preprocessor::ExportPreprocessedData(const string filename)
263{
[871]264 
265  mViewCellsManager->ExportViewCells(filename,
266                                                                         true);
267 
268  return true;
[372]269}
270
271bool
[871]272Preprocessor::PostProcessVisibility()
273{
274 
275  if (mApplyVisibilityFilter) {
276        cout<<"Applying visibility filter...";
[878]277        cout<<"filyter width = "<<mVisibilityFilterWidth<<endl;
278
[871]279        mViewCellsManager->ApplyFilter(mKdTree,
[878]280                                                                   mVisibilityFilterWidth,
281                                                                   mVisibilityFilterWidth);
[871]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
[372]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,
[492]319                                          const bool scene,
320                                          const bool kdtree,
321                                          const bool bsptree
322                                          )
[372]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}
[429]346
[508]347
[463]348bool Preprocessor::PrepareViewCells()
349{
[577]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        }
[439]366
[473]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);
[694]372       
[473]373        mRenderSimulator =
374                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
[440]375
[480]376        mViewCellsManager->SetRenderer(mRenderSimulator);
[440]377
[574]378
[538]379        if (mUseGlRenderer || mUseGlDebugger)
[540]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);
[556]384                //              renderer->makeCurrent();
[746]385               
[540]386        }
[496]387       
[463]388        return true;
[490]389}
390
391
[575]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
[577]402                mBspTree = new BspTree();
[575]403                mViewCellsManager = new BspViewCellsManager(mBspTree);
404        }
405        else if (strcmp(name, "vspBspTree") == 0)
406        {
407                Debug << "view cell type: VspBsp" << endl;
408
[870]409                mVspBspTree = new VspBspTree(environment);
[575]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        {
[664]429                cerr << "Wrong view cells type " << name << "!!!" << endl;
[575]430                exit(1);
431        }
432
433        return mViewCellsManager;
434}
435
436
[491]437// use ascii format to store rays
438#define USE_ASCII 0
439
440
[490]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       
[491]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);
[490]459
[491]460#if USE_ASCII
[656]461        ifstream samplesIn(fileName);
[490]462        if (!samplesIn.is_open())
463                return false;
464
465        string buf;
466        while (!(getline(samplesIn, buf)).eof())
467        {
[491]468                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
[490]469                           &origin.x, &origin.y, &origin.z,
[491]470                           &termination.x, &termination.y, &termination.z,
471                           &(sObj.mId), &(tObj.mId));
[490]472               
[491]473                Intersectable *sourceObj = NULL;
474                Intersectable *termObj = NULL;
475               
476                if (sObj.mId >= 0)
[490]477                {
478                        ObjectContainer::iterator oit =
[491]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                }
[490]489
[491]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;
[490]515                }
[491]516               
517                if (tObj.mId >= 0)
[490]518                {
[491]519                        ObjectContainer::iterator oit =
520                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
521                        termObj = *oit;
[490]522                }
[491]523
524                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
[490]525        }
[491]526
527#endif
[490]528        samplesIn.close();
529
530        return true;
531}
532
[508]533
534bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
[490]535{
[491]536        char fileName[100];
537        environment->GetStringValue("Preprocessor.samplesFilename", fileName);
538       
[490]539
540        VssRayContainer::const_iterator it, it_end = samples.end();
541       
[491]542#if USE_ASCII
543        ofstream samplesOut(fileName);
[490]544        if (!samplesOut.is_open())
545                return false;
546
547        for (it = samples.begin(); it != it_end; ++ it)
548        {
549                VssRay *ray = *it;
[491]550                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
551                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
552
[490]553                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
554                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
[491]555                                   << sourceid << " " << termid << "\n";
[490]556        }
[491]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
[490]577        samplesOut.close();
578        return true;
579}
[563]580
581
582
583bool
584Preprocessor::GenerateRays(
585                                                   const int number,
586                                                   const int sampleType,
587                                                   SimpleRayContainer &rays
588                                                   )
589{
590  Vector3 origin, direction;
[837]591  int startSize = (int)rays.size();
592  for (int i=0; (int)rays.size() - startSize  < number; i ++) {
[563]593        // now get the direction
594        switch (sampleType) {
595        case OBJECT_BASED_DISTRIBUTION: {
[576]596          mViewCellsManager->GetViewPoint(origin);
[563]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;
[576]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;
[563]614        case DIRECTION_BASED_DISTRIBUTION:
[576]615          mViewCellsManager->GetViewPoint(origin);
[563]616          direction = UniformRandomVector();
617          break;
618        case DIRECTION_BOX_BASED_DISTRIBUTION: {
[576]619          mViewCellsManager->GetViewPoint(origin);
[563]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:
[576]626          mViewCellsManager->GetViewPoint(origin);
[563]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}
[860]643
[878]644}
Note: See TracBrowser for help on using the repository browser.