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

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