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

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