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

Revision 712, 12.6 KB checked in by mattausch, 19 years ago (diff)

added exporter for Vrml
added transformations to x3d loader

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