Added simple autosetting of custom supports based on facet normal angle

This commit is contained in:
Lukas Matena 2020-05-06 07:03:32 +02:00
parent e0b04e7d36
commit d24a3453af
2 changed files with 150 additions and 76 deletions

View File

@ -523,6 +523,46 @@ void GLGizmoFdmSupports::update_vertex_buffers(const ModelVolume* mv,
}
void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool overwrite, bool block)
{
float threshold = (M_PI/180.)*threshold_deg;
const Selection& selection = m_parent.get_selection();
const ModelObject* mo = m_c->selection_info()->model_object();
const ModelInstance* mi = mo->instances[selection.get_instance_idx()];
int mesh_id = -1;
for (const ModelVolume* mv : mo->volumes) {
if (! mv->is_model_part())
continue;
++mesh_id;
const Transform3d trafo_matrix = mi->get_matrix(true) * mv->get_matrix(true);
Vec3f down = (trafo_matrix.inverse() * (-Vec3d::UnitZ())).cast<float>().normalized();
Vec3f limit = (trafo_matrix.inverse() * Vec3d(std::sin(threshold), 0, -std::cos(threshold))).cast<float>().normalized();
float dot_limit = limit.dot(down);
// Now calculate dot product of vert_direction and facets' normals.
int idx = -1;
for (const stl_facet& facet : mv->mesh().stl.facet_start) {
++idx;
if (facet.normal.dot(down) > dot_limit && (overwrite || m_selected_facets[mesh_id][idx] == FacetSupportType::NONE))
m_selected_facets[mesh_id][idx] = block
? FacetSupportType::BLOCKER
: FacetSupportType::ENFORCER;
}
update_vertex_buffers(mv, mesh_id, true, true);
}
Plater::TakeSnapshot(wxGetApp().plater(), block ? _L("Block supports by angle")
: _L("Add supports by angle"));
update_model_object();
m_parent.set_as_dirty();
m_setting_angle = false;
}
void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_limit)
{
if (! m_c->selection_info()->model_object())
@ -531,6 +571,8 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
const float approx_height = m_imgui->scaled(18.0f);
y = std::min(y, bottom_limit - approx_height);
m_imgui->set_next_window_pos(x, y, ImGuiCond_Always);
if (! m_setting_angle) {
m_imgui->begin(on_get_name(), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
// First calculate width of all the texts that are could possibly be shown. We will decide set the dialog width based on that:
@ -566,6 +608,12 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
m_imgui->text("");
if (m_imgui->button("Autoset by angle...")) {
m_setting_angle = true;
}
ImGui::SameLine();
if (m_imgui->button(m_desc.at("remove_all"))) {
ModelObject* mo = m_c->selection_info()->model_object();
int idx = -1;
@ -618,9 +666,29 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l
ImGui::EndTooltip();
}
m_imgui->end();
if (m_setting_angle)
m_parent.set_as_dirty();
}
else {
std::string name = "Autoset custom supports";
m_imgui->begin(wxString(name), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
m_imgui->text("Threshold:");
ImGui::SameLine();
m_imgui->slider_float("", &m_angle_threshold_deg, 0.f, 90.f, "%.f");
m_imgui->checkbox(wxString("Overwrite already selected facets"), m_overwrite_selected);
if (m_imgui->button("Enforce"))
select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, false);
ImGui::SameLine();
if (m_imgui->button("Block"))
select_facets_by_angle(m_angle_threshold_deg, m_overwrite_selected, true);
ImGui::SameLine();
if (m_imgui->button("Cancel"))
m_setting_angle = false;
m_imgui->end();
if (! m_setting_angle)
m_parent.set_as_dirty();
}
}
bool GLGizmoFdmSupports::on_is_activable() const
@ -680,6 +748,7 @@ void GLGizmoFdmSupports::on_set_state()
}
if (m_state == Off && m_old_state != Off) { // the gizmo was just turned Off
// we are actually shutting down
m_setting_angle = false;
wxGetApp().plater()->leave_gizmos_stack();
{
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("FDM gizmo turned off")));

View File

@ -61,10 +61,15 @@ private:
void update_model_object() const;
void update_from_model_object();
void select_facets_by_angle(float threshold, bool overwrite, bool block);
bool m_overwrite_selected = false;
float m_angle_threshold_deg = 45.f;
bool is_mesh_point_clipped(const Vec3d& point) const;
float m_clipping_plane_distance = 0.f;
std::unique_ptr<ClippingPlane> m_clipping_plane;
bool m_setting_angle = false;
// This map holds all translated description texts, so they can be easily referenced during layout calculations
// etc. When language changes, GUI is recreated and this class constructed again, so the change takes effect.