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

Revision 1420, 28.3 KB checked in by mattausch, 18 years ago (diff)

corrected raycasting bug for triangles because of ill defined triangles

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