diff --git a/src/libslic3r/FDMSupportSpots.cpp b/src/libslic3r/FDMSupportSpots.cpp index 7232f6375e..7d156a73f1 100644 --- a/src/libslic3r/FDMSupportSpots.cpp +++ b/src/libslic3r/FDMSupportSpots.cpp @@ -52,7 +52,6 @@ FDMSupportSpots::FDMSupportSpots(FDMSupportSpotsConfig config, indexed_triangle_ Triangle t { }; t.indices = mesh.indices[face_index]; - t.normal = normal; t.center = (vertices[0] + vertices[1] + vertices[2]) / 3.0f; t.downward_dot_value = normal.dot(down); t.index = face_index; @@ -60,6 +59,10 @@ FDMSupportSpots::FDMSupportSpots(FDMSupportSpotsConfig config, indexed_triangle_ t.lowest_z_coord = vertices[0].z(); t.edge_dot_value = std::max(lowest_edge_a.dot(down), lowest_edge_b.dot(down)); t.area = its_face_area(mesh, face_index); + t.largest_z_edge_len = std::max( + std::max((vertices[0].head<2>() - vertices[1].head<2>()).norm(), + (vertices[1].head<2>() - vertices[2].head<2>()).norm()), + (vertices[2].head<2>() - vertices[0].head<2>()).norm()); this->m_triangles.push_back(t); this->m_triangle_indexes_by_z.push_back(face_index); @@ -115,13 +118,13 @@ void FDMSupportSpots::find_support_areas() { Triangle ¤t = this->m_triangles[current_index]; size_t group_id = 0; - float neighbourhood_unsupported_area = this->m_config.patch_spacing; - bool visited_neighbour = false; + float neighbourhood_unsupported_distance = this->m_config.max_distance; + size_t visited_neighbours = 0; std::queue neighbours { }; neighbours.push(current_index); std::set explored { }; - while (!neighbours.empty() && neighbourhood_unsupported_area > 0) { + while (!neighbours.empty()) { int neighbour_index = neighbours.front(); neighbours.pop(); @@ -130,19 +133,20 @@ void FDMSupportSpots::find_support_areas() { continue; } explored.insert(neighbour_index); - if (triangle_vertices_shortest_distance(this->m_mesh, current.index, neighbour_index) - > this->m_config.islands_tolerance_distance) { + float distance = triangle_vertices_shortest_distance(this->m_mesh, current.index, neighbour_index); + if (distance > this->m_config.islands_tolerance_distance) { continue; } if (neighbour.visited) { - visited_neighbour = true; - if (neighbourhood_unsupported_area >= neighbour.unsupported_weight) { - neighbourhood_unsupported_area = neighbour.unsupported_weight; + visited_neighbours++; + neighbourhood_unsupported_distance = std::min(neighbourhood_unsupported_distance, + neighbour.unsupported_distance + distance); + if (group_id == 0) { group_id = neighbour.group_id; } - break; } + for (const auto &neighbour_index : neighbour.neighbours) { if (neighbour_index >= 0) { neighbours.push(neighbour_index); @@ -151,13 +155,14 @@ void FDMSupportSpots::find_support_areas() { } current.visited = true; - current.unsupported_weight = + current.unsupported_distance = current.downward_dot_value >= this->m_config.limit_angle_cos ? - current.area + neighbourhood_unsupported_area : 0; + neighbourhood_unsupported_distance + current.largest_z_edge_len : + 0; current.group_id = group_id; if (current.downward_dot_value > 0 - && (current.unsupported_weight > this->m_config.patch_spacing || !visited_neighbour)) { + && (current.unsupported_distance > this->m_config.max_distance || visited_neighbours == 0)) { group_id = next_group_id; next_group_id++; @@ -165,7 +170,7 @@ void FDMSupportSpots::find_support_areas() { current.visited = false; supporters.push(int(current_index)); float supported_size = 0; - while (supported_size < this->m_config.patch_size && !supporters.empty()) { + while (supported_size < this->m_config.support_patch_size && !supporters.empty()) { int s = supporters.front(); supporters.pop(); Triangle &supporter = this->m_triangles[s]; @@ -177,7 +182,7 @@ void FDMSupportSpots::find_support_areas() { supported_size += supporter.supports ? supporter.area : 0; } else { supporter.supports = true; - supporter.unsupported_weight = 0; + supporter.unsupported_distance = 0; supported_size += supporter.area; supporter.visited = true; supporter.group_id = group_id; @@ -209,7 +214,8 @@ void FDMSupportSpots::debug_export() const { for (size_t i = 0; i < this->m_triangles.size(); ++i) { Vec3f color = value_to_rgbf(0.0f, 19.0f, float(this->m_triangles[i].group_id % 20)); for (size_t index = 0; index < 3; ++index) { - fprintf(fp, "v %f %f %f %f %f %f\n", this->m_mesh.vertices[this->m_triangles[i].indices[index]](0), + fprintf(fp, "v %f %f %f %f %f %f\n", + this->m_mesh.vertices[this->m_triangles[i].indices[index]](0), this->m_mesh.vertices[this->m_triangles[i].indices[index]](1), this->m_mesh.vertices[this->m_triangles[i].indices[index]](2), color(0), color(1), color(2)); @@ -253,7 +259,8 @@ void FDMSupportSpots::debug_export() const { for (size_t i = 0; i < this->m_triangle_indexes_by_z.size(); ++i) { const Triangle &triangle = this->m_triangles[this->m_triangle_indexes_by_z[i]]; - Vec3f color = value_to_rgbf(0, this->m_config.patch_size, triangle.unsupported_weight); + Vec3f color = value_to_rgbf(0, this->m_config.max_distance, triangle.unsupported_distance); + std::cout << " unsupported dist: " << triangle.unsupported_distance << std::endl; for (size_t index = 0; index < 3; ++index) { fprintf(fp, "v %f %f %f %f %f %f\n", this->m_mesh.vertices[triangle.indices[index]](0), this->m_mesh.vertices[triangle.indices[index]](1), diff --git a/src/libslic3r/FDMSupportSpots.hpp b/src/libslic3r/FDMSupportSpots.hpp index 940c9f3a34..9f63af2833 100644 --- a/src/libslic3r/FDMSupportSpots.hpp +++ b/src/libslic3r/FDMSupportSpots.hpp @@ -21,7 +21,6 @@ namespace Slic3r { namespace FDMSupportSpotsImpl { struct Triangle { stl_triangle_vertex_indices indices; - Vec3f normal; Vec3f center; float downward_dot_value; size_t index; @@ -30,11 +29,12 @@ struct Triangle { // higher value of dot product of the downward direction and the two bottom edges float edge_dot_value; float area; + float largest_z_edge_len; size_t order_by_z; //members updated during algorithm - float unsupported_weight { 0.0 }; + float unsupported_distance { 0.0 }; bool supports = false; bool visited = false; size_t group_id = 0; @@ -43,8 +43,8 @@ struct Triangle { struct FDMSupportSpotsConfig { float limit_angle_cos { 35.0f * PI / 180.0f }; - float patch_size { 1.0f }; // (mm) - float patch_spacing { 2.0f }; // (mm) + float support_patch_size { 1.0f }; // (mm) + float max_distance { 2.0f }; // (mm) float islands_tolerance_distance { 0.3f }; //(mm) float max_side_length { 1.0f };// (mm) }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 2f18ba9903..e2c38253ab 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -154,7 +154,6 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::Separator(); { if (m_imgui->button("Subdivide")) { - const Selection &selection = m_parent.get_selection(); const ModelObject *mo = m_c->selection_info()->model_object(); for (ModelVolume *mv : mo->volumes) if (mv->is_model_part()) { @@ -178,7 +177,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l 1.0f, true); m_imgui->slider_float("##patch_size", &m_smart_support_patch_size, 0.f, 100.f, tenth_mm.data(), 1.0f, false); - m_imgui->slider_float("##patch_spacing", &m_smart_support_patch_spacing, 0.f, 100.f, tenth_mm.data(), + m_imgui->slider_float("##patch_spacing", &m_smart_support_max_distance, 0.f, 100.f, tenth_mm.data(), 1.0f, false); m_imgui->slider_float("##island_tolerance", &m_smart_support_islands_tolerance, 0.f, 100.f, hundreth_mm.data(), 1.0f, false); @@ -187,7 +186,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l ImGui::SameLine(window_width - buttons_width - m_imgui->scaled(0.5f)); if (m_imgui->button(m_desc["enforce_button"], buttons_width, 0.f)) { compute_smart_support_placement(m_smart_support_limit_angle_deg, m_smart_support_patch_size * 0.1f, - m_smart_support_patch_spacing * 0.1f, m_smart_support_islands_tolerance * 0.01f); + m_smart_support_max_distance * 0.1f, m_smart_support_islands_tolerance * 0.01f); } if (m_imgui->button(m_desc.at("remove_all"))) { @@ -437,12 +436,13 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) m_parent.set_as_dirty(); } -void GLGizmoFdmSupports::compute_smart_support_placement(float limit_angle_deg, float patch_size, float patch_spacing, +void GLGizmoFdmSupports::compute_smart_support_placement(float limit_angle_deg, float support_patch_size, + float max_distance, float islands_tolerance) { float threshold = (float(M_PI) / 180.f) * (90.0f - limit_angle_deg); FDMSupportSpotsConfig support_spots_config { - threshold, patch_size, patch_spacing, islands_tolerance + threshold, support_patch_size, max_distance, islands_tolerance }; const Selection &selection = m_parent.get_selection(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp index 2ef275c9f6..c80acf2c84 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp @@ -44,7 +44,7 @@ private: float m_smart_support_limit_angle_deg = 45.0f; float m_smart_support_patch_size = 10.0f; //0.1mm - float m_smart_support_patch_spacing = 20.0f; //0.1mm + float m_smart_support_max_distance = 20.0f; //0.1mm float m_smart_support_islands_tolerance = 30.0f; //0.01mm };