Fix of Add option to change support interface pattern #1197

New config field for switching the support interface pattern between
default (rectilinear for non-soluble interface, concentric for soluble interface),
explicit rectilinear and explicit concentric.

Also the config layer was reworked a bit to reduce some switch statements
on ConfigOptionEnum<> templates.
This commit is contained in:
Vojtech Bubnik 2021-02-24 15:59:09 +01:00
parent 88bd189047
commit 61a5b43ac3
13 changed files with 66 additions and 70 deletions

View File

@ -1313,6 +1313,7 @@ public:
ConfigOptionEnum<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; } ConfigOptionEnum<T>& operator=(const ConfigOption *opt) { this->set(opt); return *this; }
bool operator==(const ConfigOptionEnum<T> &rhs) const { return this->value == rhs.value; } bool operator==(const ConfigOptionEnum<T> &rhs) const { return this->value == rhs.value; }
int getInt() const override { return (int)this->value; } int getInt() const override { return (int)this->value; }
void setInt(int val) override { this->value = T(val); }
bool operator==(const ConfigOption &rhs) const override bool operator==(const ConfigOption &rhs) const override
{ {

View File

@ -429,7 +429,7 @@ const std::vector<std::string>& Preset::print_options()
"raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion", "raft_layers", "raft_first_layer_density", "raft_first_layer_expansion", "raft_contact_distance", "raft_expansion",
"support_material_pattern", "support_material_with_sheath", "support_material_spacing", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers", "support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance", "support_material_interface_pattern", "support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius", "support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder", "extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "perimeter_extruder",
"infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder", "infill_extruder", "solid_infill_extruder", "support_material_extruder", "support_material_interface_extruder",

View File

@ -2341,6 +2341,22 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced; def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear)); def->set_default_value(new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear));
def = this->add("support_material_interface_pattern", coEnum);
def->label = L("Interface pattern");
def->category = L("Support material");
def->tooltip = L("Pattern used to generate support material interface. "
"Default pattern for non-soluble support interface is Rectilinear, "
"while default pattern for soluble support interface is Concentric.");
def->enum_keys_map = &ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values();
def->enum_values.push_back("auto");
def->enum_values.push_back("rectilinear");
def->enum_values.push_back("concentric");
def->enum_labels.push_back(L("Default"));
def->enum_labels.push_back(L("Rectilinear"));
def->enum_labels.push_back(L("Concentric"));
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionEnum<SupportMaterialPattern>(smpRectilinear));
def = this->add("support_material_spacing", coFloat); def = this->add("support_material_spacing", coFloat);
def->label = L("Pattern spacing"); def->label = L("Pattern spacing");
def->category = L("Support material"); def->category = L("Support material");

View File

@ -65,6 +65,10 @@ enum SupportMaterialPattern {
smpRectilinear, smpRectilinearGrid, smpHoneycomb, smpRectilinear, smpRectilinearGrid, smpHoneycomb,
}; };
enum SupportMaterialInterfacePattern {
smipAuto, smipRectilinear, smipConcentric,
};
enum SeamPosition { enum SeamPosition {
spRandom, spNearest, spAligned, spRear spRandom, spNearest, spAligned, spRear
}; };
@ -207,6 +211,16 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialPa
return keys_map; return keys_map;
} }
template<> inline const t_config_enum_values& ConfigOptionEnum<SupportMaterialInterfacePattern>::get_enum_values() {
static t_config_enum_values keys_map;
if (keys_map.empty()) {
keys_map["auto"] = smipAuto;
keys_map["rectilinear"] = smipRectilinear;
keys_map["concentric"] = smipConcentric;
}
return keys_map;
}
template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() { template<> inline const t_config_enum_values& ConfigOptionEnum<SeamPosition>::get_enum_values() {
static t_config_enum_values keys_map; static t_config_enum_values keys_map;
if (keys_map.empty()) { if (keys_map.empty()) {
@ -499,6 +513,7 @@ public:
ConfigOptionFloat support_material_interface_spacing; ConfigOptionFloat support_material_interface_spacing;
ConfigOptionFloatOrPercent support_material_interface_speed; ConfigOptionFloatOrPercent support_material_interface_speed;
ConfigOptionEnum<SupportMaterialPattern> support_material_pattern; ConfigOptionEnum<SupportMaterialPattern> support_material_pattern;
ConfigOptionEnum<SupportMaterialPattern> support_material_interface_pattern;
// Spacing between support material lines (the hatching distance). // Spacing between support material lines (the hatching distance).
ConfigOptionFloat support_material_spacing; ConfigOptionFloat support_material_spacing;
ConfigOptionFloat support_material_speed; ConfigOptionFloat support_material_speed;
@ -547,6 +562,7 @@ protected:
OPT_PTR(support_material_interface_spacing); OPT_PTR(support_material_interface_spacing);
OPT_PTR(support_material_interface_speed); OPT_PTR(support_material_interface_speed);
OPT_PTR(support_material_pattern); OPT_PTR(support_material_pattern);
OPT_PTR(support_material_interface_pattern);
OPT_PTR(support_material_spacing); OPT_PTR(support_material_spacing);
OPT_PTR(support_material_speed); OPT_PTR(support_material_speed);
OPT_PTR(support_material_synchronize_layers); OPT_PTR(support_material_synchronize_layers);

View File

@ -568,6 +568,7 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "support_material_extruder" || opt_key == "support_material_extruder"
|| opt_key == "support_material_extrusion_width" || opt_key == "support_material_extrusion_width"
|| opt_key == "support_material_interface_layers" || opt_key == "support_material_interface_layers"
|| opt_key == "support_material_interface_pattern"
|| opt_key == "support_material_interface_contact_loops" || opt_key == "support_material_interface_contact_loops"
|| opt_key == "support_material_interface_extruder" || opt_key == "support_material_interface_extruder"
|| opt_key == "support_material_interface_spacing" || opt_key == "support_material_interface_spacing"

View File

@ -3573,9 +3573,15 @@ void PrintObjectSupportMaterial::generate_toolpaths(
}; };
std::vector<LayerCache> layer_caches(support_layers.size(), LayerCache()); std::vector<LayerCache> layer_caches(support_layers.size(), LayerCache());
const auto fill_type_interface =
(m_object_config->support_material_interface_pattern == smipAuto && m_slicing_params.soluble_interface) ||
m_object_config->support_material_interface_pattern == smipConcentric ?
ipConcentric : ipRectilinear;
tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()), tbb::parallel_for(tbb::blocked_range<size_t>(n_raft_layers, support_layers.size()),
[this, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor, [this, &support_layers, &bottom_contacts, &top_contacts, &intermediate_layers, &interface_layers, &base_interface_layers, &layer_caches, &loop_interface_processor,
infill_pattern, &bbox_object, support_density, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath] infill_pattern, &bbox_object, support_density, fill_type_interface, interface_density, interface_angle, &angles, link_max_length_factor, with_sheath]
(const tbb::blocked_range<size_t>& range) { (const tbb::blocked_range<size_t>& range) {
// Indices of the 1st layer in their respective container at the support layer height. // Indices of the 1st layer in their respective container at the support layer height.
size_t idx_layer_bottom_contact = size_t(-1); size_t idx_layer_bottom_contact = size_t(-1);
@ -3583,7 +3589,6 @@ void PrintObjectSupportMaterial::generate_toolpaths(
size_t idx_layer_intermediate = size_t(-1); size_t idx_layer_intermediate = size_t(-1);
size_t idx_layer_interface = size_t(-1); size_t idx_layer_interface = size_t(-1);
size_t idx_layer_base_interface = size_t(-1); size_t idx_layer_base_interface = size_t(-1);
const auto fill_type_interface = m_slicing_params.soluble_interface ? ipConcentric : ipRectilinear;
const auto fill_type_first_layer = ipRectilinear; const auto fill_type_first_layer = ipRectilinear;
auto filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(fill_type_interface)); auto filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(fill_type_interface));
// Filler for the 1st layer interface, if different from filler_interface. // Filler for the 1st layer interface, if different from filler_interface.

View File

@ -279,7 +279,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
bool have_support_interface = config->opt_int("support_material_interface_layers") > 0; bool have_support_interface = config->opt_int("support_material_interface_layers") > 0;
bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0; bool have_support_soluble = have_support_material && config->opt_float("support_material_contact_distance") == 0;
for (auto el : { "support_material_pattern", "support_material_with_sheath", for (auto el : { "support_material_pattern", "support_material_with_sheath",
"support_material_spacing", "support_material_angle", "support_material_interface_layers", "support_material_spacing", "support_material_angle",
"support_material_interface_pattern", "support_material_interface_layers",
"dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance", "dont_support_bridges", "support_material_extrusion_width", "support_material_contact_distance",
"support_material_xy_spacing" }) "support_material_xy_spacing" })
toggle_field(el, have_support_material); toggle_field(el, have_support_material);

View File

@ -1210,6 +1210,8 @@ boost::any& Choice::get_value()
m_value = static_cast<MachineLimitsUsage>(ret_enum); m_value = static_cast<MachineLimitsUsage>(ret_enum);
else if (m_opt_id.compare("support_material_pattern") == 0) else if (m_opt_id.compare("support_material_pattern") == 0)
m_value = static_cast<SupportMaterialPattern>(ret_enum); m_value = static_cast<SupportMaterialPattern>(ret_enum);
else if (m_opt_id.compare("support_material_interface_pattern") == 0)
m_value = static_cast<SupportMaterialInterfacePattern>(ret_enum);
else if (m_opt_id.compare("seam_position") == 0) else if (m_opt_id.compare("seam_position") == 0)
m_value = static_cast<SeamPosition>(ret_enum); m_value = static_cast<SeamPosition>(ret_enum);
else if (m_opt_id.compare("host_type") == 0) else if (m_opt_id.compare("host_type") == 0)

View File

@ -104,7 +104,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
return; return;
} }
switch (config.def()->get(opt_key)->type) { const ConfigOptionDef *opt_def = config.def()->get(opt_key);
switch (opt_def->type) {
case coFloatOrPercent:{ case coFloatOrPercent:{
std::string str = boost::any_cast<std::string>(value); std::string str = boost::any_cast<std::string>(value);
bool percent = false; bool percent = false;
@ -176,6 +177,11 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
} }
break; break;
case coEnum:{ case coEnum:{
#if 0
auto *opt = opt_def->default_value.get()->clone();
opt->setInt(0);
config.set_key_value(opt_key, opt);
#else
if (opt_key == "top_fill_pattern" || if (opt_key == "top_fill_pattern" ||
opt_key == "bottom_fill_pattern" || opt_key == "bottom_fill_pattern" ||
opt_key == "fill_pattern") opt_key == "fill_pattern")
@ -190,6 +196,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
config.set_key_value(opt_key, new ConfigOptionEnum<MachineLimitsUsage>(boost::any_cast<MachineLimitsUsage>(value))); config.set_key_value(opt_key, new ConfigOptionEnum<MachineLimitsUsage>(boost::any_cast<MachineLimitsUsage>(value)));
else if (opt_key.compare("support_material_pattern") == 0) else if (opt_key.compare("support_material_pattern") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value))); config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialPattern>(boost::any_cast<SupportMaterialPattern>(value)));
else if (opt_key.compare("support_material_interface_pattern") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SupportMaterialInterfacePattern>(boost::any_cast<SupportMaterialInterfacePattern>(value)));
else if (opt_key.compare("seam_position") == 0) else if (opt_key.compare("seam_position") == 0)
config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value))); config.set_key_value(opt_key, new ConfigOptionEnum<SeamPosition>(boost::any_cast<SeamPosition>(value)));
else if (opt_key.compare("host_type") == 0) else if (opt_key.compare("host_type") == 0)
@ -203,6 +211,7 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
else if(opt_key == "brim_type") else if(opt_key == "brim_type")
config.set_key_value(opt_key, new ConfigOptionEnum<BrimType>(boost::any_cast<BrimType>(value))); config.set_key_value(opt_key, new ConfigOptionEnum<BrimType>(boost::any_cast<BrimType>(value)));
} }
#endif
break; break;
case coPoints:{ case coPoints:{
if (opt_key == "bed_shape" || opt_key == "thumbnails") { if (opt_key == "bed_shape" || opt_key == "thumbnails") {

View File

@ -35,7 +35,7 @@ static SettingsBundle FREQ_SETTINGS_BUNDLE_FFF =
{ L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } }, { L("Layers and Perimeters"), { "layer_height" , "perimeters", "top_solid_layers", "bottom_solid_layers" } },
{ L("Infill") , { "fill_density", "fill_pattern" } }, { L("Infill") , { "fill_density", "fill_pattern" } },
{ L("Support material") , { "support_material", "support_material_auto", "support_material_threshold", { L("Support material") , { "support_material", "support_material_auto", "support_material_threshold",
"support_material_pattern", "support_material_buildplate_only", "support_material_pattern", "support_material_interface_pattern", "support_material_buildplate_only",
"support_material_spacing" } }, "support_material_spacing" } },
{ L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } } { L("Wipe options") , { "wipe_into_infill", "wipe_into_objects" } }
}; };

View File

@ -860,46 +860,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
case coInts: case coInts:
ret = config.opt_int(opt_key, idx); ret = config.opt_int(opt_key, idx);
break; break;
case coEnum:{ case coEnum:
if (opt_key == "top_fill_pattern" || ret = config.option(opt_key)->getInt();
opt_key == "bottom_fill_pattern" ||
opt_key == "fill_pattern" ) {
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
}
else if (opt_key == "ironing_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<IroningType>>(opt_key)->value);
}
else if (opt_key == "fuzzy_skin") {
ret = static_cast<int>(config.option<ConfigOptionEnum<FuzzySkinType>>(opt_key)->value);
}
else if (opt_key == "gcode_flavor") {
ret = static_cast<int>(config.option<ConfigOptionEnum<GCodeFlavor>>(opt_key)->value);
}
else if (opt_key == "machine_limits_usage") {
ret = static_cast<int>(config.option<ConfigOptionEnum<MachineLimitsUsage>>(opt_key)->value);
}
else if (opt_key == "support_material_pattern") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SupportMaterialPattern>>(opt_key)->value);
}
else if (opt_key == "seam_position") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SeamPosition>>(opt_key)->value);
}
else if (opt_key == "host_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<PrintHostType>>(opt_key)->value);
}
else if (opt_key == "display_orientation") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SLADisplayOrientation>>(opt_key)->value);
}
else if (opt_key == "support_pillar_connection_mode") {
ret = static_cast<int>(config.option<ConfigOptionEnum<SLAPillarConnectionMode>>(opt_key)->value);
}
else if (opt_key == "printhost_authorization_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<AuthorizationType>>(opt_key)->value);
}
else if (opt_key == "brim_type") {
ret = static_cast<int>(config.option<ConfigOptionEnum<BrimType>>(opt_key)->value);
}
}
break; break;
case coPoints: case coPoints:
if (opt_key == "bed_shape") if (opt_key == "bed_shape")

View File

@ -1511,6 +1511,7 @@ void TabPrint::build()
optgroup->append_single_option_line("support_material_spacing", category_path + "pattern-spacing-0-inf"); optgroup->append_single_option_line("support_material_spacing", category_path + "pattern-spacing-0-inf");
optgroup->append_single_option_line("support_material_angle", category_path + "pattern-angle"); optgroup->append_single_option_line("support_material_angle", category_path + "pattern-angle");
optgroup->append_single_option_line("support_material_interface_layers", category_path + "interface-layers"); optgroup->append_single_option_line("support_material_interface_layers", category_path + "interface-layers");
optgroup->append_single_option_line("support_material_interface_pattern", category_path + "interface-pattern");
optgroup->append_single_option_line("support_material_interface_spacing", category_path + "interface-pattern-spacing"); optgroup->append_single_option_line("support_material_interface_spacing", category_path + "interface-pattern-spacing");
optgroup->append_single_option_line("support_material_interface_contact_loops", category_path + "interface-loops"); optgroup->append_single_option_line("support_material_interface_contact_loops", category_path + "interface-loops");
optgroup->append_single_option_line("support_material_buildplate_only", category_path + "support-on-build-plate-only"); optgroup->append_single_option_line("support_material_buildplate_only", category_path + "support-on-build-plate-only");

View File

@ -986,18 +986,17 @@ bool UnsavedChangesDialog::save(PresetCollection* dependent_presets)
return true; return true;
} }
template<class T>
wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConfig& config, bool is_infill = false) wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConfig& config, bool is_infill = false)
{ {
const ConfigOptionDef& def = config.def()->options.at(opt_key); const ConfigOptionDef& def = config.def()->options.at(opt_key);
const std::vector<std::string>& names = def.enum_labels;//ConfigOptionEnum<T>::get_enum_names(); const std::vector<std::string>& names = def.enum_labels;//ConfigOptionEnum<T>::get_enum_names();
T val = config.option<ConfigOptionEnum<T>>(opt_key)->value; int val = config.option(opt_key)->getInt();
// Each infill doesn't use all list of infill declared in PrintConfig.hpp. // Each infill doesn't use all list of infill declared in PrintConfig.hpp.
// So we should "convert" val to the correct one // So we should "convert" val to the correct one
if (is_infill) { if (is_infill) {
for (auto key_val : *def.enum_keys_map) for (auto key_val : *def.enum_keys_map)
if ((int)key_val.second == (int)val) { if (int(key_val.second) == val) {
auto it = std::find(def.enum_values.begin(), def.enum_values.end(), key_val.first); auto it = std::find(def.enum_values.begin(), def.enum_values.end(), key_val.first);
if (it == def.enum_values.end()) if (it == def.enum_values.end())
return ""; return "";
@ -1005,7 +1004,7 @@ wxString get_string_from_enum(const std::string& opt_key, const DynamicPrintConf
} }
return _L("Undef"); return _L("Undef");
} }
return from_u8(_utf8(names[static_cast<int>(val)])); return from_u8(_utf8(names[val]));
} }
static size_t get_id_from_opt_key(std::string opt_key) static size_t get_id_from_opt_key(std::string opt_key)
@ -1128,27 +1127,10 @@ static wxString get_string_value(std::string opt_key, const DynamicPrintConfig&
return out; return out;
} }
case coEnum: { case coEnum: {
if (opt_key == "top_fill_pattern" || return get_string_from_enum(opt_key, config,
opt_key == "top_fill_pattern" ||
opt_key == "bottom_fill_pattern" || opt_key == "bottom_fill_pattern" ||
opt_key == "fill_pattern") opt_key == "fill_pattern");
return get_string_from_enum<InfillPattern>(opt_key, config, true);
if (opt_key == "gcode_flavor")
return get_string_from_enum<GCodeFlavor>(opt_key, config);
if (opt_key == "machine_limits_usage")
return get_string_from_enum<MachineLimitsUsage>(opt_key, config);
if (opt_key == "ironing_type")
return get_string_from_enum<IroningType>(opt_key, config);
if (opt_key == "support_material_pattern")
return get_string_from_enum<SupportMaterialPattern>(opt_key, config);
if (opt_key == "seam_position")
return get_string_from_enum<SeamPosition>(opt_key, config);
if (opt_key == "display_orientation")
return get_string_from_enum<SLADisplayOrientation>(opt_key, config);
if (opt_key == "support_pillar_connection_mode")
return get_string_from_enum<SLAPillarConnectionMode>(opt_key, config);
if (opt_key == "brim_type")
return get_string_from_enum<BrimType>(opt_key, config);
break;
} }
case coPoints: { case coPoints: {
if (opt_key == "bed_shape") { if (opt_key == "bed_shape") {