source: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp @ 863

Revision 863, 31.3 KB checked in by mattausch, 18 years ago (diff)

working on preprocessor integration
added iv stuff

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