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

Revision 749, 12.7 KB checked in by bittner, 18 years ago (diff)

ply parser support

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