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

Revision 712, 31.7 KB checked in by mattausch, 19 years ago (diff)

added exporter for Vrml
added transformations to x3d loader

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