mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-17 02:25:53 +08:00
reworked the core parameter from area to length
This commit is contained in:
parent
e9b456c30d
commit
c2481bc7f5
@ -52,7 +52,6 @@ FDMSupportSpots::FDMSupportSpots(FDMSupportSpotsConfig config, indexed_triangle_
|
|||||||
|
|
||||||
Triangle t { };
|
Triangle t { };
|
||||||
t.indices = mesh.indices[face_index];
|
t.indices = mesh.indices[face_index];
|
||||||
t.normal = normal;
|
|
||||||
t.center = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
|
t.center = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
|
||||||
t.downward_dot_value = normal.dot(down);
|
t.downward_dot_value = normal.dot(down);
|
||||||
t.index = face_index;
|
t.index = face_index;
|
||||||
@ -60,6 +59,10 @@ FDMSupportSpots::FDMSupportSpots(FDMSupportSpotsConfig config, indexed_triangle_
|
|||||||
t.lowest_z_coord = vertices[0].z();
|
t.lowest_z_coord = vertices[0].z();
|
||||||
t.edge_dot_value = std::max(lowest_edge_a.dot(down), lowest_edge_b.dot(down));
|
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.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_triangles.push_back(t);
|
||||||
this->m_triangle_indexes_by_z.push_back(face_index);
|
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];
|
Triangle ¤t = this->m_triangles[current_index];
|
||||||
|
|
||||||
size_t group_id = 0;
|
size_t group_id = 0;
|
||||||
float neighbourhood_unsupported_area = this->m_config.patch_spacing;
|
float neighbourhood_unsupported_distance = this->m_config.max_distance;
|
||||||
bool visited_neighbour = false;
|
size_t visited_neighbours = 0;
|
||||||
|
|
||||||
std::queue<int> neighbours { };
|
std::queue<int> neighbours { };
|
||||||
neighbours.push(current_index);
|
neighbours.push(current_index);
|
||||||
std::set<int> explored { };
|
std::set<int> explored { };
|
||||||
while (!neighbours.empty() && neighbourhood_unsupported_area > 0) {
|
while (!neighbours.empty()) {
|
||||||
int neighbour_index = neighbours.front();
|
int neighbour_index = neighbours.front();
|
||||||
neighbours.pop();
|
neighbours.pop();
|
||||||
|
|
||||||
@ -130,19 +133,20 @@ void FDMSupportSpots::find_support_areas() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
explored.insert(neighbour_index);
|
explored.insert(neighbour_index);
|
||||||
if (triangle_vertices_shortest_distance(this->m_mesh, current.index, neighbour_index)
|
float distance = triangle_vertices_shortest_distance(this->m_mesh, current.index, neighbour_index);
|
||||||
> this->m_config.islands_tolerance_distance) {
|
if (distance > this->m_config.islands_tolerance_distance) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neighbour.visited) {
|
if (neighbour.visited) {
|
||||||
visited_neighbour = true;
|
visited_neighbours++;
|
||||||
if (neighbourhood_unsupported_area >= neighbour.unsupported_weight) {
|
neighbourhood_unsupported_distance = std::min(neighbourhood_unsupported_distance,
|
||||||
neighbourhood_unsupported_area = neighbour.unsupported_weight;
|
neighbour.unsupported_distance + distance);
|
||||||
|
if (group_id == 0) {
|
||||||
group_id = neighbour.group_id;
|
group_id = neighbour.group_id;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &neighbour_index : neighbour.neighbours) {
|
for (const auto &neighbour_index : neighbour.neighbours) {
|
||||||
if (neighbour_index >= 0) {
|
if (neighbour_index >= 0) {
|
||||||
neighbours.push(neighbour_index);
|
neighbours.push(neighbour_index);
|
||||||
@ -151,13 +155,14 @@ void FDMSupportSpots::find_support_areas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
current.visited = true;
|
current.visited = true;
|
||||||
current.unsupported_weight =
|
current.unsupported_distance =
|
||||||
current.downward_dot_value >= this->m_config.limit_angle_cos ?
|
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;
|
current.group_id = group_id;
|
||||||
|
|
||||||
if (current.downward_dot_value > 0
|
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;
|
group_id = next_group_id;
|
||||||
next_group_id++;
|
next_group_id++;
|
||||||
|
|
||||||
@ -165,7 +170,7 @@ void FDMSupportSpots::find_support_areas() {
|
|||||||
current.visited = false;
|
current.visited = false;
|
||||||
supporters.push(int(current_index));
|
supporters.push(int(current_index));
|
||||||
float supported_size = 0;
|
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();
|
int s = supporters.front();
|
||||||
supporters.pop();
|
supporters.pop();
|
||||||
Triangle &supporter = this->m_triangles[s];
|
Triangle &supporter = this->m_triangles[s];
|
||||||
@ -177,7 +182,7 @@ void FDMSupportSpots::find_support_areas() {
|
|||||||
supported_size += supporter.supports ? supporter.area : 0;
|
supported_size += supporter.supports ? supporter.area : 0;
|
||||||
} else {
|
} else {
|
||||||
supporter.supports = true;
|
supporter.supports = true;
|
||||||
supporter.unsupported_weight = 0;
|
supporter.unsupported_distance = 0;
|
||||||
supported_size += supporter.area;
|
supported_size += supporter.area;
|
||||||
supporter.visited = true;
|
supporter.visited = true;
|
||||||
supporter.group_id = group_id;
|
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) {
|
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));
|
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) {
|
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]](1),
|
||||||
this->m_mesh.vertices[this->m_triangles[i].indices[index]](2), color(0),
|
this->m_mesh.vertices[this->m_triangles[i].indices[index]](2), color(0),
|
||||||
color(1), color(2));
|
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) {
|
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]];
|
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) {
|
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),
|
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),
|
this->m_mesh.vertices[triangle.indices[index]](1),
|
||||||
|
@ -21,7 +21,6 @@ namespace Slic3r {
|
|||||||
namespace FDMSupportSpotsImpl {
|
namespace FDMSupportSpotsImpl {
|
||||||
struct Triangle {
|
struct Triangle {
|
||||||
stl_triangle_vertex_indices indices;
|
stl_triangle_vertex_indices indices;
|
||||||
Vec3f normal;
|
|
||||||
Vec3f center;
|
Vec3f center;
|
||||||
float downward_dot_value;
|
float downward_dot_value;
|
||||||
size_t index;
|
size_t index;
|
||||||
@ -30,11 +29,12 @@ struct Triangle {
|
|||||||
// higher value of dot product of the downward direction and the two bottom edges
|
// higher value of dot product of the downward direction and the two bottom edges
|
||||||
float edge_dot_value;
|
float edge_dot_value;
|
||||||
float area;
|
float area;
|
||||||
|
float largest_z_edge_len;
|
||||||
|
|
||||||
size_t order_by_z;
|
size_t order_by_z;
|
||||||
|
|
||||||
//members updated during algorithm
|
//members updated during algorithm
|
||||||
float unsupported_weight { 0.0 };
|
float unsupported_distance { 0.0 };
|
||||||
bool supports = false;
|
bool supports = false;
|
||||||
bool visited = false;
|
bool visited = false;
|
||||||
size_t group_id = 0;
|
size_t group_id = 0;
|
||||||
@ -43,8 +43,8 @@ struct Triangle {
|
|||||||
|
|
||||||
struct FDMSupportSpotsConfig {
|
struct FDMSupportSpotsConfig {
|
||||||
float limit_angle_cos { 35.0f * PI / 180.0f };
|
float limit_angle_cos { 35.0f * PI / 180.0f };
|
||||||
float patch_size { 1.0f }; // (mm)
|
float support_patch_size { 1.0f }; // (mm)
|
||||||
float patch_spacing { 2.0f }; // (mm)
|
float max_distance { 2.0f }; // (mm)
|
||||||
float islands_tolerance_distance { 0.3f }; //(mm)
|
float islands_tolerance_distance { 0.3f }; //(mm)
|
||||||
float max_side_length { 1.0f };// (mm)
|
float max_side_length { 1.0f };// (mm)
|
||||||
};
|
};
|
||||||
|
@ -154,7 +154,6 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
|
|||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
{
|
{
|
||||||
if (m_imgui->button("Subdivide")) {
|
if (m_imgui->button("Subdivide")) {
|
||||||
const Selection &selection = m_parent.get_selection();
|
|
||||||
const ModelObject *mo = m_c->selection_info()->model_object();
|
const ModelObject *mo = m_c->selection_info()->model_object();
|
||||||
for (ModelVolume *mv : mo->volumes)
|
for (ModelVolume *mv : mo->volumes)
|
||||||
if (mv->is_model_part()) {
|
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);
|
1.0f, true);
|
||||||
m_imgui->slider_float("##patch_size", &m_smart_support_patch_size, 0.f, 100.f, tenth_mm.data(),
|
m_imgui->slider_float("##patch_size", &m_smart_support_patch_size, 0.f, 100.f, tenth_mm.data(),
|
||||||
1.0f, false);
|
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);
|
1.0f, false);
|
||||||
m_imgui->slider_float("##island_tolerance", &m_smart_support_islands_tolerance, 0.f, 100.f, hundreth_mm.data(),
|
m_imgui->slider_float("##island_tolerance", &m_smart_support_islands_tolerance, 0.f, 100.f, hundreth_mm.data(),
|
||||||
1.0f, false);
|
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));
|
ImGui::SameLine(window_width - buttons_width - m_imgui->scaled(0.5f));
|
||||||
if (m_imgui->button(m_desc["enforce_button"], buttons_width, 0.f)) {
|
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,
|
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"))) {
|
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();
|
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 islands_tolerance) {
|
||||||
float threshold = (float(M_PI) / 180.f) * (90.0f - limit_angle_deg);
|
float threshold = (float(M_PI) / 180.f) * (90.0f - limit_angle_deg);
|
||||||
|
|
||||||
FDMSupportSpotsConfig support_spots_config {
|
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();
|
const Selection &selection = m_parent.get_selection();
|
||||||
|
@ -44,7 +44,7 @@ private:
|
|||||||
|
|
||||||
float m_smart_support_limit_angle_deg = 45.0f;
|
float m_smart_support_limit_angle_deg = 45.0f;
|
||||||
float m_smart_support_patch_size = 10.0f; //0.1mm
|
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
|
float m_smart_support_islands_tolerance = 30.0f; //0.01mm
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user