diff --git a/tests/libslic3r/test_emboss.cpp b/tests/libslic3r/test_emboss.cpp index 67653bf97..e0481f11e 100644 --- a/tests/libslic3r/test_emboss.cpp +++ b/tests/libslic3r/test_emboss.cpp @@ -266,170 +266,147 @@ TEST_CASE("Italic check", "[Emboss]") } #endif // not __APPLE__ - #include #include #include #include // Referencing a glyph contour (an ExPolygon) plus a vertex base of the contour. -struct GlyphContour -{ +struct GlyphContour { // Index of a glyph in a vector of glyphs. - int32_t glyph{-1}; + int32_t glyph{ -1 }; // Index of an ExPolygon in ExPolygons of a glyph. - int32_t expoly{-1}; + int32_t expoly{ -1 }; // Index of a contour in ExPolygon. // 0 - outer contour, >0 - hole - int32_t contour{-1}; + int32_t contour{ -1 }; // Base of the zero'th point of a contour in text mesh. // There are two vertices (front and rear) created for each contour, // thus there are 2x more vertices in text mesh than the number of contour points. - int32_t vertex_base{-1}; + int32_t vertex_base{ -1 }; }; struct GlyphID { - int32_t glyph_contour{-1}; + int32_t glyph_contour{ -1 }; // vertex or edge ID, where edge ID is the index of the source point. // There are 4 consecutive indices generated for a single glyph edge: // 0th - 1st text edge (straight) // 1th - 1st text face // 2nd - 2nd text edge (diagonal) // 3th - 2nd text face - int32_t idx{-1}; + int32_t idx { -1 }; - GlyphID &operator++() - { - ++idx; - return *this; - } + GlyphID& operator++() { ++idx; return *this; } }; namespace Slic3r::MeshBoolean::cgal2 { -namespace CGALProc = CGAL::Polygon_mesh_processing; -namespace CGALParams = CGAL::Polygon_mesh_processing::parameters; + namespace CGALProc = CGAL::Polygon_mesh_processing; + namespace CGALParams = CGAL::Polygon_mesh_processing::parameters; // using EpecKernel = CGAL::Exact_predicates_exact_constructions_kernel; -using EpicKernel = CGAL::Exact_predicates_inexact_constructions_kernel; -using _EpicMesh = CGAL::Surface_mesh; + using EpicKernel = CGAL::Exact_predicates_inexact_constructions_kernel; + using _EpicMesh = CGAL::Surface_mesh; // using _EpecMesh = CGAL::Surface_mesh; -using CGALMesh = _EpicMesh; + using CGALMesh = _EpicMesh; -// Add an indexed triangle mesh to CGAL Surface_mesh. -// Store map of CGAL face to source face index into object_face_source_id. -void triangle_mesh_to_cgal( - const std::vector &V, - const std::vector &F, - CGALMesh &out, - CGALMesh::Property_map object_face_source_id) -{ - if (F.empty()) return; + // Add an indexed triangle mesh to CGAL Surface_mesh. + // Store map of CGAL face to source face index into object_face_source_id. + void triangle_mesh_to_cgal( + const std::vector &V, + const std::vector &F, + CGALMesh &out, + CGALMesh::Property_map object_face_source_id) + { + if (F.empty()) + return; - size_t vertices_count = V.size(); - size_t edges_count = (F.size() * 3) / 2; - size_t faces_count = F.size(); - out.reserve(vertices_count, edges_count, faces_count); + size_t vertices_count = V.size(); + size_t edges_count = (F.size() * 3) / 2; + size_t faces_count = F.size(); + out.reserve(vertices_count, edges_count, faces_count); - for (auto &v : V) - out.add_vertex(typename CGALMesh::Point{v.x(), v.y(), v.z()}); + for (auto& v : V) + out.add_vertex(typename CGALMesh::Point{ v.x(), v.y(), v.z() }); - using VI = typename CGALMesh::Vertex_index; - for (auto &f : F) { - auto fid = out.add_face(VI(f(0)), VI(f(1)), VI(f(2))); - object_face_source_id[fid] = int32_t(&f - &F.front()); + using VI = typename CGALMesh::Vertex_index; + for (auto& f : F) { + auto fid = out.add_face(VI(f(0)), VI(f(1)), VI(f(2))); + object_face_source_id[fid] = int32_t(&f - &F.front()); + } + } + + void glyph2model( + const ExPolygons &glyph, + int32_t glyph_id, + const Slic3r::Emboss::IProject &projection, + CGALMesh &out, + std::vector &glyph_contours, + CGALMesh::Property_map &glyph_id_edge, + CGALMesh::Property_map &glyph_id_face) + { + std::vector indices; + auto insert_contour = [&projection, &indices , &out, glyph_id, &glyph_contours, &glyph_id_edge, &glyph_id_face](const Polygon& polygon, int32_t iexpoly, int32_t id) { + indices.clear(); + indices.reserve(polygon.points.size() * 2); + size_t num_vertices_old = out.number_of_vertices(); + GlyphID glid{ int32_t(glyph_contours.size()), 0 }; + glyph_contours.push_back({ glyph_id, iexpoly, id, int32_t(num_vertices_old) }); + for (const Point& p2 : polygon.points) { + auto p = projection.project(p2); + auto vi = out.add_vertex(typename CGALMesh::Point{ p.first.x(), p.first.y(), p.first.z() }); + assert((size_t)vi == indices.size() + num_vertices_old); + indices.emplace_back(vi); + vi = out.add_vertex(typename CGALMesh::Point{ p.second.x(), p.second.y(), p.second.z() }); + assert((size_t)vi == indices.size() + num_vertices_old); + indices.emplace_back(vi); + } + for (int32_t i = 0; i < int32_t(indices.size()); i += 2) { + int32_t j = (i + 2) % int32_t(indices.size()); + auto find_edge = [&out](CGALMesh::Face_index fi, CGALMesh::Vertex_index from, CGALMesh::Vertex_index to) { + CGALMesh::Halfedge_index hi = out.halfedge(fi); + for (; out.target(hi) != to; hi = out.next(hi)); + assert(out.source(hi) == from); + assert(out.target(hi) == to); + return hi; + }; + auto fi = out.add_face(indices[i], indices[i + 1], indices[j]); + glyph_id_edge[out.edge(find_edge(fi, indices[i], indices[i + 1]))] = glid; + glyph_id_face[fi] = ++ glid; + glyph_id_edge[out.edge(find_edge(fi, indices[i + 1], indices[j]))] = ++ glid; + glyph_id_face[out.add_face(indices[j], indices[i + 1], indices[j + 1])] = ++ glid; + ++ glid; + } + }; + + size_t count_point = count_points(glyph); + out.reserve(out.number_of_vertices() + 2 * count_point, out.number_of_edges() + 4 * count_point, out.number_of_faces() + 2 * count_point); + + for (const ExPolygon &expolygon : glyph) { + int32_t idx_contour = &expolygon - &glyph.front(); + insert_contour(expolygon.contour, idx_contour, 0); + for (const Polygon& hole : expolygon.holes) + insert_contour(hole, idx_contour, 1 + (&hole - &expolygon.holes.front())); + } } } -void glyph2model( - const ExPolygons &glyph, - int32_t glyph_id, - const Slic3r::Emboss::IProject &projection, - CGALMesh &out, - std::vector &glyph_contours, - CGALMesh::Property_map &glyph_id_edge, - CGALMesh::Property_map &glyph_id_face) -{ - std::vector indices; - auto insert_contour = [&projection, &indices, &out, glyph_id, - &glyph_contours, &glyph_id_edge, - &glyph_id_face](const Polygon &polygon, - int32_t iexpoly, int32_t id) { - indices.clear(); - indices.reserve(polygon.points.size() * 2); - size_t num_vertices_old = out.number_of_vertices(); - GlyphID glid{int32_t(glyph_contours.size()), 0}; - glyph_contours.push_back( - {glyph_id, iexpoly, id, int32_t(num_vertices_old)}); - for (const Point &p2 : polygon.points) { - auto p = projection.project(p2); - auto vi = out.add_vertex(typename CGALMesh::Point{p.first.x(), - p.first.y(), - p.first.z()}); - assert((size_t) vi == indices.size() + num_vertices_old); - indices.emplace_back(vi); - vi = out.add_vertex(typename CGALMesh::Point{p.second.x(), - p.second.y(), - p.second.z()}); - assert((size_t) vi == indices.size() + num_vertices_old); - indices.emplace_back(vi); - } - for (int32_t i = 0; i < int32_t(indices.size()); i += 2) { - int32_t j = (i + 2) % int32_t(indices.size()); - auto find_edge = [&out](CGALMesh::Face_index fi, - CGALMesh::Vertex_index from, - CGALMesh::Vertex_index to) { - CGALMesh::Halfedge_index hi = out.halfedge(fi); - for (; out.target(hi) != to; hi = out.next(hi)) - ; - assert(out.source(hi) == from); - assert(out.target(hi) == to); - return hi; - }; - auto fi = out.add_face(indices[i], indices[i + 1], indices[j]); - glyph_id_edge[out.edge( - find_edge(fi, indices[i], indices[i + 1]))] = glid; - glyph_id_face[fi] = ++glid; - glyph_id_edge[out.edge( - find_edge(fi, indices[i + 1], indices[j]))] = ++glid; - glyph_id_face[out.add_face(indices[j], indices[i + 1], - indices[j + 1])] = ++glid; - ++glid; - } - }; - - size_t count_point = count_points(glyph); - out.reserve(out.number_of_vertices() + 2 * count_point, - out.number_of_edges() + 4 * count_point, - out.number_of_faces() + 2 * count_point); - - for (const ExPolygon &expolygon : glyph) { - int32_t idx_contour = &expolygon - &glyph.front(); - insert_contour(expolygon.contour, idx_contour, 0); - for (const Polygon &hole : expolygon.holes) - insert_contour(hole, idx_contour, - 1 + (&hole - &expolygon.holes.front())); - } -} -} // namespace Slic3r::MeshBoolean::cgal2 - -bool its_write_obj(const indexed_triangle_set &its, - const std::vector &color, - const char *file) +bool its_write_obj(const indexed_triangle_set& its, const std::vector &color, const char* file) { Slic3r::CNumericLocalesSetter locales_setter; - FILE *fp = fopen(file, "w"); - if (fp == nullptr) { return false; } + FILE* fp = fopen(file, "w"); + if (fp == nullptr) { + return false; + } for (size_t i = 0; i < its.vertices.size(); ++i) - fprintf(fp, "v %f %f %f %f %f %f\n", its.vertices[i](0), - its.vertices[i](1), its.vertices[i](2), color[i](0), - color[i](1), color[i](2)); + fprintf(fp, "v %f %f %f %f %f %f\n", + its.vertices[i](0), its.vertices[i](1), its.vertices[i](2), + color[i](0), color[i](1), color[i](2)); for (size_t i = 0; i < its.indices.size(); ++i) - fprintf(fp, "f %d %d %d\n", its.indices[i][0] + 1, - its.indices[i][1] + 1, its.indices[i][2] + 1); + fprintf(fp, "f %d %d %d\n", its.indices[i][0] + 1, its.indices[i][1] + 1, its.indices[i][2] + 1); fclose(fp); return true; } @@ -459,116 +436,89 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") CHECK(!text.indices.empty()); #endif - + auto cube = its_make_cube(782 - 49 + 50, 724 + 10 + 50, 5); its_translate(cube, Vec3f(49 - 25, -10 - 25, 2.5)); auto cube2 = cube; - // its_translate(cube2, Vec3f(0, 0, 40)); +// its_translate(cube2, Vec3f(0, 0, 40)); its_translate(cube2, Vec3f(0, -40, 40)); for (auto &face : cube2.indices) - for (int i = 0; i < 3; ++i) face(i) += int(cube.vertices.size()); + for (int i = 0; i < 3; ++ i) + face(i) += int(cube.vertices.size()); append(cube.vertices, cube2.vertices); append(cube.indices, cube2.indices); MeshBoolean::cgal2::CGALMesh cgalcube, cgaltext; - auto object_face_source_id = - cgalcube - .add_property_map("f:object_face_source_id") - .first; - MeshBoolean::cgal2::triangle_mesh_to_cgal(cube.vertices, cube.indices, - cgalcube, - object_face_source_id); + auto object_face_source_id = cgalcube.add_property_map("f:object_face_source_id").first; + MeshBoolean::cgal2::triangle_mesh_to_cgal(cube.vertices, cube.indices, cgalcube, object_face_source_id); - auto edge_glyph_id = - cgaltext - .add_property_map("e:glyph_id") - .first; - auto face_glyph_id = - cgaltext - .add_property_map("f:glyph_id") - .first; - auto vertex_glyph_id = - cgalcube - .add_property_map("v:glyph_id") - .first; + auto edge_glyph_id = cgaltext.add_property_map("e:glyph_id").first; + auto face_glyph_id = cgaltext.add_property_map("f:glyph_id").first; + auto vertex_glyph_id = cgalcube.add_property_map("v:glyph_id").first; std::vector glyph_contours; - MeshBoolean::cgal2::glyph2model(shape, 0, projection, cgaltext, - glyph_contours, edge_glyph_id, - face_glyph_id); + MeshBoolean::cgal2::glyph2model(shape, 0, projection, cgaltext, glyph_contours, edge_glyph_id, face_glyph_id); - struct Visitor - { + struct Visitor { using TriangleMesh = Slic3r::MeshBoolean::cgal2::CGALMesh; const TriangleMesh &object; const TriangleMesh &glyphs; - // const std::vector &glyph_contours; +// const std::vector &glyph_contours; // Properties of the glyphs mesh: TriangleMesh::Property_map glyph_id_edge; TriangleMesh::Property_map glyph_id_face; // Properties of the object mesh. - TriangleMesh::Property_map - object_face_source_id; - TriangleMesh::Property_map - object_vertex_glyph_id; + TriangleMesh::Property_map object_face_source_id; + TriangleMesh::Property_map object_vertex_glyph_id; typedef boost::graph_traits GT; - typedef typename GT::face_descriptor face_descriptor; - typedef typename GT::halfedge_descriptor halfedge_descriptor; - typedef typename GT::vertex_descriptor vertex_descriptor; + typedef typename GT::face_descriptor face_descriptor; + typedef typename GT::halfedge_descriptor halfedge_descriptor; + typedef typename GT::vertex_descriptor vertex_descriptor; int32_t source_face_id; - void before_subface_creations(face_descriptor f_old, - TriangleMesh &mesh) + void before_subface_creations(face_descriptor f_old, TriangleMesh& mesh) { assert(&mesh == &object); source_face_id = object_face_source_id[f_old]; } - void after_subface_created(face_descriptor f_new, TriangleMesh &mesh) - { + void after_subface_created(face_descriptor f_new, TriangleMesh& mesh) { assert(&mesh == &object); object_face_source_id[f_new] = source_face_id; } - std::vector intersection_point_glyph; + std::vector intersection_point_glyph; // Intersecting an edge hh_edge from tm_edge with a face hh_face of tm_face. void intersection_point_detected( // ID of the intersection point, starting at 0. Ids are consecutive. - std::size_t i_id, - // Dimension of a simplex part of face(hh_face) that is - // intersected by hh_edge: 0 for vertex: target(hh_face) 1 for - // edge: hh_face 2 for the interior of face: face(hh_face) - int simplex_dimension, - // Edge of tm_edge, see edge_source_coplanar_with_face & - // edge_target_coplanar_with_face whether any vertex of hh_edge is - // coplanar with face(hh_face). + std::size_t i_id, + // Dimension of a simplex part of face(hh_face) that is intersected by hh_edge: + // 0 for vertex: target(hh_face) + // 1 for edge: hh_face + // 2 for the interior of face: face(hh_face) + int simplex_dimension, + // Edge of tm_edge, see edge_source_coplanar_with_face & edge_target_coplanar_with_face whether any vertex of hh_edge is coplanar with face(hh_face). halfedge_descriptor hh_edge, - // Vertex, halfedge or face of tm_face intersected by hh_edge, see - // comment at simplex_dimension. + // Vertex, halfedge or face of tm_face intersected by hh_edge, see comment at simplex_dimension. halfedge_descriptor hh_face, // Mesh containing hh_edge - const TriangleMesh &tm_edge, + const TriangleMesh& tm_edge, // Mesh containing hh_face - const TriangleMesh &tm_face, + const TriangleMesh& tm_face, // source(hh_edge) is coplanar with face(hh_face). - bool edge_source_coplanar_with_face, + bool edge_source_coplanar_with_face, // target(hh_edge) is coplanar with face(hh_face). - bool edge_target_coplanar_with_face) + bool edge_target_coplanar_with_face) { if (i_id <= intersection_point_glyph.size()) { - intersection_point_glyph.reserve( - Slic3r::next_highest_power_of_2(i_id + 1)); + intersection_point_glyph.reserve(Slic3r::next_highest_power_of_2(i_id + 1)); intersection_point_glyph.resize(i_id + 1); } - const GlyphID *glyph = nullptr; + const GlyphID* glyph = nullptr; if (&tm_face == &glyphs) { assert(&tm_edge == &object); switch (simplex_dimension) { @@ -580,7 +530,8 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") // edge x face intersection glyph = &glyph_id_face[glyphs.face(hh_face)]; break; - default: assert(false); + default: + assert(false); } if (edge_source_coplanar_with_face) object_vertex_glyph_id[object.source(hh_edge)] = *glyph; @@ -597,106 +548,67 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") intersection_point_glyph[i_id] = glyph; } - void new_vertex_added(std::size_t node_id, - vertex_descriptor vh, - const TriangleMesh &tm) + void new_vertex_added(std::size_t node_id, vertex_descriptor vh, const TriangleMesh &tm) { assert(&tm == &object); assert(node_id < intersection_point_glyph.size()); - const GlyphID *glyph = intersection_point_glyph[node_id]; + const GlyphID * glyph = intersection_point_glyph[node_id]; assert(glyph != nullptr); assert(glyph->glyph_contour != -1); assert(glyph->idx != -1); object_vertex_glyph_id[vh] = glyph ? *glyph : GlyphID{}; } - void after_subface_creations(TriangleMesh &) {} - void before_subface_created(TriangleMesh &) {} - void before_edge_split(halfedge_descriptor /* h */, - TriangleMesh & /* tm */) - {} - void edge_split(halfedge_descriptor /* hnew */, - TriangleMesh & /* tm */) - {} + void after_subface_creations(TriangleMesh&) {} + void before_subface_created(TriangleMesh&) {} + void before_edge_split(halfedge_descriptor /* h */, TriangleMesh& /* tm */) {} + void edge_split(halfedge_descriptor /* hnew */, TriangleMesh& /* tm */) {} void after_edge_split() {} - void add_retriangulation_edge(halfedge_descriptor /* h */, - TriangleMesh & /* tm */) - {} - } visitor{cgalcube, - cgaltext, - /* glyph_contours, */ edge_glyph_id, - face_glyph_id, - object_face_source_id, - vertex_glyph_id}; + void add_retriangulation_edge(halfedge_descriptor /* h */, TriangleMesh& /* tm */) {} + } + visitor { cgalcube, cgaltext, /* glyph_contours, */ edge_glyph_id, face_glyph_id, object_face_source_id, vertex_glyph_id}; - auto ecm = get(CGAL::dynamic_edge_property_t(), cgalcube); - const auto &p = - CGAL::Polygon_mesh_processing::parameters::throw_on_self_intersection( - false) - .visitor(visitor) - .edge_is_constrained_map(ecm); - const auto &q = CGAL::Polygon_mesh_processing::parameters::visitor(visitor) - .do_not_modify(true); + auto ecm = get(CGAL::dynamic_edge_property_t(), cgalcube); + const auto& p = CGAL::Polygon_mesh_processing::parameters::throw_on_self_intersection(false).visitor(visitor).edge_is_constrained_map(ecm); + const auto& q = CGAL::Polygon_mesh_processing::parameters::visitor(visitor).do_not_modify(true); // CGAL::Polygon_mesh_processing::corefine(cgalcube, cgalcube2, p, p); CGAL::Polygon_mesh_processing::corefine(cgalcube, cgaltext, p, q); - auto vertex_colors = - cgalcube - .add_property_map("v:color") - .first; - auto face_colors = - cgalcube - .add_property_map("f:color") - .first; + auto vertex_colors = cgalcube.add_property_map("v:color").first; + auto face_colors = cgalcube.add_property_map("f:color").first; - const CGAL::Color marked{255, 0, 0}; + const CGAL::Color marked { 255, 0, 0 }; for (auto fi : cgalcube.faces()) { CGAL::Color color(0, 255, 0); - auto hi_end = cgalcube.halfedge(fi); - auto hi = hi_end; + auto hi_end = cgalcube.halfedge(fi); + auto hi = hi_end; do { if (get(ecm, cgalcube.edge(hi))) { // This face has a constrained edge. GlyphID g1 = vertex_glyph_id[cgalcube.source(hi)]; GlyphID g2 = vertex_glyph_id[cgalcube.target(hi)]; - assert(g1.glyph_contour != -1 && - g1.glyph_contour == g2.glyph_contour); + assert(g1.glyph_contour != -1 && g1.glyph_contour == g2.glyph_contour); assert(g1.idx != -1); assert(g2.idx != -1); - const GlyphContour &glyph_contour = - glyph_contours[g1.glyph_contour]; - const auto &expoly = glyph->shape[glyph_contour.expoly]; - const auto &contour = - glyph_contour.contour == 0 ? - expoly.contour : - expoly.holes[glyph_contour.contour - 1]; - bool inside = false; - int32_t i1 = g1.idx / 4; - int32_t i2 = g2.idx / 4; + const GlyphContour &glyph_contour = glyph_contours[g1.glyph_contour]; + const auto &expoly = glyph->shape[glyph_contour.expoly]; + const auto &contour = glyph_contour.contour == 0 ? expoly.contour : expoly.holes[glyph_contour.contour - 1]; + bool inside = false; + int32_t i1 = g1.idx / 4; + int32_t i2 = g2.idx / 4; if (g1.idx == g2.idx) { // Crossing both object vertices with the same glyph face. int type = g1.idx % 4; assert(type == 1 || type == 3); - const auto &p = cgalcube.point( - cgalcube.target(cgalcube.next(hi))); + const auto& p = cgalcube.point(cgalcube.target(cgalcube.next(hi))); int i = i1 * 2; int j = (i1 + 1 == int(contour.size())) ? 0 : i + 2; i += glyph_contour.vertex_base; j += glyph_contour.vertex_base; - auto abcp = - type == 1 ? - CGAL::orientation( - cgaltext.point(CGAL::SM_Vertex_index(i)), - cgaltext.point(CGAL::SM_Vertex_index(i + 1)), - cgaltext.point(CGAL::SM_Vertex_index(j)), p) : - CGAL::orientation( - cgaltext.point(CGAL::SM_Vertex_index(j)), - cgaltext.point(CGAL::SM_Vertex_index(i + 1)), - cgaltext.point(CGAL::SM_Vertex_index(j + 1)), - p); + auto abcp = type == 1 ? + CGAL::orientation(cgaltext.point(CGAL::SM_Vertex_index(i)), cgaltext.point(CGAL::SM_Vertex_index(i + 1)), cgaltext.point(CGAL::SM_Vertex_index(j)), p) : + CGAL::orientation(cgaltext.point(CGAL::SM_Vertex_index(j)), cgaltext.point(CGAL::SM_Vertex_index(i + 1)), cgaltext.point(CGAL::SM_Vertex_index(j + 1)), p); inside = abcp == CGAL::POSITIVE; } else if (g1.idx < g2.idx) { if (i1 == 0 && i2 + 1 == contour.size()) { @@ -715,15 +627,13 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") // Is this face oriented towards p or away from p? const auto &a = cgalcube.point(cgalcube.source(hi)); const auto &b = cgalcube.point(cgalcube.target(hi)); - const auto &c = cgalcube.point( - cgalcube.target(cgalcube.next(hi))); - // FIXME prosim nahrad skutecnou projekci. - // projection.project() - const auto p = - a + - MeshBoolean::cgal2::EpicKernel::Vector_3(0, 0, 10); + const auto &c = cgalcube.point(cgalcube.target(cgalcube.next(hi))); + //FIXME prosim nahrad skutecnou projekci. + //projection.project() + const auto p = a + MeshBoolean::cgal2::EpicKernel::Vector_3(0, 0, 10); auto abcp = CGAL::orientation(a, b, c, p); - if (abcp == CGAL::POSITIVE) color = marked; + if (abcp == CGAL::POSITIVE) + color = marked; } break; } @@ -742,9 +652,7 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") auto hi = cgalcube.halfedge(fi_seed); auto hi_prev = cgalcube.prev(hi); auto hi_next = cgalcube.next(hi); - if (!get(ecm, cgalcube.edge(hi)) && - !get(ecm, cgalcube.edge(hi_prev)) && - !get(ecm, cgalcube.edge(hi_next))) { + if (! get(ecm, cgalcube.edge(hi)) && ! get(ecm, cgalcube.edge(hi_prev)) && ! get(ecm, cgalcube.edge(hi_next))) { queue.emplace_back(fi_seed); do { auto fi = queue.back(); @@ -752,28 +660,21 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") auto hi = cgalcube.halfedge(fi); auto hi_prev = cgalcube.prev(hi); auto hi_next = cgalcube.next(hi); - // The following condition may not apply if crossing a - // silhouette wrt. the glyph projection direction. - // assert(! get(ecm, cgalcube.edge(hi)) - // && ! get(ecm, cgalcube.edge(hi_prev)) - // && ! get(ecm, cgalcube.edge(hi_next))); + // The following condition may not apply if crossing a silhouette wrt. the glyph projection direction. +// assert(! get(ecm, cgalcube.edge(hi)) && ! get(ecm, cgalcube.edge(hi_prev)) && ! get(ecm, cgalcube.edge(hi_next))); auto this_opposite = cgalcube.face(cgalcube.opposite(hi)); bool this_marked = face_colors[this_opposite] == marked; - auto prev_opposite = cgalcube.face( - cgalcube.opposite(hi_prev)); + auto prev_opposite = cgalcube.face(cgalcube.opposite(hi_prev)); bool prev_marked = face_colors[prev_opposite] == marked; - auto next_opposite = cgalcube.face( - cgalcube.opposite(hi_next)); - bool next_marked = face_colors[next_opposite] == marked; - int num_marked = this_marked + prev_marked + next_marked; + auto next_opposite = cgalcube.face(cgalcube.opposite(hi_next)); + bool next_marked = face_colors[next_opposite] == marked; + int num_marked = this_marked + prev_marked + next_marked; if (num_marked >= 2) { face_colors[fi] = marked; if (num_marked == 2) - queue.emplace_back(!this_marked ? this_opposite : - !prev_marked ? prev_opposite : - next_opposite); + queue.emplace_back(! this_marked ? this_opposite : ! prev_marked ? prev_opposite : next_opposite); } - } while (!queue.empty()); + } while (! queue.empty()); } } @@ -788,8 +689,7 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") MarkedSplit = -5, UnmarkedEmitted = -6, }; - std::vector face_states(cube.indices.size(), - FaceState::Unknown); + std::vector face_states(cube.indices.size(), FaceState::Unknown); for (auto fi_seed : cgalcube.faces()) { FaceState &state = face_states[object_face_source_id[fi_seed]]; bool m = face_colors[fi_seed] == marked; @@ -802,126 +702,94 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") state = m ? FaceState::MarkedSplit : FaceState::UnmarkedSplit; break; case FaceState::Marked: - case FaceState::MarkedSplit: state = FaceState::MarkedSplit; break; - default: assert(false); + case FaceState::MarkedSplit: + state = FaceState::MarkedSplit; + break; + default: + assert(false); } } indexed_triangle_set its_extruded; its_extruded.indices.reserve(cgalcube.number_of_faces()); its_extruded.vertices.reserve(cgalcube.number_of_vertices()); - // Mapping of its_extruded vertices (original and offsetted) to - // cgalcuble's vertices. - std::vector> - map_vertices(cgalcube.number_of_vertices(), - std::pair{-1, -1}); + // Mapping of its_extruded vertices (original and offsetted) to cgalcuble's vertices. + std::vector> map_vertices(cgalcube.number_of_vertices(), std::pair{-1, -1}); - Vec3f extrude_dir{0, 0, 5.f}; + Vec3f extrude_dir { 0, 0, 5.f }; for (auto fi : cgalcube.faces()) { const int32_t source_face_id = object_face_source_id[fi]; const FaceState state = face_states[source_face_id]; - assert(state == FaceState::Unmarked || - state == FaceState::UnmarkedSplit || - state == FaceState::UnmarkedEmitted || + assert(state == FaceState::Unmarked || state == FaceState::UnmarkedSplit || state == FaceState::UnmarkedEmitted || state == FaceState::Marked || state == FaceState::MarkedSplit); if (state == FaceState::UnmarkedEmitted) { // Already emitted. - } else if (state == FaceState::Unmarked || - state == FaceState::UnmarkedSplit) { + } else if (state == FaceState::Unmarked || state == FaceState::UnmarkedSplit) { // Just copy the unsplit source face. const Vec3i source_vertices = cube.indices[source_face_id]; Vec3i target_vertices; for (int i = 0; i < 3; ++i) { target_vertices(i) = map_vertices[source_vertices(i)].first; if (target_vertices(i) == -1) { - map_vertices[source_vertices(i)].first = target_vertices( - i) = int(its_extruded.vertices.size()); - its_extruded.vertices.emplace_back( - cube.vertices[source_vertices(i)]); + map_vertices[source_vertices(i)].first = target_vertices(i) = int(its_extruded.vertices.size()); + its_extruded.vertices.emplace_back(cube.vertices[source_vertices(i)]); } } its_extruded.indices.emplace_back(target_vertices); face_states[source_face_id] = FaceState::UnmarkedEmitted; } else { - auto hi = cgalcube.halfedge(fi); + auto hi = cgalcube.halfedge(fi); auto hi_prev = cgalcube.prev(hi); auto hi_next = cgalcube.next(hi); - const Vec3i - source_vertices{int((std::size_t) cgalcube.target(hi)), - int((std::size_t) cgalcube.target(hi_next)), - int((std::size_t) cgalcube.target(hi_prev))}; - Vec3i target_vertices; + const Vec3i source_vertices{ int((std::size_t)cgalcube.target(hi)), int((std::size_t)cgalcube.target(hi_next)), int((std::size_t)cgalcube.target(hi_prev)) }; + Vec3i target_vertices; if (face_colors[fi] == marked) { - // Extrude the face. Neighbor edges separating extruded face - // from non-extruded face will be extruded. - bool boundary_vertex[3] = {false, false, false}; - Vec3i target_vertices_extruded{-1, -1, -1}; + // Extrude the face. Neighbor edges separating extruded face from non-extruded face will be extruded. + bool boundary_vertex[3] = { false, false, false }; + Vec3i target_vertices_extruded { -1, -1, -1 }; for (int i = 0; i < 3; ++i) { - if (face_colors[cgalcube.face(cgalcube.opposite(hi))] != - marked) + if (face_colors[cgalcube.face(cgalcube.opposite(hi))] != marked) // Edge separating extruded / non-extruded region. - boundary_vertex[i] = boundary_vertex[(i + 2) % 3] = - true; + boundary_vertex[i] = boundary_vertex[(i + 2) % 3] = true; hi = cgalcube.next(hi); } - for (int i = 0; i < 3; ++i) { - target_vertices_extruded( - i) = map_vertices[source_vertices(i)].second; + for (int i = 0; i < 3; ++ i) { + target_vertices_extruded(i) = map_vertices[source_vertices(i)].second; if (target_vertices_extruded(i) == -1) { - map_vertices[source_vertices(i)].second = - target_vertices_extruded(i) = int( - its_extruded.vertices.size()); - const auto &p = cgalcube.point(cgalcube.target(hi)); - its_extruded.vertices.emplace_back( - Vec3f{float(p.x()), float(p.y()), float(p.z())} + - extrude_dir); + map_vertices[source_vertices(i)].second = target_vertices_extruded(i) = int(its_extruded.vertices.size()); + const auto& p = cgalcube.point(cgalcube.target(hi)); + its_extruded.vertices.emplace_back(Vec3f{ float(p.x()), float(p.y()), float(p.z()) } + extrude_dir); } if (boundary_vertex[i]) { - target_vertices( - i) = map_vertices[source_vertices(i)].first; + target_vertices(i) = map_vertices[source_vertices(i)].first; if (target_vertices(i) == -1) { - map_vertices[source_vertices(i)].first = - target_vertices(i) = int( - its_extruded.vertices.size()); - const auto &p = cgalcube.point( - cgalcube.target(hi)); - its_extruded.vertices.emplace_back(p.x(), p.y(), - p.z()); + map_vertices[source_vertices(i)].first = target_vertices(i) = int(its_extruded.vertices.size()); + const auto& p = cgalcube.point(cgalcube.target(hi)); + its_extruded.vertices.emplace_back(p.x(), p.y(), p.z()); } } hi = cgalcube.next(hi); } its_extruded.indices.emplace_back(target_vertices_extruded); // Add the sides. - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++ i) { int j = (i + 1) % 3; - assert(target_vertices_extruded[i] != -1 && - target_vertices_extruded[j] != -1); + assert(target_vertices_extruded[i] != -1 && target_vertices_extruded[j] != -1); if (boundary_vertex[i] && boundary_vertex[j]) { - assert(target_vertices[i] != -1 && - target_vertices[j] != -1); - its_extruded.indices.emplace_back( - Vec3i{target_vertices[i], target_vertices[j], - target_vertices_extruded[i]}); - its_extruded.indices.emplace_back( - Vec3i{target_vertices_extruded[i], - target_vertices[j], - target_vertices_extruded[j]}); + assert(target_vertices[i] != -1 && target_vertices[j] != -1); + its_extruded.indices.emplace_back(Vec3i{ target_vertices[i], target_vertices[j], target_vertices_extruded[i] }); + its_extruded.indices.emplace_back(Vec3i{ target_vertices_extruded[i], target_vertices[j], target_vertices_extruded[j] }); } } } else { // Copy the face. Vec3i target_vertices; - for (int i = 0; i < 3; ++i) { - target_vertices( - i) = map_vertices[source_vertices(i)].first; + for (int i = 0; i < 3; ++ i) { + target_vertices(i) = map_vertices[source_vertices(i)].first; if (target_vertices(i) == -1) { - map_vertices[source_vertices(i)].first = - target_vertices(i) = int( - its_extruded.vertices.size()); + map_vertices[source_vertices(i)].first = target_vertices(i) = int(its_extruded.vertices.size()); const auto &p = cgalcube.point(cgalcube.target(hi)); - its_extruded.vertices.emplace_back(p.x(), p.y(), - p.z()); + its_extruded.vertices.emplace_back(p.x(), p.y(), p.z()); } hi = cgalcube.next(hi); } @@ -936,25 +804,21 @@ TEST_CASE("Emboss extrude cut", "[Emboss-Cut]") std::vector edges_its_colors; for (auto ei : cgalcube.edges()) if (cgalcube.is_valid(ei)) { - const auto &p1 = cgalcube.point(cgalcube.vertex(ei, 0)); - const auto &p2 = cgalcube.point(cgalcube.vertex(ei, 1)); - bool constrained = get(ecm, ei); - Vec3f color = constrained ? Vec3f{1.f, 0, 0} : Vec3f{0, 1., 0}; - edges_its.indices.emplace_back( - Vec3i(edges_its.vertices.size(), edges_its.vertices.size() + 1, - edges_its.vertices.size() + 2)); + const auto &p1 = cgalcube.point(cgalcube.vertex(ei, 0)); + const auto &p2 = cgalcube.point(cgalcube.vertex(ei, 1)); + bool constrained = get(ecm, ei); + Vec3f color = constrained ? Vec3f{ 1.f, 0, 0 } : Vec3f{ 0, 1., 0 }; + edges_its.indices.emplace_back(Vec3i(edges_its.vertices.size(), edges_its.vertices.size() + 1, edges_its.vertices.size() + 2)); edges_its.vertices.emplace_back(Vec3f(p1.x(), p1.y(), p1.z())); edges_its.vertices.emplace_back(Vec3f(p2.x(), p2.y(), p2.z())); - edges_its.vertices.emplace_back( - Vec3f(p2.x(), p2.y(), p2.z() + 0.001)); + edges_its.vertices.emplace_back(Vec3f(p2.x(), p2.y(), p2.z() + 0.001)); edges_its_colors.emplace_back(color); edges_its_colors.emplace_back(color); edges_its_colors.emplace_back(color); } - its_write_obj(edges_its, edges_its_colors, - "c:\\data\\temp\\corefined-edges.obj"); + its_write_obj(edges_its, edges_its_colors, "c:\\data\\temp\\corefined-edges.obj"); - // MeshBoolean::cgal::minus(cube, cube2); +// MeshBoolean::cgal::minus(cube, cube2); - // REQUIRE(!MeshBoolean::cgal::does_self_intersect(cube)); +// REQUIRE(!MeshBoolean::cgal::does_self_intersect(cube)); }