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

Revision 1020, 31.6 KB checked in by mattausch, 18 years ago (diff)

worked on view-object space partition
fixed some loading bugs
fixeds some exporting bugs using line segments
enabling other methods for view space sampling in ViewCellsManager? OBJECT_DIRECTION_BASED_DISTRIBUTION)
added class interface for a sampling strategy

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