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

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

added exporter for Vrml
added transformations to x3d loader

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