source: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp @ 678

Revision 678, 31.1 KB checked in by mattausch, 18 years ago (diff)
RevLine 
[162]1#include <stack>
2#include "common.h"
3#include "SceneGraph.h"
4#include "X3dExporter.h"
5#include "Mesh.h"
6#include "KdTree.h"
[242]7#include "ViewCellBsp.h"
8#include "ViewCell.h"
[260]9#include "Polygon3.h"
[386]10#include "VssRay.h"
[418]11#include "VspKdTree.h"
[434]12#include "VssTree.h"
[449]13#include "VspBspTree.h"
[450]14#include "RssTree.h"
[535]15#include "Beam.h"
[162]16
[449]17
[162]18X3dExporter::X3dExporter(const string filename):Exporter(filename)
19{
20  stream.open(mFilename.c_str());
21  stream<<"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
22  stream<<"<X3D>"<<endl;
23  stream<<"<Scene>"<<endl;
24 
25}
26
27X3dExporter::~X3dExporter()
28{
29  stream<<"</Scene>"<<endl;
30  stream<<"</X3D>"<<endl;
31  stream.close();
32}
33
[176]34
[386]35//  bool
36//  X3dExporter::ExportRays(const vector<Ray> &rays,
37//                                                                                              const float length,
38//                                                                                              const RgbColor &color)
39//  {
40//    vector<Ray>::const_iterator ri = rays.begin();
41//    stream<<"<Shape>"<<endl;
42//    stream<<"<Appearance>"<<endl;
43//    stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
44//      "\" />"<<endl;
45//    stream<<"</Appearance>"<<endl;
46 
47//    stream<<"<IndexedLineSet coordIndex=\""<<endl;
48
49//    int index = 0;
50//    for (; ri != rays.end(); ri++) {
51//      stream<<index<<" "<<index+1<<" -1\n";
52//      index+=2;
53//    }
54 
55//    stream<<"\" >"<<endl;
56 
57//    stream<<"<Coordinate  point=\""<<endl;
58 
59//    ri = rays.begin();
60//    for (; ri != rays.end(); ri++) {
61//      Vector3 a = (*ri).GetLoc();
62   
63//      Vector3 b;
64//      if (length < 0)
65//        b = (*ri).GetLoc() - length*(*ri).GetDir();
66//      else
67//        if ((*ri).intersections.size()==0)
68//      b = (*ri).GetLoc() + length*(*ri).GetDir();
69//        else
70//      b = (*ri).Extrap((*ri).intersections[0].mT);
71   
72//      stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
73//      stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
74//    }
75 
76//    stream<<"\" >"<<endl;
77//    stream<<"</Coordinate>"<<endl;
78//    stream<<"</IndexedLineSet>"<<endl;
79//    stream<<"</Shape>"<<endl;
80//    return true;
81//  }
82
83
[162]84bool
[386]85X3dExporter::ExportRays(const RayContainer &rays,
[444]86                                                const float length,
87                                                const RgbColor &color)
[162]88{
[386]89  RayContainer::const_iterator ri = rays.begin();
90
[162]91  stream<<"<Shape>"<<endl;
[176]92  stream<<"<Appearance>"<<endl;
[427]93  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
[176]94    "\" />"<<endl;
95  stream<<"</Appearance>"<<endl;
96 
[209]97  stream<<"<IndexedLineSet coordIndex=\""<<endl;
[162]98
99  int index = 0;
100  for (; ri != rays.end(); ri++) {
101    stream<<index<<" "<<index+1<<" -1\n";
102    index+=2;
103  }
104 
105  stream<<"\" >"<<endl;
106 
107  stream<<"<Coordinate  point=\""<<endl;
108 
109  ri = rays.begin();
110  for (; ri != rays.end(); ri++) {
[386]111    Vector3 a = (*ri)->GetLoc();
[162]112   
[176]113    Vector3 b;
114    if (length < 0)
[386]115      b = (*ri)->GetLoc() - length*(*ri)->GetDir();
[176]116    else
[386]117      if ((*ri)->intersections.size()==0)
[492]118                b = (*ri)->GetLoc() + length*(*ri)->GetDir();
[176]119      else
[492]120                b = (*ri)->Extrap((*ri)->intersections[0].mT);
[176]121   
[162]122    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
123    stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
124  }
125 
126  stream<<"\" >"<<endl;
127  stream<<"</Coordinate>"<<endl;
128  stream<<"</IndexedLineSet>"<<endl;
129  stream<<"</Shape>"<<endl;
[386]130
[162]131  return true;
132}
133
[349]134bool
[386]135X3dExporter::ExportRays(const VssRayContainer &rays,
[444]136                                                const RgbColor &color)
[349]137{
[386]138  VssRayContainer::const_iterator ri = rays.begin();
[349]139
140  stream<<"<Shape>"<<endl;
141  stream<<"<Appearance>"<<endl;
[427]142  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
[349]143    "\" />"<<endl;
144  stream<<"</Appearance>"<<endl;
145 
146  stream<<"<IndexedLineSet coordIndex=\""<<endl;
147
148  int index = 0;
149  for (; ri != rays.end(); ri++) {
150    stream<<index<<" "<<index+1<<" -1\n";
151    index+=2;
152  }
153 
154  stream<<"\" >"<<endl;
155 
156  stream<<"<Coordinate  point=\""<<endl;
157 
158  ri = rays.begin();
159  for (; ri != rays.end(); ri++) {
[444]160    const Vector3 a = (*ri)->GetOrigin();
[483]161        //const Vector3 b = (*ri)->mTerminationObject ? (*ri)->GetTermination() : a + 1000 * Normalize((*ri)->GetDir());
162        const Vector3 b = (*ri)->GetTermination(); // matt: change again!!
163
[349]164    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
[444]165        stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
[349]166  }
167 
168  stream<<"\" >"<<endl;
169  stream<<"</Coordinate>"<<endl;
170  stream<<"</IndexedLineSet>"<<endl;
171  stream<<"</Shape>"<<endl;
[386]172       
[349]173  return true;
174}
175
[162]176void
177X3dExporter::ExportSceneNode(SceneGraphNode *node)
178{
179  stream<<"<Group>"<<endl;
180
181  SceneGraphNodeContainer::iterator ni = node->mChildren.begin();
182  for (; ni != node->mChildren.end(); ni++)
183    ExportSceneNode(*ni);
184 
185 
[176]186  ObjectContainer::const_iterator mi = node->mGeometry.begin();
[162]187  for (; mi != node->mGeometry.end(); mi++) {
188    // export the transform...
[176]189    ExportIntersectable(*mi);
[162]190  }
191 
192  stream<<"</Group>"<<endl;
193
194}
[176]195void
196X3dExporter::ExportIntersectable(Intersectable *object)
197{
198  switch (object->Type()) {
199  case Intersectable::MESH_INSTANCE:
200  case Intersectable::TRANSFORMED_MESH_INSTANCE:
201    ExportMeshInstance((MeshInstance *)object);
[242]202        break;
[308]203  case Intersectable::VIEW_CELL:
[242]204        ExportViewCell((ViewCell *)object);
[176]205    break;
206  default:
207    cerr<<"Sorry the export for object not yet defined"<<endl;
208    break;
209  }
210}
[162]211
212void
[176]213X3dExporter::ExportMeshInstance(MeshInstance *object)
214{
215  // $$JB$$
[312]216  // in the future check whether the mesh was not already exported
[176]217  // and use a reference to the that mesh instead
218  ExportMesh(object->GetMesh());
219}
220
[313]221void
222X3dExporter::ExportViewCells(const ViewCellContainer &viewCells)
[261]223{
[313]224        ViewCellContainer::const_iterator it, it_end = viewCells.end();
[261]225
[313]226        for (it = viewCells.begin(); it != it_end; ++ it)
[261]227                ExportViewCell(*it);
228}
[313]229
[373]230void
[396]231X3dExporter::ExportBspLeaves(const BspTree &tree, const int maxPvs)
[373]232{
[396]233        stack<pair<BspNode *, BspNodeGeometry *> > tStack;
234        ViewCell::NewMail();
[373]235
[396]236        BspNodeGeometry *geom = new BspNodeGeometry();
237        tree.ConstructGeometry(tree.GetRoot(), *geom);
[373]238
[396]239        tStack.push(pair<BspNode *, BspNodeGeometry *>(tree.GetRoot(), geom));
240
241        if (maxPvs > 0)
242                mUseForcedMaterial = true;
243
244        while (!tStack.empty())
[373]245        {
[396]246                BspNode *node = tStack.top().first;
247                BspNodeGeometry *cell = tStack.top().second;
248                tStack.pop();
249
250                if (!node->IsLeaf())
251                {
252                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
253                                                               
254                        BspNodeGeometry *front = new BspNodeGeometry();
255                        BspNodeGeometry *back = new BspNodeGeometry();
256
[449]257                        cell->SplitGeometry(*front,
258                                                                *back,
259                                                                interior->GetPlane(),
260                                                                tree.GetBoundingBox(),
261                                                                tree.GetEpsilon());
[396]262
263                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetFront(), front));
264                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetBack(), back));
265                }
266                else
267                {
268                        if (maxPvs > 0)
269                        {
270                                BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
271
272                                mForcedMaterial.mDiffuseColor.b = 1.0f;
273                                float importance = (float)leaf->GetViewCell()->GetPvs().GetSize() / (float)maxPvs;
274
275                                mForcedMaterial.mDiffuseColor.r = importance;
276                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
277                        }
278
[678]279                        ExportPolygons(cell->GetPolys());
[396]280                }
281               
282                DEL_PTR(cell);
[373]283        }
284}
285
[176]286void
[261]287X3dExporter::ExportViewCell(ViewCell *viewCell)
[242]288{
[261]289        if (viewCell->GetMesh())
290                ExportMesh(viewCell->GetMesh());
[242]291}
292
293void
[162]294X3dExporter::ExportMesh(Mesh *mesh)
295{
296
297  stream<<"<Shape>"<<endl;
298  stream<<"<Appearance>"<<endl;
[176]299 
[162]300  // $$ tmp -> random material
301 
302  float r, g, b;
303
[176]304  if (mUseForcedMaterial) {
305    r = mForcedMaterial.mDiffuseColor.r;
306    g = mForcedMaterial.mDiffuseColor.g;
307    b = mForcedMaterial.mDiffuseColor.b;
308   
309  } else
310    if (mesh->mMaterial) {
311      r = mesh->mMaterial->mDiffuseColor.r;
312      g = mesh->mMaterial->mDiffuseColor.g;
313      b = mesh->mMaterial->mDiffuseColor.b;
314    } else {
315      r = RandomValue(0.5, 1.0);
316      g = RandomValue(0.5, 1.0);
317      b = RandomValue(0.5, 1.0);
318    }
[162]319  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
320    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
321  stream<<"</Appearance>"<<endl;
322
323
[191]324  if (mWireframe)
[427]325    stream<<"<IndexedLineSet coordIndex=\""<<endl;
[162]326  else
[465]327    //stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
328        stream << "<IndexedFaceSet coordIndex=\"" << endl;
[162]329
330  FaceContainer::const_iterator fi = mesh->mFaces.begin();
331
332  int index = 0;
333 
334  for (; fi != mesh->mFaces.end(); fi++) {
335    Face *face = *fi;
336    VertexIndexContainer::const_iterator vi = face->mVertexIndices.begin();
337    for (; vi != face->mVertexIndices.end(); vi++)
338      stream<<*vi<<" ";
[378]339        if (mWireframe) // final line to finish polygon
340                stream << (*face->mVertexIndices.begin()) << " ";
341
[162]342    stream<<"-1"<<endl;
343  }
344  stream<<"\" >"<<endl;
345
346  stream<<"<Coordinate  point=\""<<endl;
347 
348  VertexContainer::const_iterator vi = mesh->mVertices.begin();
349  for (; vi != mesh->mVertices.end(); vi++) {
350    stream<<(*vi).x<<" "<<(*vi).y<<" "<<(*vi).z;
351    stream<<","<<endl;
352  }
353 
354  stream<<"\" >"<<endl;
355  stream<<"</Coordinate>"<<endl;
356
[191]357  if (mWireframe)
[162]358    stream<<"</IndexedLineSet>"<<endl;
359  else
360    stream<<"</IndexedFaceSet>"<<endl;
361 
362  stream<<"</Shape>"<<endl;
363
364}
365
[242]366
367void X3dExporter::ExportPolygon(Polygon3 *poly)
368{
369        stream << "<Shape>" << endl;
370        stream << "<Appearance>" << endl;
371 
372        // $$ tmp -> random material
373 
374        float r, g, b;
375
376        if (mUseForcedMaterial)
377        {
378                r = mForcedMaterial.mDiffuseColor.r;
379                g = mForcedMaterial.mDiffuseColor.g;
380                b = mForcedMaterial.mDiffuseColor.b;
381        }
382        else if (poly->mMaterial)
383        {
384                r = poly->mMaterial->mDiffuseColor.r;
385                g = poly->mMaterial->mDiffuseColor.g;
386                b = poly->mMaterial->mDiffuseColor.b;
387        } else
388        {
389                r = RandomValue(0.5, 1.0);
390                g = RandomValue(0.5, 1.0);
391                b = RandomValue(0.5, 1.0);
392        }
393
394        stream << "<Material diffuseColor=\"" << r << " " << g << " " << b
395                   << "\" specularColor=\"0.0 0.0 0.0\"/>" << endl;
396
397    stream << "</Appearance>" << endl;
398
399
[262]400        //-- create and write indices
[242]401        if (mWireframe)
[465]402                stream<<"<IndexedLineSet coordIndex=\""<<endl;
[242]403        else
[465]404                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
405                stream << "<IndexedFaceSet coordIndex=\"" << endl;
[262]406        int index = 0;
407       
408        VertexContainer::const_iterator vi; 
409       
[333]410        for (index = 0; index < (int)poly->mVertices.size(); ++ index)
[318]411                stream << index << " ";
412       
413        if (mWireframe) // final line to finish polygon
414                stream << "0 ";
415
[262]416        stream << "-1" << endl;
417        stream << "\" >" << endl;
418       
[242]419        stream << "<Coordinate  point=\"" << endl;
420 
[262]421        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
[242]422        {
423                stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
424                stream << "," << endl;
425        }
426 
[262]427        stream << "\" >" << endl;
428        stream << "</Coordinate>" << endl;
[242]429
430        if (mWireframe)
431                stream << "</IndexedLineSet>" << endl;
432        else
433                stream << "</IndexedFaceSet>" << endl;
434 
435        stream << "</Shape>" << endl;
436}
437
[313]438void X3dExporter::ExportPolygons(const PolygonContainer &polys)
[263]439{
[318]440        stream << "<Shape>" << endl;
[263]441        stream << "<Appearance>" << endl;
442 
443        // $$ tmp -> random material
444 
445        float r, g, b;
[242]446
[263]447        if (mUseForcedMaterial)
448        {
449                r = mForcedMaterial.mDiffuseColor.r;
450                g = mForcedMaterial.mDiffuseColor.g;
451                b = mForcedMaterial.mDiffuseColor.b;
452        }
453        else
454        {
455                r = RandomValue(0.5, 1.0);
456                g = RandomValue(0.5, 1.0);
457                b = RandomValue(0.5, 1.0);
458        }
459
460        stream << "<Material diffuseColor=\"" << r << " " << g << " " << b
461                   << "\" specularColor=\"0.0 0.0 0.0\"/>" << endl;
462
463    stream << "</Appearance>" << endl;
464
465
466        //-- create and write indices
467        if (mWireframe)
[465]468                stream<<"<IndexedLineSet coordIndex=\""<<endl;
[263]469        else
[465]470                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
471                stream << "<IndexedFaceSet coordIndex=\"" << endl;
[263]472
473        int index = 0;
474       
475        PolygonContainer::const_iterator pit;
476
477    VertexContainer::const_iterator vi; 
478       
[313]479        for (pit = polys.begin(); pit != polys.end(); ++pit)
[263]480        {
481                Polygon3 *poly = *pit;
[318]482                int startIdx = index;
[263]483                for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
484                {
485                        stream << index ++ << " ";
486                }
[318]487
488                stream << startIdx << " ";// finish line
[263]489                stream << "-1" << endl;
490        }
491
492        stream << "\" >" << endl;
493       
494        stream << "<Coordinate  point=\"" << endl;
[318]495        for (pit = polys.begin(); pit != polys.end(); ++ pit)
[263]496        {
497                Polygon3 *poly = *pit;
498        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
499                {
500                        stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
501                        stream << "," << endl;
502                }
503        }
504        stream << "\" >" << endl;
505        stream << "</Coordinate>" << endl;
506
507        if (mWireframe)
508                stream << "</IndexedLineSet>" << endl;
509        else
510                stream << "</IndexedFaceSet>" << endl;
511 
512        stream << "</Shape>" << endl;
513}
514
[162]515bool
516X3dExporter::ExportBox(const AxisAlignedBox3 &box)
517{
518  Mesh *mesh = new Mesh;
[547]519  // add 8 vertices of the box
[289]520  int index = (int)mesh->mVertices.size();
[162]521  for (int i=0; i < 8; i++) {
522    Vector3 v;
523    box.GetVertex(i, v);
524    mesh->mVertices.push_back(v);
525  }
526 
527  mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
528  mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
529  mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
530 
531  mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
532  mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
533  mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
534 
535  ExportMesh(mesh);
536  delete mesh;
537  return true;
538}
539
540bool
[242]541X3dExporter::ExportBspTree(const BspTree &tree)
[162]542{
[242]543        if (mExportRayDensity)
544        {
[263]545                return ExportBspTreeRayDensity(tree);
[242]546        }
547 
[264]548        bool savedWireframe = mWireframe;
549
550        SetWireframe();
551       
[396]552        ExportBox(tree.GetBoundingBox());
553       
[264]554        if (!savedWireframe)
555                SetFilled();
556
[373]557        // export view cells
[482]558        ExportBspLeaves(tree); 
[289]559
[263]560        return true;
[242]561}
562
[425]563bool X3dExporter::ExportVspKdTree(const VspKdTree &tree, const int maxPvs)
[418]564{
[462]565        stack<VspKdNode *> tStack;
[418]566
[422]567        tStack.push(tree.GetRoot());
568
[425]569        //Mesh *mesh = new Mesh;
[418]570 
[425]571        if (maxPvs > 0)
572                mUseForcedMaterial = true;
573
[422]574        while (!tStack.empty())
575        {
[462]576                VspKdNode *node = tStack.top();
[418]577   
[422]578                tStack.pop();
[418]579
[426]580                if (node->IsLeaf())
581                {
582                        AxisAlignedBox3 box = tree.GetBBox(node);
[425]583
[426]584                        Mesh *mesh = new Mesh;
[425]585
[426]586                        // add 6 vertices of the box
587                        int index = (int)mesh->mVertices.size();
[418]588
[426]589                        for (int i=0; i < 8; ++ i)
590                        {
591                                Vector3 v;
592                                box.GetVertex(i, v);
593                                mesh->mVertices.push_back(v);
594                        }
[418]595
[426]596                        mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
597                        mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
598                        mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
[418]599
[426]600                        mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
601                        mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
602                        mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
[425]603
[426]604                        if (maxPvs > 0)
605                        {
[462]606                                VspKdLeaf *leaf = dynamic_cast<VspKdLeaf *>(node);
[425]607
[426]608                                mForcedMaterial.mDiffuseColor.b = 1.0f;
609                               
610                                leaf->UpdatePvsSize();
611                       
612                                const float importance = (float)leaf->GetPvsSize() / (float)maxPvs;
613                                mForcedMaterial.mDiffuseColor.r = importance;
614                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
615                        }
[425]616
[426]617                        ExportMesh(mesh);
618                        DEL_PTR(mesh);
619                }
620                else 
[422]621                {
[462]622                        VspKdInterior *interior = dynamic_cast<VspKdInterior *>(node);
[422]623                        tStack.push(interior->GetFront());
624                        tStack.push(interior->GetBack());
625                }
626        }
[418]627 
[425]628        //ExportMesh(mesh);
629        //DEL_PTR(mesh);
[418]630
[422]631        return true;
[418]632}
633
[462]634
[242]635bool X3dExporter::ExportKdTree(const KdTree &tree)
636{
637         if (mExportRayDensity) {
[191]638    return ExportKdTreeRayDensity(tree);
639  }
640 
[162]641  stack<KdNode *> tStack;
642
643  tStack.push(tree.GetRoot());
644
645  Mesh *mesh = new Mesh;
646 
647  while (!tStack.empty()) {
648    KdNode *node = tStack.top();
649    tStack.pop();
650    AxisAlignedBox3 box = tree.GetBox(node);
651    // add 6 vertices of the box
[289]652    int index = (int)mesh->mVertices.size();
[162]653    for (int i=0; i < 8; i++) {
654      Vector3 v;
655      box.GetVertex(i, v);
656      mesh->mVertices.push_back(v);
657    }
658    mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
659    mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
660    mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
661
662    mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
663    mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
664    mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
665
666    if (!node->IsLeaf()) {
667      KdInterior *interior = (KdInterior *)node;
668      tStack.push(interior->mFront);
669      tStack.push(interior->mBack);
670    }
671  }
672 
673  ExportMesh(mesh);
674  delete mesh;
675  return true;
[242]676        // TODO
677        return true;
[162]678}
679
680
[434]681
682
[191]683bool
[438]684X3dExporter::ExportVssTree(const VssTree &tree
685                                                   )
[434]686{
687  stack<VssTreeNode *> tStack;
688       
689  tStack.push(tree.GetRoot());
690       
691  Mesh *mesh = new Mesh;
692  VssRayContainer rays;
693       
694  while (!tStack.empty()) {
695
696                VssTreeNode *node = tStack.top();
697    tStack.pop();
698
699                       
700    if (!node->IsLeaf()) {
701      VssTreeInterior *interior = (VssTreeInterior *)node;
702      tStack.push(interior->front);
703      tStack.push(interior->back);
704    } else {
705                        VssTreeLeaf *leaf = (VssTreeLeaf *)node;
706                        AxisAlignedBox3 box;
707                        box = tree.GetBBox(leaf);
[486]708                        box.AddBoxToMesh(mesh);
[434]709
710                        if (tree.ValidLeaf(leaf)) {
711                               
712                                Vector3 origin = box.Center();
713                                box = tree.GetDirBBox(leaf);
714                                VssRay *ray;
715                               
716                                const indices[][2] = {{0,0}, {0,1}, {1,1}, {1,0}};
717                                MeshInstance dummy(mesh);
718                                for (int i=0; i < 4; i++) {
719                                        //                              Vector3 v = box.GetVertex(indices[i][0], indices[i][1], 0);
720                                        Vector3 v = box.Center();
721                                       
722                                        Vector3 direction = VssRay::GetDirection(v.x, v.y);
[438]723                                        if (Magnitude(direction) > Limits::Small)
724                                          direction.Normalize();
725                                        else
726                                          direction = Vector3(0, 1, 0);
[435]727                                        float k = 100.0f*leaf->GetImportance();
[434]728                                        // get 4 corners of the ray directions
729                                       
730                                        ray = new VssRay(origin, origin + (direction*k), NULL, &dummy);
731                                        rays.push_back(ray);
732                                }
733                        }
734                }
735  }
736
737  ExportMesh(mesh);
[438]738  ExportRays(rays);
739  CLEAR_CONTAINER(rays);
[434]740  delete mesh;
741  return true;
742}
743
744bool
[438]745X3dExporter::ExportVssTree2(const VssTree &tree,
746                                                        const Vector3 direction
747                                                        )
748{
749  stack<VssTreeNode *> tStack;
750       
751
752  mUseForcedMaterial = true;
753
754  Vector3 dirParam;
755
756  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
757  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
758
759  float maxImportance = 0.0f;
760  tStack.push(tree.GetRoot());
761  while (!tStack.empty()) {
762       
763        VssTreeNode *node = tStack.top();
764    tStack.pop();
765       
766    if (!node->IsLeaf()) {
767      VssTreeInterior *interior = (VssTreeInterior *)node;
768          if (interior->axis < 3) {
769                tStack.push(interior->front);
770                tStack.push(interior->back);
771          } else {
772                if (dirParam[interior->axis-3] < interior->position)
773                  tStack.push(interior->back);
774                else
775                  tStack.push(interior->front);
776          }
777    } else {
778          VssTreeLeaf *leaf = (VssTreeLeaf *)node;
779          if (tree.ValidLeaf(leaf)) {
780                float i = leaf->GetImportance();
781                if (i > maxImportance)
782                  maxImportance = i;
783          }
784        }
785  }
786
787  tStack.push(tree.GetRoot());
788  while (!tStack.empty()) {
789
790        VssTreeNode *node = tStack.top();
791    tStack.pop();
792       
793                       
794    if (!node->IsLeaf()) {
795      VssTreeInterior *interior = (VssTreeInterior *)node;
796          if (interior->axis < 3) {
797                tStack.push(interior->front);
798                tStack.push(interior->back);
799          } else {
800                if (dirParam[interior->axis-3] < interior->position)
801                  tStack.push(interior->back);
802                else
803                  tStack.push(interior->front);
804          }
805    } else {
806          VssTreeLeaf *leaf = (VssTreeLeaf *)node;
807          if (tree.ValidLeaf(leaf)) {
808                AxisAlignedBox3 box;
809                box = tree.GetBBox(leaf);
810                Mesh *mesh = new Mesh;
[486]811                box.AddBoxToMesh(mesh);
[438]812               
813                // get 4 corners of the ray directions
814               
815                mForcedMaterial.mDiffuseColor.b = 1.0f;
816                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
817                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
818               
819                ExportMesh(mesh);
820                delete mesh;
821          }
822        }
823  }
824
825  mUseForcedMaterial = false;
826
827  return true;
828}
829
830bool
[263]831X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
832{
[311]833        stack<BspNode *> tStack;
834
835        tStack.push(tree.GetRoot());
836
837        bool fm = mUseForcedMaterial;
838       
839        mUseForcedMaterial = true;
840       
841        mForcedMaterial.mDiffuseColor.g = 1.0f;
842        mForcedMaterial.mDiffuseColor.b = 1.0f;
843 
844        while (!tStack.empty())
845        {
846                BspNode *node = tStack.top();
847                tStack.pop();
848
849                if (node->IsLeaf())
850                {
851                        ViewCell *vc = dynamic_cast<BspLeaf *>(node)->GetViewCell();
[580]852#if 0     
[311]853                        // set the mesh material according to the ray density
854                        if (vc->mPassingRays.mRays)
855                        {
[313]856                                float importance =
[438]857                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
858                               
[311]859                                mForcedMaterial.mDiffuseColor.r = importance;
860                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
861                                ExportViewCell(vc);
[580]862
[438]863                        }
[580]864#endif
865                }
866                else
[311]867                {
868                        BspInterior *interior = (BspInterior *)node;
869                        tStack.push(interior->GetFront());
870                        tStack.push(interior->GetBack());
871                }
872        }
873 
874        // restore the state of forced material
875        mUseForcedMaterial = fm;
876
[263]877        return true;
878}
879
880bool
[191]881X3dExporter::ExportKdTreeRayDensity(const KdTree &tree)
882{
883  stack<KdNode *> tStack;
884
885  tStack.push(tree.GetRoot());
886
887  bool fm = mUseForcedMaterial;
888  mUseForcedMaterial = true;
889  mForcedMaterial.mDiffuseColor.g = 1.0f;
890  mForcedMaterial.mDiffuseColor.b = 1.0f;
891  while (!tStack.empty()) {
892    KdNode *node = tStack.top();
893    tStack.pop();
894    if (node->IsLeaf()) {
895      AxisAlignedBox3 box = tree.GetBox(node);
896      Mesh *mesh = new Mesh;
897     
898      // add 6 vertices of the box
[289]899      int index = (int)mesh->mVertices.size();
[191]900      for (int i=0; i < 8; i++) {
901        Vector3 v;
902        box.GetVertex(i, v);
903        mesh->mVertices.push_back(v);
904      }
905      mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
906      mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
907      mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
908     
909      mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
910      mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
911      mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
912
913
914      // set the mesh material according to the ray density
915      KdLeaf *leaf = (KdLeaf *) node;
916      if (leaf->mPassingRays.mRays) {
917        float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays;
918        //      float importance = leaf->mPassingRays.mContributions/1000.0f;
919        //      float importance = leaf->mPassingRays.mRays/1000.0f;
920        ///(float)leaf->mPassingRays.mRays;
921        // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f;
922        mForcedMaterial.mDiffuseColor.r = importance;
923        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
924        ExportMesh(mesh);
925      }
926      delete mesh;
927    } else {
928      KdInterior *interior = (KdInterior *)node;
929      tStack.push(interior->mFront);
930      tStack.push(interior->mBack);
931    }
932  }
933  // restore the state of forced material
934  mUseForcedMaterial = fm;
935  return true;
936}
[312]937
[329]938
[312]939struct BspSplitData
940{
[372]941        /// the current node
942        BspNode *mNode;
943
[449]944        vector<Plane3> mPlanes;
[372]945        vector<bool> mSides;
946        bool mIsFront;
[383]947        int mDepth;
[372]948
[313]949        BspSplitData(BspNode *node):
[383]950        mNode(node), mIsFront(false), mDepth(0)
[372]951        {};     
[383]952
[312]953        BspSplitData(BspNode *node,
[449]954                                vector<Plane3> planes,
[329]955                                vector<bool> sides,
[383]956                                const bool isFront,
957                                const int depth):
958        mNode(node), mPlanes(planes), mSides(sides),
959        mIsFront(isFront), mDepth(depth)
[312]960        {};
961};
962
[383]963void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
964                                                                           const vector<BspLeaf *> &leaves)
[360]965{
966        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
967
968        for (it = leaves.begin(); it != it_end; ++ it)
969        {
[503]970                BspNodeGeometry geom;
971                tree.ConstructGeometry(*it, geom);
[360]972               
[678]973                ExportPolygons(geom.GetPolys());
[360]974        }
975}
976
[449]977void X3dExporter::ExportBspNodeSplits(BspNode *root,
978                                                                          const AxisAlignedBox3 &box,
979                                                                          const bool exportDepth,
980                                                                          const bool epsilon)
[372]981{
982        std::stack<BspSplitData> tStack;
983
[449]984        BspSplitData tData(root);
[372]985        tStack.push(tData);
986 
987        PolygonContainer polys;
[383]988        vector <int> depths;
[372]989
[383]990        int maxDepth = 0;
991
[372]992        while (!tStack.empty())
993        {
994                // filter polygons donw the tree
995                BspSplitData tData = tStack.top();
996            tStack.pop();       
997               
[383]998                if (tData.mNode->IsLeaf())
[372]999                {
[383]1000                        if (tData.mDepth > maxDepth)
1001                                maxDepth = tData.mDepth;
1002                }
1003                else
1004                {
[372]1005                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
1006
[383]1007                        // add current side of split plane
[449]1008                        if (tData.mNode != root)
[383]1009                                tData.mSides.push_back(tData.mIsFront);
[372]1010
1011                        // bounded plane is added to the polygons
[383]1012                        Polygon3 *planePoly =
[449]1013                                box.CrossSection(interior->GetPlane());
[372]1014               
1015                        // do all the splits with the previous planes
1016                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
[436]1017                        {                               
[449]1018                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
1019                                        == Polygon3::SPLIT)
[372]1020                                {
1021                                        Polygon3 *frontPoly = new Polygon3();
1022                                        Polygon3 *backPoly = new Polygon3();
1023
[449]1024                                        planePoly->Split(tData.mPlanes[i],
1025                                                                         *frontPoly,
1026                                                                         *backPoly,
1027                                                                         epsilon);
1028
[372]1029                                        DEL_PTR(planePoly);
1030
1031                                        if(tData.mSides[i] == true)
1032                                        {
1033                                                planePoly = frontPoly;
1034                                                DEL_PTR(backPoly);
1035                                        }
1036                                        else
1037                                        {
1038                                                planePoly = backPoly;
1039                                                DEL_PTR(frontPoly);
1040                                        }
1041                                }
1042                        }
1043
1044                        tData.mPlanes.push_back(interior->GetPlane()); // add plane to split planes
1045
[449]1046                        if (planePoly->Valid(epsilon))
[383]1047                        {
[372]1048                                polys.push_back(planePoly);
[383]1049                                depths.push_back(tData.mDepth);
1050                        }
[372]1051                        else
1052                                DEL_PTR(planePoly);
1053                       
1054                        // push the children on the stack
[383]1055                        tStack.push(BspSplitData(interior->GetFront(), tData.mPlanes,
1056                                                     tData.mSides, true, tData.mDepth + 1));
1057                        tStack.push(BspSplitData(interior->GetBack(), tData.mPlanes,
1058                                                     tData.mSides, false, tData.mDepth + 1));
[372]1059                }
[383]1060        }
1061
1062        if (maxDepth > 0)
1063        {       
1064                mUseForcedMaterial = true;
1065                       
1066                for (int i = 0; i < (int)polys.size(); ++ i)
1067                {
1068                        mForcedMaterial.mDiffuseColor.b = 1.0f;
1069                        float importance =  (float)depths[i]/ (float)maxDepth;
1070           
1071                        mForcedMaterial.mDiffuseColor.r = importance;
1072                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1073
1074                        ExportPolygon(polys[i]);
1075                }
1076        }
1077        else
1078        {
1079                ExportPolygons(polys);
1080        }
1081
[372]1082        CLEAR_CONTAINER(polys);
1083}
1084
[449]1085void X3dExporter::ExportBspSplits(const BspTree &tree,
1086                                                                  const bool exportDepth)
1087{
1088        ExportBspNodeSplits(tree.GetRoot(),
1089                                                tree.GetBoundingBox(),
1090                                                exportDepth,
1091                                                tree.GetEpsilon());
1092}
1093
1094void X3dExporter::ExportBspSplits(const VspBspTree &tree,
1095                                                                  const bool exportDepth)
1096{
1097        ExportBspNodeSplits(tree.GetRoot(),
1098                                                tree.GetBoundingBox(),
1099                                                exportDepth,
1100                                                tree.GetEpsilon());
1101}
1102
[372]1103void X3dExporter::ExportBspSplitPlanes(const BspTree &tree)
1104{
1105        std::stack<BspNode *> tStack;
1106
1107        tStack.push(tree.GetRoot());
1108 
1109        PolygonContainer polys;
1110
1111        while (!tStack.empty())
1112        {
1113                // filter polygons donw the tree
1114                BspNode *node = tStack.top();
1115            tStack.pop();       
1116               
1117                if (!node->IsLeaf())
1118                {
1119                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
1120
1121                        // bounded plane is added to the polygons
[449]1122                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
[372]1123               
1124                        // push the children on the stack
1125                        tStack.push(interior->GetBack());
1126                        tStack.push(interior->GetFront());
1127                }
1128        }
1129
1130        ExportPolygons(polys);
1131        CLEAR_CONTAINER(polys);
1132}
[440]1133
1134
[449]1135void X3dExporter::ExportGeometry(const ObjectContainer &objects)
[440]1136{
[449]1137        for (int j = 0; j < objects.size(); ++ j)
1138                ExportIntersectable(objects[j]);
[440]1139}
[449]1140
1141
[450]1142bool
1143X3dExporter::ExportRssTree2(const RssTree &tree,
1144                                                        const Vector3 direction
1145                                                        )
1146{
1147  stack<RssTreeNode *> tStack;
1148 
1149 
1150  mUseForcedMaterial = true;
1151
1152  Vector3 dirParam;
1153
1154  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
1155  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
1156
1157  float maxImportance = 0.0f;
1158  tStack.push(tree.GetRoot());
1159  while (!tStack.empty()) {
1160       
1161        RssTreeNode *node = tStack.top();
1162    tStack.pop();
1163       
1164    if (!node->IsLeaf()) {
1165      RssTreeInterior *interior = (RssTreeInterior *)node;
1166          if (interior->axis < 3) {
1167                tStack.push(interior->front);
1168                tStack.push(interior->back);
1169          } else {
1170                if (dirParam[interior->axis-3] < interior->position)
1171                  tStack.push(interior->back);
1172                else
1173                  tStack.push(interior->front);
1174          }
1175    } else {
1176          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1177          if (tree.ValidLeaf(leaf)) {
1178                float i = leaf->GetImportance();
1179                if (i > maxImportance)
1180                  maxImportance = i;
1181          }
1182        }
1183  }
1184
1185  tStack.push(tree.GetRoot());
1186  while (!tStack.empty()) {
1187
1188        RssTreeNode *node = tStack.top();
1189    tStack.pop();
1190       
1191                       
1192    if (!node->IsLeaf()) {
1193      RssTreeInterior *interior = (RssTreeInterior *)node;
1194          if (interior->axis < 3) {
1195                tStack.push(interior->front);
1196                tStack.push(interior->back);
1197          } else {
1198                if (dirParam[interior->axis-3] < interior->position)
1199                  tStack.push(interior->back);
1200                else
1201                  tStack.push(interior->front);
1202          }
1203    } else {
1204          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1205          if (tree.ValidLeaf(leaf)) {
1206                AxisAlignedBox3 box;
1207                box = tree.GetShrankedBBox(leaf);
1208                Mesh *mesh = new Mesh;
[486]1209                box.AddBoxToMesh(mesh);
[450]1210               
1211                // get 4 corners of the ray directions
1212               
1213                mForcedMaterial.mDiffuseColor.b = 1.0f;
1214                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
1215                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1216               
1217                ExportMesh(mesh);
1218                delete mesh;
1219          }
1220        }
1221  }
1222
1223  mUseForcedMaterial = false;
1224
1225  return true;
1226}
[459]1227
1228
1229void
1230X3dExporter::ExportViewpoint(const Vector3 &point,
1231                                                         const Vector3 &direction)
1232{
1233  stream<<"<Viewpoint "<<endl;
1234 
1235  stream<<"position=\""<<point.x<<" "<<point.y<<" "<<point.z<<"\""<<endl;
1236  //  stream<<"orientation "<<direction.x<<direction.y<<direction.z<<endl;
1237 
1238  stream<<">"<<endl;
1239  stream<<"</Viewpoint>"<<endl;
[535]1240
[459]1241}
[535]1242
1243
1244
1245void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1246{
[540]1247        if (beam.mMesh)
1248        {
1249                ExportMesh(beam.mMesh);
1250                return;
1251        }
1252
[535]1253        PolygonContainer polys;
1254        //ExportBox(beam.mBox);
1255
[540]1256        const float zfar = 2.0f * Magnitude(box.Diagonal());
1257
1258        // box should not never remove part of beam polygons
[564]1259        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0f);
1260        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0f);
[540]1261
1262        AxisAlignedBox3 bbox(bmin, bmax);
1263        Plane3 fplane;
1264        fplane.mNormal = -beam.mPlanes[0].mNormal;
1265
1266        fplane.mD = beam.mPlanes[0].mD - zfar - 1.0f;
1267       
1268        vector<Plane3> planes = beam.mPlanes;
1269        planes.push_back(fplane);
1270
1271        for (int i = 0; i < planes.size(); ++ i)
[535]1272        {
[540]1273                Polygon3 *poly = bbox.CrossSection(planes[i]);
1274                if (!poly->Valid(Limits::Small))
1275                        DEL_PTR(poly);
[535]1276               
[540]1277                for (int j = 0; (j < planes.size()) && poly; ++ j)
[535]1278                {
1279                        if (j != i)
1280                        {
1281                                Polygon3 *front = new Polygon3();
1282                                Polygon3 *back = new Polygon3();
1283                               
[540]1284                                poly->Split(planes[j], *front, *back, Limits::Small);
[535]1285                                DEL_PTR(poly);
1286                                DEL_PTR(front);
1287
1288                                if (!back->Valid(Limits::Small))
1289                                        DEL_PTR(back);
1290                                poly = back;
1291                        }
1292                }
1293                if (poly)
1294                        polys.push_back(poly);
1295        }
1296
1297        ExportPolygons(polys);
1298        CLEAR_CONTAINER(polys);
1299}
Note: See TracBrowser for help on using the repository browser.