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

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