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

Revision 712, 31.2 KB checked in by mattausch, 18 years ago (diff)

added exporter for Vrml
added transformations to x3d loader

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