diff --git a/src/libslic3r/CutSurface.cpp b/src/libslic3r/CutSurface.cpp index 9971f2c684..d34b9b8ea8 100644 --- a/src/libslic3r/CutSurface.cpp +++ b/src/libslic3r/CutSurface.cpp @@ -260,19 +260,24 @@ void create_reduce_map(ReductionMap &reduction_map, const FaceTypeMap &face_type_map, const VertexShapeMap &vert_shape_map); +using ConvertMap = CutMesh::Property_map; /// /// Create surface cuts from mesh model /// /// Model /// Cutted shapes -/// Define Triangle of interest - Edge between -/// inside / outside NOTE: Not const because it need to flag proccessed -/// faces Info about source of vertices -/// in mesh Created surface cuts +/// Reduction of vertices +/// Define Triangles of interest. +/// Edge between inside / outside. +/// NOTE: Not const because it need to flag proccessed faces +/// Used only inside function. +/// Store conversion from mesh to result. +/// Created surface cuts SurfaceCuts create_surface_cut(const CutMesh &mesh, const ExPolygons &shapes, - FaceTypeMap &face_type_map, - const VertexShapeMap &vert_shape_map); + const ReductionMap &reduction_map, + FaceTypeMap &face_type_map, + ConvertMap &convert_map); /// /// Collect connected inside faces @@ -297,12 +302,12 @@ void collect_surface_data(std::queue &process, /// Faces to copy /// Count of outlines /// Source CGAL mesh -/// [Output] map to convert CGAL vertex to its::vertex +/// [Output] map to convert CGAL vertex to its::vertex index /// Surface cut (Partialy filled - only index triangle set) SurfaceCut create_index_triangle_set(const std::vector &faces, size_t count_outlines, const CutMesh &mesh, - std::map &v2v); + ConvertMap &v2v); /// /// Connect outlines into closed loops @@ -311,9 +316,9 @@ SurfaceCut create_index_triangle_set(const std::vector &faces, /// Source CGAL mesh /// Map to convert CGAL vertex to its::vertex /// Cuts - outlines of surface -SurfaceCut::CutType create_cut(const std::vector &outlines, - const CutMesh &mesh, - const std::map &v2v); +SurfaceCut::CutType create_cut(const std::vector &outlines, + const CutMesh &mesh, + const ConvertMap &v2v); /// /// Debug purpose store of mesh with colored face by face type @@ -324,6 +329,7 @@ SurfaceCut::CutType create_cut(const std::vector &outlines, /// File to store void store(CutMesh &mesh, const FaceTypeMap &face_type_map, const std::string &file); void store(CutMesh &mesh, const ReductionMap &reduction_map, const std::string &file); +void store(const SurfaceCuts &cut, const std::string &file_prefix); } // namespace privat void Slic3r::append(SurfaceCut &sc, SurfaceCut &&sc_add) @@ -390,12 +396,14 @@ SurfaceCuts Slic3r::cut_surface(const indexed_triangle_set &model, priv::create_reduce_map(vertex_reduction_map, cgal_model, face_type_map, vert_shape_map); priv::store(cgal_model, vertex_reduction_map, "C:/data/temp/reduction.off"); // only debug - SurfaceCuts result = priv::create_surface_cut(cgal_model, shapes, face_type_map, vert_shape_map); - for (auto &r : result) { - size_t index = &r - &result.front(); - std::string file = "C:/data/temp/cut" + std::to_string(index) + ".obj"; - its_write_obj(r, file.c_str()); - } + // conversion map between vertex index in cgal_model and indices in result + // used instead of std::map + std::string vertec_convert_map_name = "v:convert"; + priv::ConvertMap vertex_convert_map = cgal_model.add_property_map(vertec_convert_map_name).first; + SurfaceCuts result = priv::create_surface_cut(cgal_model, shapes, vertex_reduction_map, face_type_map, vertex_convert_map); + + + priv::store(result, "C:/data/temp/cut"); // only debug // TODO: Filter surfaceCuts to only the top most. return result; @@ -815,7 +823,7 @@ void priv::create_reduce_map(ReductionMap &reduction_map, SurfaceCut priv::create_index_triangle_set(const std::vector &faces, size_t count_outlines, const CutMesh &mesh, - std::map &v2v) + ConvertMap &v2v) { size_t indices_size = faces.size(); size_t vertices_size = (indices_size * 3 - count_outlines / 2) / 2; @@ -833,20 +841,16 @@ SurfaceCut priv::create_index_triangle_set(const std::vector &faces, // index into its_face int its_face_id = 0; do { - // copy its - VI reduction_from = mesh.source(hi); - auto it = v2v.find(reduction_from); - - size_t index = -1; - if (it != v2v.end()) { - index = it->second; - } else { + VI vi = mesh.source(hi); + size_t index = v2v[vi]; + if (index == std::numeric_limits::max()) { index = sc.vertices.size(); - const auto &p = mesh.point(reduction_from); + const auto &p = mesh.point(vi); + // create vertex in result sc.vertices.emplace_back(p.x(), p.y(), p.z()); - v2v[reduction_from] = index; + v2v[vi] = index; } - assert(index != -1); + assert(index != std::numeric_limits::max()); its_face[its_face_id++] = index; hi = mesh.next(hi); } while (hi != hi_end); @@ -856,9 +860,9 @@ SurfaceCut priv::create_index_triangle_set(const std::vector &faces, } -SurfaceCut::CutType priv::create_cut(const std::vector &outlines, - const CutMesh &mesh, - const std::map &v2v) +SurfaceCut::CutType priv::create_cut(const std::vector &outlines, + const CutMesh &mesh, + const ConvertMap &v2v) { SurfaceCut::CutType cut; using Index = SurfaceCut::Index; @@ -866,12 +870,12 @@ SurfaceCut::CutType priv::create_cut(const std::vector &outlines, for (HI hi : outlines) { // source vertex (from) VI vi_s = mesh.source(hi); - assert(v2v.find(vi_s) != v2v.end()); - Index vi_from = v2v.at(vi_s); + Index vi_from = v2v[vi_s]; + assert(vi_from != std::numeric_limits::max()); // target vertex (to) VI vi_t = mesh.target(hi); - assert(v2v.find(vi_t) != v2v.end()); - Index vi_to = v2v.at(vi_t); + Index vi_to = v2v[vi_t]; + assert(vi_to != std::numeric_limits::max()); std::vector *cut_move = nullptr; std::vector *cut_connect = nullptr; @@ -929,10 +933,11 @@ SurfaceCut::CutType priv::create_cut(const std::vector &outlines, return cut; } -SurfaceCuts priv::create_surface_cut(const CutMesh &mesh, - const ExPolygons &shapes, - FaceTypeMap &face_type_map, - const VertexShapeMap &vert_shape_map) +SurfaceCuts priv::create_surface_cut(const CutMesh &mesh, + const ExPolygons &shapes, + const ReductionMap &reduction_map, + FaceTypeMap &face_type_map, + ConvertMap &convert_map) { // faces from one surface cut std::vector faces; @@ -943,6 +948,10 @@ SurfaceCuts priv::create_surface_cut(const CutMesh &mesh, size_t max_outline_count = mesh.faces().size()/2; outlines.reserve(max_outline_count); + // initialize convert_map to MAX values + for (VI vi : mesh.vertices()) + convert_map[vi] = std::numeric_limits::max(); + std::queue process; SurfaceCuts result; @@ -957,12 +966,10 @@ SurfaceCuts priv::create_surface_cut(const CutMesh &mesh, process.push(fi); collect_surface_data(process, faces, outlines, face_type_map, mesh); - // convert vertex index from mesh to index of vertices in result - std::map v2v; - SurfaceCut sc = create_index_triangle_set(faces, outlines.size(), mesh, v2v); + SurfaceCut sc = create_index_triangle_set(faces, outlines.size(), mesh, convert_map); // connect outlines - sc.cut = create_cut(outlines, mesh, v2v); + sc.cut = create_cut(outlines, mesh, convert_map); // TODO: create vertex2contour map @@ -1007,4 +1014,12 @@ void priv::store(CutMesh &mesh, const ReductionMap &reduction_map, const std::st } CGAL::IO::write_OFF(file, mesh); mesh.remove_property_map(vertex_colors); +} + +void priv::store(const SurfaceCuts &cut, const std::string &file_prefix) { + for (auto &c : cut) { + size_t index = &c - &cut.front(); + std::string file = file_prefix + std::to_string(index) + ".obj"; + its_write_obj(c, file.c_str()); + } } \ No newline at end of file