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

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