From 6877c075dc14c24d8b036ade7cf540ce228dd061 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Tue, 11 Jun 2019 17:57:39 +0200 Subject: [PATCH] SPE-742: Parameter layer for zero elevation feature. --- src/libslic3r/PrintConfig.cpp | 47 ++++++++++++++- src/libslic3r/PrintConfig.hpp | 26 ++++++++- src/libslic3r/SLA/SLABasePool.hpp | 15 +++-- src/libslic3r/SLA/SLACommon.hpp | 6 +- src/libslic3r/SLA/SLASupportTree.cpp | 14 ++--- src/libslic3r/SLA/SLASupportTree.hpp | 11 ++-- src/libslic3r/SLAPrint.cpp | 31 +++++++--- src/slic3r/GUI/Preset.cpp | 4 ++ src/slic3r/GUI/Tab.cpp | 85 ++++++++++++++++++---------- 9 files changed, 179 insertions(+), 60 deletions(-) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 87ea26301..45ff20e78 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2490,6 +2490,19 @@ void PrintConfigDef::init_sla_params() def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(1.0)); + + def = this->add("support_base_safety_distance", coFloat); + def->label = L("Support base safety distance"); + def->category = L("Supports"); + def->tooltip = L( + "The minimum distance of the pillar base from the model in mm. " + "Makes sense in zero elevation mode where a gap according " + "to this parameter is inserted between the model and the pad."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 10; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(0.5)); def = this->add("support_critical_angle", coFloat); def->label = L("Critical angle"); @@ -2523,7 +2536,9 @@ void PrintConfigDef::init_sla_params() def = this->add("support_object_elevation", coFloat); def->label = L("Object elevation"); def->category = L("Supports"); - def->tooltip = L("How much the supports should lift up the supported object."); + def->tooltip = L("How much the supports should lift up the supported object. " + "If this value is zero, the bottom of the model geometry " + "will be considered as part of the pad."); def->sidetext = L("mm"); def->min = 0; def->max = 150; // This is the max height of print on SL1 @@ -2609,6 +2624,36 @@ void PrintConfigDef::init_sla_params() def->max = 90; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloat(45.0)); + + def = this->add("pad_object_connector_stride", coFloat); + def->label = L("Pad object connector stride"); + def->category = L("Pad"); + def->tooltip = L("Distance between two connector sticks between " + "the object pad and the generated pad."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(10)); + + def = this->add("pad_object_connector_width", coFloat); + def->label = L("Pad object connector width"); + def->category = L("Pad"); + def->tooltip = L("The width of the connectors sticks which connect the " + "object pad and the generated pad."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(0.3)); + + def = this->add("pad_object_connector_penetration", coFloat); + def->label = L("Pad object connector penetration"); + def->category = L("Pad"); + def->tooltip = L( + "How much should the tiny connectors penetrate into the model body."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(0.3)); } void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 1da22b377..e632e6946 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -983,6 +983,9 @@ public: // The height of the pillar base cone in mm. ConfigOptionFloat support_base_height /*= 1.0*/; + + // The minimum distance of the pillar base from the model in mm. + ConfigOptionFloat support_base_safety_distance; /*= 1.0*/; // The default angle for connecting support sticks and junctions. ConfigOptionFloat support_critical_angle /*= 45*/; @@ -996,7 +999,7 @@ public: // The elevation in Z direction upwards. This is the space between the pad // and the model object's bounding box bottom. Units in mm. ConfigOptionFloat support_object_elevation /*= 5.0*/; - + /////// Following options influence automatic support points placement: ConfigOptionInt support_points_density_relative; ConfigOptionFloat support_points_minimal_distance; @@ -1021,6 +1024,23 @@ public: // The slope of the pad wall... ConfigOptionFloat pad_wall_slope; + + // ///////////////////////////////////////////////////////////////////////// + // Zero elevation mode parameters: + // - The object pad will be derived from the the model geometry. + // - There will be a gap between the object pad and the generated pad + // according to the support_base_safety_distance parameter. + // - The two pads will be connected with tiny connector sticks + // ///////////////////////////////////////////////////////////////////////// + + // How far to place the connector sticks on the object pad perimeter + ConfigOptionFloat pad_object_connector_stride; + + // The width of the connectors sticks + ConfigOptionFloat pad_object_connector_width; + + // How much should the tiny connectors penetrate into the model body + ConfigOptionFloat pad_object_connector_penetration; protected: void initialize(StaticCacheBase &cache, const char *base_ptr) @@ -1038,6 +1058,7 @@ protected: OPT_PTR(support_pillar_widening_factor); OPT_PTR(support_base_diameter); OPT_PTR(support_base_height); + OPT_PTR(support_base_safety_distance); OPT_PTR(support_critical_angle); OPT_PTR(support_max_bridge_length); OPT_PTR(support_max_pillar_link_distance); @@ -1050,6 +1071,9 @@ protected: OPT_PTR(pad_max_merge_distance); OPT_PTR(pad_edge_radius); OPT_PTR(pad_wall_slope); + OPT_PTR(pad_object_connector_stride); + OPT_PTR(pad_object_connector_width); + OPT_PTR(pad_object_connector_penetration); } }; diff --git a/src/libslic3r/SLA/SLABasePool.hpp b/src/libslic3r/SLA/SLABasePool.hpp index 0ed26b6e7..129f7ccd4 100644 --- a/src/libslic3r/SLA/SLABasePool.hpp +++ b/src/libslic3r/SLA/SLABasePool.hpp @@ -42,7 +42,14 @@ struct PoolConfig { double max_merge_distance_mm = 50; double edge_radius_mm = 1; double wall_slope = std::atan(1.0); // Universal constant for Pi/4 - bool embed_object = false; + struct EmbedObject { + double object_gap_mm = 0.5; + double stick_stride_mm = 10; + double stick_width_mm = 0.3; + double stick_penetration_mm = 0.1; + bool enabled = false; + operator bool() const { return enabled; } + } embed_object; ThrowOnCancel throw_on_cancel = [](){}; @@ -61,11 +68,7 @@ void create_base_pool(const Polygons& base_plate, const ExPolygons& holes, const PoolConfig& = PoolConfig()); -/// TODO: Currently the base plate of the pool will have half the height of the -/// whole pool. So the carved out space has also half the height. This is not -/// a particularly elegant solution, the thickness should be exactly -/// min_wall_thickness and it should be corrected in the future. This method -/// will return the correct value for further processing. +/// Returns the elevation needed for compensating the pad. inline double get_pad_elevation(const PoolConfig& cfg) { return cfg.min_wall_thickness_mm; } diff --git a/src/libslic3r/SLA/SLACommon.hpp b/src/libslic3r/SLA/SLACommon.hpp index 2b72aa92c..2666f2a9c 100644 --- a/src/libslic3r/SLA/SLACommon.hpp +++ b/src/libslic3r/SLA/SLACommon.hpp @@ -60,7 +60,7 @@ class EigenMesh3D { Eigen::MatrixXd m_V; Eigen::MatrixXi m_F; - double m_ground_level = 0; + double m_ground_level = 0, m_gnd_offset = 0; std::unique_ptr m_aabb; public: @@ -71,8 +71,8 @@ public: ~EigenMesh3D(); - inline double ground_level() const { return m_ground_level; } - inline double& ground_level() { return m_ground_level; } + inline double ground_level() const { return m_ground_level + m_gnd_offset; } + inline void ground_level_offset(double o) { m_gnd_offset = o; } inline const Eigen::MatrixXd& V() const { return m_V; } inline const Eigen::MatrixXi& F() const { return m_F; } diff --git a/src/libslic3r/SLA/SLASupportTree.cpp b/src/libslic3r/SLA/SLASupportTree.cpp index 9705e8600..b9f2cc14e 100644 --- a/src/libslic3r/SLA/SLASupportTree.cpp +++ b/src/libslic3r/SLA/SLASupportTree.cpp @@ -72,8 +72,6 @@ const double SupportConfig::normal_cutoff_angle = 150.0 * M_PI / 180.0; // The shortest distance of any support structure from the model surface const double SupportConfig::safety_distance_mm = 0.5; -const double SupportConfig::pillar_base_safety_distance_mm = 0.5; - const double SupportConfig::max_solo_pillar_height_mm = 15.0; const double SupportConfig::max_dual_pillar_height_mm = 35.0; const double SupportConfig::optimizer_rel_score_diff = 1e-6; @@ -590,10 +588,10 @@ struct Pad { for(auto& poly : modelbase_sticks) sla::offset_with_breakstick_holes( poly, - SupportConfig::pillar_base_safety_distance_mm, // padding - 10, // stride (mm) - 0.3, // stick_width (mm) - 0.1); // penetration (mm) + pcfg.embed_object.object_gap_mm, // padding + pcfg.embed_object.stick_stride_mm, + pcfg.embed_object.stick_width_mm, + pcfg.embed_object.stick_penetration_mm); create_base_pool(basep, tmesh, modelbase_sticks, cfg); } else { @@ -1407,7 +1405,7 @@ class SLASupportTree::Algorithm { double gndlvl = m_result.ground_level; Vec3d endp = {jp(X), jp(Y), gndlvl}; - double sd = SupportConfig::pillar_base_safety_distance_mm; + double sd = m_cfg.pillar_base_safety_distance_mm; int pillar_id = -1; double min_dist = sd + m_cfg.base_radius_mm + EPSILON; double dist = 0; @@ -2160,7 +2158,7 @@ public: std::vector spts(needpillars); // vector of starting points double gnd = m_result.ground_level; - double min_dist = SupportConfig::pillar_base_safety_distance_mm + + double min_dist = m_cfg.pillar_base_safety_distance_mm + m_cfg.base_radius_mm + EPSILON; while(!found && alpha < 2*PI) { diff --git a/src/libslic3r/SLA/SLASupportTree.hpp b/src/libslic3r/SLA/SLASupportTree.hpp index 1602316e8..93627d10c 100644 --- a/src/libslic3r/SLA/SLASupportTree.hpp +++ b/src/libslic3r/SLA/SLASupportTree.hpp @@ -81,6 +81,10 @@ struct SupportConfig { // The elevation in Z direction upwards. This is the space between the pad // and the model object's bounding box bottom. double object_elevation_mm = 10; + + // The shortest distance between a pillar base perimeter from the model + // body. This is only useful when elevation is set to zero. + const double pillar_base_safety_distance_mm = 0.5; // ///////////////////////////////////////////////////////////////////////// // Compile time configuration values (candidates for runtime) @@ -91,10 +95,6 @@ struct SupportConfig { // The shortest distance of any support structure from the model surface static const double safety_distance_mm; - - // The shortest distance between a pillar base perimeter from the model - // body. This is only useful when elevation is set to zero. - static const double pillar_base_safety_distance_mm; static const double max_solo_pillar_height_mm; static const double max_dual_pillar_height_mm; @@ -186,7 +186,8 @@ public: /// Get the sliced 2d layers of the support geometry. std::vector slice(float layerh, float init_layerh = -1.0) const; - std::vector slice(const std::vector&, float closing_radius) const; + std::vector slice(const std::vector &, + float closing_radius) const; /// Adding the "pad" (base pool) under the supports /// modelbase will be used according to the embed_object flag in PoolConfig. diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index f4599a266..14cf2b6ff 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -599,9 +599,20 @@ sla::SupportConfig make_support_cfg(const SLAPrintObjectConfig& c) { return scfg; } -bool use_builtin_pad(const SLAPrintObjectConfig& c) { - return c.support_object_elevation.getFloat() <= EPSILON && - c.pad_enable.getBool(); +sla::PoolConfig::EmbedObject use_builtin_pad(const SLAPrintObjectConfig& c) { + sla::PoolConfig::EmbedObject ret; + + ret.enabled = c.support_object_elevation.getFloat() <= EPSILON && + c.pad_enable.getBool(); + + if(ret.enabled) { + ret.object_gap_mm = c.support_base_safety_distance.getFloat(); + ret.stick_width_mm = c.pad_object_connector_width.getFloat(); + ret.stick_stride_mm = c.pad_object_connector_stride.getFloat(); + ret.stick_width_mm = c.pad_object_connector_penetration.getFloat(); + } + + return ret; } sla::PoolConfig make_pool_config(const SLAPrintObjectConfig& c) { @@ -871,9 +882,10 @@ void SLAPrint::process() if(!po.m_supportdata) return; sla::PoolConfig pcfg = make_pool_config(po.m_config); - - if(pcfg.embed_object) - po.m_supportdata->emesh.ground_level() += pcfg.min_wall_thickness_mm; + + if (pcfg.embed_object) + po.m_supportdata->emesh.ground_level_offset( + pcfg.min_wall_thickness_mm); if(!po.m_config.supports_enable.getBool()) { @@ -1635,13 +1647,18 @@ bool SLAPrintObject::invalidate_state_by_config_options(const std::vector& Preset::sla_print_options() "support_pillar_widening_factor", "support_base_diameter", "support_base_height", + "support_base_safety_distance", "support_critical_angle", "support_max_bridge_length", "support_max_pillar_link_distance", @@ -474,6 +475,9 @@ const std::vector& Preset::sla_print_options() "pad_max_merge_distance", "pad_edge_radius", "pad_wall_slope", + "pad_object_connector_stride", + "pad_object_connector_width", + "pad_object_connector_penetration", "output_filename_format", "default_sla_print_profile", "compatible_printers", diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 6cd270e5b..8ca47f1b1 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -3481,6 +3481,7 @@ void TabSLAPrint::build() // optgroup->append_single_option_line("support_pillar_widening_factor"); optgroup->append_single_option_line("support_base_diameter"); optgroup->append_single_option_line("support_base_height"); + optgroup->append_single_option_line("support_base_safety_distance"); optgroup->append_single_option_line("support_object_elevation"); optgroup = page->new_optgroup(_(L("Connection of the support sticks and junctions"))); @@ -3501,7 +3502,11 @@ void TabSLAPrint::build() // TODO: Disabling this parameter for the beta release // optgroup->append_single_option_line("pad_edge_radius"); optgroup->append_single_option_line("pad_wall_slope"); - + + optgroup->append_single_option_line("pad_object_connector_stride"); + optgroup->append_single_option_line("pad_object_connector_width"); + optgroup->append_single_option_line("pad_object_connector_penetration"); + page = add_options_page(_(L("Advanced")), "wrench"); optgroup = page->new_optgroup(_(L("Slicing"))); optgroup->append_single_option_line("slice_closing_radius"); @@ -3541,42 +3546,64 @@ void TabSLAPrint::reload_config() void TabSLAPrint::update() { - if (m_preset_bundle->printers.get_selected_preset().printer_technology() == ptFFF) + if (m_preset_bundle->printers.get_selected_preset().printer_technology() + == ptFFF) return; // #ys_FIXME -// #ys_FIXME - m_update_cnt++; + // #ys_FIXME + m_update_cnt++; - double head_penetration = m_config->opt_float("support_head_penetration"); - double head_width = m_config->opt_float("support_head_width"); - if(head_penetration > head_width) { - wxString msg_text = _(L("Head penetration should not be greater than the head width.")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Invalid Head penetration")), wxICON_WARNING | wxOK); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_OK) { - new_conf.set_key_value("support_head_penetration", new ConfigOptionFloat(head_width)); - } + double head_penetration = m_config->opt_float("support_head_penetration"); + double head_width = m_config->opt_float("support_head_width"); + if (head_penetration > head_width) { + wxString msg_text = _( + L("Head penetration should not be greater than the head width.")); - load_config(new_conf); - } + auto dialog = new wxMessageDialog(parent(), + msg_text, + _(L("Invalid Head penetration")), + wxICON_WARNING | wxOK); - double pinhead_d = m_config->opt_float("support_head_front_diameter"); - double pillar_d = m_config->opt_float("support_pillar_diameter"); - if(pinhead_d > pillar_d) { - wxString msg_text = _(L("Pinhead diameter should be smaller than the pillar diameter.")); - auto dialog = new wxMessageDialog(parent(), msg_text, _(L("Invalid pinhead diameter")), wxICON_WARNING | wxOK); - DynamicPrintConfig new_conf = *m_config; - if (dialog->ShowModal() == wxID_OK) { - new_conf.set_key_value("support_head_front_diameter", new ConfigOptionFloat(pillar_d / 2.0)); - } + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_OK) { + new_conf.set_key_value("support_head_penetration", + new ConfigOptionFloat(head_width)); + } - load_config(new_conf); - } + load_config(new_conf); + } - m_update_cnt--; + double pinhead_d = m_config->opt_float("support_head_front_diameter"); + double pillar_d = m_config->opt_float("support_pillar_diameter"); + if (pinhead_d > pillar_d) { + wxString msg_text = _(L( + "Pinhead diameter should be smaller than the pillar diameter.")); - if (m_update_cnt == 0) - wxGetApp().mainframe->on_config_changed(m_config); + auto dialog = new wxMessageDialog(parent(), + msg_text, + _(L("Invalid pinhead diameter")), + wxICON_WARNING | wxOK); + + DynamicPrintConfig new_conf = *m_config; + if (dialog->ShowModal() == wxID_OK) { + new_conf.set_key_value("support_head_front_diameter", + new ConfigOptionFloat(pillar_d / 2.0)); + } + + load_config(new_conf); + } + + // if(m_config->opt_float("support_object_elevation") < EPSILON && + // m_config->opt_bool("pad_enable")) { + // // TODO: disable editding of: + // // pad_object_connector_stride + // // pad_object_connector_width + // // pad_object_connector_penetration + // } + + m_update_cnt--; + + if (m_update_cnt == 0) wxGetApp().mainframe->on_config_changed(m_config); } } // GUI