SLA supports - added parameters for the automatic generation (relative density measure and minimal distance of the points)
This commit is contained in:
parent
1bb0af1588
commit
eb0fd03861
9 changed files with 54 additions and 59 deletions
|
@ -2630,28 +2630,19 @@ void PrintConfigDef::init_sla_params()
|
|||
def->min = 0;
|
||||
def->default_value = new ConfigOptionFloat(5.0);
|
||||
|
||||
def = this->add("support_density_at_horizontal", coInt);
|
||||
def->label = L("Density on horizontal surfaces");
|
||||
def = this->add("support_points_density_relative", coInt);
|
||||
def->label = L("Support points density");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("How many support points (approximately) should be placed on horizontal surface.");
|
||||
def->sidetext = L("points per square dm");
|
||||
def->tooltip = L("This is a relative measure of support points density.");
|
||||
def->sidetext = L("%");
|
||||
def->cli = "";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionInt(500);
|
||||
def->default_value = new ConfigOptionInt(100);
|
||||
|
||||
def = this->add("support_density_at_45", coInt);
|
||||
def->label = L("Density on surfaces at 45 degrees");
|
||||
def = this->add("support_points_minimal_distance", coFloat);
|
||||
def->label = L("Minimal distance of the support points");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("How many support points (approximately) should be placed on surface sloping at 45 degrees.");
|
||||
def->sidetext = L("points per square dm");
|
||||
def->cli = "";
|
||||
def->min = 0;
|
||||
def->default_value = new ConfigOptionInt(250);
|
||||
|
||||
def = this->add("support_minimal_z", coFloat);
|
||||
def->label = L("Minimal support point height");
|
||||
def->category = L("Supports");
|
||||
def->tooltip = L("No support points will be placed lower than this value from the bottom.");
|
||||
def->tooltip = L("No support points will be placed closer than this threshold.");
|
||||
def->sidetext = L("mm");
|
||||
def->cli = "";
|
||||
def->min = 0;
|
||||
|
|
|
@ -1002,9 +1002,8 @@ public:
|
|||
ConfigOptionFloat support_object_elevation /*= 5.0*/;
|
||||
|
||||
/////// Following options influence automatic support points placement:
|
||||
ConfigOptionInt support_density_at_horizontal;
|
||||
ConfigOptionInt support_density_at_45;
|
||||
ConfigOptionFloat support_minimal_z;
|
||||
ConfigOptionInt support_points_density_relative;
|
||||
ConfigOptionFloat support_points_minimal_distance;
|
||||
|
||||
// Now for the base pool (pad) /////////////////////////////////////////////
|
||||
|
||||
|
@ -1040,9 +1039,8 @@ protected:
|
|||
OPT_PTR(support_base_height);
|
||||
OPT_PTR(support_critical_angle);
|
||||
OPT_PTR(support_max_bridge_length);
|
||||
OPT_PTR(support_density_at_horizontal);
|
||||
OPT_PTR(support_density_at_45);
|
||||
OPT_PTR(support_minimal_z);
|
||||
OPT_PTR(support_points_density_relative);
|
||||
OPT_PTR(support_points_minimal_distance);
|
||||
OPT_PTR(support_object_elevation);
|
||||
OPT_PTR(pad_enable);
|
||||
OPT_PTR(pad_wall_thickness);
|
||||
|
|
|
@ -230,7 +230,7 @@ void SLAAutoSupports::process(const std::vector<ExPolygons>& slices, const std::
|
|||
// s.supports_force_inherited /= std::max(1.f, (layer_height / 0.3f) * e_area / s.area);
|
||||
s.supports_force_inherited /= std::max(1.f, 0.17f * (s.overhangs_area) / s.area);
|
||||
|
||||
float force_deficit = s.support_force_deficit(m_config.tear_pressure);
|
||||
float force_deficit = s.support_force_deficit(m_config.tear_pressure());
|
||||
if (s.islands_below.empty()) // completely new island - needs support no doubt
|
||||
uniformly_cover({ *s.polygon }, s, point_grid, true);
|
||||
else if (! s.dangling_areas.empty()) {
|
||||
|
@ -436,16 +436,16 @@ void SLAAutoSupports::uniformly_cover(const ExPolygons& islands, Structure& stru
|
|||
{
|
||||
//int num_of_points = std::max(1, (int)((island.area()*pow(SCALING_FACTOR, 2) * m_config.tear_pressure)/m_config.support_force));
|
||||
|
||||
const float support_force_deficit = structure.support_force_deficit(m_config.tear_pressure);
|
||||
const float support_force_deficit = structure.support_force_deficit(m_config.tear_pressure());
|
||||
if (support_force_deficit < 0)
|
||||
return;
|
||||
|
||||
// Number of newly added points.
|
||||
const size_t poisson_samples_target = size_t(ceil(support_force_deficit / m_config.support_force));
|
||||
const size_t poisson_samples_target = size_t(ceil(support_force_deficit / m_config.support_force()));
|
||||
|
||||
const float density_horizontal = m_config.tear_pressure / m_config.support_force;
|
||||
const float density_horizontal = m_config.tear_pressure() / m_config.support_force();
|
||||
//FIXME why?
|
||||
float poisson_radius = 1.f / (5.f * density_horizontal);
|
||||
float poisson_radius = std::max(m_config.minimal_distance, 1.f / (5.f * density_horizontal));
|
||||
// const float poisson_radius = 1.f / (15.f * density_horizontal);
|
||||
const float samples_per_mm2 = 30.f / (float(M_PI) * poisson_radius * poisson_radius);
|
||||
// Minimum distance between samples, in 3D space.
|
||||
|
@ -462,13 +462,13 @@ void SLAAutoSupports::uniformly_cover(const ExPolygons& islands, Structure& stru
|
|||
[&structure, &grid3d, min_spacing](const Vec2f &pos) {
|
||||
return grid3d.collides_with(pos, &structure, min_spacing);
|
||||
});
|
||||
if (poisson_samples.size() >= poisson_samples_target)
|
||||
if (poisson_samples.size() >= poisson_samples_target || m_config.minimal_distance > poisson_radius-EPSILON)
|
||||
break;
|
||||
float coeff = 0.5f;
|
||||
if (poisson_samples.size() * 2 > poisson_samples_target)
|
||||
coeff = float(poisson_samples.size()) / float(poisson_samples_target);
|
||||
poisson_radius *= coeff;
|
||||
min_spacing *= coeff;
|
||||
poisson_radius = std::max(m_config.minimal_distance, poisson_radius * coeff);
|
||||
min_spacing = std::max(m_config.minimal_distance, min_spacing * coeff);
|
||||
}
|
||||
|
||||
#ifdef SLA_AUTOSUPPORTS_DEBUG
|
||||
|
@ -491,7 +491,7 @@ void SLAAutoSupports::uniformly_cover(const ExPolygons& islands, Structure& stru
|
|||
}
|
||||
for (const Vec2f &pt : poisson_samples) {
|
||||
m_output.emplace_back(float(pt(0)), float(pt(1)), structure.height, 0.2f, is_new_island);
|
||||
structure.supports_force_this_layer += m_config.support_force;
|
||||
structure.supports_force_this_layer += m_config.support_force();
|
||||
grid3d.insert(pt, &structure);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,13 +14,11 @@ namespace Slic3r {
|
|||
class SLAAutoSupports {
|
||||
public:
|
||||
struct Config {
|
||||
float density_at_horizontal;
|
||||
float density_at_45;
|
||||
float minimal_z;
|
||||
float density_relative;
|
||||
float minimal_distance;
|
||||
///////////////
|
||||
// float support_force = 30.f; // a force one point can support (arbitrary force unit)
|
||||
float support_force = 10.f; // a force one point can support (arbitrary force unit)
|
||||
float tear_pressure = 1.f; // pressure that the display exerts (the force unit per mm2)
|
||||
inline float support_force() const { return 10.f / density_relative; } // a force one point can support (arbitrary force unit)
|
||||
inline float tear_pressure() const { return 1.f; } // pressure that the display exerts (the force unit per mm2)
|
||||
};
|
||||
|
||||
SLAAutoSupports(const TriangleMesh& mesh, const sla::EigenMesh3D& emesh, const std::vector<ExPolygons>& slices,
|
||||
|
|
|
@ -532,9 +532,8 @@ void SLAPrint::process()
|
|||
this->throw_if_canceled();
|
||||
SLAAutoSupports::Config config;
|
||||
const SLAPrintObjectConfig& cfg = po.config();
|
||||
config.minimal_z = float(cfg.support_minimal_z);
|
||||
config.density_at_45 = cfg.support_density_at_45 / 10000.f;
|
||||
config.density_at_horizontal = cfg.support_density_at_horizontal / 10000.f;
|
||||
config.density_relative = (float)cfg.support_points_density_relative / 100.f; // the config value is in percents
|
||||
config.minimal_distance = cfg.support_points_minimal_distance;
|
||||
|
||||
// Construction of this object does the calculation.
|
||||
this->throw_if_canceled();
|
||||
|
@ -1064,7 +1063,10 @@ bool SLAPrintObject::invalidate_state_by_config_options(const std::vector<t_conf
|
|||
for (const t_config_option_key &opt_key : opt_keys) {
|
||||
if (opt_key == "layer_height") {
|
||||
steps.emplace_back(slaposObjectSlice);
|
||||
} else if (opt_key == "supports_enable") {
|
||||
} else if (
|
||||
opt_key == "supports_enable"
|
||||
|| opt_key == "support_points_density_relative"
|
||||
|| opt_key == "support_points_minimal_distance") {
|
||||
steps.emplace_back(slaposSupportPoints);
|
||||
} else if (
|
||||
opt_key == "support_head_front_diameter"
|
||||
|
|
|
@ -2287,12 +2287,13 @@ RENDER_AGAIN:
|
|||
}
|
||||
}
|
||||
else {
|
||||
//m_imgui->text("Some settings could");
|
||||
//m_imgui->text("be exposed here...");
|
||||
m_imgui->text("");
|
||||
m_imgui->text("");
|
||||
|
||||
m_imgui->text("");
|
||||
/* ImGui::PushItemWidth(50.0f);
|
||||
m_imgui->text(_(L("Minimal points distance: ")));
|
||||
ImGui::SameLine();
|
||||
bool value_changed = ImGui::InputDouble("mm", &m_minimal_point_distance, 0.0f, 0.0f, "%.2f");
|
||||
m_imgui->text(_(L("Support points density: ")));
|
||||
ImGui::SameLine();
|
||||
value_changed |= ImGui::InputDouble("%", &m_density, 0.0f, 0.0f, "%.f");*/
|
||||
|
||||
bool generate = m_imgui->button(_(L("Auto-generate points")));
|
||||
|
||||
|
@ -2342,8 +2343,9 @@ RENDER_AGAIN:
|
|||
force_refresh = true;
|
||||
}
|
||||
#endif
|
||||
ImGui::SameLine();
|
||||
bool editing_clicked = m_imgui->button("Editing");
|
||||
m_imgui->text("");
|
||||
m_imgui->text("");
|
||||
bool editing_clicked = m_imgui->button(_(L("Manual editing")));
|
||||
if (editing_clicked) {
|
||||
editing_mode_reload_cache();
|
||||
m_editing_mode = true;
|
||||
|
@ -2463,9 +2465,13 @@ void GLGizmoSlaSupports::editing_mode_discard_changes()
|
|||
|
||||
void GLGizmoSlaSupports::editing_mode_apply_changes()
|
||||
{
|
||||
m_model_object->sla_support_points.clear();
|
||||
for (const std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache)
|
||||
m_model_object->sla_support_points.push_back(point_and_selection.first);
|
||||
// If there are no changes, don't touch the front-end. The data in the cache could have been
|
||||
// taken from the backend and copying them to ModelObject would needlessly invalidate them.
|
||||
if (m_unsaved_changes) {
|
||||
m_model_object->sla_support_points.clear();
|
||||
for (const std::pair<sla::SupportPoint, bool>& point_and_selection : m_editing_mode_cache)
|
||||
m_model_object->sla_support_points.push_back(point_and_selection.first);
|
||||
}
|
||||
m_editing_mode = false;
|
||||
m_unsaved_changes = false;
|
||||
}
|
||||
|
|
|
@ -492,6 +492,8 @@ private:
|
|||
bool m_lock_unique_islands = false;
|
||||
bool m_editing_mode = false;
|
||||
float m_new_point_head_diameter = 0.4f;
|
||||
double m_minimal_point_distance = 20.;
|
||||
double m_density = 100.;
|
||||
std::vector<std::pair<sla::SupportPoint, bool>> m_editing_mode_cache; // a support point and whether it is currently selected
|
||||
|
||||
bool m_selection_rectangle_active = false;
|
||||
|
|
|
@ -457,9 +457,8 @@ const std::vector<std::string>& Preset::sla_print_options()
|
|||
"support_critical_angle",
|
||||
"support_max_bridge_length",
|
||||
"support_object_elevation",
|
||||
"support_density_at_horizontal",
|
||||
"support_density_at_45",
|
||||
"support_minimal_z",
|
||||
"support_points_density_relative",
|
||||
"support_points_minimal_distance",
|
||||
"pad_enable",
|
||||
"pad_wall_thickness",
|
||||
"pad_wall_height",
|
||||
|
|
|
@ -3202,9 +3202,8 @@ void TabSLAPrint::build()
|
|||
optgroup->append_single_option_line("support_max_bridge_length");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Automatic generation")));
|
||||
optgroup->append_single_option_line("support_density_at_horizontal");
|
||||
optgroup->append_single_option_line("support_density_at_45");
|
||||
optgroup->append_single_option_line("support_minimal_z");
|
||||
optgroup->append_single_option_line("support_points_density_relative");
|
||||
optgroup->append_single_option_line("support_points_minimal_distance");
|
||||
|
||||
page = add_options_page(_(L("Pad")), "brick.png");
|
||||
optgroup = page->new_optgroup(_(L("Pad")));
|
||||
|
|
Loading…
Reference in a new issue