#include "X3dExporter.h" #include "VrmlExporter.h" #include "OspTree.h" #include "KdTree.h" #include "IntersectableWrapper.h" #include "BvHierarchy.h" #include "Triangle3.h" #include "Polygon3.h" #include "TraversalTree.h" #include "Material.h" using namespace std; namespace GtpVisibilityPreprocessor { Exporter * Exporter::GetExporter(const string filename) { Exporter *exporter = NULL; if (strstr(filename.c_str(), ".x3d")) { exporter = new X3dExporter(filename); } else if (strstr(filename.c_str(), ".wrl")) { exporter = new VrmlExporter(filename); } else { cerr<<"Error: Currently unsuported export format, filename " << filename << endl; } return exporter; } bool Exporter::ExportOspTree(const OspTree &ospTree, const int maxPvs ) { vector leaves; ospTree.CollectLeaves(leaves); mUseForcedMaterial = true; vector::const_iterator it, it_end = leaves.end(); Material white; white.mDiffuseColor.r = 1; white.mDiffuseColor.g = 1; white.mDiffuseColor.b = 1; for (it = leaves.begin(); it != it_end; ++ it) { KdLeaf *leaf = *it; SetWireframe(); SetForcedMaterial(white); ExportBox(ospTree.GetBoundingBox(leaf)); SetFilled(); if (maxPvs) // color code pvs { mForcedMaterial.mDiffuseColor.b = 1.0f; const float importance = (float)leaf->mObjects.size() / (float)maxPvs; mForcedMaterial.mDiffuseColor.r = importance; mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r; } else { SetForcedMaterial(RandomMaterial()); } if (0) ExportGeometry(leaf->mObjects); } return true; } void Exporter::ExportKdIntersectable(const KdIntersectable &kdObj) { KdNode *root = kdObj.GetItem(); Intersectable::NewMail(); stack tStack; tStack.push(root); while (!tStack.empty()) { KdNode *node = tStack.top(); tStack.pop(); // todo: traverse to leaves if (node->IsLeaf()) { // eyport leaf pvs KdLeaf *leaf = static_cast(node); ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end(); for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit) { Intersectable *obj = *oit; if (1 || !obj->Mailed()) { ExportIntersectable(obj); obj->Mail(); } } } else { KdInterior *interior = (KdInterior *)node; tStack.push(interior->mBack); tStack.push(interior->mFront); } } } bool Exporter::ExportBvHierarchy(const BvHierarchy &bvHierarchy, const float maxPvs, AxisAlignedBox3 *box, const bool exportBoundingBoxes) { vector leaves; bvHierarchy.CollectLeaves(bvHierarchy.GetRoot(), leaves); mUseForcedMaterial = true; vector::const_iterator it, it_end = leaves.end(); Material white; white.mDiffuseColor.r = 1; white.mDiffuseColor.g = 1; white.mDiffuseColor.b = 1; for (it = leaves.begin(); it != it_end; ++ it) { BvhLeaf *leaf = *it; if (leaf->mObjects.empty() || (box && !Overlap(*box, leaf->GetBoundingBox()))) continue; if (exportBoundingBoxes) { SetWireframe(); SetForcedMaterial(white); ExportBox(leaf->GetBoundingBox()); } if (maxPvs > 0) // color code pvs { mForcedMaterial.mDiffuseColor.b = 1.0f; const float importance = (float)leaf->mRenderCost / (float)maxPvs; mForcedMaterial.mDiffuseColor.r = importance; mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r; } else { SetForcedMaterial(RandomMaterial()); } SetFilled(); ExportGeometry(leaf->mObjects, true, box); } // reset to filled SetFilled(); return true; } void Exporter::ExportIntersectable(Intersectable *object) { switch (object->Type()) { case Intersectable::MESH_INSTANCE: ExportMeshInstance((MeshInstance *)object); break; case Intersectable::TRANSFORMED_MESH_INSTANCE: ExportTransformedMeshInstance(static_cast(object)); break; case Intersectable::VIEW_CELL: ExportViewCell(static_cast(object)); break; case Intersectable::KD_INTERSECTABLE: ExportKdIntersectable(*(static_cast(object))); break; case Intersectable::TRIANGLE_INTERSECTABLE: { // if (mClampToBox && !Overlap(mBoundingBox, object->GetBox())) return; const Triangle3 triangle = static_cast(object)->GetItem(); Polygon3 poly(triangle); ExportPolygon(&poly); break; } case Intersectable::BVH_INTERSECTABLE: { BvhNode *node = static_cast(object); if (node->IsLeaf()) { ExportGeometry(static_cast(node)->mObjects, true); } break; } default: cerr << "Sorry the export for object type " << Intersectable::GetTypeName(object) << " is not available yet" << endl; break; } } void Exporter::ExportMeshInstance(MeshInstance *object) { // $$JB$$ // in the future check whether the mesh was not already exported // and use a reference to the that mesh instead ExportMesh(object->GetMesh()); } void Exporter::ExportTransformedMeshInstance(TransformedMeshInstance *mi) { Mesh mesh(*mi->GetMesh()); Matrix4x4 m; mi->GetWorldTransform(m); mesh.ApplyTransformation(m); ExportMesh(&mesh); } void Exporter::ExportViewCells(const ViewCellContainer &viewCells) { ViewCellContainer::const_iterator it, it_end = viewCells.end(); for (it = viewCells.begin(); it != it_end; ++ it) { ExportViewCell(*it); } } void Exporter::ExportGeometry(const ObjectContainer &objects, const bool exportSingleMesh, AxisAlignedBox3 *bbox) { ObjectContainer::const_iterator oit, oit_end = objects.end(); if (!exportSingleMesh) { for (oit = objects.begin(); oit != oit_end; ++ oit) { if (!bbox || Overlap(*bbox, (*oit)->GetBox())) { if (0) SetForcedMaterial(RandomMaterial()); ExportIntersectable(*oit); } } return; } /////////////////////// //-- all objects exported as one mesh //-- warning: currently works only for triangles PolygonContainer polys; for (oit = objects.begin(); oit != oit_end; ++ oit) { Intersectable *obj = *oit; if (bbox && !Overlap(*bbox, obj->GetBox())) { continue; } switch (obj->Type()) { case Intersectable::TRIANGLE_INTERSECTABLE: { TriangleIntersectable *ti = static_cast(obj); polys.push_back(new Polygon3(ti->GetItem())); break; } case Intersectable::MESH_INSTANCE: { MeshInstance *mi = static_cast(obj); ExportMesh(mi->GetMesh()); break; } default: cout << "merge of object type " << obj->Type() << " not implemented yet" << endl; break; } } Mesh dummyMesh; PolygonContainer::const_iterator pit, pit_end = polys.end(); for (pit = polys.begin(); pit != pit_end; ++ pit) { Polygon3 *poly = (*pit); IncludePolyInMesh(*poly, dummyMesh); } ExportMesh(&dummyMesh); CLEAR_CONTAINER(polys); } bool Exporter::ExportTraversalTree(const TraversalTree &tree, const bool exportGeometry) { stack tStack; tStack.push(tree.GetRoot()); Mesh *mesh = new Mesh; SetWireframe(); while (!tStack.empty()) { TraversalNode *node = tStack.top(); tStack.pop(); const AxisAlignedBox3 box = tree.GetBox(node); // add 6 vertices of the box const int index = (int)mesh->mVertices.size(); SetForcedMaterial(RandomMaterial()); for (int i=0; i < 8; i++) { Vector3 v; box.GetVertex(i, v); mesh->mVertices.push_back(v); } mesh->AddFace(new Face(index + 0, index + 1, index + 3, index + 2) ); mesh->AddFace(new Face(index + 0, index + 2, index + 6, index + 4) ); mesh->AddFace(new Face(index + 4, index + 6, index + 7, index + 5) ); mesh->AddFace(new Face(index + 3, index + 1, index + 5, index + 7) ); mesh->AddFace(new Face(index + 0, index + 4, index + 5, index + 1) ); mesh->AddFace(new Face(index + 2, index + 3, index + 7, index + 6) ); if (!node->IsLeaf()) { TraversalInterior *interior = static_cast(node); tStack.push(interior->mFront); tStack.push(interior->mBack); } else if (exportGeometry) { SetFilled(); SetForcedMaterial(RandomMaterial()); ExportViewCells(static_cast(node)->mViewCells); SetWireframe(); } } ExportMesh(mesh); delete mesh; return true; } }