#ifndef FLOORPLANMESH_H #define FLOORPLANMESH_H #include "Obstacle3.h" namespace Ray3D { /** * meshed version of the floorplan */ struct FloorplanMesh { std::vector elements; /** DEBUG: convert to .obj file code for exporting */ std::string toOBJ() { int nVerts = 1; int nObjs = 0; std::string res; // write each obstacle for (const Obstacle3D& o : elements) { // write the vertices for (const Triangle3& t : o.triangles) { res += "v " + std::to_string(t.p1.x) + " " + std::to_string(t.p1.y) + " " + std::to_string(t.p1.z) + "\n"; res += "v " + std::to_string(t.p2.x) + " " + std::to_string(t.p2.y) + " " + std::to_string(t.p2.z) + "\n"; res += "v " + std::to_string(t.p3.x) + " " + std::to_string(t.p3.y) + " " + std::to_string(t.p3.z) + "\n"; } // create a new group res += "g elem_" + std::to_string(++nObjs) + "\n"; // write the group's faces for (size_t i = 0; i < o.triangles.size(); ++i) { res += "f " + std::to_string(nVerts+0) + " " + std::to_string(nVerts+1) + " " + std::to_string(nVerts+2) + "\n"; nVerts += 3; } } // done return res; } /** convert to .ply file format */ std::string toPLY() const { std::stringstream res; res << "ply\n"; res << "format ascii 1.0\n"; int faces = 0; int vertices = 0; for (const Obstacle3D& obs : elements) { vertices += obs.triangles.size() * 3; faces += obs.triangles.size(); } // material std::vector mats = { Material(0,128,0,255), // ground outdoor Material(64,64,64,255), // ground outdoor Material(255,96,96,255), // stair Material(128,128,128,255), // concrete Material(64,128,255,64), // glass Material(200,200,200,255), // default }; res << "element material " << mats.size() << "\n"; res << "property uchar red\n"; res << "property uchar green\n"; res << "property uchar blue\n"; res << "property uchar alpha\n"; res << "element vertex " << vertices << "\n"; res << "property float x\n"; res << "property float y\n"; res << "property float z\n"; res << "property float nx\n"; res << "property float ny\n"; res << "property float nz\n"; res << "property int material_index\n"; res << "property uchar red\n"; res << "property uchar green\n"; res << "property uchar blue\n"; res << "property uchar alpha\n"; res << "element face " << faces << "\n"; res << "property list uchar int vertex_indices\n"; res << "end_header\n"; for (const Material& mat : mats) { res << mat.r << " " << mat.g << " " << mat.b << " " << mat.a << "\n"; } for (const Obstacle3D& obs : elements) { const int matIdx = getMaterial(obs); const Material& mat = mats[matIdx]; for (const Triangle3& tria : obs.triangles) { const Point3 n = cross(tria.p2-tria.p1, tria.p3-tria.p1).normalized(); res << tria.p1.x << " " << tria.p1.y << " " << tria.p1.z << " " << n.x << " " << n.y << " " << n.z << " " << matIdx << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a << "\n"; res << tria.p2.x << " " << tria.p2.y << " " << tria.p2.z << " " << n.x << " " << n.y << " " << n.z << " " << matIdx << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a <<"\n"; res << tria.p3.x << " " << tria.p3.y << " " << tria.p3.z << " " << n.x << " " << n.y << " " << n.z << " " << matIdx << " " << mat.r << " " << mat.g << " " << mat.b << " " << mat.a <<"\n"; } } int vidx = 0; for (const Obstacle3D& obs : elements) { for (const Triangle3& tria : obs.triangles) { (void) tria; res << "3 " << vidx++ << " " << vidx++ << " " << vidx++ << "\n"; } } // done return res.str(); } struct Material { int r, g, b, a; Material(int r, int g, int b, int a) : r(r), g(g), b(b), a(a) {;} }; int getMaterial(const Obstacle3D& o) const { if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return 0;} if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return 1;} if (o.type == Obstacle3D::Type::STAIR) {return 2;} if (o.mat == Floorplan::Material::CONCRETE) {return 3;} if (o.mat == Floorplan::Material::GLASS) {return 4;} return 5; } // Color getColor(const Obstacle3D& o) const { // if (o.type == Obstacle3D::Type::GROUND_OUTDOOR) {return Color(0,128,0,255);} // if (o.type == Obstacle3D::Type::GROUND_INDOOR) {return Color(64,64,64,255);} // if (o.mat == Floorplan::Material::CONCRETE) {return Color(128,128,128,255);} // if (o.mat == Floorplan::Material::GLASS) {return Color(128,128,255,64);} // return Color(200,200,200,255); // } }; } #endif // FLOORPLANMESH_H