#include #include "common.h" #include "SceneGraph.h" #include "X3dExporter.h" #include "Mesh.h" #include "KdTree.h" #include "ViewCellBsp.h" #include "ViewCell.h" #include "Polygon3.h" ViewCellContainer X3dExporter::foundViewCells; // TODO: delete later X3dExporter::X3dExporter(const string filename):Exporter(filename) { stream.open(mFilename.c_str()); stream<<""<"<"<"<"< &rays, const float length, const RgbColor &color) { vector::const_iterator ri = rays.begin(); stream<<""<"<"<"<"<"<"<"<"<"<mChildren.begin(); for (; ni != node->mChildren.end(); ni++) ExportSceneNode(*ni); ObjectContainer::const_iterator mi = node->mGeometry.begin(); for (; mi != node->mGeometry.end(); mi++) { // export the transform... ExportIntersectable(*mi); } stream<<""<Type()) { case Intersectable::MESH_INSTANCE: case Intersectable::TRANSFORMED_MESH_INSTANCE: ExportMeshInstance((MeshInstance *)object); break; case Intersectable::VIEW_CELL: ExportViewCell((ViewCell *)object); break; default: cerr<<"Sorry the export for object not yet defined"<GetMesh()); } void X3dExporter::ExportViewCells(const ViewCellContainer &viewCells) { ViewCellContainer::const_iterator it, it_end = viewCells.end(); for (it = viewCells.begin(); it != it_end; ++ it) ExportViewCell(*it); } void X3dExporter::ExportViewCell(ViewCell *viewCell) { if (viewCell->GetMesh()) ExportMesh(viewCell->GetMesh()); } void X3dExporter::ExportMesh(Mesh *mesh) { stream<<""<"< random material float r, g, b; if (mUseForcedMaterial) { r = mForcedMaterial.mDiffuseColor.r; g = mForcedMaterial.mDiffuseColor.g; b = mForcedMaterial.mDiffuseColor.b; } else if (mesh->mMaterial) { r = mesh->mMaterial->mDiffuseColor.r; g = mesh->mMaterial->mDiffuseColor.g; b = mesh->mMaterial->mDiffuseColor.b; } else { r = RandomValue(0.5, 1.0); g = RandomValue(0.5, 1.0); b = RandomValue(0.5, 1.0); } stream<<""<"<mFaces.begin(); int index = 0; for (; fi != mesh->mFaces.end(); fi++) { Face *face = *fi; VertexIndexContainer::const_iterator vi = face->mVertexIndices.begin(); for (; vi != face->mVertexIndices.end(); vi++) stream<<*vi<<" "; stream<<"-1"<"<mVertices.begin(); for (; vi != mesh->mVertices.end(); vi++) { stream<<(*vi).x<<" "<<(*vi).y<<" "<<(*vi).z; stream<<","<"<"<"<"<"<" << endl; stream << "" << endl; // $$ tmp -> random material float r, g, b; if (mUseForcedMaterial) { r = mForcedMaterial.mDiffuseColor.r; g = mForcedMaterial.mDiffuseColor.g; b = mForcedMaterial.mDiffuseColor.b; } else if (poly->mMaterial) { r = poly->mMaterial->mDiffuseColor.r; g = poly->mMaterial->mDiffuseColor.g; b = poly->mMaterial->mDiffuseColor.b; } else { r = RandomValue(0.5, 1.0); g = RandomValue(0.5, 1.0); b = RandomValue(0.5, 1.0); } stream << "" << endl; stream << "" << endl; //-- create and write indices if (mWireframe) stream << "mVertices.begin(); vi != poly->mVertices.end(); ++vi) { stream << index ++ << " "; } stream << "-1" << endl; stream << "\" >" << endl; stream << "mVertices.begin(); vi != poly->mVertices.end(); ++vi) { stream << (*vi).x << " " << (*vi).y << " " << (*vi).z; stream << "," << endl; } stream << "\" >" << endl; stream << "" << endl; if (mWireframe) stream << "" << endl; else stream << "" << endl; stream << "" << endl; } void X3dExporter::ExportPolygons(const PolygonContainer &polys) { stream << "" << endl; stream << "" << endl; // $$ tmp -> random material float r, g, b; if (mUseForcedMaterial) { r = mForcedMaterial.mDiffuseColor.r; g = mForcedMaterial.mDiffuseColor.g; b = mForcedMaterial.mDiffuseColor.b; } else { r = RandomValue(0.5, 1.0); g = RandomValue(0.5, 1.0); b = RandomValue(0.5, 1.0); } stream << "" << endl; stream << "" << endl; //-- create and write indices if (mWireframe) stream << "mVertices.begin(); vi != poly->mVertices.end(); ++vi) { stream << index ++ << " "; } stream << "-1" << endl; } stream << "\" >" << endl; stream << "mVertices.begin(); vi != poly->mVertices.end(); ++vi) { stream << (*vi).x << " " << (*vi).y << " " << (*vi).z; stream << "," << endl; } } stream << "\" >" << endl; stream << "" << endl; if (mWireframe) stream << "" << endl; else stream << "" << endl; stream << "" << endl; } bool X3dExporter::ExportBox(const AxisAlignedBox3 &box) { Mesh *mesh = new Mesh; // add 6 vertices of the box int index = (int)mesh->mVertices.size(); 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) ); ExportMesh(mesh); delete mesh; return true; } bool X3dExporter::ExportBspTree(const BspTree &tree) { if (mExportRayDensity) { return ExportBspTreeRayDensity(tree); } stack tStack; tStack.push(tree.GetRoot()); Mesh *mesh = new Mesh; AxisAlignedBox3 box = tree.GetBoundingBox(); bool savedWireframe = mWireframe; SetWireframe(); ExportBox(box); if (!savedWireframe) SetFilled(); //ViewCellContainer foundViewCells; if (tree.StorePolys()) { while (!tStack.empty()) { BspNode *node = tStack.top(); tStack.pop(); if (tree.StorePolys()) // extract the polygons { PolygonContainer::const_iterator it; PolygonContainer::const_iterator it_end = node->GetPolygons()->end(); for (it = node->GetPolygons()->begin(); it != it_end; ++ it) ExportPolygon(*it); } if (!node->IsLeaf()) { BspInterior *interior = dynamic_cast(node); tStack.push(interior->GetFront()); tStack.push(interior->GetBack()); } } } else // export view cells { while (!tStack.empty()) { BspNode *node = tStack.top(); tStack.pop(); if (node->IsLeaf()) { ViewCell *viewCell = dynamic_cast(node)->GetViewCell(); if (viewCell) foundViewCells.push_back(viewCell); } else { BspInterior *interior = dynamic_cast(node); tStack.push(interior->GetFront()); tStack.push(interior->GetBack()); } } Debug << "Number of view cells with dublicates: " << (int)foundViewCells.size() << endl; //-- erase dublicates sort(foundViewCells.begin(), foundViewCells.end()); ViewCellContainer::iterator new_end = unique(foundViewCells.begin(), foundViewCells.end()); foundViewCells.erase(new_end, foundViewCells.end()); ExportViewCells(foundViewCells); Debug << "Number of view cells after erasing dublicates: " << (int)foundViewCells.size() << endl; } return true; } bool X3dExporter::ExportKdTree(const KdTree &tree) { if (mExportRayDensity) { return ExportKdTreeRayDensity(tree); } stack tStack; tStack.push(tree.GetRoot()); Mesh *mesh = new Mesh; while (!tStack.empty()) { KdNode *node = tStack.top(); tStack.pop(); AxisAlignedBox3 box = tree.GetBox(node); // add 6 vertices of the box int index = (int)mesh->mVertices.size(); 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()) { KdInterior *interior = (KdInterior *)node; tStack.push(interior->mFront); tStack.push(interior->mBack); } } ExportMesh(mesh); delete mesh; return true; // TODO return true; } bool X3dExporter::ExportBspTreeRayDensity(const BspTree &tree) { stack tStack; tStack.push(tree.GetRoot()); bool fm = mUseForcedMaterial; mUseForcedMaterial = true; mForcedMaterial.mDiffuseColor.g = 1.0f; mForcedMaterial.mDiffuseColor.b = 1.0f; while (!tStack.empty()) { BspNode *node = tStack.top(); tStack.pop(); if (node->IsLeaf()) { ViewCell *vc = dynamic_cast(node)->GetViewCell(); // set the mesh material according to the ray density if (vc->mPassingRays.mRays) { float importance = vc->mPassingRays.mContributions / (float)vc->mPassingRays.mRays; mForcedMaterial.mDiffuseColor.r = importance; mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r; ExportViewCell(vc); } } else { BspInterior *interior = (BspInterior *)node; tStack.push(interior->GetFront()); tStack.push(interior->GetBack()); } } // restore the state of forced material mUseForcedMaterial = fm; return true; } bool X3dExporter::ExportKdTreeRayDensity(const KdTree &tree) { stack tStack; tStack.push(tree.GetRoot()); bool fm = mUseForcedMaterial; mUseForcedMaterial = true; mForcedMaterial.mDiffuseColor.g = 1.0f; mForcedMaterial.mDiffuseColor.b = 1.0f; while (!tStack.empty()) { KdNode *node = tStack.top(); tStack.pop(); if (node->IsLeaf()) { AxisAlignedBox3 box = tree.GetBox(node); Mesh *mesh = new Mesh; // add 6 vertices of the box int index = (int)mesh->mVertices.size(); 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) ); // set the mesh material according to the ray density KdLeaf *leaf = (KdLeaf *) node; if (leaf->mPassingRays.mRays) { float importance = leaf->mPassingRays.mContributions/(float)leaf->mPassingRays.mRays; // float importance = leaf->mPassingRays.mContributions/1000.0f; // float importance = leaf->mPassingRays.mRays/1000.0f; ///(float)leaf->mPassingRays.mRays; // mForcedMaterial.mDiffuseColor.r = log10(leaf->mPassingRays.mRays)/3.0f; mForcedMaterial.mDiffuseColor.r = importance; mForcedMaterial.mDiffuseColor.g = 1.0f - mForcedMaterial.mDiffuseColor.r; ExportMesh(mesh); } delete mesh; } else { KdInterior *interior = (KdInterior *)node; tStack.push(interior->mFront); tStack.push(interior->mBack); } } // restore the state of forced material mUseForcedMaterial = fm; return true; } struct BspSplitData { /// the current node BspNode *mNode; vector mPlanes; vector mSides; bool mIsFront; BspSplitData(BspNode *node): mNode(node), mIsFront(false) {}; BspSplitData(BspNode *node, vector planes, vector sides, bool isFront): mNode(node), mPlanes(planes), mSides(sides), mIsFront(isFront) {}; }; void X3dExporter::ExportBspSplits(const BspTree &tree) { std::stack tStack; BspSplitData tData(tree.GetRoot()); tStack.push(tData); PolygonContainer polys; while (!tStack.empty()) { // filter polygons donw the tree BspSplitData tData = tStack.top(); tStack.pop(); if (!tData.mNode->IsLeaf()) { BspInterior *interior = dynamic_cast(tData.mNode); if (tData.mNode != tree.GetRoot()) tData.mSides.push_back(tData.mIsFront); // add current side // bounded plane is added to the polygons Polygon3 *planePoly = tree.GetBoundingBox().BoundPlane(*interior->GetPlane()); // do all the splits with the previous planes for (int i = 0; i < (int)tData.mPlanes.size(); ++i) { VertexContainer splitPts; Polygon3 *frontPoly = new Polygon3(); Polygon3 *backPoly = new Polygon3(); if (planePoly->ClassifyPlane(*tData.mPlanes[i]) == Polygon3::SPLIT) { planePoly->Split(*tData.mPlanes[i], *frontPoly, *backPoly, splitPts); DEL_PTR(planePoly); if(tData.mSides[i] == true) { planePoly = frontPoly; DEL_PTR(backPoly); } else { planePoly = backPoly; DEL_PTR(frontPoly); } } } tData.mPlanes.push_back(interior->GetPlane()); // add plane to split planes if (planePoly->Valid()) polys.push_back(planePoly); else { Debug << "polygon not valid: " << *planePoly << " size: " << (int)planePoly->mVertices.size() << endl; DEL_PTR(planePoly); } // push the children on the stack tStack.push(BspSplitData(interior->GetFront(), tData.mPlanes, tData.mSides, true)); tStack.push(BspSplitData(interior->GetBack(), tData.mPlanes, tData.mSides, false)); } } ExportPolygons(polys); CLEAR_CONTAINER(polys); } void X3dExporter::ExportBspSplitPlanes(const BspTree &tree) { std::stack tStack; tStack.push(tree.GetRoot()); PolygonContainer polys; while (!tStack.empty()) { // filter polygons donw the tree BspNode *node = tStack.top(); tStack.pop(); if (!node->IsLeaf()) { BspInterior *interior = dynamic_cast(node); // bounded plane is added to the polygons polys.push_back(tree.GetBoundingBox().BoundPlane(*interior->GetPlane())); // push the children on the stack tStack.push(interior->GetBack()); tStack.push(interior->GetFront()); } } ExportPolygons(polys); CLEAR_CONTAINER(polys); }