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

Revision 1545, 28.6 KB checked in by mattausch, 18 years ago (diff)
RevLine 
[162]1#include <stack>
2#include "common.h"
3#include "SceneGraph.h"
4#include "X3dExporter.h"
5#include "Mesh.h"
6#include "KdTree.h"
[242]7#include "ViewCellBsp.h"
8#include "ViewCell.h"
[260]9#include "Polygon3.h"
[386]10#include "VssRay.h"
[1233]11#include "HierarchyManager.h"
[434]12#include "VssTree.h"
[449]13#include "VspBspTree.h"
[450]14#include "RssTree.h"
[535]15#include "Beam.h"
[162]16
[863]17namespace GtpVisibilityPreprocessor {
[449]18
[694]19
[162]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
[1486]29
[162]30X3dExporter::~X3dExporter()
31{
32  stream<<"</Scene>"<<endl;
33  stream<<"</X3D>"<<endl;
34  stream.close();
35}
36
[176]37
[1112]38
[162]39bool
[386]40X3dExporter::ExportRays(const RayContainer &rays,
[444]41                                                const float length,
42                                                const RgbColor &color)
[162]43{
[386]44  RayContainer::const_iterator ri = rays.begin();
45
[162]46  stream<<"<Shape>"<<endl;
[176]47  stream<<"<Appearance>"<<endl;
[427]48  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
[176]49    "\" />"<<endl;
50  stream<<"</Appearance>"<<endl;
51 
[209]52  stream<<"<IndexedLineSet coordIndex=\""<<endl;
[162]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++) {
[386]66    Vector3 a = (*ri)->GetLoc();
[162]67   
[176]68    Vector3 b;
69    if (length < 0)
[386]70      b = (*ri)->GetLoc() - length*(*ri)->GetDir();
[176]71    else
[386]72      if ((*ri)->intersections.size()==0)
[492]73                b = (*ri)->GetLoc() + length*(*ri)->GetDir();
[176]74      else
[492]75                b = (*ri)->Extrap((*ri)->intersections[0].mT);
[176]76   
[162]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;
[386]85
[162]86  return true;
87}
88
[1112]89
[349]90bool
[1112]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;
[1178]117  int size = (int)rays.size() + 2;
[1112]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
[386]143X3dExporter::ExportRays(const VssRayContainer &rays,
[444]144                                                const RgbColor &color)
[349]145{
[386]146  VssRayContainer::const_iterator ri = rays.begin();
[349]147
148  stream<<"<Shape>"<<endl;
149  stream<<"<Appearance>"<<endl;
[427]150  stream<<"<Material diffuseColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
[349]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++) {
[444]168    const Vector3 a = (*ri)->GetOrigin();
[483]169        //const Vector3 b = (*ri)->mTerminationObject ? (*ri)->GetTermination() : a + 1000 * Normalize((*ri)->GetDir());
170        const Vector3 b = (*ri)->GetTermination(); // matt: change again!!
171
[349]172    stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
[444]173        stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
[349]174  }
175 
176  stream<<"\" >"<<endl;
177  stream<<"</Coordinate>"<<endl;
178  stream<<"</IndexedLineSet>"<<endl;
179  stream<<"</Shape>"<<endl;
[386]180       
[349]181  return true;
182}
183
[162]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 
[176]194  ObjectContainer::const_iterator mi = node->mGeometry.begin();
[162]195  for (; mi != node->mGeometry.end(); mi++) {
196    // export the transform...
[176]197    ExportIntersectable(*mi);
[162]198  }
199 
200  stream<<"</Group>"<<endl;
201
202}
203
[694]204
[313]205void
[396]206X3dExporter::ExportBspLeaves(const BspTree &tree, const int maxPvs)
[373]207{
[396]208        stack<pair<BspNode *, BspNodeGeometry *> > tStack;
209        ViewCell::NewMail();
[373]210
[396]211        BspNodeGeometry *geom = new BspNodeGeometry();
212        tree.ConstructGeometry(tree.GetRoot(), *geom);
[373]213
[396]214        tStack.push(pair<BspNode *, BspNodeGeometry *>(tree.GetRoot(), geom));
215
[1020]216        if (maxPvs)
[396]217                mUseForcedMaterial = true;
218
219        while (!tStack.empty())
[373]220        {
[396]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
[449]232                        cell->SplitGeometry(*front,
233                                                                *back,
234                                                                interior->GetPlane(),
235                                                                tree.GetBoundingBox(),
236                                                                tree.GetEpsilon());
[396]237
238                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetFront(), front));
239                        tStack.push(pair<BspNode *, BspNodeGeometry *>(interior->GetBack(), back));
240                }
241                else
242                {
[1020]243                        if (maxPvs)
[396]244                        {
245                                BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
246
247                                mForcedMaterial.mDiffuseColor.b = 1.0f;
[1141]248                                const float importance =
[1168]249                                        (float)leaf->GetViewCell()->GetPvs().CountObjectsInPvs() / (float)maxPvs;
[396]250
251                                mForcedMaterial.mDiffuseColor.r = importance;
252                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
253                        }
[678]254                        ExportPolygons(cell->GetPolys());
[1344]255                }               
[396]256                DEL_PTR(cell);
[373]257        }
258}
259
[176]260void
[261]261X3dExporter::ExportViewCell(ViewCell *viewCell)
[242]262{
[261]263        if (viewCell->GetMesh())
[1344]264        {
[261]265                ExportMesh(viewCell->GetMesh());
[1344]266        }
[242]267}
268
269void
[162]270X3dExporter::ExportMesh(Mesh *mesh)
271{
272
273  stream<<"<Shape>"<<endl;
274  stream<<"<Appearance>"<<endl;
[176]275 
[162]276  // $$ tmp -> random material
277 
278  float r, g, b;
279
[176]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    }
[1001]295   
[162]296  stream<<"<Material diffuseColor=\""<<r<<" "<<g<<" "<<b<<
297    "\" specularColor=\"0.0 0.0 0.0\"/>"<<endl;
298  stream<<"</Appearance>"<<endl;
299
300
[191]301  if (mWireframe)
[427]302    stream<<"<IndexedLineSet coordIndex=\""<<endl;
[162]303  else
[465]304    //stream<<"<IndexedFaceSet ccw=\"TRUE\" coordIndex=\""<<endl;
305        stream << "<IndexedFaceSet coordIndex=\"" << endl;
[162]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<<" ";
[378]316        if (mWireframe) // final line to finish polygon
317                stream << (*face->mVertexIndices.begin()) << " ";
318
[162]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
[191]334  if (mWireframe)
[162]335    stream<<"</IndexedLineSet>"<<endl;
336  else
337    stream<<"</IndexedFaceSet>"<<endl;
338 
339  stream<<"</Shape>"<<endl;
340
341}
342
[242]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
[262]377        //-- create and write indices
[242]378        if (mWireframe)
[465]379                stream<<"<IndexedLineSet coordIndex=\""<<endl;
[242]380        else
[465]381                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
382                stream << "<IndexedFaceSet coordIndex=\"" << endl;
[262]383        int index = 0;
384       
385        VertexContainer::const_iterator vi; 
386       
[333]387        for (index = 0; index < (int)poly->mVertices.size(); ++ index)
[318]388                stream << index << " ";
389       
390        if (mWireframe) // final line to finish polygon
391                stream << "0 ";
392
[262]393        stream << "-1" << endl;
394        stream << "\" >" << endl;
395       
[242]396        stream << "<Coordinate  point=\"" << endl;
397 
[262]398        for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
[242]399        {
400                stream << (*vi).x << " " << (*vi).y << " " << (*vi).z;
401                stream << "," << endl;
402        }
403 
[262]404        stream << "\" >" << endl;
405        stream << "</Coordinate>" << endl;
[242]406
407        if (mWireframe)
408                stream << "</IndexedLineSet>" << endl;
409        else
410                stream << "</IndexedFaceSet>" << endl;
411 
412        stream << "</Shape>" << endl;
413}
414
[712]415
[1006]416
[313]417void X3dExporter::ExportPolygons(const PolygonContainer &polys)
[263]418{
[318]419        stream << "<Shape>" << endl;
[263]420        stream << "<Appearance>" << endl;
421 
422        // $$ tmp -> random material
423 
424        float r, g, b;
[242]425
[263]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)
[465]447                stream<<"<IndexedLineSet coordIndex=\""<<endl;
[263]448        else
[465]449                //stream << "<IndexedFaceSet ccw=\"TRUE\" coordIndex=\"" << endl;
450                stream << "<IndexedFaceSet coordIndex=\"" << endl;
[263]451
452        int index = 0;
453       
454        PolygonContainer::const_iterator pit;
455
456    VertexContainer::const_iterator vi; 
457       
[313]458        for (pit = polys.begin(); pit != polys.end(); ++pit)
[263]459        {
460                Polygon3 *poly = *pit;
[318]461                int startIdx = index;
[263]462                for (vi = poly->mVertices.begin(); vi != poly->mVertices.end(); ++vi)
463                {
464                        stream << index ++ << " ";
465                }
[318]466
467                stream << startIdx << " ";// finish line
[263]468                stream << "-1" << endl;
469        }
470
471        stream << "\" >" << endl;
472       
473        stream << "<Coordinate  point=\"" << endl;
[318]474        for (pit = polys.begin(); pit != polys.end(); ++ pit)
[263]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
[1006]494
[162]495bool
496X3dExporter::ExportBox(const AxisAlignedBox3 &box)
497{
498  Mesh *mesh = new Mesh;
[547]499  // add 8 vertices of the box
[289]500  int index = (int)mesh->mVertices.size();
[162]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
[1006]520
[162]521bool
[242]522X3dExporter::ExportBspTree(const BspTree &tree)
[162]523{
[242]524        if (mExportRayDensity)
525        {
[263]526                return ExportBspTreeRayDensity(tree);
[242]527        }
528 
[264]529        bool savedWireframe = mWireframe;
530
531        SetWireframe();
532       
[396]533        ExportBox(tree.GetBoundingBox());
534       
[264]535        if (!savedWireframe)
536                SetFilled();
537
[373]538        // export view cells
[482]539        ExportBspLeaves(tree); 
[289]540
[263]541        return true;
[242]542}
543
[418]544
[1197]545bool X3dExporter::ExportKdTree(const KdTree &tree,
546                                                           const bool exportGeometry)
[242]547{
548         if (mExportRayDensity) {
[191]549    return ExportKdTreeRayDensity(tree);
550  }
551 
[162]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
[289]563    int index = (int)mesh->mVertices.size();
[162]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    }
[1197]582        else if (exportGeometry)
583        {
584                SetFilled();
585                SetForcedMaterial(RandomMaterial());
586                ExportGeometry(dynamic_cast<KdLeaf *>(node)->mObjects);
587                SetWireframe();
588        }
[162]589  }
590 
591  ExportMesh(mesh);
592  delete mesh;
[1006]593
[162]594  return true;
595}
596
597
[191]598bool
[438]599X3dExporter::ExportVssTree(const VssTree &tree
600                                                   )
[434]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);
[860]623                        IncludeBoxInMesh(box, *mesh);
[434]624
625                        if (tree.ValidLeaf(leaf)) {
626                               
627                                Vector3 origin = box.Center();
628                                box = tree.GetDirBBox(leaf);
629                                VssRay *ray;
630                               
[1004]631                                const int indices[][2] = {{0,0}, {0,1}, {1,1}, {1,0}};
[434]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);
[438]638                                        if (Magnitude(direction) > Limits::Small)
639                                          direction.Normalize();
640                                        else
641                                          direction = Vector3(0, 1, 0);
[435]642                                        float k = 100.0f*leaf->GetImportance();
[434]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);
[438]653  ExportRays(rays);
654  CLEAR_CONTAINER(rays);
[434]655  delete mesh;
656  return true;
657}
658
659bool
[438]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;
[860]726                IncludeBoxInMesh(box, *mesh);
[438]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
[263]746X3dExporter::ExportBspTreeRayDensity(const BspTree &tree)
747{
[311]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();
[580]767#if 0     
[311]768                        // set the mesh material according to the ray density
769                        if (vc->mPassingRays.mRays)
770                        {
[313]771                                float importance =
[438]772                                  vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays;
773                               
[311]774                                mForcedMaterial.mDiffuseColor.r = importance;
775                                mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r;
776                                ExportViewCell(vc);
[580]777
[438]778                        }
[580]779#endif
780                }
781                else
[311]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
[263]792        return true;
793}
794
795bool
[191]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
[289]814      int index = (int)mesh->mVertices.size();
[191]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}
[312]852
[329]853
[312]854struct BspSplitData
855{
[372]856        /// the current node
857        BspNode *mNode;
858
[449]859        vector<Plane3> mPlanes;
[372]860        vector<bool> mSides;
861        bool mIsFront;
[383]862        int mDepth;
[372]863
[313]864        BspSplitData(BspNode *node):
[383]865        mNode(node), mIsFront(false), mDepth(0)
[372]866        {};     
[383]867
[312]868        BspSplitData(BspNode *node,
[449]869                                vector<Plane3> planes,
[329]870                                vector<bool> sides,
[383]871                                const bool isFront,
872                                const int depth):
873        mNode(node), mPlanes(planes), mSides(sides),
874        mIsFront(isFront), mDepth(depth)
[312]875        {};
876};
877
[383]878void X3dExporter::ExportLeavesGeometry(const BspTree &tree,
879                                                                           const vector<BspLeaf *> &leaves)
[360]880{
881        vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
882
883        for (it = leaves.begin(); it != it_end; ++ it)
884        {
[503]885                BspNodeGeometry geom;
886                tree.ConstructGeometry(*it, geom);
[360]887               
[678]888                ExportPolygons(geom.GetPolys());
[360]889        }
890}
891
[449]892void X3dExporter::ExportBspNodeSplits(BspNode *root,
893                                                                          const AxisAlignedBox3 &box,
894                                                                          const bool exportDepth,
895                                                                          const bool epsilon)
[372]896{
897        std::stack<BspSplitData> tStack;
898
[449]899        BspSplitData tData(root);
[372]900        tStack.push(tData);
901 
902        PolygonContainer polys;
[383]903        vector <int> depths;
[372]904
[383]905        int maxDepth = 0;
906
[372]907        while (!tStack.empty())
908        {
909                // filter polygons donw the tree
910                BspSplitData tData = tStack.top();
911            tStack.pop();       
912               
[383]913                if (tData.mNode->IsLeaf())
[372]914                {
[383]915                        if (tData.mDepth > maxDepth)
916                                maxDepth = tData.mDepth;
917                }
918                else
919                {
[372]920                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
921
[383]922                        // add current side of split plane
[449]923                        if (tData.mNode != root)
[383]924                                tData.mSides.push_back(tData.mIsFront);
[372]925
926                        // bounded plane is added to the polygons
[383]927                        Polygon3 *planePoly =
[449]928                                box.CrossSection(interior->GetPlane());
[372]929               
930                        // do all the splits with the previous planes
931                        for (int i = 0; i < (int)tData.mPlanes.size(); ++ i)
[436]932                        {                               
[449]933                                if (planePoly->ClassifyPlane(tData.mPlanes[i], epsilon)
934                                        == Polygon3::SPLIT)
[372]935                                {
936                                        Polygon3 *frontPoly = new Polygon3();
937                                        Polygon3 *backPoly = new Polygon3();
938
[449]939                                        planePoly->Split(tData.mPlanes[i],
940                                                                         *frontPoly,
941                                                                         *backPoly,
942                                                                         epsilon);
943
[372]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
[449]961                        if (planePoly->Valid(epsilon))
[383]962                        {
[372]963                                polys.push_back(planePoly);
[383]964                                depths.push_back(tData.mDepth);
965                        }
[372]966                        else
967                                DEL_PTR(planePoly);
968                       
969                        // push the children on the stack
[383]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));
[372]974                }
[383]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
[372]997        CLEAR_CONTAINER(polys);
998}
999
[1545]1000
[449]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
[1545]1010
[449]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
[1545]1020
[372]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
[449]1040                        polys.push_back(tree.GetBoundingBox().CrossSection(interior->GetPlane()));
[372]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}
[440]1051
1052
[450]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;
[860]1120                IncludeBoxInMesh(box, *mesh);
[450]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}
[459]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;
[535]1151
[459]1152}
[535]1153
1154
1155
1156void X3dExporter::ExportBeam(const Beam &beam, const AxisAlignedBox3 &box)
1157{
[540]1158        if (beam.mMesh)
1159        {
1160                ExportMesh(beam.mMesh);
1161                return;
1162        }
1163
[535]1164        PolygonContainer polys;
1165        //ExportBox(beam.mBox);
1166
[540]1167        const float zfar = 2.0f * Magnitude(box.Diagonal());
1168
1169        // box should not never remove part of beam polygons
[564]1170        Vector3 bmin = beam.mBox.Min() - Vector3(zfar * 2.0f);
1171        Vector3 bmax = beam.mBox.Max() + Vector3(zfar * 2.0f);
[540]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)
[535]1183        {
[540]1184                Polygon3 *poly = bbox.CrossSection(planes[i]);
1185                if (!poly->Valid(Limits::Small))
1186                        DEL_PTR(poly);
[535]1187               
[540]1188                for (int j = 0; (j < planes.size()) && poly; ++ j)
[535]1189                {
1190                        if (j != i)
1191                        {
1192                                Polygon3 *front = new Polygon3();
1193                                Polygon3 *back = new Polygon3();
1194                               
[540]1195                                poly->Split(planes[j], *front, *back, Limits::Small);
[535]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);
[685]1210}
[860]1211
[1106]1212
1213}
1214
Note: See TracBrowser for help on using the repository browser.