SPE-742: Parameter layer for zero elevation feature.

This commit is contained in:
tamasmeszaros 2019-06-11 17:57:39 +02:00
parent b7e3ee0709
commit 6877c075dc
9 changed files with 179 additions and 60 deletions

View File

@ -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)

View File

@ -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);
}
};

View File

@ -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;
}

View File

@ -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<AABBImpl> 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; }

View File

@ -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<Vec3d> 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) {

View File

@ -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<ExPolygons> slice(float layerh, float init_layerh = -1.0) const;
std::vector<ExPolygons> slice(const std::vector<float>&, float closing_radius) const;
std::vector<ExPolygons> slice(const std::vector<float> &,
float closing_radius) const;
/// Adding the "pad" (base pool) under the supports
/// modelbase will be used according to the embed_object flag in PoolConfig.

View File

@ -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<t_conf
|| opt_key == "support_critical_angle"
|| opt_key == "support_max_bridge_length"
|| opt_key == "support_max_pillar_link_distance"
|| opt_key == "support_base_safety_distance"
) {
steps.emplace_back(slaposSupportTree);
} else if (
opt_key == "pad_wall_height"
|| opt_key == "pad_max_merge_distance"
|| opt_key == "pad_wall_slope"
|| opt_key == "pad_edge_radius") {
|| opt_key == "pad_edge_radius"
|| opt_key == "pad_object_connector_stride"
|| opt_key == "pad_object_connector_width"
|| opt_key == "pad_object_connector_penetration"
) {
steps.emplace_back(slaposBasePool);
} else {
// All keys should be covered.

View File

@ -461,6 +461,7 @@ const std::vector<std::string>& 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<std::string>& 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",

View File

@ -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