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

Revision 678, 31.1 KB checked in by mattausch, 19 years ago (diff)
Line 
1#include <stack>
2#include "common.h"
3#include "SceneGraph.h"
4#include "X3dExporter.h"
5#include "Mesh.h"
6#include "KdTree.h"
7#include "ViewCellBsp.h"
8#include "ViewCell.h"
9#include "Polygon3.h"
10#include "VssRay.h"
11#include "VspKdTree.h"
12#include "VssTree.h"
13#include "VspBspTree.h"
14#include "RssTree.h"
15#include "Beam.h"
16
17
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
34
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
84bool
85X3dExporter::ExportRays(const RayContainer &rays,
86                                                const float length,
87                                                const RgbColor &color)
88{
89  RayContainer::const_iterator ri = rays.begin();
90
91  stream<<"<Shape>"<<endl;
92  stream<<"<Appearance>"<<endl;
93  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
94    "\" />"<<endl;
95  stream<<"</Appearance>"<<endl;
96 
97  stream<<"<IndexedLineSet coordIndex=\""<<endl;
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++) {
111    Vector3 a = (*ri)->GetLoc();
112   
113    Vector3 b;
114    if (length < 0)
115      b = (*ri)->GetLoc() - length*(*ri)->GetDir();
116    else
117      if ((*ri)->intersections.size()==0)
118                b = (*ri)->GetLoc() + length*(*ri)->GetDir();
119      else
120                b = (*ri)->Extrap((*ri)->intersections[0].mT);
121   
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;
130
131  return true;
132}
133
134bool
135X3dExporter::ExportRays(const VssRayContainer &rays,
136                                                const RgbColor &color)
137{
138  VssRayContainer::const_iterator ri = rays.begin();
139
140  stream<<"<Shape>"<<endl;
141  stream<<"<Appearance>"<<endl;
142  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
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++) {
160    const Vector3 a = (*ri)->GetOrigin();
161        //const Vector3 b = (*ri)->mTerminationObject ? (*ri)->GetTermination() : a + 1000 * Normalize((*ri)->GetDir());
162        const Vector3 b = (*ri)->GetTermination(); // matt: change again!!
163
164    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
165        stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
166  }
167 
168  stream<<"\" >"<<endl;
169  stream<<"</Coordinate>"<<endl;
170  stream<<"</IndexedLineSet>"<<endl;
171  stream<<"</Shape>"<<endl;
172       
173  return true;
174}
175
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 
186  ObjectContainer::const_iterator mi = node->mGeometry.begin();
187  for (; mi != node->mGeometry.end(); mi++) {
188    // export the transform...
189    ExportIntersectable(*mi);
190  }
191 
192  stream<<"</Group>"<<endl;
193
194}
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);
202        break;
203  case Intersectable::VIEW_CELL:
204        ExportViewCell((ViewCell *)object);
205    break;
206  default:
207    cerr<<"Sorry the export for object not yet defined"<<endl;
208    break;
209  }
210}
211
212void
213X3dExporter::ExportMeshInstance(MeshInstance *object)
214{
215  // $$JB$$
216  // in the future check whether the mesh was not already exported
217  // and use a reference to the that mesh instead
218  ExportMesh(object->GetMesh());
219}
220
221void
222X3dExporter::ExportViewCells(const ViewCellContainer &viewCells)
223{
224        ViewCellContainer::const_iterator it, it_end = viewCells.end();
225
226        for (it = viewCells.begin(); it != it_end; ++ it)
227                ExportViewCell(*it);
228}
229
230void
231X3dExporter::ExportBspLeaves(const BspTree &tree, const int maxPvs)
232{
233        stack<pair<BspNode *, BspNodeGeometry *> > tStack;
234        ViewCell::NewMail();
235
236        BspNodeGeometry *geom = new BspNodeGeometry();
237        tree.ConstructGeometry(tree.GetRoot(), *geom);
238
239        tStack.push(pair<BspNode *, BspNodeGeometry *>(tree.GetRoot(), geom));
240
241        if (maxPvs > 0)
242                mUseForcedMaterial = true;
243
244        while (!tStack.empty())
245        {
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
257                        cell->SplitGeometry(*front,
258                                                                *back,
259                                                                interior->GetPlane(),
260                                                                tree.GetBoundingBox(),
261                                                                tree.GetEpsilon());
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->GetPolys());
280                }
281               
282                DEL_PTR(cell);
283        }
284}
285
286void
287X3dExporter::ExportViewCell(ViewCell *viewCell)
288{
289        if (viewCell->GetMesh())
290                ExportMesh(viewCell->GetMesh());
291}
292
293void
294X3dExporter::ExportMesh(Mesh *mesh)
295{
296
297  stream<<"<Shape>"<<endl;
298  stream<<"<Appearance>"<<endl;
299 
300  // $$ tmp -> random material
301 
302  float r, g, b;
303
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    }
319  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
320    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
321  stream<<"</Appearance>"<<endl;
322
323
324  if (mWireframe)
325    stream<<"<IndexedLineSet coordIndex=\""<<endl;
326  else
327    //stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
328        stream << "<IndexedFaceSet coordIndex=\"" << endl;
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<<" ";
339        if (mWireframe) // final line to finish polygon
340                stream << (*face->mVertexIndices.begin()) << " ";
341
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
357  if (mWireframe)
358    stream<<"</IndexedLineSet>"<<endl;
359  else
360    stream<<"</IndexedFaceSet>"<<endl;
361 
362  stream<<"</Shape>"<<endl;
363
364}
365
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
400        //-- create and write indices
401        if (mWireframe)
402                stream<<"<IndexedLineSet coordIndex=\""<<endl;
403        else
404                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
405                stream << "<IndexedFaceSet coordIndex=\"" << endl;
406        int index = 0;
407       
408        VertexContainer::const_iterator vi; 
409       
410        for (index = 0; index < (int)poly->mVertices.size(); ++ index)
411                stream << index << " ";
412       
413        if (mWireframe) // final line to finish polygon
414                stream << "0 ";
415
416        stream << "-1" << endl;
417        stream << "\" >" << endl;
418       
419        stream << "<Coordinate  point=\"" << endl;
420 
421        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
422        {
423                stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
424                stream << "," << endl;
425        }
426 
427        stream << "\" >" << endl;
428        stream << "</Coordinate>" << endl;
429
430        if (mWireframe)
431                stream << "</IndexedLineSet>" << endl;
432        else
433                stream << "</IndexedFaceSet>" << endl;
434 
435        stream << "</Shape>" << endl;
436}
437
438void X3dExporter::ExportPolygons(const PolygonContainer &polys)
439{
440        stream << "<Shape>" << endl;
441        stream << "<Appearance>" << endl;
442 
443        // $$ tmp -> random material
444 
445        float r, g, b;
446
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)
468                stream<<"<IndexedLineSet coordIndex=\""<<endl;
469        else
470                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
471                stream << "<IndexedFaceSet coordIndex=\"" << endl;
472
473        int index = 0;
474       
475        PolygonContainer::const_iterator pit;
476
477    VertexContainer::const_iterator vi; 
478       
479        for (pit = polys.begin(); pit != polys.end(); ++pit)
480        {
481                Polygon3 *poly = *pit;
482                int startIdx = index;
483                for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
484                {
485                        stream << index ++ << " ";
486                }
487
488                stream << startIdx << " ";// finish line
489                stream << "-1" << endl;
490        }
491
492        stream << "\" >" << endl;
493       
494        stream << "<Coordinate  point=\"" << endl;
495        for (pit = polys.begin(); pit != polys.end(); ++ pit)
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
515bool
516X3dExporter::ExportBox(const AxisAlignedBox3 &box)
517{
518  Mesh *mesh = new Mesh;
519  // add 8 vertices of the box
520  int index = (int)mesh->mVertices.size();
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
541X3dExporter::ExportBspTree(const BspTree &tree)
542{
543        if (mExportRayDensity)
544        {
545                return ExportBspTreeRayDensity(tree);
546        }
547 
548        bool savedWireframe = mWireframe;
549
550        SetWireframe();
551       
552        ExportBox(tree.GetBoundingBox());
553       
554        if (!savedWireframe)
555                SetFilled();
556
557        // export view cells
558        ExportBspLeaves(tree); 
559
560        return true;
561}
562
563bool X3dExporter::ExportVspKdTree(const VspKdTree &tree, const int maxPvs)
564{
565        stack<VspKdNode *> tStack;
566
567        tStack.push(tree.GetRoot());
568
569        //Mesh *mesh = new Mesh;
570 
571        if (maxPvs > 0)
572                mUseForcedMaterial = true;
573
574        while (!tStack.empty())
575        {
576                VspKdNode *node = tStack.top();
577   
578                tStack.pop();
579
580                if (node->IsLeaf())
581                {
582                        AxisAlignedBox3 box = tree.GetBBox(node);
583
584                        Mesh *mesh = new Mesh;
585
586                        // add 6 vertices of the box
587                        int index = (int)mesh->mVertices.size();
588
589                        for (int i=0; i < 8; ++ i)
590                        {
591                                Vector3 v;
592                                box.GetVertex(i, v);
593                                mesh->mVertices.push_back(v);
594                        }
595
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) );
599
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) );
603
604                        if (maxPvs > 0)
605                        {
606                                VspKdLeaf *leaf = dynamic_cast<VspKdLeaf *>(node);
607
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                        }
616
617                        ExportMesh(mesh);
618                        DEL_PTR(mesh);
619                }
620                else 
621                {
622                        VspKdInterior *interior = dynamic_cast<VspKdInterior *>(node);
623                        tStack.push(interior->GetFront());
624                        tStack.push(interior->GetBack());
625                }
626        }
627 
628        //ExportMesh(mesh);
629        //DEL_PTR(mesh);
630
631        return true;
632}
633
634
635bool X3dExporter::ExportKdTree(const KdTree &tree)
636{
637         if (mExportRayDensity) {
638    return ExportKdTreeRayDensity(tree);
639  }
640 
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
652    int index = (int)mesh->mVertices.size();
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;
676        // TODO
677        return true;
678}
679
680
681
682
683bool
684X3dExporter::ExportVssTree(const VssTree &tree
685                                                   )
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);
708                        box.AddBoxToMesh(mesh);
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);
723                                        if (Magnitude(direction) > Limits::Small)
724                                          direction.Normalize();
725                                        else
726                                          direction = Vector3(0, 1, 0);
727                                        float k = 100.0f*leaf->GetImportance();
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);
738  ExportRays(rays);
739  CLEAR_CONTAINER(rays);
740  delete mesh;
741  return true;
742}
743
744bool
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;
811                box.AddBoxToMesh(mesh);
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
831X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
832{
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#if 0     
853                        // set the mesh material according to the ray density
854                        if (vc->mPassingRays.mRays)
855                        {
856                                float importance =
857                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
858                               
859                                mForcedMaterial.mDiffuseColor.r = importance;
860                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
861                                ExportViewCell(vc);
862
863                        }
864#endif
865                }
866                else
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
877        return true;
878}
879
880bool
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
899      int index = (int)mesh->mVertices.size();
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}
937
938
939struct BspSplitData
940{
941        /// the current node
942        BspNode *mNode;
943
944        vector<Plane3> mPlanes;
945        vector<bool> mSides;
946        bool mIsFront;
947        int mDepth;
948
949        BspSplitData(BspNode *node):
950        mNode(node), mIsFront(false), mDepth(0)
951        {};     
952
953        BspSplitData(BspNode *node,
954                                vector<Plane3> planes,
955                                vector<bool> sides,
956                                const bool isFront,
957                                const int depth):
958        mNode(node), mPlanes(planes), mSides(sides),
959        mIsFront(isFront), mDepth(depth)
960        {};
961};
962
963void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
964                                                                           const vector<BspLeaf *> &leaves)
965{
966        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
967
968        for (it = leaves.begin(); it != it_end; ++ it)
969        {
970                BspNodeGeometry geom;
971                tree.ConstructGeometry(*it, geom);
972               
973                ExportPolygons(geom.GetPolys());
974        }
975}
976
977void X3dExporter::ExportBspNodeSplits(BspNode *root,
978                                                                          const AxisAlignedBox3 &box,
979                                                                          const bool exportDepth,
980                                                                          const bool epsilon)
981{
982        std::stack<BspSplitData> tStack;
983
984        BspSplitData tData(root);
985        tStack.push(tData);
986 
987        PolygonContainer polys;
988        vector <int> depths;
989
990        int maxDepth = 0;
991
992        while (!tStack.empty())
993        {
994                // filter polygons donw the tree
995                BspSplitData tData = tStack.top();
996            tStack.pop();       
997               
998                if (tData.mNode->IsLeaf())
999                {
1000                        if (tData.mDepth > maxDepth)
1001                                maxDepth = tData.mDepth;
1002                }
1003                else
1004                {
1005                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
1006
1007                        // add current side of split plane
1008                        if (tData.mNode != root)
1009                                tData.mSides.push_back(tData.mIsFront);
1010
1011                        // bounded plane is added to the polygons
1012                        Polygon3 *planePoly =
1013                                box.CrossSection(interior->GetPlane());
1014               
1015                        // do all the splits with the previous planes
1016                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
1017                        {                               
1018                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
1019                                        == Polygon3::SPLIT)
1020                                {
1021                                        Polygon3 *frontPoly = new Polygon3();
1022                                        Polygon3 *backPoly = new Polygon3();
1023
1024                                        planePoly->Split(tData.mPlanes[i],
1025                                                                         *frontPoly,
1026                                                                         *backPoly,
1027                                                                         epsilon);
1028
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
1046                        if (planePoly->Valid(epsilon))
1047                        {
1048                                polys.push_back(planePoly);
1049                                depths.push_back(tData.mDepth);
1050                        }
1051                        else
1052                                DEL_PTR(planePoly);
1053                       
1054                        // push the children on the stack
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));
1059                }
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
1082        CLEAR_CONTAINER(polys);
1083}
1084
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
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
1122                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
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}
1133
1134
1135void X3dExporter::ExportGeometry(const ObjectContainer &objects)
1136{
1137        for (int j = 0; j < objects.size(); ++ j)
1138                ExportIntersectable(objects[j]);
1139}
1140
1141
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;
1209                box.AddBoxToMesh(mesh);
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}
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;
1240
1241}
1242
1243
1244
1245void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1246{
1247        if (beam.mMesh)
1248        {
1249                ExportMesh(beam.mMesh);
1250                return;
1251        }
1252
1253        PolygonContainer polys;
1254        //ExportBox(beam.mBox);
1255
1256        const float zfar = 2.0f * Magnitude(box.Diagonal());
1257
1258        // box should not never remove part of beam polygons
1259        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0f);
1260        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0f);
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)
1272        {
1273                Polygon3 *poly = bbox.CrossSection(planes[i]);
1274                if (!poly->Valid(Limits::Small))
1275                        DEL_PTR(poly);
1276               
1277                for (int j = 0; (j < planes.size()) && poly; ++ j)
1278                {
1279                        if (j != i)
1280                        {
1281                                Polygon3 *front = new Polygon3();
1282                                Polygon3 *back = new Polygon3();
1283                               
1284                                poly->Split(planes[j], *front, *back, Limits::Small);
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.