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

Revision 1020, 30.8 KB checked in by mattausch, 18 years ago (diff)

worked on view-object space partition
fixed some loading bugs
fixeds some exporting bugs using line segments
enabling other methods for view space sampling in ViewCellsManager? OBJECT_DIRECTION_BASED_DISTRIBUTION)
added class interface for a sampling strategy

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