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

Revision 547, 31.0 KB checked in by mattausch, 19 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
279                        ExportPolygons(cell->mPolys);
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();
852     
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);
[438]862                        }
[311]863                } else
864                {
865                        BspInterior *interior = (BspInterior *)node;
866                        tStack.push(interior->GetFront());
867                        tStack.push(interior->GetBack());
868                }
869        }
870 
871        // restore the state of forced material
872        mUseForcedMaterial = fm;
873
[263]874        return true;
875}
876
877bool
[191]878X3dExporter::ExportKdTreeRayDensity(const KdTree &tree)
879{
880  stack<KdNode *> tStack;
881
882  tStack.push(tree.GetRoot());
883
884  bool fm = mUseForcedMaterial;
885  mUseForcedMaterial = true;
886  mForcedMaterial.mDiffuseColor.g = 1.0f;
887  mForcedMaterial.mDiffuseColor.b = 1.0f;
888  while (!tStack.empty()) {
889    KdNode *node = tStack.top();
890    tStack.pop();
891    if (node->IsLeaf()) {
892      AxisAlignedBox3 box = tree.GetBox(node);
893      Mesh *mesh = new Mesh;
894     
895      // add 6 vertices of the box
[289]896      int index = (int)mesh->mVertices.size();
[191]897      for (int i=0; i < 8; i++) {
898        Vector3 v;
899        box.GetVertex(i, v);
900        mesh->mVertices.push_back(v);
901      }
902      mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) );
903      mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) );
904      mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) );
905     
906      mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) );
907      mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) );
908      mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) );
909
910
911      // set the mesh material according to the ray density
912      KdLeaf *leaf = (KdLeaf *) node;
913      if (leaf->mPassingRays.mRays) {
914        float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays;
915        //      float importance = leaf->mPassingRays.mContributions/1000.0f;
916        //      float importance = leaf->mPassingRays.mRays/1000.0f;
917        ///(float)leaf->mPassingRays.mRays;
918        // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f;
919        mForcedMaterial.mDiffuseColor.r = importance;
920        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
921        ExportMesh(mesh);
922      }
923      delete mesh;
924    } else {
925      KdInterior *interior = (KdInterior *)node;
926      tStack.push(interior->mFront);
927      tStack.push(interior->mBack);
928    }
929  }
930  // restore the state of forced material
931  mUseForcedMaterial = fm;
932  return true;
933}
[312]934
[329]935
[312]936struct BspSplitData
937{
[372]938        /// the current node
939        BspNode *mNode;
940
[449]941        vector<Plane3> mPlanes;
[372]942        vector<bool> mSides;
943        bool mIsFront;
[383]944        int mDepth;
[372]945
[313]946        BspSplitData(BspNode *node):
[383]947        mNode(node), mIsFront(false), mDepth(0)
[372]948        {};     
[383]949
[312]950        BspSplitData(BspNode *node,
[449]951                                vector<Plane3> planes,
[329]952                                vector<bool> sides,
[383]953                                const bool isFront,
954                                const int depth):
955        mNode(node), mPlanes(planes), mSides(sides),
956        mIsFront(isFront), mDepth(depth)
[312]957        {};
958};
959
[383]960void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
961                                                                           const vector<BspLeaf *> &leaves)
[360]962{
963        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
964
965        for (it = leaves.begin(); it != it_end; ++ it)
966        {
[503]967                BspNodeGeometry geom;
968                tree.ConstructGeometry(*it, geom);
[360]969               
[503]970                ExportPolygons(geom.mPolys);
[360]971        }
972}
973
[449]974void X3dExporter::ExportBspNodeSplits(BspNode *root,
975                                                                          const AxisAlignedBox3 &box,
976                                                                          const bool exportDepth,
977                                                                          const bool epsilon)
[372]978{
979        std::stack<BspSplitData> tStack;
980
[449]981        BspSplitData tData(root);
[372]982        tStack.push(tData);
983 
984        PolygonContainer polys;
[383]985        vector <int> depths;
[372]986
[383]987        int maxDepth = 0;
988
[372]989        while (!tStack.empty())
990        {
991                // filter polygons donw the tree
992                BspSplitData tData = tStack.top();
993            tStack.pop();       
994               
[383]995                if (tData.mNode->IsLeaf())
[372]996                {
[383]997                        if (tData.mDepth > maxDepth)
998                                maxDepth = tData.mDepth;
999                }
1000                else
1001                {
[372]1002                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
1003
[383]1004                        // add current side of split plane
[449]1005                        if (tData.mNode != root)
[383]1006                                tData.mSides.push_back(tData.mIsFront);
[372]1007
1008                        // bounded plane is added to the polygons
[383]1009                        Polygon3 *planePoly =
[449]1010                                box.CrossSection(interior->GetPlane());
[372]1011               
1012                        // do all the splits with the previous planes
1013                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
[436]1014                        {                               
[449]1015                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
1016                                        == Polygon3::SPLIT)
[372]1017                                {
1018                                        Polygon3 *frontPoly = new Polygon3();
1019                                        Polygon3 *backPoly = new Polygon3();
1020
[449]1021                                        planePoly->Split(tData.mPlanes[i],
1022                                                                         *frontPoly,
1023                                                                         *backPoly,
1024                                                                         epsilon);
1025
[372]1026                                        DEL_PTR(planePoly);
1027
1028                                        if(tData.mSides[i] == true)
1029                                        {
1030                                                planePoly = frontPoly;
1031                                                DEL_PTR(backPoly);
1032                                        }
1033                                        else
1034                                        {
1035                                                planePoly = backPoly;
1036                                                DEL_PTR(frontPoly);
1037                                        }
1038                                }
1039                        }
1040
1041                        tData.mPlanes.push_back(interior->GetPlane()); // add plane to split planes
1042
[449]1043                        if (planePoly->Valid(epsilon))
[383]1044                        {
[372]1045                                polys.push_back(planePoly);
[383]1046                                depths.push_back(tData.mDepth);
1047                        }
[372]1048                        else
1049                                DEL_PTR(planePoly);
1050                       
1051                        // push the children on the stack
[383]1052                        tStack.push(BspSplitData(interior->GetFront(), tData.mPlanes,
1053                                                     tData.mSides, true, tData.mDepth + 1));
1054                        tStack.push(BspSplitData(interior->GetBack(), tData.mPlanes,
1055                                                     tData.mSides, false, tData.mDepth + 1));
[372]1056                }
[383]1057        }
1058
1059        if (maxDepth > 0)
1060        {       
1061                mUseForcedMaterial = true;
1062                       
1063                for (int i = 0; i < (int)polys.size(); ++ i)
1064                {
1065                        mForcedMaterial.mDiffuseColor.b = 1.0f;
1066                        float importance =  (float)depths[i]/ (float)maxDepth;
1067           
1068                        mForcedMaterial.mDiffuseColor.r = importance;
1069                        mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1070
1071                        ExportPolygon(polys[i]);
1072                }
1073        }
1074        else
1075        {
1076                ExportPolygons(polys);
1077        }
1078
[372]1079        CLEAR_CONTAINER(polys);
1080}
1081
[449]1082void X3dExporter::ExportBspSplits(const BspTree &tree,
1083                                                                  const bool exportDepth)
1084{
1085        ExportBspNodeSplits(tree.GetRoot(),
1086                                                tree.GetBoundingBox(),
1087                                                exportDepth,
1088                                                tree.GetEpsilon());
1089}
1090
1091void X3dExporter::ExportBspSplits(const VspBspTree &tree,
1092                                                                  const bool exportDepth)
1093{
1094        ExportBspNodeSplits(tree.GetRoot(),
1095                                                tree.GetBoundingBox(),
1096                                                exportDepth,
1097                                                tree.GetEpsilon());
1098}
1099
[372]1100void X3dExporter::ExportBspSplitPlanes(const BspTree &tree)
1101{
1102        std::stack<BspNode *> tStack;
1103
1104        tStack.push(tree.GetRoot());
1105 
1106        PolygonContainer polys;
1107
1108        while (!tStack.empty())
1109        {
1110                // filter polygons donw the tree
1111                BspNode *node = tStack.top();
1112            tStack.pop();       
1113               
1114                if (!node->IsLeaf())
1115                {
1116                        BspInterior *interior = dynamic_cast<BspInterior *>(node);
1117
1118                        // bounded plane is added to the polygons
[449]1119                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
[372]1120               
1121                        // push the children on the stack
1122                        tStack.push(interior->GetBack());
1123                        tStack.push(interior->GetFront());
1124                }
1125        }
1126
1127        ExportPolygons(polys);
1128        CLEAR_CONTAINER(polys);
1129}
[440]1130
1131
[449]1132void X3dExporter::ExportGeometry(const ObjectContainer &objects)
[440]1133{
[449]1134        for (int j = 0; j < objects.size(); ++ j)
1135                ExportIntersectable(objects[j]);
[440]1136}
[449]1137
1138
[450]1139bool
1140X3dExporter::ExportRssTree2(const RssTree &tree,
1141                                                        const Vector3 direction
1142                                                        )
1143{
1144  stack<RssTreeNode *> tStack;
1145 
1146 
1147  mUseForcedMaterial = true;
1148
1149  Vector3 dirParam;
1150
1151  dirParam.x = VssRay::GetDirParam(0, Normalize(direction));
1152  dirParam.y = VssRay::GetDirParam(1, Normalize(direction));
1153
1154  float maxImportance = 0.0f;
1155  tStack.push(tree.GetRoot());
1156  while (!tStack.empty()) {
1157       
1158        RssTreeNode *node = tStack.top();
1159    tStack.pop();
1160       
1161    if (!node->IsLeaf()) {
1162      RssTreeInterior *interior = (RssTreeInterior *)node;
1163          if (interior->axis < 3) {
1164                tStack.push(interior->front);
1165                tStack.push(interior->back);
1166          } else {
1167                if (dirParam[interior->axis-3] < interior->position)
1168                  tStack.push(interior->back);
1169                else
1170                  tStack.push(interior->front);
1171          }
1172    } else {
1173          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1174          if (tree.ValidLeaf(leaf)) {
1175                float i = leaf->GetImportance();
1176                if (i > maxImportance)
1177                  maxImportance = i;
1178          }
1179        }
1180  }
1181
1182  tStack.push(tree.GetRoot());
1183  while (!tStack.empty()) {
1184
1185        RssTreeNode *node = tStack.top();
1186    tStack.pop();
1187       
1188                       
1189    if (!node->IsLeaf()) {
1190      RssTreeInterior *interior = (RssTreeInterior *)node;
1191          if (interior->axis < 3) {
1192                tStack.push(interior->front);
1193                tStack.push(interior->back);
1194          } else {
1195                if (dirParam[interior->axis-3] < interior->position)
1196                  tStack.push(interior->back);
1197                else
1198                  tStack.push(interior->front);
1199          }
1200    } else {
1201          RssTreeLeaf *leaf = (RssTreeLeaf *)node;
1202          if (tree.ValidLeaf(leaf)) {
1203                AxisAlignedBox3 box;
1204                box = tree.GetShrankedBBox(leaf);
1205                Mesh *mesh = new Mesh;
[486]1206                box.AddBoxToMesh(mesh);
[450]1207               
1208                // get 4 corners of the ray directions
1209               
1210                mForcedMaterial.mDiffuseColor.b = 1.0f;
1211                mForcedMaterial.mDiffuseColor.r = leaf->GetImportance()/maxImportance;
1212                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
1213               
1214                ExportMesh(mesh);
1215                delete mesh;
1216          }
1217        }
1218  }
1219
1220  mUseForcedMaterial = false;
1221
1222  return true;
1223}
[459]1224
1225
1226void
1227X3dExporter::ExportViewpoint(const Vector3 &point,
1228                                                         const Vector3 &direction)
1229{
1230  stream<<"<Viewpoint "<<endl;
1231 
1232  stream<<"position=\""<<point.x<<" "<<point.y<<" "<<point.z<<"\""<<endl;
1233  //  stream<<"orientation "<<direction.x<<direction.y<<direction.z<<endl;
1234 
1235  stream<<">"<<endl;
1236  stream<<"</Viewpoint>"<<endl;
[535]1237
[459]1238}
[535]1239
1240
1241
1242void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1243{
[540]1244        if (beam.mMesh)
1245        {
1246                ExportMesh(beam.mMesh);
1247                return;
1248        }
1249
[535]1250        PolygonContainer polys;
1251        //ExportBox(beam.mBox);
1252
[540]1253        const float zfar = 2.0f * Magnitude(box.Diagonal());
1254
1255        // box should not never remove part of beam polygons
1256        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0);
1257        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0);
1258
1259        AxisAlignedBox3 bbox(bmin, bmax);
1260        Plane3 fplane;
1261        fplane.mNormal = -beam.mPlanes[0].mNormal;
1262
1263        fplane.mD = beam.mPlanes[0].mD - zfar - 1.0f;
1264       
1265        vector<Plane3> planes = beam.mPlanes;
1266        planes.push_back(fplane);
1267
1268        for (int i = 0; i < planes.size(); ++ i)
[535]1269        {
[540]1270                Polygon3 *poly = bbox.CrossSection(planes[i]);
1271                if (!poly->Valid(Limits::Small))
1272                        DEL_PTR(poly);
[535]1273               
[540]1274                for (int j = 0; (j < planes.size()) && poly; ++ j)
[535]1275                {
1276                        if (j != i)
1277                        {
1278                                Polygon3 *front = new Polygon3();
1279                                Polygon3 *back = new Polygon3();
1280                               
[540]1281                                poly->Split(planes[j], *front, *back, Limits::Small);
[535]1282                                DEL_PTR(poly);
1283                                DEL_PTR(front);
1284
1285                                if (!back->Valid(Limits::Small))
1286                                        DEL_PTR(back);
1287                                poly = back;
1288                        }
1289                }
1290                if (poly)
1291                        polys.push_back(poly);
1292        }
1293
1294        ExportPolygons(polys);
1295        CLEAR_CONTAINER(polys);
1296}
Note: See TracBrowser for help on using the repository browser.