mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-07 11:58:59 +08:00
SPE-2400: Add an option for setting the gap size between the beginning and the end of closed perimeters.
Negative values extend the loop, causing the endpoints to overlap slightly.
This commit is contained in:
parent
6cc7ff754c
commit
56a2a5973d
@ -69,6 +69,8 @@ namespace Slic3r {
|
|||||||
double value;
|
double value;
|
||||||
bool percent;
|
bool percent;
|
||||||
|
|
||||||
|
double get_abs_value(double ratio_over) const { return this->percent ? (ratio_over * this->value / 100) : this->value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class cereal::access;
|
friend class cereal::access;
|
||||||
template<class Archive> void serialize(Archive& ar) { ar(this->value); ar(this->percent); }
|
template<class Archive> void serialize(Archive& ar) { ar(this->value); ar(this->percent); }
|
||||||
@ -2265,17 +2267,18 @@ public:
|
|||||||
bool is_scalar() const { return (int(this->type) & int(coVectorType)) == 0; }
|
bool is_scalar() const { return (int(this->type) & int(coVectorType)) == 0; }
|
||||||
|
|
||||||
template<class Archive> ConfigOption* load_option_from_archive(Archive &archive) const {
|
template<class Archive> ConfigOption* load_option_from_archive(Archive &archive) const {
|
||||||
if (this->nullable) {
|
if (this->nullable) {
|
||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case coFloat: { auto opt = new ConfigOptionFloatNullable(); archive(*opt); return opt; }
|
case coFloat: { auto opt = new ConfigOptionFloatNullable(); archive(*opt); return opt; }
|
||||||
case coInt: { auto opt = new ConfigOptionIntNullable(); archive(*opt); return opt; }
|
case coInt: { auto opt = new ConfigOptionIntNullable(); archive(*opt); return opt; }
|
||||||
case coFloats: { auto opt = new ConfigOptionFloatsNullable(); archive(*opt); return opt; }
|
case coFloats: { auto opt = new ConfigOptionFloatsNullable(); archive(*opt); return opt; }
|
||||||
case coInts: { auto opt = new ConfigOptionIntsNullable(); archive(*opt); return opt; }
|
case coInts: { auto opt = new ConfigOptionIntsNullable(); archive(*opt); return opt; }
|
||||||
case coPercents: { auto opt = new ConfigOptionPercentsNullable();archive(*opt); return opt; }
|
case coPercents: { auto opt = new ConfigOptionPercentsNullable(); archive(*opt); return opt; }
|
||||||
case coBools: { auto opt = new ConfigOptionBoolsNullable(); archive(*opt); return opt; }
|
case coBools: { auto opt = new ConfigOptionBoolsNullable(); archive(*opt); return opt; }
|
||||||
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown nullable option type for option ") + this->opt_key);
|
case coFloatsOrPercents: { auto opt = new ConfigOptionFloatsOrPercentsNullable(); archive(*opt); return opt; }
|
||||||
}
|
default: throw ConfigurationError(std::string("ConfigOptionDef::load_option_from_archive(): Unknown nullable option type for option ") + this->opt_key);
|
||||||
} else {
|
}
|
||||||
|
} else {
|
||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case coFloat: { auto opt = new ConfigOptionFloat(); archive(*opt); return opt; }
|
case coFloat: { auto opt = new ConfigOptionFloat(); archive(*opt); return opt; }
|
||||||
case coFloats: { auto opt = new ConfigOptionFloats(); archive(*opt); return opt; }
|
case coFloats: { auto opt = new ConfigOptionFloats(); archive(*opt); return opt; }
|
||||||
@ -2300,16 +2303,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<class Archive> ConfigOption* save_option_to_archive(Archive &archive, const ConfigOption *opt) const {
|
template<class Archive> ConfigOption* save_option_to_archive(Archive &archive, const ConfigOption *opt) const {
|
||||||
if (this->nullable) {
|
if (this->nullable) {
|
||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case coFloat: archive(*static_cast<const ConfigOptionFloatNullable*>(opt)); break;
|
case coFloat: archive(*static_cast<const ConfigOptionFloatNullable*>(opt)); break;
|
||||||
case coInt: archive(*static_cast<const ConfigOptionIntNullable*>(opt)); break;
|
case coInt: archive(*static_cast<const ConfigOptionIntNullable*>(opt)); break;
|
||||||
case coFloats: archive(*static_cast<const ConfigOptionFloatsNullable*>(opt)); break;
|
case coFloats: archive(*static_cast<const ConfigOptionFloatsNullable*>(opt)); break;
|
||||||
case coInts: archive(*static_cast<const ConfigOptionIntsNullable*>(opt)); break;
|
case coInts: archive(*static_cast<const ConfigOptionIntsNullable*>(opt)); break;
|
||||||
case coPercents: archive(*static_cast<const ConfigOptionPercentsNullable*>(opt));break;
|
case coPercents: archive(*static_cast<const ConfigOptionPercentsNullable*>(opt)); break;
|
||||||
case coBools: archive(*static_cast<const ConfigOptionBoolsNullable*>(opt)); break;
|
case coBools: archive(*static_cast<const ConfigOptionBoolsNullable*>(opt)); break;
|
||||||
default: throw ConfigurationError(std::string("ConfigOptionDef::save_option_to_archive(): Unknown nullable option type for option ") + this->opt_key);
|
case coFloatsOrPercents: archive(*static_cast<const ConfigOptionFloatsOrPercentsNullable*>(opt)); break;
|
||||||
}
|
default: throw ConfigurationError(std::string("ConfigOptionDef::save_option_to_archive(): Unknown nullable option type for option ") + this->opt_key);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (this->type) {
|
switch (this->type) {
|
||||||
case coFloat: archive(*static_cast<const ConfigOptionFloat*>(opt)); break;
|
case coFloat: archive(*static_cast<const ConfigOptionFloat*>(opt)); break;
|
||||||
|
@ -2311,6 +2311,17 @@ std::pair<GCode::SmoothPath, std::size_t> split_with_seam(
|
|||||||
}
|
}
|
||||||
} // namespace GCode
|
} // namespace GCode
|
||||||
|
|
||||||
|
static inline double get_seam_gap_distance_value(const PrintConfig &config, const unsigned extruder_id)
|
||||||
|
{
|
||||||
|
const double nozzle_diameter = config.nozzle_diameter.get_at(extruder_id);
|
||||||
|
const FloatOrPercent seam_gap_distance_override = config.filament_seam_gap_distance.get_at(extruder_id);
|
||||||
|
if (!std::isnan(seam_gap_distance_override.value)) {
|
||||||
|
return seam_gap_distance_override.get_abs_value(nozzle_diameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.seam_gap_distance.get_abs_value(nozzle_diameter);
|
||||||
|
}
|
||||||
|
|
||||||
using GCode::ExtrusionOrder::InstancePoint;
|
using GCode::ExtrusionOrder::InstancePoint;
|
||||||
|
|
||||||
struct SmoothPathGenerator
|
struct SmoothPathGenerator
|
||||||
@ -2361,12 +2372,20 @@ struct SmoothPathGenerator
|
|||||||
// Clip the path to avoid the extruder to get exactly on the first point of the
|
// Clip the path to avoid the extruder to get exactly on the first point of the
|
||||||
// loop; if polyline was shorter than the clipping distance we'd get a null
|
// loop; if polyline was shorter than the clipping distance we'd get a null
|
||||||
// polyline, so we discard it in that case.
|
// polyline, so we discard it in that case.
|
||||||
const auto nozzle_diameter{config.nozzle_diameter.get_at(extruder_id)};
|
if (const double extrusion_clipping = get_seam_gap_distance_value(config, extruder_id); enable_loop_clipping && extrusion_clipping > 0.) {
|
||||||
if (enable_loop_clipping) {
|
|
||||||
clip_end(
|
clip_end(
|
||||||
result, scale_(nozzle_diameter) * LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER,
|
result,
|
||||||
|
scaled<double>(extrusion_clipping),
|
||||||
scaled<double>(GCode::ExtrusionOrder::min_gcode_segment_length)
|
scaled<double>(GCode::ExtrusionOrder::min_gcode_segment_length)
|
||||||
);
|
);
|
||||||
|
} else if (enable_loop_clipping && extrusion_clipping < 0.) {
|
||||||
|
// Extend the extrusion slightly after the seam.
|
||||||
|
const double smooth_path_extension_length = -1. * scaled<double>(extrusion_clipping);
|
||||||
|
const double smooth_path_extension_cut_length = length(result) - smooth_path_extension_length;
|
||||||
|
GCode::SmoothPath smooth_path_extension = result;
|
||||||
|
|
||||||
|
clip_end(smooth_path_extension, smooth_path_extension_cut_length, scaled<double>(GCode::ExtrusionOrder::min_gcode_segment_length));
|
||||||
|
Slic3r::append(result, smooth_path_extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(validate_smooth_path(result, !enable_loop_clipping));
|
assert(validate_smooth_path(result, !enable_loop_clipping));
|
||||||
|
@ -456,7 +456,8 @@ static std::vector<std::string> s_Preset_print_options {
|
|||||||
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
|
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
|
||||||
"ensure_vertical_shell_thickness", "extra_perimeters", "extra_perimeters_on_overhangs",
|
"ensure_vertical_shell_thickness", "extra_perimeters", "extra_perimeters_on_overhangs",
|
||||||
"avoid_crossing_curled_overhangs", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
"avoid_crossing_curled_overhangs", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||||
"seam_position","staggered_inner_seams", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
|
"seam_position", "staggered_inner_seams", "seam_gap_distance",
|
||||||
|
"external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
|
||||||
"scarf_seam_placement", "scarf_seam_only_on_smooth", "scarf_seam_start_height", "scarf_seam_entire_loop", "scarf_seam_length", "scarf_seam_max_segment_length", "scarf_seam_on_inner_perimeters",
|
"scarf_seam_placement", "scarf_seam_only_on_smooth", "scarf_seam_start_height", "scarf_seam_entire_loop", "scarf_seam_length", "scarf_seam_max_segment_length", "scarf_seam_on_inner_perimeters",
|
||||||
"infill_every_layers", /*"infill_only_where_needed",*/ "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
"infill_every_layers", /*"infill_only_where_needed",*/ "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||||
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
|
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first",
|
||||||
@ -512,6 +513,8 @@ static std::vector<std::string> s_Preset_filament_options {
|
|||||||
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits",
|
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||||
// Shrinkage compensation
|
// Shrinkage compensation
|
||||||
"filament_shrinkage_compensation_xy", "filament_shrinkage_compensation_z",
|
"filament_shrinkage_compensation_xy", "filament_shrinkage_compensation_z",
|
||||||
|
// Seams overrides
|
||||||
|
"filament_seam_gap_distance"
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::vector<std::string> s_Preset_machine_limits_options {
|
static std::vector<std::string> s_Preset_machine_limits_options {
|
||||||
|
@ -120,6 +120,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||||||
"filament_density",
|
"filament_density",
|
||||||
"filament_notes",
|
"filament_notes",
|
||||||
"filament_cost",
|
"filament_cost",
|
||||||
|
"filament_seam_gap_distance",
|
||||||
"filament_spool_weight",
|
"filament_spool_weight",
|
||||||
"first_layer_acceleration",
|
"first_layer_acceleration",
|
||||||
"first_layer_acceleration_over_raft",
|
"first_layer_acceleration_over_raft",
|
||||||
@ -161,6 +162,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
|||||||
"retract_restart_extra",
|
"retract_restart_extra",
|
||||||
"retract_restart_extra_toolchange",
|
"retract_restart_extra_toolchange",
|
||||||
"retract_speed",
|
"retract_speed",
|
||||||
|
"seam_gap_distance",
|
||||||
"single_extruder_multi_material_priming",
|
"single_extruder_multi_material_priming",
|
||||||
"slowdown_below_layer_time",
|
"slowdown_below_layer_time",
|
||||||
"solid_infill_acceleration",
|
"solid_infill_acceleration",
|
||||||
|
@ -2654,6 +2654,17 @@ void PrintConfigDef::init_fff_params()
|
|||||||
def->mode = comAdvanced;
|
def->mode = comAdvanced;
|
||||||
def->set_default_value(new ConfigOptionFloats { 0. });
|
def->set_default_value(new ConfigOptionFloats { 0. });
|
||||||
|
|
||||||
|
def = this->add("seam_gap_distance", coFloatOrPercent);
|
||||||
|
def->label = L("Seam gap distance");
|
||||||
|
def->tooltip = L("The distance between the endpoints of a closed loop perimeter. "
|
||||||
|
"Positive values will shorten and interrupt the loop slightly to reduce the seam. "
|
||||||
|
"Negative values will extend the loop, causing the endpoints to overlap slightly. "
|
||||||
|
"When percents are used, the distance is derived from the nozzle diameter. "
|
||||||
|
"Set to zero to disable this feature.");
|
||||||
|
def->sidetext = L("mm or %");
|
||||||
|
def->mode = comAdvanced;
|
||||||
|
def->set_default_value(new ConfigOptionFloatOrPercent{ 15., true });
|
||||||
|
|
||||||
def = this->add("seam_position", coEnum);
|
def = this->add("seam_position", coEnum);
|
||||||
def->label = L("Seam position");
|
def->label = L("Seam position");
|
||||||
def->category = L("Layers and Perimeters");
|
def->category = L("Layers and Perimeters");
|
||||||
@ -3775,9 +3786,9 @@ void PrintConfigDef::init_fff_params()
|
|||||||
auto it_opt = options.find(opt_key);
|
auto it_opt = options.find(opt_key);
|
||||||
assert(it_opt != options.end());
|
assert(it_opt != options.end());
|
||||||
def = this->add_nullable(std::string("filament_") + opt_key, it_opt->second.type);
|
def = this->add_nullable(std::string("filament_") + opt_key, it_opt->second.type);
|
||||||
def->label = it_opt->second.label;
|
def->label = it_opt->second.label;
|
||||||
def->full_label = it_opt->second.full_label;
|
def->full_label = it_opt->second.full_label;
|
||||||
def->tooltip = it_opt->second.tooltip;
|
def->tooltip = it_opt->second.tooltip;
|
||||||
def->sidetext = it_opt->second.sidetext;
|
def->sidetext = it_opt->second.sidetext;
|
||||||
def->mode = it_opt->second.mode;
|
def->mode = it_opt->second.mode;
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
@ -3787,6 +3798,44 @@ void PrintConfigDef::init_fff_params()
|
|||||||
default: assert(false);
|
default: assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Declare values for filament profile, overriding printer's profile.
|
||||||
|
for (const char *opt_key : {
|
||||||
|
// Floats or Percents
|
||||||
|
"seam_gap_distance"}) {
|
||||||
|
|
||||||
|
auto it_opt = options.find(opt_key);
|
||||||
|
assert(it_opt != options.end());
|
||||||
|
|
||||||
|
switch (it_opt->second.type) {
|
||||||
|
case coFloatOrPercent: {
|
||||||
|
def = this->add_nullable(std::string("filament_") + opt_key, coFloatsOrPercents);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def->label = it_opt->second.label;
|
||||||
|
def->full_label = it_opt->second.full_label;
|
||||||
|
def->tooltip = it_opt->second.tooltip;
|
||||||
|
def->sidetext = it_opt->second.sidetext;
|
||||||
|
def->mode = it_opt->second.mode;
|
||||||
|
|
||||||
|
switch (def->type) {
|
||||||
|
case coFloatsOrPercents: {
|
||||||
|
const auto &default_value = *static_cast<const ConfigOptionFloatOrPercent *>(it_opt->second.default_value.get());
|
||||||
|
def->set_default_value(new ConfigOptionFloatsOrPercentsNullable{{default_value.value, default_value.percent}});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintConfigDef::init_extruder_option_keys()
|
void PrintConfigDef::init_extruder_option_keys()
|
||||||
|
@ -830,6 +830,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionFloats, filament_multitool_ramming_flow))
|
((ConfigOptionFloats, filament_multitool_ramming_flow))
|
||||||
((ConfigOptionFloats, filament_stamping_loading_speed))
|
((ConfigOptionFloats, filament_stamping_loading_speed))
|
||||||
((ConfigOptionFloats, filament_stamping_distance))
|
((ConfigOptionFloats, filament_stamping_distance))
|
||||||
|
((ConfigOptionFloatsOrPercentsNullable, filament_seam_gap_distance))
|
||||||
((ConfigOptionPercents, filament_shrinkage_compensation_xy))
|
((ConfigOptionPercents, filament_shrinkage_compensation_xy))
|
||||||
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
((ConfigOptionPercents, filament_shrinkage_compensation_z))
|
||||||
((ConfigOptionBool, gcode_comments))
|
((ConfigOptionBool, gcode_comments))
|
||||||
@ -860,6 +861,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
|||||||
((ConfigOptionFloats, retract_restart_extra))
|
((ConfigOptionFloats, retract_restart_extra))
|
||||||
((ConfigOptionFloats, retract_restart_extra_toolchange))
|
((ConfigOptionFloats, retract_restart_extra_toolchange))
|
||||||
((ConfigOptionFloats, retract_speed))
|
((ConfigOptionFloats, retract_speed))
|
||||||
|
((ConfigOptionFloatOrPercent, seam_gap_distance))
|
||||||
((ConfigOptionString, start_gcode))
|
((ConfigOptionString, start_gcode))
|
||||||
((ConfigOptionStrings, start_filament_gcode))
|
((ConfigOptionStrings, start_filament_gcode))
|
||||||
((ConfigOptionBool, single_extruder_multi_material))
|
((ConfigOptionBool, single_extruder_multi_material))
|
||||||
|
@ -331,19 +331,22 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true
|
|||||||
if ((m_opt.type == coFloatOrPercent || m_opt.type == coFloatsOrPercents) && !str.IsEmpty() && str.Last() != '%')
|
if ((m_opt.type == coFloatOrPercent || m_opt.type == coFloatsOrPercents) && !str.IsEmpty() && str.Last() != '%')
|
||||||
{
|
{
|
||||||
double val = 0.;
|
double val = 0.;
|
||||||
|
|
||||||
|
bool is_na_value = m_opt.nullable && str == na_value();
|
||||||
|
|
||||||
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
|
const char dec_sep = is_decimal_separator_point() ? '.' : ',';
|
||||||
const char dec_sep_alt = dec_sep == '.' ? ',' : '.';
|
const char dec_sep_alt = dec_sep == '.' ? ',' : '.';
|
||||||
// Replace the first incorrect separator in decimal number.
|
// Replace the first incorrect separator in decimal number.
|
||||||
if (str.Replace(dec_sep_alt, dec_sep, false) != 0)
|
if (!is_na_value && str.Replace(dec_sep_alt, dec_sep, false) != 0)
|
||||||
set_value(str, false);
|
set_value(str, false);
|
||||||
|
|
||||||
|
|
||||||
// remove space and "mm" substring, if any exists
|
// remove space and "mm" substring, if any exists
|
||||||
str.Replace(" ", "", true);
|
str.Replace(" ", "", true);
|
||||||
str.Replace("m", "", true);
|
str.Replace("m", "", true);
|
||||||
|
|
||||||
if (!str.ToDouble(&val))
|
if (is_na_value) {
|
||||||
{
|
val = ConfigOptionFloatsOrPercentsNullable::nil_value().value;
|
||||||
|
} else if (!str.ToDouble(&val)) {
|
||||||
if (!check_value) {
|
if (!check_value) {
|
||||||
m_value.clear();
|
m_value.clear();
|
||||||
break;
|
break;
|
||||||
@ -453,8 +456,11 @@ void TextCtrl::BUILD() {
|
|||||||
case coFloatsOrPercents: {
|
case coFloatsOrPercents: {
|
||||||
const auto val = m_opt.get_default_value<ConfigOptionFloatsOrPercents>()->get_at(m_opt_idx);
|
const auto val = m_opt.get_default_value<ConfigOptionFloatsOrPercents>()->get_at(m_opt_idx);
|
||||||
text_value = double_to_string(val.value);
|
text_value = double_to_string(val.value);
|
||||||
if (val.percent)
|
if (val.percent) {
|
||||||
text_value += "%";
|
text_value += "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
m_last_meaningful_value = text_value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case coPercent:
|
case coPercent:
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <boost/algorithm/string/split.hpp>
|
#include <boost/algorithm/string/split.hpp>
|
||||||
#include <boost/algorithm/string/classification.hpp>
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
#include "slic3r/GUI/Search.hpp" // IWYU pragma: keep
|
#include "slic3r/GUI/Search.hpp" // IWYU pragma: keep
|
||||||
|
#include "slic3r/GUI/Field.hpp"
|
||||||
#include "libslic3r/Exception.hpp"
|
#include "libslic3r/Exception.hpp"
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
#include "libslic3r/AppConfig.hpp"
|
#include "libslic3r/AppConfig.hpp"
|
||||||
@ -175,8 +176,10 @@ void OptionsGroup::change_opt_value(DynamicPrintConfig& config, const t_config_o
|
|||||||
str.pop_back();
|
str.pop_back();
|
||||||
percent = true;
|
percent = true;
|
||||||
}
|
}
|
||||||
double val = std::stod(str); // locale-dependent (on purpose - the input is the actual content of the field)
|
|
||||||
ConfigOptionFloatsOrPercents* vec_new = new ConfigOptionFloatsOrPercents({ {val, percent} });
|
const bool is_na_value = opt_def->nullable && str == _(L("N/A"));
|
||||||
|
const FloatOrPercent val = is_na_value ? ConfigOptionFloatsOrPercentsNullable::nil_value() : FloatOrPercent{std::stod(str), percent};
|
||||||
|
ConfigOptionFloatsOrPercents *vec_new = new ConfigOptionFloatsOrPercents({val});
|
||||||
config.option<ConfigOptionFloatsOrPercents>(opt_key)->set_at(vec_new, opt_index, opt_index);
|
config.option<ConfigOptionFloatsOrPercents>(opt_key)->set_at(vec_new, opt_index, opt_index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1020,6 +1023,21 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
|||||||
ret = double_to_string(val); }
|
ret = double_to_string(val); }
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case coFloatsOrPercents: {
|
||||||
|
if (config.option(opt_key)->is_nil()) {
|
||||||
|
ret = _(L("N/A"));
|
||||||
|
} else {
|
||||||
|
const auto &config_option = config.option<ConfigOptionFloatsOrPercentsNullable>(opt_key)->get_at(idx);
|
||||||
|
|
||||||
|
text_value = double_to_string(config_option.value);
|
||||||
|
if (config_option.percent) {
|
||||||
|
text_value += "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = text_value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case coBools:
|
case coBools:
|
||||||
ret = config.option<ConfigOptionBoolsNullable>(opt_key)->values[idx];
|
ret = config.option<ConfigOptionBoolsNullable>(opt_key)->values[idx];
|
||||||
break;
|
break;
|
||||||
|
@ -1458,6 +1458,7 @@ void TabPrint::build()
|
|||||||
|
|
||||||
optgroup = page->new_optgroup(L("Advanced"));
|
optgroup = page->new_optgroup(L("Advanced"));
|
||||||
optgroup->append_single_option_line("seam_position", category_path + "seam-position");
|
optgroup->append_single_option_line("seam_position", category_path + "seam-position");
|
||||||
|
optgroup->append_single_option_line("seam_gap_distance", category_path + "seam-gap-distance");
|
||||||
optgroup->append_single_option_line("staggered_inner_seams", category_path + "staggered-inner-seams");
|
optgroup->append_single_option_line("staggered_inner_seams", category_path + "staggered-inner-seams");
|
||||||
|
|
||||||
optgroup->append_single_option_line("scarf_seam_placement", category_path + "scarf-seam-placement");
|
optgroup->append_single_option_line("scarf_seam_placement", category_path + "scarf-seam-placement");
|
||||||
@ -1968,6 +1969,9 @@ std::vector<std::pair<std::string, std::vector<std::string>>> filament_overrides
|
|||||||
{"Retraction when tool is disabled", {
|
{"Retraction when tool is disabled", {
|
||||||
"filament_retract_length_toolchange",
|
"filament_retract_length_toolchange",
|
||||||
"filament_retract_restart_extra_toolchange"
|
"filament_retract_restart_extra_toolchange"
|
||||||
|
}},
|
||||||
|
{"Seams", {
|
||||||
|
"filament_seam_gap_distance"
|
||||||
}}
|
}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user