source: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp @ 316

Revision 316, 18.0 KB checked in by mattausch, 19 years ago (diff)

queries are realized as templates

Line 
1#include <stack>
2#include "common.h"
3#include "SceneGraph.h"
4#include "X3dExporter.h"
5#include "Mesh.h"
6#include "KdTree.h"
7#include "ViewCellBsp.h"
8#include "ViewCell.h"
9#include "Polygon3.h"
10ViewCellContainer X3dExporter::foundViewCells; // TODO: delete later
11
12X3dExporter::X3dExporter(const string filename):Exporter(filename)
13{
14  stream.open(mFilename.c_str());
15  stream<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
16  stream<<"<X3D>"<<endl;
17  stream<<"<Scene>"<<endl;
18 
19}
20
21X3dExporter::~X3dExporter()
22{
23  stream<<"</Scene>"<<endl;
24  stream<<"</X3D>"<<endl;
25  stream.close();
26}
27
28
29bool
30X3dExporter::ExportRays(const vector<Ray> &rays,
31                        const float length,
32                        const RgbColor &color)
33{
34  vector<Ray>::const_iterator ri = rays.begin();
35  stream<<"<Shape>"<<endl;
36  stream<<"<Appearance>"<<endl;
37  stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
38    "\" />"<<endl;
39  stream<<"</Appearance>"<<endl;
40 
41  stream<<"<IndexedLineSet coordIndex=\""<<endl;
42
43  int index = 0;
44  for (; ri != rays.end(); ri++) {
45    stream<<index<<" "<<index+1<<" -1\n";
46    index+=2;
47  }
48 
49  stream<<"\" >"<<endl;
50 
51  stream<<"<Coordinate  point=\""<<endl;
52 
53  ri = rays.begin();
54  for (; ri != rays.end(); ri++) {
55    Vector3 a = (*ri).GetLoc();
56   
57    Vector3 b;
58    if (length < 0)
59      b = (*ri).GetLoc() - length*(*ri).GetDir();
60    else
61      if ((*ri).intersections.size()==0)
62        b = (*ri).GetLoc() + length*(*ri).GetDir();
63      else
64        b = (*ri).Extrap((*ri).intersections[0].mT);
65   
66    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
67    stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
68  }
69 
70  stream<<"\" >"<<endl;
71  stream<<"</Coordinate>"<<endl;
72  stream<<"</IndexedLineSet>"<<endl;
73  stream<<"</Shape>"<<endl;
74  return true;
75}
76
77void
78X3dExporter::ExportSceneNode(SceneGraphNode *node)
79{
80  stream<<"<Group>"<<endl;
81
82  SceneGraphNodeContainer::iterator ni = node->mChildren.begin();
83  for (; ni != node->mChildren.end(); ni++)
84    ExportSceneNode(*ni);
85 
86 
87  ObjectContainer::const_iterator mi = node->mGeometry.begin();
88  for (; mi != node->mGeometry.end(); mi++) {
89    // export the transform...
90    ExportIntersectable(*mi);
91  }
92 
93  stream<<"</Group>"<<endl;
94
95}
96void
97X3dExporter::ExportIntersectable(Intersectable *object)
98{
99  switch (object->Type()) {
100  case Intersectable::MESH_INSTANCE:
101  case Intersectable::TRANSFORMED_MESH_INSTANCE:
102    ExportMeshInstance((MeshInstance *)object);
103        break;
104  case Intersectable::VIEW_CELL:
105        ExportViewCell((ViewCell *)object);
106    break;
107  default:
108    cerr<<"Sorry the export for object not yet defined"<<endl;
109    break;
110  }
111}
112
113void
114X3dExporter::ExportMeshInstance(MeshInstance *object)
115{
116  // $$JB$$
117  // in the future check whether the mesh was not already exported
118  // and use a reference to the that mesh instead
119  ExportMesh(object->GetMesh());
120}
121
122void
123X3dExporter::ExportViewCells(const ViewCellContainer &viewCells)
124{
125        ViewCellContainer::const_iterator it, it_end = viewCells.end();
126
127        for (it = viewCells.begin(); it != it_end; ++ it)
128                ExportViewCell(*it);
129}
130
131void
132X3dExporter::ExportViewCell(ViewCell *viewCell)
133{
134        if (viewCell->GetMesh())
135                ExportMesh(viewCell->GetMesh());
136}
137
138void
139X3dExporter::ExportMesh(Mesh *mesh)
140{
141
142  stream<<"<Shape>"<<endl;
143  stream<<"<Appearance>"<<endl;
144 
145  // $$ tmp -> random material
146 
147  float r, g, b;
148
149  if (mUseForcedMaterial) {
150    r = mForcedMaterial.mDiffuseColor.r;
151    g = mForcedMaterial.mDiffuseColor.g;
152    b = mForcedMaterial.mDiffuseColor.b;
153   
154  } else
155    if (mesh->mMaterial) {
156      r = mesh->mMaterial->mDiffuseColor.r;
157      g = mesh->mMaterial->mDiffuseColor.g;
158      b = mesh->mMaterial->mDiffuseColor.b;
159    } else {
160      r = RandomValue(0.5, 1.0);
161      g = RandomValue(0.5, 1.0);
162      b = RandomValue(0.5, 1.0);
163    }
164  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
165    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
166  stream<<"</Appearance>"<<endl;
167
168
169  if (mWireframe)
170    stream<<"<IndexedLineSet ccw=\"TRUE\" coordIndex=\""<<endl;
171  else
172    stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
173
174  FaceContainer::const_iterator fi = mesh->mFaces.begin();
175
176  int index = 0;
177 
178  for (; fi != mesh->mFaces.end(); fi++) {
179    Face *face = *fi;
180    VertexIndexContainer::const_iterator vi = face->mVertexIndices.begin();
181    for (; vi != face->mVertexIndices.end(); vi++)
182      stream<<*vi<<" ";
183    stream<<"-1"<<endl;
184  }
185  stream<<"\" >"<<endl;
186
187  stream<<"<Coordinate  point=\""<<endl;
188 
189  VertexContainer::const_iterator vi = mesh->mVertices.begin();
190  for (; vi != mesh->mVertices.end(); vi++) {
191    stream<<(*vi).x<<" "<<(*vi).y<<" "<<(*vi).z;
192    stream<<","<<endl;
193  }
194 
195  stream<<"\" >"<<endl;
196  stream<<"</Coordinate>"<<endl;
197
198  if (mWireframe)
199    stream<<"</IndexedLineSet>"<<endl;
200  else
201    stream<<"</IndexedFaceSet>"<<endl;
202 
203  stream<<"</Shape>"<<endl;
204
205}
206
207
208void X3dExporter::ExportPolygon(Polygon3 *poly)
209{
210        stream << "<Shape>" << endl;
211        stream << "<Appearance>" << endl;
212 
213        // $$ tmp -> random material
214 
215        float r, g, b;
216
217        if (mUseForcedMaterial)
218        {
219                r = mForcedMaterial.mDiffuseColor.r;
220                g = mForcedMaterial.mDiffuseColor.g;
221                b = mForcedMaterial.mDiffuseColor.b;
222        }
223        else if (poly->mMaterial)
224        {
225                r = poly->mMaterial->mDiffuseColor.r;
226                g = poly->mMaterial->mDiffuseColor.g;
227                b = poly->mMaterial->mDiffuseColor.b;
228        } else
229        {
230                r = RandomValue(0.5, 1.0);
231                g = RandomValue(0.5, 1.0);
232                b = RandomValue(0.5, 1.0);
233        }
234
235        stream << "<Material diffuseColor=\"" << r << " " << g << " " << b
236                   << "\" specularColor=\"0.0 0.0 0.0\"/>" << endl;
237
238    stream << "</Appearance>" << endl;
239
240
241        //-- create and write indices
242        if (mWireframe)
243                stream << "<IndexedLineSet ccw=\"TRUE\" coordIndex=\"" << endl;
244        else
245                stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
246
247        int index = 0;
248       
249        VertexContainer::const_iterator vi; 
250       
251        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
252        {
253                stream << index ++ << " ";
254        }
255        stream << "-1" << endl;
256
257        stream << "\" >" << endl;
258       
259        stream << "<Coordinate  point=\"" << endl;
260 
261        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
262        {
263                stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
264                stream << "," << endl;
265        }
266 
267        stream << "\" >" << endl;
268        stream << "</Coordinate>" << endl;
269
270        if (mWireframe)
271                stream << "</IndexedLineSet>" << endl;
272        else
273                stream << "</IndexedFaceSet>" << endl;
274 
275        stream << "</Shape>" << endl;
276}
277
278void X3dExporter::ExportPolygons(const PolygonContainer &polys)
279{
280        stream << "<Shape>" << endl;
281        stream << "<Appearance>" << endl;
282 
283        // $$ tmp -> random material
284 
285        float r, g, b;
286
287        if (mUseForcedMaterial)
288        {
289                r = mForcedMaterial.mDiffuseColor.r;
290                g = mForcedMaterial.mDiffuseColor.g;
291                b = mForcedMaterial.mDiffuseColor.b;
292        }
293        else
294        {
295                r = RandomValue(0.5, 1.0);
296                g = RandomValue(0.5, 1.0);
297                b = RandomValue(0.5, 1.0);
298        }
299
300        stream << "<Material diffuseColor=\"" << r << " " << g << " " << b
301                   << "\" specularColor=\"0.0 0.0 0.0\"/>" << endl;
302
303    stream << "</Appearance>" << endl;
304
305
306        //-- create and write indices
307        if (mWireframe)
308                stream << "<IndexedLineSet ccw=\"TRUE\" coordIndex=\"" << endl;
309        else
310                stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
311
312        int index = 0;
313       
314        PolygonContainer::const_iterator pit;
315
316    VertexContainer::const_iterator vi; 
317       
318        for (pit = polys.begin(); pit != polys.end(); ++pit)
319        {
320                Polygon3 *poly = *pit;
321                for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
322                {
323                        stream << index ++ << " ";
324                }
325                stream << "-1" << endl;
326        }
327
328        stream << "\" >" << endl;
329       
330        stream << "<Coordinate  point=\"" << endl;
331        for (pit = polys.begin(); pit != polys.end(); ++pit)
332        {
333                Polygon3 *poly = *pit;
334        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
335                {
336                        stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
337                        stream << "," << endl;
338                }
339        }
340        stream << "\" >" << endl;
341        stream << "</Coordinate>" << endl;
342
343        if (mWireframe)
344                stream << "</IndexedLineSet>" << endl;
345        else
346                stream << "</IndexedFaceSet>" << endl;
347 
348        stream << "</Shape>" << endl;
349}
350
351bool
352X3dExporter::ExportBox(const AxisAlignedBox3 &box)
353{
354  Mesh *mesh = new Mesh;
355  // add 6 vertices of the box
356  int index = (int)mesh->mVertices.size();
357  for (int i=0; i < 8; i++) {
358    Vector3 v;
359    box.GetVertex(i, v);
360    mesh->mVertices.push_back(v);
361  }
362 
363  mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
364  mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
365  mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
366 
367  mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
368  mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
369  mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
370 
371  ExportMesh(mesh);
372  delete mesh;
373  return true;
374}
375
376bool
377X3dExporter::ExportBspTree(const BspTree &tree)
378{
379        if (mExportRayDensity)
380        {
381                return ExportBspTreeRayDensity(tree);
382        }
383 
384        stack<BspNode *> tStack;
385
386        tStack.push(tree.GetRoot());
387
388        Mesh *mesh = new Mesh;
389
390        AxisAlignedBox3 box = tree.GetBoundingBox();
391        bool savedWireframe = mWireframe;
392
393        SetWireframe();
394        ExportBox(box);
395       
396        if (!savedWireframe)
397                SetFilled();
398
399        //ViewCellContainer foundViewCells;
400
401        if (tree.StorePolys())
402        {
403                while (!tStack.empty())
404                {
405            BspNode *node = tStack.top();
406   
407                        tStack.pop();
408       
409                        if (tree.StorePolys()) // extract the polygons
410                        {
411                                PolygonContainer::const_iterator it;
412                                PolygonContainer::const_iterator it_end = node->GetPolygons()->end();
413
414                                for (it = node->GetPolygons()->begin(); it != it_end; ++ it)
415                                        ExportPolygon(*it);
416                        }
417
418                        if (!node->IsLeaf())
419                        {
420                                BspInterior *interior = dynamic_cast<BspInterior *>(node);
421     
422                                tStack.push(interior->GetFront());
423                                tStack.push(interior->GetBack());
424
425                        }
426                }
427        }
428        else // export view cells
429        {
430                while (!tStack.empty())
431                {
432            BspNode *node = tStack.top();
433   
434                        tStack.pop();
435       
436                        if (node->IsLeaf())
437                        {
438                                ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell();
439                                if (viewCell)
440                                        foundViewCells.push_back(viewCell);
441                        }
442                        else
443                        {
444                                BspInterior *interior = dynamic_cast<BspInterior *>(node);
445     
446                                tStack.push(interior->GetFront());
447                                tStack.push(interior->GetBack());
448                        }
449                }
450
451                Debug << "Number of view cells with dublicates: " << (int)foundViewCells.size() << endl;
452
453        //-- erase dublicates
454                sort(foundViewCells.begin(), foundViewCells.end());
455                ViewCellContainer::iterator new_end = unique(foundViewCells.begin(), foundViewCells.end());
456                foundViewCells.erase(new_end, foundViewCells.end());
457                ExportViewCells(foundViewCells);
458
459                Debug << "Number of view cells after erasing dublicates: " << (int)foundViewCells.size() << endl;
460        }
461
462        return true;
463}
464
465bool X3dExporter::ExportKdTree(const KdTree &tree)
466{
467         if (mExportRayDensity) {
468    return ExportKdTreeRayDensity(tree);
469  }
470 
471  stack<KdNode *> tStack;
472
473  tStack.push(tree.GetRoot());
474
475  Mesh *mesh = new Mesh;
476 
477  while (!tStack.empty()) {
478    KdNode *node = tStack.top();
479    tStack.pop();
480    AxisAlignedBox3 box = tree.GetBox(node);
481    // add 6 vertices of the box
482    int index = (int)mesh->mVertices.size();
483    for (int i=0; i < 8; i++) {
484      Vector3 v;
485      box.GetVertex(i, v);
486      mesh->mVertices.push_back(v);
487    }
488    mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
489    mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
490    mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
491
492    mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
493    mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
494    mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
495
496    if (!node->IsLeaf()) {
497      KdInterior *interior = (KdInterior *)node;
498      tStack.push(interior->mFront);
499      tStack.push(interior->mBack);
500    }
501  }
502 
503  ExportMesh(mesh);
504  delete mesh;
505  return true;
506        // TODO
507        return true;
508}
509
510
511bool
512X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
513{
514        stack<BspNode *> tStack;
515
516        tStack.push(tree.GetRoot());
517
518        bool fm = mUseForcedMaterial;
519       
520        mUseForcedMaterial = true;
521       
522        mForcedMaterial.mDiffuseColor.g = 1.0f;
523        mForcedMaterial.mDiffuseColor.b = 1.0f;
524 
525        while (!tStack.empty())
526        {
527                BspNode *node = tStack.top();
528                tStack.pop();
529
530                if (node->IsLeaf())
531                {
532                        ViewCell *vc = dynamic_cast<BspLeaf *>(node)->GetViewCell();
533     
534                        // set the mesh material according to the ray density
535                        if (vc->mPassingRays.mRays)
536                        {
537                                float importance =
538                                        vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
539
540                                mForcedMaterial.mDiffuseColor.r = importance;
541                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
542                                ExportViewCell(vc);
543                        } 
544                } else
545                {
546                        BspInterior *interior = (BspInterior *)node;
547                        tStack.push(interior->GetFront());
548                        tStack.push(interior->GetBack());
549                }
550        }
551 
552        // restore the state of forced material
553        mUseForcedMaterial = fm;
554
555        return true;
556}
557
558bool
559X3dExporter::ExportKdTreeRayDensity(const KdTree &tree)
560{
561  stack<KdNode *> tStack;
562
563  tStack.push(tree.GetRoot());
564
565  bool fm = mUseForcedMaterial;
566  mUseForcedMaterial = true;
567  mForcedMaterial.mDiffuseColor.g = 1.0f;
568  mForcedMaterial.mDiffuseColor.b = 1.0f;
569  while (!tStack.empty()) {
570    KdNode *node = tStack.top();
571    tStack.pop();
572    if (node->IsLeaf()) {
573      AxisAlignedBox3 box = tree.GetBox(node);
574      Mesh *mesh = new Mesh;
575     
576      // add 6 vertices of the box
577      int index = (int)mesh->mVertices.size();
578      for (int i=0; i < 8; i++) {
579        Vector3 v;
580        box.GetVertex(i, v);
581        mesh->mVertices.push_back(v);
582      }
583      mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
584      mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
585      mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
586     
587      mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
588      mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
589      mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
590
591
592      // set the mesh material according to the ray density
593      KdLeaf *leaf = (KdLeaf *) node;
594      if (leaf->mPassingRays.mRays) {
595        float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays;
596        //      float importance = leaf->mPassingRays.mContributions/1000.0f;
597        //      float importance = leaf->mPassingRays.mRays/1000.0f;
598        ///(float)leaf->mPassingRays.mRays;
599        // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f;
600        mForcedMaterial.mDiffuseColor.r = importance;
601        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
602        ExportMesh(mesh);
603      }
604      delete mesh;
605    } else {
606      KdInterior *interior = (KdInterior *)node;
607      tStack.push(interior->mFront);
608      tStack.push(interior->mBack);
609    }
610  }
611  // restore the state of forced material
612  mUseForcedMaterial = fm;
613  return true;
614}
615
616struct BspSplitData
617{
618        /// the current node
619        BspNode *mNode;
620
621        vector<Plane3 *> mPlanes;
622        vector<bool> mSides;
623        bool mIsFront;
624
625        BspSplitData(BspNode *node):
626        mNode(node), mIsFront(false)
627        {};     
628        BspSplitData(BspNode *node,
629                                 vector<Plane3 *> planes,
630                                 vector<bool> sides,
631                                 bool isFront):
632        mNode(node), mPlanes(planes),
633        mSides(sides), mIsFront(isFront)
634        {};
635};
636
637void X3dExporter::ExportBspSplits(const BspTree &tree)
638{
639        std::stack<BspSplitData> tStack;
640
641        BspSplitData tData(tree.GetRoot());
642        tStack.push(tData);
643 
644        PolygonContainer polys;
645
646        while (!tStack.empty())
647        {
648                // filter polygons donw the tree
649                BspSplitData tData = tStack.top();
650            tStack.pop();       
651               
652                if (!tData.mNode->IsLeaf())
653                {
654                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
655                        if (tData.mNode != tree.GetRoot())
656                                tData.mSides.push_back(tData.mIsFront); // add current side
657
658                        // bounded plane is added to the polygons
659                        Polygon3 *planePoly = tree.GetBoundingBox().BoundPlane(*interior->GetPlane());
660               
661                        // do all the splits with the previous planes
662                        for (int i = 0; i < (int)tData.mPlanes.size(); ++i)
663                        {
664                                VertexContainer splitPts;
665                                Polygon3 *frontPoly = new Polygon3();
666                                Polygon3 *backPoly = new Polygon3();
667
668                                if (planePoly->ClassifyPlane(*tData.mPlanes[i]) == Polygon3::SPLIT)
669                                {
670                                        planePoly->Split(*tData.mPlanes[i], *frontPoly, *backPoly, splitPts);
671                                        DEL_PTR(planePoly);
672
673                                        if(tData.mSides[i] == true)
674                                        {
675                                                planePoly = frontPoly;
676                                                DEL_PTR(backPoly);
677                                        }
678                                        else
679                                        {
680                                                planePoly = backPoly;
681                                                DEL_PTR(frontPoly);
682                                        }
683                                }
684                        }
685
686                        tData.mPlanes.push_back(interior->GetPlane()); // add plane to split planes
687                        if (planePoly->Valid())
688                                polys.push_back(planePoly);
689                        else
690                        {
691                                Debug << "polygon not valid: " << *planePoly << " size: " << (int)planePoly->mVertices.size() << endl;
692                                DEL_PTR(planePoly);
693                        }
694                        // push the children on the stack
695                        tStack.push(BspSplitData(interior->GetFront(), tData.mPlanes, tData.mSides, true));
696                        tStack.push(BspSplitData(interior->GetBack(), tData.mPlanes, tData.mSides, false));
697                }
698        }       
699        ExportPolygons(polys);
700        CLEAR_CONTAINER(polys);
701}
702
703void X3dExporter::ExportBspSplitPlanes(const BspTree &tree)
704{
705        std::stack<BspNode *> tStack;
706
707        tStack.push(tree.GetRoot());
708 
709        PolygonContainer polys;
710
711        while (!tStack.empty())
712        {
713                // filter polygons donw the tree
714                BspNode *node = tStack.top();
715            tStack.pop();       
716               
717                if (!node->IsLeaf())
718                {
719                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
720
721                        // bounded plane is added to the polygons
722                        polys.push_back(tree.GetBoundingBox().BoundPlane(*interior->GetPlane()));
723               
724                        // push the children on the stack
725                        tStack.push(interior->GetBack());
726                        tStack.push(interior->GetFront());
727                }
728        }
729
730        ExportPolygons(polys);
731        CLEAR_CONTAINER(polys);
732}
Note: See TracBrowser for help on using the repository browser.