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

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

added exporter for Vrml
added transformations to x3d loader

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"
[372]14
[492]15Preprocessor *preprocessor;
16
[372]17Preprocessor::Preprocessor():
18mKdTree(NULL),
[409]19mBspTree(NULL),
[422]20mVspKdTree(NULL),
[445]21mVspBspTree(NULL),
[439]22mViewCellsManager(NULL)
[308]23{
[492]24  environment->GetBoolValue("Preprocessor.useGlRenderer", mUseGlRenderer);
[538]25 
[496]26  // renderer will be constructed when the scene graph and viewcell manager will be known
27  renderer = NULL;
28 
[538]29  environment->GetBoolValue("Preprocessor.useGlDebugger", mUseGlDebugger);
[658]30  environment->GetBoolValue("Preprocessor.loadPolygonsAsMeshes", mLoadPolygonsAsMeshes);
[599]31  environment->GetBoolValue("Preprocessor.quitOnFinish", mQuitOnFinish);
[685]32  environment->GetBoolValue("Preprocessor.computeVisibility", mComputeVisibility);
[694]33  environment->GetBoolValue("Preprocessor.detectEmptyViewSpace", mDetectEmptyViewSpace);
34 
35  Debug << "detect empty view space=" << mDetectEmptyViewSpace << endl;
[675]36  Debug << "load polygons as meshes: " << mLoadPolygonsAsMeshes << endl;
[599]37
[372]38}
39
40
41Preprocessor::~Preprocessor()
42{
[563]43  Debug<<"Deleting view cells manager...\n";
[496]44  DEL_PTR(mViewCellsManager);
[563]45  Debug<<"done.\n";
46  Debug<<"Deleting bsp tree...\n";
[496]47  DEL_PTR(mBspTree);
[563]48  Debug<<"done.\n";
49  Debug<<"Deleting kd tree...\n";
[496]50  DEL_PTR(mKdTree);
[563]51  Debug<<"done.\n";
52  Debug<<"Deleting vspkd tree...\n";
[496]53  DEL_PTR(mVspKdTree);
[563]54  Debug<<"done.\n";
55  Debug<<"Deleting vspbsp tree...\n";
[496]56  DEL_PTR(mVspBspTree);
[563]57  Debug<<"done.\n";
[372]58}
59
[387]60int
[419]61SplitFilenames(const string str, vector<string> &filenames)
[387]62{
63        int pos = 0;
64
65        while(1) {
[469]66                int npos = (int)str.find(';', pos);
[387]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));
[440]75        return (int)filenames.size();
[387]76}
77
[372]78bool
79Preprocessor::LoadScene(const string filename)
80{
[508]81        // use leaf nodes of the original spatial hiearrchy as occludees
82        mSceneGraph = new SceneGraph;
[372]83 
[508]84        Parser *parser;
[387]85        vector<string> filenames;
86        int files = SplitFilenames(filename, filenames);
[712]87        cout << "number of input files: " << files << endl;
[387]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;
[372]95
[387]96                cout<<filename<<endl;
[658]97                result = parser->ParseFile(filename, &mSceneGraph->mRoot, mLoadPolygonsAsMeshes);
[372]98
[387]99                delete parser;
[372]100
[387]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        }
[372]119       
120
[387]121        if (result) {
[492]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();
[658]131
[659]132         /* Exporter *exporter = Exporter::GetExporter("testload.x3d");
[658]133
[659]134          if (exporter)
135          {
136                  exporter->ExportGeometry(mObjects);
137                  delete exporter;
138          }*/
[658]139
[387]140        }
[372]141       
[492]142       
143        return result;
[372]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,
[492]178                                          const bool scene,
179                                          const bool kdtree,
180                                          const bool bsptree
181                                          )
[372]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}
[429]205
[508]206
[463]207bool Preprocessor::PrepareViewCells()
208{
[577]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        }
[439]225
[473]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);
[694]231       
[473]232        mRenderSimulator =
233                new RenderSimulator(mViewCellsManager, objRenderCost, vcOverhead, moveSpeed);
[440]234
[480]235        mViewCellsManager->SetRenderer(mRenderSimulator);
[440]236
[574]237
[538]238        if (mUseGlRenderer || mUseGlDebugger)
[540]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);
[556]243                //              renderer->makeCurrent();
[540]244        }
[496]245       
[463]246        return true;
[490]247}
248
249
[575]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
[577]260                mBspTree = new BspTree();
[575]261                mViewCellsManager = new BspViewCellsManager(mBspTree);
262        }
263        else if (strcmp(name, "vspBspTree") == 0)
264        {
265                Debug << "view cell type: VspBsp" << endl;
266
[577]267                mVspBspTree = new VspBspTree();
[575]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        {
[664]287                cerr << "Wrong view cells type " << name << "!!!" << endl;
[575]288                exit(1);
289        }
290
291        return mViewCellsManager;
292}
293
294
[491]295// use ascii format to store rays
296#define USE_ASCII 0
297
298
[490]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       
[491]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);
[490]317
[491]318#if USE_ASCII
[656]319        ifstream samplesIn(fileName);
[490]320        if (!samplesIn.is_open())
321                return false;
322
323        string buf;
324        while (!(getline(samplesIn, buf)).eof())
325        {
[491]326                sscanf(buf.c_str(), "%f %f %f %f %f %f %d %d",
[490]327                           &origin.x, &origin.y, &origin.z,
[491]328                           &termination.x, &termination.y, &termination.z,
329                           &(sObj.mId), &(tObj.mId));
[490]330               
[491]331                Intersectable *sourceObj = NULL;
332                Intersectable *termObj = NULL;
333               
334                if (sObj.mId >= 0)
[490]335                {
336                        ObjectContainer::iterator oit =
[491]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                }
[490]347
[491]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;
[490]373                }
[491]374               
375                if (tObj.mId >= 0)
[490]376                {
[491]377                        ObjectContainer::iterator oit =
378                                lower_bound(objects.begin(), objects.end(), &tObj, ilt);
379                        termObj = *oit;
[490]380                }
[491]381
382                samples.push_back(new VssRay(origin, termination, sourceObj, termObj));
[490]383        }
[491]384
385#endif
[490]386        samplesIn.close();
387
388        return true;
389}
390
[508]391
392bool Preprocessor::ExportSamples(const VssRayContainer &samples) const
[490]393{
[491]394        char fileName[100];
395        environment->GetStringValue("Preprocessor.samplesFilename", fileName);
396       
[490]397
398        VssRayContainer::const_iterator it, it_end = samples.end();
399       
[491]400#if USE_ASCII
401        ofstream samplesOut(fileName);
[490]402        if (!samplesOut.is_open())
403                return false;
404
405        for (it = samples.begin(); it != it_end; ++ it)
406        {
407                VssRay *ray = *it;
[491]408                int sourceid = ray->mOriginObject ? ray->mOriginObject->mId : -1;               
409                int termid = ray->mTerminationObject ? ray->mTerminationObject->mId : -1;       
410
[490]411                samplesOut << ray->GetOrigin().x << " " << ray->GetOrigin().y << " " << ray->GetOrigin().z << " "
412                                   << ray->GetTermination().x << " " << ray->GetTermination().y << " " << ray->GetTermination().z << " "
[491]413                                   << sourceid << " " << termid << "\n";
[490]414        }
[491]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
[490]435        samplesOut.close();
436        return true;
437}
[563]438
439
440
441bool
442Preprocessor::GenerateRays(
443                                                   const int number,
444                                                   const int sampleType,
445                                                   SimpleRayContainer &rays
446                                                   )
447{
448  Vector3 origin, direction;
[576]449  int startSize = rays.size();
450  for (int i=0; rays.size() - startSize  < number; i++) {
[563]451        // now get the direction
452        switch (sampleType) {
453        case OBJECT_BASED_DISTRIBUTION: {
[576]454          mViewCellsManager->GetViewPoint(origin);
[563]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;
[576]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;
[563]472        case DIRECTION_BASED_DISTRIBUTION:
[576]473          mViewCellsManager->GetViewPoint(origin);
[563]474          direction = UniformRandomVector();
475          break;
476        case DIRECTION_BOX_BASED_DISTRIBUTION: {
[576]477          mViewCellsManager->GetViewPoint(origin);
[563]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:
[576]484          mViewCellsManager->GetViewPoint(origin);
[563]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.