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

Revision 1004, 31.6 KB checked in by mattausch, 18 years ago (diff)

environment as a singleton

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