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

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