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

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