mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-14 07:45:58 +08:00
Add some spacing settings at the side of width
- now a setting can be "phony" - a phony setting isn't saved in a config file - a phony setting should be computed from other settings - change/add colors, icons, and callbacks (in PrintConfig.cpp) to make phony settings works
This commit is contained in:
parent
1d405304b9
commit
715d58da88
@ -258,15 +258,40 @@ group:Autospeed (advanced)
|
||||
|
||||
page:Width & Flow:width
|
||||
group:Extrusion width
|
||||
setting:extrusion_width
|
||||
setting:first_layer_extrusion_width
|
||||
setting:perimeter_extrusion_width
|
||||
setting:external_perimeter_extrusion_width
|
||||
setting:infill_extrusion_width
|
||||
setting:solid_infill_extrusion_width
|
||||
setting:top_infill_extrusion_width
|
||||
setting:support_material_extrusion_width
|
||||
setting:skirt_extrusion_width
|
||||
line:default
|
||||
setting:sidetext_width$10:label$width:extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$spacing:extrusion_spacing
|
||||
end_line
|
||||
line:first layer
|
||||
setting:sidetext_width$10:label$width:first_layer_extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$spacing:first_layer_extrusion_spacing
|
||||
end_line
|
||||
line:perimeter
|
||||
setting:sidetext_width$10:label$width:perimeter_extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$spacing:perimeter_extrusion_spacing
|
||||
end_line
|
||||
line:external perimeter
|
||||
setting:sidetext_width$10:label$width:external_perimeter_extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$width&spacing combo:external_perimeter_extrusion_spacing
|
||||
end_line
|
||||
line:infill
|
||||
setting:sidetext_width$10:label$width:infill_extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$spacing:infill_extrusion_spacing
|
||||
end_line
|
||||
line:solid infill
|
||||
setting:sidetext_width$10:label$width:solid_infill_extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$spacing:solid_infill_extrusion_spacing
|
||||
end_line
|
||||
line:top infill
|
||||
setting:sidetext_width$10:label$width:top_infill_extrusion_width
|
||||
setting:sidetext_width$10:label_width$15:label$spacing:top_infill_extrusion_spacing
|
||||
end_line
|
||||
line:support material
|
||||
setting:sidetext_width$10:label$width:support_material_extrusion_width
|
||||
end_line
|
||||
line:skirt
|
||||
setting:sidetext_width$10:label$width:skirt_extrusion_width
|
||||
end_line
|
||||
recommended_extrusion_width_description
|
||||
group:Overlap
|
||||
line:Perimeter overlap
|
||||
|
@ -473,7 +473,9 @@ t_config_option_keys ConfigBase::diff(const ConfigBase &other) const
|
||||
for (const t_config_option_key &opt_key : this->keys()) {
|
||||
const ConfigOption *this_opt = this->option(opt_key);
|
||||
const ConfigOption *other_opt = other.option(opt_key);
|
||||
if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt)
|
||||
//dirty if both exist, they aren't both phony and value is different
|
||||
if (this_opt != nullptr && other_opt != nullptr && !(this_opt->phony && other_opt->phony)
|
||||
&& ((*this_opt != *other_opt) || (this_opt->phony != other_opt->phony)))
|
||||
diff.emplace_back(opt_key);
|
||||
}
|
||||
return diff;
|
||||
@ -495,6 +497,8 @@ std::string ConfigBase::opt_serialize(const t_config_option_key &opt_key) const
|
||||
{
|
||||
const ConfigOption* opt = this->option(opt_key);
|
||||
assert(opt != nullptr);
|
||||
if (opt->phony)
|
||||
return "";
|
||||
return opt->serialize();
|
||||
}
|
||||
|
||||
@ -584,7 +588,19 @@ bool ConfigBase::set_deserialize_raw(const t_config_option_key &opt_key_src, con
|
||||
ConfigOption *opt = this->option(opt_key, true);
|
||||
if (opt == nullptr)
|
||||
throw new UnknownOptionException(opt_key);
|
||||
bool ok= opt->deserialize(value, append);
|
||||
|
||||
bool ok = true;
|
||||
if (!optdef->can_phony || value != "")
|
||||
ok = opt->deserialize(value, append);
|
||||
//set phony status
|
||||
if (optdef->can_phony)
|
||||
if(value == "")
|
||||
opt->phony = true;
|
||||
else
|
||||
opt->phony = false;
|
||||
else
|
||||
opt->phony = false;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -214,6 +214,12 @@ inline OutputFormat operator&=(OutputFormat& a, OutputFormat b) {
|
||||
// A generic value of a configuration option.
|
||||
class ConfigOption {
|
||||
public:
|
||||
// if true, this option doesn't need to be saved, it's a computed value from an other configOption.
|
||||
bool phony;
|
||||
|
||||
ConfigOption() : phony(false) {}
|
||||
ConfigOption(bool phony) : phony(phony) {}
|
||||
|
||||
virtual ~ConfigOption() {}
|
||||
|
||||
virtual ConfigOptionType type() const = 0;
|
||||
@ -258,6 +264,7 @@ class ConfigOptionSingle : public ConfigOption {
|
||||
public:
|
||||
T value;
|
||||
explicit ConfigOptionSingle(T value) : value(value) {}
|
||||
explicit ConfigOptionSingle(T value, bool phony) : ConfigOption(phony), value(value) {}
|
||||
operator T() const { return this->value; }
|
||||
|
||||
void set(const ConfigOption *rhs) override
|
||||
@ -266,6 +273,7 @@ public:
|
||||
throw Slic3r::RuntimeError("ConfigOptionSingle: Assigning an incompatible type");
|
||||
assert(dynamic_cast<const ConfigOptionSingle<T>*>(rhs));
|
||||
this->value = static_cast<const ConfigOptionSingle<T>*>(rhs)->value;
|
||||
this->phony = rhs->phony;
|
||||
}
|
||||
|
||||
bool operator==(const ConfigOption &rhs) const override
|
||||
@ -340,6 +348,7 @@ public:
|
||||
throw Slic3r::RuntimeError("ConfigOptionVector: Assigning an incompatible type");
|
||||
assert(dynamic_cast<const ConfigOptionVector<T>*>(rhs));
|
||||
this->values = static_cast<const ConfigOptionVector<T>*>(rhs)->values;
|
||||
this->phony = rhs->phony;
|
||||
}
|
||||
|
||||
// Set from a vector of ConfigOptions.
|
||||
@ -504,6 +513,7 @@ class ConfigOptionFloat : public ConfigOptionSingle<double>
|
||||
public:
|
||||
ConfigOptionFloat() : ConfigOptionSingle<double>(0) {}
|
||||
explicit ConfigOptionFloat(double _value) : ConfigOptionSingle<double>(_value) {}
|
||||
explicit ConfigOptionFloat(double _value, bool _phony) : ConfigOptionSingle<double>(_value, _phony) {}
|
||||
|
||||
static ConfigOptionType static_type() { return coFloat; }
|
||||
ConfigOptionType type() const override { return static_type(); }
|
||||
@ -850,6 +860,7 @@ class ConfigOptionPercent : public ConfigOptionFloat
|
||||
public:
|
||||
ConfigOptionPercent() : ConfigOptionFloat(0) {}
|
||||
explicit ConfigOptionPercent(double _value) : ConfigOptionFloat(_value) {}
|
||||
explicit ConfigOptionPercent(double _value, bool _phony) : ConfigOptionFloat(_value, _phony) {}
|
||||
|
||||
static ConfigOptionType static_type() { return coPercent; }
|
||||
ConfigOptionType type() const override { return static_type(); }
|
||||
@ -943,6 +954,7 @@ public:
|
||||
bool percent;
|
||||
ConfigOptionFloatOrPercent() : ConfigOptionPercent(0), percent(false) {}
|
||||
explicit ConfigOptionFloatOrPercent(double _value, bool _percent) : ConfigOptionPercent(_value), percent(_percent) {}
|
||||
explicit ConfigOptionFloatOrPercent(double _value, bool _percent, bool _phony) : ConfigOptionPercent(_value, _phony), percent(_percent) {}
|
||||
|
||||
static ConfigOptionType static_type() { return coFloatOrPercent; }
|
||||
ConfigOptionType type() const override { return static_type(); }
|
||||
@ -1427,6 +1439,7 @@ public:
|
||||
throw Slic3r::RuntimeError("ConfigOptionEnum<T>: Assigning an incompatible type");
|
||||
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
|
||||
this->value = (T)rhs->getInt();
|
||||
this->phony = rhs->phony;
|
||||
}
|
||||
|
||||
std::string serialize() const override
|
||||
@ -1511,6 +1524,7 @@ public:
|
||||
throw Slic3r::RuntimeError("ConfigOptionEnumGeneric: Assigning an incompatible type");
|
||||
// rhs could be of the following type: ConfigOptionEnumGeneric or ConfigOptionEnum<T>
|
||||
this->value = rhs->getInt();
|
||||
this->phony = rhs->phony;
|
||||
}
|
||||
|
||||
std::string serialize() const override
|
||||
@ -1658,7 +1672,9 @@ public:
|
||||
// For text input: If true, the GUI formats text as code (fixed-width)
|
||||
bool is_code = false;
|
||||
// Not editable. Currently only used for the display of the number of threads.
|
||||
bool readonly = false;
|
||||
bool readonly = false;
|
||||
// Can be phony. if not present at laoding, mark it as phony. Also adapt the gui to look for phony status.
|
||||
bool can_phony = false;
|
||||
// Height of a multiline GUI text box.
|
||||
int height = -1;
|
||||
// Optional width of an input field.
|
||||
|
@ -299,8 +299,8 @@ std::pair<double, double> adaptive_fill_line_spacing(const PrintObject &print_ob
|
||||
for (const PrintRegion *region : print_object.print()->regions()) {
|
||||
const PrintRegionConfig &config = region->config();
|
||||
bool nonempty = config.fill_density > 0;
|
||||
bool has_adaptive_infill = nonempty && config.fill_pattern == ipAdaptiveCubic;
|
||||
bool has_support_infill = nonempty && config.fill_pattern == ipSupportCubic;
|
||||
bool has_adaptive_infill = nonempty && config.fill_pattern.value == ipAdaptiveCubic;
|
||||
bool has_support_infill = nonempty && config.fill_pattern.value == ipSupportCubic;
|
||||
double infill_extrusion_width = config.infill_extrusion_width.get_abs_value(max_nozzle_diameter);
|
||||
region_fill_data.push_back(RegionFillData({
|
||||
has_adaptive_infill ? Tristate::Maybe : Tristate::No,
|
||||
|
@ -743,7 +743,7 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessor::Result* re
|
||||
namespace DoExport {
|
||||
static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled)
|
||||
{
|
||||
silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlin) && config.silent_mode;
|
||||
silent_time_estimator_enabled = (config.gcode_flavor.value == gcfMarlin) && config.silent_mode;
|
||||
processor.reset();
|
||||
processor.apply_config(config);
|
||||
processor.enable_stealth_time_estimator(silent_time_estimator_enabled);
|
||||
@ -1490,7 +1490,7 @@ void GCode::_do_export(Print& print, FILE* file, ThumbnailsGeneratorCallback thu
|
||||
bbox_prime.offset(0.5f);
|
||||
bool overlap = bbox_prime.overlap(bbox_print);
|
||||
|
||||
if (print.config().gcode_flavor == gcfMarlin) {
|
||||
if (print.config().gcode_flavor.value == gcfMarlin) {
|
||||
_write(file, this->retract());
|
||||
_write(file, "M300 S800 P500\n"); // Beep for 500ms, tone 800Hz.
|
||||
if (overlap) {
|
||||
@ -1727,14 +1727,14 @@ void GCode::print_machine_envelope(FILE *file, Print &print)
|
||||
int(print.config().machine_max_acceleration_travel.values.front() + 0.5),
|
||||
int(print.config().machine_max_acceleration_travel.values.front() + 0.5));
|
||||
if (std::set<uint8_t>{gcfMarlin, gcfLerdge, gcfRepetier, gcfSmoothie, gcfSprinter}.count(print.config().gcode_flavor.value) > 0)
|
||||
fprintf(file, (print.config().gcode_flavor == gcfMarlin || print.config().gcode_flavor == gcfSmoothie)
|
||||
fprintf(file, (print.config().gcode_flavor.value == gcfMarlin || print.config().gcode_flavor.value == gcfSmoothie)
|
||||
? "M203 X%d Y%d Z%d E%d ; sets maximum feedrates, mm/sec\n"
|
||||
: "M203 X%d Y%d Z%d E%d ; sets maximum feedrates, mm/min\n",
|
||||
int(print.config().machine_max_feedrate_x.values.front() + 0.5),
|
||||
int(print.config().machine_max_feedrate_y.values.front() + 0.5),
|
||||
int(print.config().machine_max_feedrate_z.values.front() + 0.5),
|
||||
int(print.config().machine_max_feedrate_e.values.front() + 0.5));
|
||||
if (print.config().gcode_flavor == gcfRepRap) {
|
||||
if (print.config().gcode_flavor.value == gcfRepRap) {
|
||||
fprintf(file, "M203 X%d Y%d Z%d E%d I%d; sets maximum feedrates, mm/min\n",
|
||||
int(print.config().machine_max_feedrate_x.values.front() + 0.5),
|
||||
int(print.config().machine_max_feedrate_y.values.front() + 0.5),
|
||||
@ -1806,7 +1806,7 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c
|
||||
{
|
||||
// Is the bed temperature set by the provided custom G-code?
|
||||
int temp_by_gcode = -1;
|
||||
bool include_g10 = print.config().gcode_flavor == gcfRepRap;
|
||||
bool include_g10 = print.config().gcode_flavor.value == gcfRepRap;
|
||||
if (custom_gcode_sets_temperature(gcode, 104, 109, include_g10, temp_by_gcode)) {
|
||||
// Set the extruder temperature at m_writer, but throw away the generated G-code as it will be written with the custom G-code.
|
||||
int temp = print.config().first_layer_temperature.get_at(first_printing_extruder_id);
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include <map>
|
||||
#include <assert.h>
|
||||
|
||||
#define FLAVOR_IS(val) this->config.gcode_flavor == val
|
||||
#define FLAVOR_IS_NOT(val) this->config.gcode_flavor != val
|
||||
#define COMMENT(comment) if (this->config.gcode_comments && !comment.empty()) gcode << " ; " << comment;
|
||||
#define FLAVOR_IS(val) this->config.gcode_flavor.value == val
|
||||
#define FLAVOR_IS_NOT(val) this->config.gcode_flavor.value != val
|
||||
#define COMMENT(comment) if (this->config.gcode_comments.value && !comment.empty()) gcode << " ; " << comment;
|
||||
#define PRECISION(val, precision) std::fixed << std::setprecision(precision) << (val)
|
||||
#define XYZF_NUM(val) PRECISION(val, this->config.gcode_precision_xyz.value)
|
||||
#define E_NUM(val) PRECISION(val, this->config.gcode_precision_e.get_at(m_tool->id()))
|
||||
|
@ -156,7 +156,7 @@ void PerimeterGenerator::process()
|
||||
ExPolygons bridgeable = union_ex(detector.coverage(-1, true));
|
||||
if (!bridgeable.empty()) {
|
||||
//check if we get everything or just the bridgeable area
|
||||
if (this->config->no_perimeter_unsupported_algo == npuaNoPeri || this->config->no_perimeter_unsupported_algo == npuaFilled) {
|
||||
if (this->config->no_perimeter_unsupported_algo.value == npuaNoPeri || this->config->no_perimeter_unsupported_algo.value == npuaFilled) {
|
||||
//we bridge everything, even the not-bridgeable bits
|
||||
for (size_t i = 0; i < unsupported_filtered.size();) {
|
||||
ExPolygon &poly_unsupp = *(unsupported_filtered.begin() + i);
|
||||
@ -177,7 +177,7 @@ void PerimeterGenerator::process()
|
||||
}
|
||||
unsupported_filtered = intersection_ex(last,
|
||||
offset2_ex(unsupported_filtered, double(-perimeter_spacing / 2), double(perimeter_spacing * 3 / 2)));
|
||||
if (this->config->no_perimeter_unsupported_algo == npuaFilled) {
|
||||
if (this->config->no_perimeter_unsupported_algo.value == npuaFilled) {
|
||||
for (ExPolygon &expol : unsupported_filtered) {
|
||||
//check if the holes won't be covered by the upper layer
|
||||
//TODO: if we want to do that, we must modify the geometry before making perimeters.
|
||||
@ -227,7 +227,7 @@ void PerimeterGenerator::process()
|
||||
|
||||
}
|
||||
//TODO: add other polys as holes inside this one (-margin)
|
||||
} else if (this->config->no_perimeter_unsupported_algo == npuaBridgesOverhangs || this->config->no_perimeter_unsupported_algo == npuaBridges){
|
||||
} else if (this->config->no_perimeter_unsupported_algo.value == npuaBridgesOverhangs || this->config->no_perimeter_unsupported_algo.value == npuaBridges){
|
||||
//simplify to avoid most of artefacts from printing lines.
|
||||
ExPolygons bridgeable_simplified;
|
||||
for (ExPolygon &poly : bridgeable) {
|
||||
@ -246,7 +246,7 @@ void PerimeterGenerator::process()
|
||||
//unbridgeable = offset2_ex(unbridgeable, -ext_perimeter_width, ext_perimeter_width);
|
||||
|
||||
|
||||
if (this->config->no_perimeter_unsupported_algo == npuaBridges) {
|
||||
if (this->config->no_perimeter_unsupported_algo.value == npuaBridges) {
|
||||
ExPolygons unbridgeable = unsupported_filtered;
|
||||
for (ExPolygon &expol : unbridgeable)
|
||||
expol.holes.clear();
|
||||
|
@ -535,9 +535,23 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"extruder_clearance_radius",
|
||||
"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",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio",
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells",
|
||||
"extrusion_spacing",
|
||||
"extrusion_width",
|
||||
"first_layer_extrusion_spacing",
|
||||
"first_layer_extrusion_width",
|
||||
"perimeter_extrusion_spacing",
|
||||
"perimeter_extrusion_width",
|
||||
"external_perimeter_extrusion_spacing",
|
||||
"external_perimeter_extrusion_width",
|
||||
"infill_extrusion_spacing",
|
||||
"infill_extrusion_width",
|
||||
"solid_infill_extrusion_spacing",
|
||||
"solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_spacing",
|
||||
"top_infill_extrusion_width",
|
||||
"support_material_extrusion_width",
|
||||
"infill_overlap", "bridge_flow_ratio",
|
||||
"infill_anchor",
|
||||
"infill_anchor_max",
|
||||
"clip_multipart_objects",
|
||||
@ -1373,7 +1387,9 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
|
||||
for (const t_config_option_key &opt_key : config_this.keys()) {
|
||||
const ConfigOption *this_opt = config_this.option(opt_key);
|
||||
const ConfigOption *other_opt = config_other.option(opt_key);
|
||||
if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt)
|
||||
//dirty if both exist, they aren't both phony and value is different
|
||||
if (this_opt != nullptr && other_opt != nullptr && !(this_opt->phony && other_opt->phony)
|
||||
&& ((*this_opt != *other_opt) || (this_opt->phony != other_opt->phony)))
|
||||
{
|
||||
if (opt_key == "bed_shape" || opt_key == "thumbnails" || opt_key == "compatible_prints" || opt_key == "compatible_printers") {
|
||||
// Scalar variable, or a vector variable, which is independent from number of extruders,
|
||||
|
@ -1535,7 +1535,7 @@ std::pair<PrintBase::PrintValidationError, std::string> Print::validate() const
|
||||
"all nozzles have to be of the same diameter.") };
|
||||
}
|
||||
if (this->has_wipe_tower()) {
|
||||
if (object->config().support_material_contact_distance_type == zdNone) {
|
||||
if (object->config().support_material_contact_distance_type.value == zdNone) {
|
||||
// Soluble interface
|
||||
if (! object->config().support_material_synchronize_layers)
|
||||
return { PrintBase::PrintValidationError::pveWrongSettings,L("For the Wipe Tower to work with the soluble supports, the support layers need to be synchronized with the object layers.") };
|
||||
|
@ -830,9 +830,23 @@ void PrintConfigDef::init_fff_params()
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
def = this->add("external_perimeter_extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("External perimeters");
|
||||
def->full_label = L("External perimeters spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like the External perimeters width, but this value is the distance between the edge and the 'frontier' to the next perimeter."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("external_perimeter_cut_corners", coPercent);
|
||||
def->label = L("Cutting corners");
|
||||
def->full_label = L("Ext. peri. cut corners");
|
||||
@ -1140,16 +1154,30 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Default extrusion width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to allow a manual extrusion width. "
|
||||
"If left to zero, Slic3r derives extrusion widths from the nozzle diameter "
|
||||
"(see the tooltips for perimeter extrusion width, infill extrusion width etc). "
|
||||
"If expressed as percentage (for example: 105%), it will be computed over nozzle diameter.");
|
||||
"If left to zero, Slic3r derives extrusion widths from the nozzle diameter "
|
||||
"(see the tooltips for perimeter extrusion width, infill extrusion width etc). "
|
||||
"If expressed as percentage (for example: 105%), it will be computed over nozzle diameter.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
def = this->add("extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("Default extrusion spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like Default extrusion width but spacing is the distance between two lines (as they overlap a bit, it's not the same)."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("fan_always_on", coBools);
|
||||
def->label = L("Keep fan always on");
|
||||
def->category = OptionCategory::cooling;
|
||||
@ -1709,16 +1737,32 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_label = L("First layer width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for first layer. "
|
||||
"You can use this to force fatter extrudates for better adhesion. If expressed "
|
||||
"as percentage (for example 140%) it will be computed over the nozzle diameter "
|
||||
"of the nozzle used for the type of extrusion. "
|
||||
"If set to zero, it will use the default extrusion width.");
|
||||
"You can use this to force fatter extrudates for better adhesion. If expressed "
|
||||
"as percentage (for example 140%) it will be computed over the nozzle diameter "
|
||||
"of the nozzle used for the type of extrusion. "
|
||||
"If set to zero, it will use the default extrusion width.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(140, true));
|
||||
|
||||
def = this->add("first_layer_extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("First layer");
|
||||
def->full_label = L("First layer spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like First layer width but spacing is the distance between two lines (as they overlap a bit, it's not the same)."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("first_layer_height", coFloatOrPercent);
|
||||
def->label = L("First layer height");
|
||||
def->category = OptionCategory::perimeter;
|
||||
@ -2086,17 +2130,34 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("infill_extrusion_width", coFloatOrPercent);
|
||||
def->label = L("Infill");
|
||||
def->full_label = L("Infill width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for infill. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"You may want to use fatter extrudates to speed up the infill and make your parts stronger. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"You may want to use fatter extrudates to speed up the infill and make your parts stronger. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
def = this->add("infill_extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("Infill");
|
||||
def->full_label = L("Infill spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like First layer width but spacing is the distance between two lines (as they overlap a bit, it's not the same)."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("infill_first", coBool);
|
||||
def->label = L("Infill before perimeters");
|
||||
def->category = OptionCategory::infill;
|
||||
@ -2799,15 +2860,31 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_label = ("Perimeter width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for perimeters. "
|
||||
"You may want to use thinner extrudates to get more accurate surfaces. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 105%) it will be computed over nozzle diameter.");
|
||||
"You may want to use thinner extrudates to get more accurate surfaces. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 105%) it will be computed over nozzle diameter.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->aliases = { "perimeters_extrusion_width" };
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
def = this->add("perimeter_extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("Perimeters");
|
||||
def->full_label = ("Perimeter spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like Perimeter width but spacing is the distance between two perimeter lines (as they overlap a bit, it's not the same)."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->aliases = { "perimeters_extrusion_width" };
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("perimeter_speed", coFloat);
|
||||
def->label = L("Default");
|
||||
def->full_label = ("Default speed");
|
||||
@ -3141,10 +3218,12 @@ void PrintConfigDef::init_fff_params()
|
||||
|
||||
def = this->add("skirt_extrusion_width", coFloatOrPercent);
|
||||
def->label = L("Skirt");
|
||||
def->full_label = L("Skirt width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Horizontal width of the skirt that will be printed around each object.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
@ -3306,14 +3385,30 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_label = ("Solid infill width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for infill for solid surfaces. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
"If left zero, default extrusion width will be used if set, otherwise 1.125 x nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
def = this->add("solid_infill_extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("Solid spacing");
|
||||
def->full_label = ("Solid infill spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like Solid infill width but spacing is the distance between two lines (as they overlap a bit, it's not the same)."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("solid_infill_speed", coFloatOrPercent);
|
||||
def->label = L("Solid");
|
||||
def->full_label = ("Solid infill speed");
|
||||
@ -3577,11 +3672,12 @@ void PrintConfigDef::init_fff_params()
|
||||
def->full_label = L("Support material width");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for support material. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
"If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
@ -3857,15 +3953,30 @@ void PrintConfigDef::init_fff_params()
|
||||
def->label = L("Top solid infill");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Set this to a non-zero value to set a manual extrusion width for infill for top surfaces. "
|
||||
"You may want to use thinner extrudates to fill all narrow regions and get a smoother finish. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
"You may want to use thinner extrudates to fill all narrow regions and get a smoother finish. "
|
||||
"If left zero, default extrusion width will be used if set, otherwise nozzle diameter will be used. "
|
||||
"If expressed as percentage (for example 110%) it will be computed over nozzle diameter.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false));
|
||||
|
||||
def = this->add("top_infill_extrusion_spacing", coFloatOrPercent);
|
||||
def->label = L("Top solid spacing");
|
||||
def->category = OptionCategory::width;
|
||||
def->tooltip = L("Like Top solid infill width but spacing is the distance between two lines (as they overlap a bit, it's not the same)."
|
||||
"\nSetting the spacing will deactivate the width setting, and vice versa.");
|
||||
def->sidetext = L("mm or %");
|
||||
def->ratio_over = "nozzle_diameter";
|
||||
def->min = 0;
|
||||
def->max = 1000;
|
||||
def->can_phony = true;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(0, false, true));
|
||||
|
||||
def = this->add("top_solid_infill_speed", coFloatOrPercent);
|
||||
def->label = L("Top solid");
|
||||
def->full_label = L("Top solid speed");
|
||||
@ -5141,6 +5252,12 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va
|
||||
// In PrusaSlicer 2.3.0-alpha0 the "monotonic" infill was introduced, which was later renamed to "monotonous".
|
||||
if (value == "monotonous" && (opt_key == "top_fill_pattern" || opt_key == "bottom_fill_pattern" || opt_key == "fill_pattern" || opt_key == "solid_fill_pattern" || opt_key == "support_material_interface_pattern"))
|
||||
value = "monotonic";
|
||||
// some changes has occurs between rectilineargapfill and monotonicgapfill. Set them at the right value for each type
|
||||
if (value == "rectilineargapfill" && (opt_key == "top_fill_pattern" || opt_key == "bottom_fill_pattern" || opt_key == "fill_pattern" || opt_key == "support_material_interface_pattern"))
|
||||
value = "monotonicgapfill";
|
||||
if (value == "monotonicgapfill" && (opt_key == "solid_fill_pattern"))
|
||||
value = "rectilineargapfill";
|
||||
|
||||
|
||||
if (ignore.find(opt_key) != ignore.end()) {
|
||||
opt_key = "";
|
||||
@ -5292,7 +5409,14 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
|
||||
"milling_post_process",
|
||||
"milling_extra_size",
|
||||
"milling_after_z",
|
||||
"milling_speed"
|
||||
"milling_speed",
|
||||
"extrusion_spacing",
|
||||
"first_layer_extrusion_spacing",
|
||||
"perimeter_extrusion_spacing",
|
||||
"external_perimeter_extrusion_spacing",
|
||||
"infill_extrusion_spacing",
|
||||
"solid_infill_extrusion_spacing",
|
||||
"top_infill_extrusion_spacing"
|
||||
|
||||
};
|
||||
//looks if it's to be removed, or have to be transformed
|
||||
@ -5360,6 +5484,15 @@ void PrintConfigDef::to_prusa(t_config_option_key& opt_key, std::string& value,
|
||||
value = "marlin";
|
||||
else if ("klipper" == value)
|
||||
value = "reprap";
|
||||
} else if (opt_key.find("extrusion_width") != std::string::npos) {
|
||||
if (std::set<std::string>{"extrusion_width", "first_layer_extrusion_width", "perimeter_extrusion_width", "external_perimeter_extrusion_width",
|
||||
"infill_extrusion_width", "solid_infill_extrusion_width", "top_infill_extrusion_width"}.count(opt_key) > 0) {
|
||||
const ConfigOptionFloatOrPercent* opt = all_conf.option<ConfigOptionFloatOrPercent>(opt_key);
|
||||
if (opt->phony) {
|
||||
//bypass the phony kill switch from Config::opt_serialize
|
||||
value = opt->serialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -5592,6 +5725,7 @@ std::string DynamicPrintConfig::validate()
|
||||
{
|
||||
FullPrintConfig fpc;
|
||||
fpc.apply(*this, true);
|
||||
|
||||
// Verify this print options through the FullPrintConfig.
|
||||
return fpc.validate();
|
||||
}
|
||||
@ -5601,6 +5735,261 @@ std::string DynamicPrintConfig::validate()
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
const TYPE* find_option(const t_config_option_key &opt_key, DynamicPrintConfig* default_config, const std::vector<const DynamicPrintConfig*> &other_config) {
|
||||
const TYPE* option = default_config->option<TYPE>(opt_key);
|
||||
if (option)
|
||||
return option;
|
||||
for (const DynamicPrintConfig* conf : other_config) {
|
||||
option = conf->option<TYPE>(opt_key);
|
||||
if (option)
|
||||
return option;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool DynamicPrintConfig::update_phony(const std::vector<const DynamicPrintConfig*> config_collection) {
|
||||
bool something_changed = false;
|
||||
//update width/spacing links
|
||||
const char* widths[] = { "", "external_perimeter_", "perimeter_", "infill_", "solid_infill_", "top_infill_", "support_material_", "first_layer_", "skirt_" };
|
||||
for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++i) {
|
||||
std::string key_width(widths[i]);
|
||||
key_width += "extrusion_width";
|
||||
std::string key_spacing(widths[i]);
|
||||
key_spacing += "extrusion_spacing";
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>(key_width);
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>(key_spacing);
|
||||
if (width_option && spacing_option)
|
||||
if (!spacing_option->phony && width_option->phony)
|
||||
something_changed |= value_changed(key_spacing, config_collection);
|
||||
else
|
||||
something_changed |= value_changed(key_width, config_collection);
|
||||
}
|
||||
|
||||
return something_changed;
|
||||
}
|
||||
|
||||
bool DynamicPrintConfig::value_changed(const t_config_option_key& opt_key, const std::vector<const DynamicPrintConfig*> config_collection) {
|
||||
|
||||
if (opt_key == "layer_height") {
|
||||
update_phony(config_collection);
|
||||
}
|
||||
|
||||
bool something_changed = false;
|
||||
// width -> spacing
|
||||
if (opt_key.find("extrusion_spacing") != std::string::npos) {
|
||||
const ConfigOptionFloats* nozzle_diameter_option = find_option<ConfigOptionFloats>("nozzle_diameter", this, config_collection);
|
||||
const ConfigOptionFloat* layer_height_option = find_option<ConfigOptionFloat>("layer_height", this, config_collection);
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>(opt_key);
|
||||
if (layer_height_option && spacing_option && nozzle_diameter_option) {
|
||||
//compute spacing with current height and change the width
|
||||
double max_nozzle_diameter = 0;
|
||||
for (double dmr : nozzle_diameter_option->values)
|
||||
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
|
||||
Flow flow = Flow::new_from_spacing(spacing_option->get_abs_value(max_nozzle_diameter), max_nozzle_diameter, layer_height_option->value, false);
|
||||
if (opt_key == "extrusion_spacing") {
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("extrusion_width");
|
||||
if (width_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "first_layer_extrusion_spacing") {
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("first_layer_extrusion_width");
|
||||
if (width_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "perimeter_extrusion_spacing") {
|
||||
const ConfigOptionPercent* perimeter_overlap_option = find_option<ConfigOptionPercent>("perimeter_overlap", this, config_collection);
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("perimeter_extrusion_width");
|
||||
if (width_option && perimeter_overlap_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
flow.spacing_ratio = perimeter_overlap_option->get_abs_value(1);
|
||||
flow.width = spacing_option->get_abs_value(max_nozzle_diameter) + layer_height_option->value * (1. - 0.25 * PI) * flow.spacing_ratio;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "external_perimeter_extrusion_spacing") {
|
||||
const ConfigOptionPercent* external_perimeter_overlap_option = find_option<ConfigOptionPercent>("external_perimeter_overlap", this, config_collection);
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width");
|
||||
if (width_option && external_perimeter_overlap_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
flow.spacing_ratio = external_perimeter_overlap_option->get_abs_value(0.5);
|
||||
flow.width = spacing_option->get_abs_value(max_nozzle_diameter) + layer_height_option->value * (1. - 0.25 * PI) * flow.spacing_ratio;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "infill_extrusion_spacing") {
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("infill_extrusion_width");
|
||||
if (width_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "solid_infill_extrusion_spacing") {
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width");
|
||||
if (width_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "top_infill_extrusion_spacing") {
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>("top_infill_extrusion_width");
|
||||
if (width_option) {
|
||||
width_option->phony = true;
|
||||
spacing_option->phony = false;
|
||||
width_option->value = (spacing_option->percent) ? std::round(100 * flow.width / max_nozzle_diameter) : (std::round(flow.width * 10000) / 10000);
|
||||
width_option->percent = spacing_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
/*if (opt_key == "support_material_extrusion_spacing") {
|
||||
if (spacing_option->percent)
|
||||
this->set_key_value("support_material_extrusion_width", new ConfigOptionFloatOrPercent(std::round(100 * flow.width / max_nozzle_diameter), true));
|
||||
else
|
||||
this->set_key_value("support_material_extrusion_width", new ConfigOptionFloatOrPercent(std::round(flow.width * 10000) / 10000, false));
|
||||
something_changed = true;
|
||||
}
|
||||
if (opt_key == "skirt_extrusion_spacing") {
|
||||
if (spacing_option->percent)
|
||||
this->set_key_value("skirt_extrusion_width", new ConfigOptionFloatOrPercent(std::round(100 * flow.width / max_nozzle_diameter), true));
|
||||
else
|
||||
this->set_key_value("skirt_extrusion_width", new ConfigOptionFloatOrPercent(std::round(flow.width * 10000) / 10000, false));
|
||||
something_changed = true;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
if (opt_key.find("extrusion_width") != std::string::npos) {
|
||||
const ConfigOptionFloats* nozzle_diameter_option = find_option<ConfigOptionFloats>("nozzle_diameter", this, config_collection);
|
||||
const ConfigOptionFloat* layer_height_option = find_option<ConfigOptionFloat>("layer_height", this, config_collection);
|
||||
ConfigOptionFloatOrPercent* width_option = this->option<ConfigOptionFloatOrPercent>(opt_key);
|
||||
if (layer_height_option && width_option && nozzle_diameter_option) {
|
||||
//compute spacing with current height and change the width
|
||||
double max_nozzle_diameter = 0;
|
||||
for (double dmr : nozzle_diameter_option->values)
|
||||
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
|
||||
if (opt_key == "extrusion_width") {
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("extrusion_spacing");
|
||||
if (width_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "first_layer_extrusion_width") {
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("first_layer_extrusion_spacing");
|
||||
if (width_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "perimeter_extrusion_width") {
|
||||
const ConfigOptionPercent* perimeter_overlap_option = find_option<ConfigOptionPercent>("perimeter_overlap", this, config_collection);
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("perimeter_extrusion_spacing");
|
||||
if (width_option && perimeter_overlap_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow flow = Flow::new_from_config_width(FlowRole::frExternalPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
flow.spacing_ratio = perimeter_overlap_option->get_abs_value(1);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "external_perimeter_extrusion_width") {
|
||||
const ConfigOptionPercent* external_perimeter_overlap_option = find_option<ConfigOptionPercent>("external_perimeter_overlap", this, config_collection);
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_spacing");
|
||||
if (width_option && external_perimeter_overlap_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow ext_perimeter_flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
ext_perimeter_flow.spacing_ratio = external_perimeter_overlap_option->get_abs_value(0.5);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * ext_perimeter_flow.spacing() / max_nozzle_diameter) : (std::round(ext_perimeter_flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "infill_extrusion_width") {
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("infill_extrusion_spacing");
|
||||
if (width_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow flow = Flow::new_from_config_width(FlowRole::frInfill, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "solid_infill_extrusion_width") {
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_spacing");
|
||||
if (width_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow flow = Flow::new_from_config_width(FlowRole::frSolidInfill, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
if (opt_key == "top_infill_extrusion_width") {
|
||||
ConfigOptionFloatOrPercent* spacing_option = this->option<ConfigOptionFloatOrPercent>("top_infill_extrusion_spacing");
|
||||
if (width_option) {
|
||||
width_option->phony = false;
|
||||
spacing_option->phony = true;
|
||||
Flow flow = Flow::new_from_config_width(FlowRole::frTopSolidInfill, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000);
|
||||
spacing_option->percent = width_option->percent;
|
||||
something_changed = true;
|
||||
}
|
||||
}
|
||||
//if (opt_key == "support_material_extrusion_width") {
|
||||
// Flow flow = Flow::new_from_config_width(FlowRole::frSupportMaterial, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
// if (width_option->percent)
|
||||
// this->set_key_value("support_material_extrusion_spacing", new ConfigOptionFloatOrPercent(std::round(100 * flow.spacing() / max_nozzle_diameter), true));
|
||||
// else
|
||||
// this->set_key_value("support_material_extrusion_spacing", new ConfigOptionFloatOrPercent(std::round(flow.spacing() * 10000) / 10000, false));
|
||||
// something_changed = true;
|
||||
//}
|
||||
//if (opt_key == "skirt_extrusion_width") {
|
||||
// Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, *width_option, max_nozzle_diameter, layer_height_option->value, 0);
|
||||
// if (width_option->percent)
|
||||
// this->set_key_value("skirt_extrusion_spacing", new ConfigOptionFloatOrPercent(std::round(100 * flow.spacing() / max_nozzle_diameter), true));
|
||||
// else
|
||||
// this->set_key_value("skirt_extrusion_spacing", new ConfigOptionFloatOrPercent(std::round(flow.spacing() * 10000) / 10000, false));
|
||||
// something_changed = true;
|
||||
//}
|
||||
}
|
||||
}
|
||||
return something_changed;
|
||||
}
|
||||
|
||||
//FIXME localize this function.
|
||||
std::string FullPrintConfig::validate()
|
||||
{
|
||||
@ -5701,8 +6090,8 @@ std::string FullPrintConfig::validate()
|
||||
return "Invalid value for --extrusion-multiplier";
|
||||
|
||||
// --default-acceleration
|
||||
if ((this->perimeter_acceleration != 0. || this->infill_acceleration != 0. || this->bridge_acceleration != 0. || this->first_layer_acceleration != 0.) &&
|
||||
this->default_acceleration == 0.)
|
||||
if ((this->perimeter_acceleration.value != 0. || this->infill_acceleration.value != 0. || this->bridge_acceleration.value != 0. || this->first_layer_acceleration.value != 0.) &&
|
||||
this->default_acceleration.value == 0.)
|
||||
return "Invalid zero value for --default-acceleration when using other acceleration settings";
|
||||
|
||||
// --spiral-vase
|
||||
@ -5732,10 +6121,10 @@ std::string FullPrintConfig::validate()
|
||||
double max_nozzle_diameter = 0.;
|
||||
for (double dmr : this->nozzle_diameter.values)
|
||||
max_nozzle_diameter = std::max(max_nozzle_diameter, dmr);
|
||||
const char *widths[] = { "external_perimeter", "perimeter", "infill", "solid_infill", "top_infill", "support_material", "first_layer" };
|
||||
const char *widths[] = { "", "external_perimeter_", "perimeter_", "infill_", "solid_infill_", "top_infill_", "support_material_", "first_layer_", "skirt_" };
|
||||
for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++ i) {
|
||||
std::string key(widths[i]);
|
||||
key += "_extrusion_width";
|
||||
key += "extrusion_width";
|
||||
if (this->get_abs_value(key, max_nozzle_diameter) > 10. * max_nozzle_diameter)
|
||||
return std::string("Invalid extrusion width (too large): ") + key;
|
||||
}
|
||||
|
@ -456,6 +456,13 @@ public:
|
||||
|
||||
void to_prusa(t_config_option_key& opt_key, std::string& value) const override
|
||||
{ PrintConfigDef::to_prusa(opt_key, value, *this); }
|
||||
|
||||
/// <summary>
|
||||
/// callback to changed other settings that are linked (like width & spacing)
|
||||
/// </summary>
|
||||
/// <param name="opt_key">name of the changed option</param>
|
||||
bool value_changed(const t_config_option_key& opt_key, const std::vector<const DynamicPrintConfig*> config_collection);
|
||||
bool update_phony(const std::vector<const DynamicPrintConfig*> config_collection);
|
||||
};
|
||||
|
||||
class StaticPrintConfig : public StaticConfig
|
||||
|
@ -725,7 +725,7 @@ namespace Slic3r {
|
||||
steps.emplace_back(posSlice);
|
||||
} else if (opt_key == "support_material") {
|
||||
steps.emplace_back(posSupportMaterial);
|
||||
if (m_config.support_material_contact_distance_top == 0. || m_config.support_material_contact_distance_bottom == 0.) {
|
||||
if (m_config.support_material_contact_distance_top.value == 0. || m_config.support_material_contact_distance_bottom.value == 0.) {
|
||||
// Enabling / disabling supports while soluble support interface is enabled.
|
||||
// This changes the bridging logic (bridging enabled without supports, disabled with supports).
|
||||
// Reset everything.
|
||||
@ -1091,20 +1091,20 @@ namespace Slic3r {
|
||||
if (!intersect.empty()) {
|
||||
double area_intersect = 0;
|
||||
// calculate area to decide if area is small enough for autofill
|
||||
if (layerm->region()->config().infill_dense_algo == dfaAutoNotFull || layerm->region()->config().infill_dense_algo == dfaAutoOrEnlarged)
|
||||
if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull || layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged)
|
||||
for (ExPolygon poly_inter : intersect)
|
||||
area_intersect += poly_inter.area();
|
||||
|
||||
if (layerm->region()->config().infill_dense_algo == dfaEnlarged
|
||||
|| (layerm->region()->config().infill_dense_algo == dfaAutoOrEnlarged && surf.area() <= area_intersect * COEFF_SPLIT)) {
|
||||
if (layerm->region()->config().infill_dense_algo.value == dfaEnlarged
|
||||
|| (layerm->region()->config().infill_dense_algo.value == dfaAutoOrEnlarged && surf.area() <= area_intersect * COEFF_SPLIT)) {
|
||||
//expand the area a bit
|
||||
intersect = offset_ex(intersect, double(scale_(layerm->region()->config().external_infill_margin.get_abs_value(
|
||||
region->config().perimeters == 0 ? 0 : (layerm->flow(frExternalPerimeter).width + layerm->flow(frPerimeter).spacing() * (region->config().perimeters - 1))))));
|
||||
} else if (layerm->region()->config().infill_dense_algo == dfaAutoNotFull
|
||||
|| layerm->region()->config().infill_dense_algo == dfaAutomatic) {
|
||||
} else if (layerm->region()->config().infill_dense_algo.value == dfaAutoNotFull
|
||||
|| layerm->region()->config().infill_dense_algo.value == dfaAutomatic) {
|
||||
|
||||
//like intersect.empty() but more resilient
|
||||
if (layerm->region()->config().infill_dense_algo == dfaAutomatic
|
||||
if (layerm->region()->config().infill_dense_algo.value == dfaAutomatic
|
||||
|| surf.area() > area_intersect * COEFF_SPLIT) {
|
||||
ExPolygons cover_intersect;
|
||||
|
||||
@ -1237,7 +1237,7 @@ namespace Slic3r {
|
||||
|
||||
Polygons layerm_slices_surfaces = to_polygons(layerm->slices().surfaces);
|
||||
// no_perimeter_full_bridge allow to put bridges where there are nothing, hence adding area to slice, that's why we need to start from the result of PerimeterGenerator.
|
||||
if (layerm->region()->config().no_perimeter_unsupported_algo == npuaFilled) {
|
||||
if (layerm->region()->config().no_perimeter_unsupported_algo.value == npuaFilled) {
|
||||
layerm_slices_surfaces = union_(layerm_slices_surfaces, to_polygons(layerm->fill_surfaces));
|
||||
}
|
||||
|
||||
@ -3512,11 +3512,11 @@ namespace Slic3r {
|
||||
0.5f * layerms.back()->flow(frPerimeter).scaled_width() +
|
||||
// Because fill areas for rectilinear and honeycomb are grown
|
||||
// later to overlap perimeters, we need to counteract that too.
|
||||
((region->config().fill_pattern == ipRectilinear ||
|
||||
region->config().fill_pattern == ipMonotonic ||
|
||||
region->config().fill_pattern == ipGrid ||
|
||||
region->config().fill_pattern == ipLine ||
|
||||
region->config().fill_pattern == ipHoneycomb) ? 1.5f : 0.5f) *
|
||||
((region->config().fill_pattern.value == ipRectilinear ||
|
||||
region->config().fill_pattern.value == ipMonotonic ||
|
||||
region->config().fill_pattern.value == ipGrid ||
|
||||
region->config().fill_pattern.value == ipLine ||
|
||||
region->config().fill_pattern.value == ipHoneycomb) ? 1.5f : 0.5f) *
|
||||
layerms.back()->flow(frSolidInfill).scaled_width();
|
||||
for (ExPolygon& expoly : intersection)
|
||||
polygons_append(intersection_with_clearance, offset(expoly, clearance_offset));
|
||||
|
@ -1242,7 +1242,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::top_contact_
|
||||
// it will support layers printed with a bridging flow.
|
||||
if (SupportMaterialInternal::has_bridging_extrusions(layer)) {
|
||||
coordf_t bridging_height = layer.height;
|
||||
if (m_object_config->support_material_contact_distance_type == zdFilament) {
|
||||
if (m_object_config->support_material_contact_distance_type.value == zdFilament) {
|
||||
bridging_height = 0.;
|
||||
for (const LayerRegion *region : layer.regions())
|
||||
bridging_height += region->region()->bridging_height_avg(*m_print_config);
|
||||
@ -1513,7 +1513,7 @@ PrintObjectSupportMaterial::MyLayersPtr PrintObjectSupportMaterial::bottom_conta
|
||||
// According to Jindrich the bottom surfaces work well.
|
||||
//FIXME test the bridging flow instead?
|
||||
m_support_material_interface_flow.nozzle_diameter;
|
||||
layer_new.height_block = ((m_object_config->support_material_contact_distance_type == zdPlane) ? object.layers()[layer_id + 1]->height : layer_new.height);
|
||||
layer_new.height_block = ((m_object_config->support_material_contact_distance_type.value == zdPlane) ? object.layers()[layer_id + 1]->height : layer_new.height);
|
||||
layer_new.print_z = m_slicing_params.soluble_interface ? object.layers()[layer_id + 1]->print_z :
|
||||
(layer.print_z + layer_new.height_block + this->m_slicing_params.gap_object_support);
|
||||
layer_new.bottom_z = layer.print_z;
|
||||
@ -2135,7 +2135,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
|
||||
const Layer &object_layer = *object.layers()[i];
|
||||
bool some_region_overlaps = false;
|
||||
for (LayerRegion *region : object_layer.regions()) {
|
||||
coordf_t bridging_height = m_object_config->support_material_contact_distance_type == zdFilament
|
||||
coordf_t bridging_height = m_object_config->support_material_contact_distance_type.value == zdFilament
|
||||
? region->region()->bridging_height_avg(*this->m_print_config)
|
||||
: object_layer.height;
|
||||
if (object_layer.print_z - bridging_height > support_layer.print_z + gap_extra_above - EPSILON)
|
||||
|
@ -50,6 +50,18 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry
|
||||
grid_sizer->Add(sys_colour, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(sys_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
|
||||
|
||||
auto default_label = new wxStaticText(this, wxID_ANY, _(L("Value is the same as the last saved preset, but is not the system value")));
|
||||
default_label->SetForegroundColour(wxGetApp().get_label_clr_default());
|
||||
auto default_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_default());
|
||||
default_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([default_colour, default_label](wxCommandEvent e)
|
||||
{
|
||||
default_label->SetForegroundColour(default_colour->GetColour());
|
||||
default_label->Refresh();
|
||||
}));
|
||||
grid_sizer->Add(0, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(default_colour, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(default_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
|
||||
|
||||
auto mod_label = new wxStaticText(this, wxID_ANY, _(L("Value was changed and is not equal to the system value or the last saved preset")));
|
||||
mod_label->SetForegroundColour(wxGetApp().get_label_clr_modified());
|
||||
auto mod_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_modified());
|
||||
@ -61,15 +73,29 @@ ButtonsDescription::ButtonsDescription(wxWindow* parent, const std::vector<Entry
|
||||
grid_sizer->Add(0, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(mod_colour, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(mod_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
|
||||
|
||||
auto phony_label = new wxStaticText(this, wxID_ANY, _(L("Value isn't taken into account, it's computed over an other field.")));
|
||||
phony_label->SetForegroundColour(wxGetApp().get_label_clr_phony());
|
||||
auto phony_colour = new wxColourPickerCtrl(this, wxID_ANY, wxGetApp().get_label_clr_phony());
|
||||
phony_colour->Bind(wxEVT_COLOURPICKER_CHANGED, ([phony_colour, phony_label](wxCommandEvent e)
|
||||
{
|
||||
phony_label->SetForegroundColour(phony_colour->GetColour());
|
||||
phony_label->Refresh();
|
||||
}));
|
||||
grid_sizer->Add(0, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(phony_colour, -1, wxALIGN_CENTRE_VERTICAL);
|
||||
grid_sizer->Add(phony_label, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND);
|
||||
|
||||
|
||||
auto buttons = CreateStdDialogButtonSizer(wxOK|wxCANCEL);
|
||||
main_sizer->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
|
||||
|
||||
wxButton* btn = static_cast<wxButton*>(FindWindowById(wxID_OK, this));
|
||||
btn->Bind(wxEVT_BUTTON, [sys_colour, mod_colour, this](wxCommandEvent&) {
|
||||
btn->Bind(wxEVT_BUTTON, [sys_colour, mod_colour, default_colour, phony_colour, this](wxCommandEvent&) {
|
||||
wxGetApp().set_label_clr_sys(sys_colour->GetColour());
|
||||
wxGetApp().set_label_clr_modified(mod_colour->GetColour());
|
||||
wxGetApp().set_label_clr_default(default_colour->GetColour());
|
||||
wxGetApp().set_label_clr_phony(phony_colour->GetColour());
|
||||
EndModal(wxID_OK);
|
||||
});
|
||||
|
||||
|
@ -1033,6 +1033,7 @@ void GUI_App::init_label_colours()
|
||||
m_color_label_sys = wxColour(26, 132, 57);
|
||||
}
|
||||
m_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
m_color_label_phony = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
|
||||
}
|
||||
|
||||
void GUI_App::update_label_colours_from_appconfig()
|
||||
@ -1048,6 +1049,18 @@ void GUI_App::update_label_colours_from_appconfig()
|
||||
if (str != "")
|
||||
m_color_label_modified = wxColour(str);
|
||||
}
|
||||
|
||||
if (app_config->has("label_clr_default")) {
|
||||
auto str = app_config->get("label_clr_default");
|
||||
if (str != "")
|
||||
m_color_label_default = wxColour(str);
|
||||
}
|
||||
|
||||
if (app_config->has("label_clr_phony")) {
|
||||
auto str = app_config->get("label_clr_phony");
|
||||
if (str != "")
|
||||
m_color_label_phony = wxColour(str);
|
||||
}
|
||||
}
|
||||
|
||||
void GUI_App::init_fonts()
|
||||
@ -1099,6 +1112,22 @@ void GUI_App::set_label_clr_sys(const wxColour& clr) {
|
||||
app_config->save();
|
||||
}
|
||||
|
||||
void GUI_App::set_label_clr_default(const wxColour& clr) {
|
||||
m_color_label_default = clr;
|
||||
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
|
||||
std::string str = clr_str.ToStdString();
|
||||
app_config->set("label_clr_default", str);
|
||||
app_config->save();
|
||||
}
|
||||
|
||||
void GUI_App::set_label_clr_phony(const wxColour& clr) {
|
||||
m_color_label_phony = clr;
|
||||
auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), clr.Red(), clr.Green(), clr.Blue());
|
||||
std::string str = clr_str.ToStdString();
|
||||
app_config->set("label_clr_phony", str);
|
||||
app_config->save();
|
||||
}
|
||||
|
||||
wxSize GUI_App::get_min_size() const
|
||||
{
|
||||
return wxSize(76*m_em_unit, 49 * m_em_unit);
|
||||
@ -1154,7 +1183,7 @@ void GUI_App::check_printer_presets()
|
||||
for (const std::string& preset_name : preset_names)
|
||||
msg_text += "\n \"" + from_u8(preset_name) + "\",";
|
||||
msg_text.RemoveLast();
|
||||
msg_text += "\n\n" + _L("But since this version of PrusaSlicer we don't show this information in Printer Settings anymore.\n"
|
||||
msg_text += "\n\n" + _L("But since this version of " SLIC3R_APP_NAME " we don't show this information in Printer Settings anymore.\n"
|
||||
"Settings will be available in physical printers settings.") + "\n\n" +
|
||||
_L("By default new Printer devices will be named as \"Printer N\" during its creation.\n"
|
||||
"Note: This name can be changed later from the physical printers settings");
|
||||
|
@ -116,6 +116,7 @@ private:
|
||||
wxColour m_color_label_modified;
|
||||
wxColour m_color_label_sys;
|
||||
wxColour m_color_label_default;
|
||||
wxColour m_color_label_phony;
|
||||
|
||||
wxFont m_small_font;
|
||||
wxFont m_bold_font;
|
||||
@ -171,10 +172,13 @@ public:
|
||||
void update_fonts(const MainFrame *main_frame = nullptr);
|
||||
void set_label_clr_modified(const wxColour& clr);
|
||||
void set_label_clr_sys(const wxColour& clr);
|
||||
void set_label_clr_default(const wxColour& clr);
|
||||
void set_label_clr_phony(const wxColour& clr);
|
||||
|
||||
const wxColour& get_label_clr_modified(){ return m_color_label_modified; }
|
||||
const wxColour& get_label_clr_sys() { return m_color_label_sys; }
|
||||
const wxColour& get_label_clr_default() { return m_color_label_default; }
|
||||
const wxColour& get_label_clr_phony() { return m_color_label_phony; }
|
||||
|
||||
const wxFont& small_font() { return m_small_font; }
|
||||
const wxFont& bold_font() { return m_bold_font; }
|
||||
|
@ -251,6 +251,8 @@ void Tab::create_preset_tab()
|
||||
for (Tab *tab : wxGetApp().tabs_list) {
|
||||
tab->m_sys_label_clr = wxGetApp().get_label_clr_sys();
|
||||
tab->m_modified_label_clr = wxGetApp().get_label_clr_modified();
|
||||
tab->m_default_text_clr = wxGetApp().get_label_clr_default();
|
||||
tab->m_phony_text_clr = wxGetApp().get_label_clr_phony();
|
||||
tab->update_labels_colour();
|
||||
}
|
||||
}
|
||||
@ -260,7 +262,8 @@ void Tab::create_preset_tab()
|
||||
// Colors for ui "decoration"
|
||||
m_sys_label_clr = wxGetApp().get_label_clr_sys();
|
||||
m_modified_label_clr = wxGetApp().get_label_clr_modified();
|
||||
m_default_text_clr = wxGetApp().get_label_clr_default();
|
||||
m_default_text_clr = wxGetApp().get_label_clr_default();
|
||||
m_phony_text_clr = wxGetApp().get_label_clr_phony();
|
||||
|
||||
// Sizer with buttons for mode changing
|
||||
m_mode_sizer = new ModeSizer(panel);
|
||||
@ -513,6 +516,15 @@ void Tab::update_labels_colour()
|
||||
else
|
||||
color = &m_modified_label_clr;
|
||||
}
|
||||
if ((opt.second & osCurrentPhony) != 0)
|
||||
color = &m_phony_text_clr;
|
||||
else {
|
||||
if ((opt.second & osInitPhony) != 0)
|
||||
color = &m_modified_label_clr;
|
||||
else if ((opt.second & osSystemPhony) != 0)
|
||||
color = &m_default_text_clr;
|
||||
}
|
||||
|
||||
if (opt.first == "bed_shape" || opt.first == "filament_ramming_parameters" ||
|
||||
opt.first == "compatible_prints" || opt.first == "compatible_printers" ) {
|
||||
if (m_colored_Label_colors.find(opt.first) != m_colored_Label_colors.end())
|
||||
@ -591,7 +603,17 @@ void Tab::decorate()
|
||||
icon = &m_bmp_white_bullet;
|
||||
tt = &m_tt_white_bullet;
|
||||
}
|
||||
|
||||
|
||||
//color for phony things
|
||||
if ((opt.second & osCurrentPhony) != 0)
|
||||
color = &m_phony_text_clr;
|
||||
else {
|
||||
if ((opt.second & osInitPhony) != 0)
|
||||
color = &m_modified_label_clr;
|
||||
else if ((opt.second & osSystemPhony) != 0)
|
||||
color = &m_default_text_clr;
|
||||
}
|
||||
|
||||
if (colored_label_clr) {
|
||||
*colored_label_clr = *color;
|
||||
continue;
|
||||
@ -634,8 +656,28 @@ void Tab::update_changed_ui()
|
||||
for (auto& it : m_options_list)
|
||||
it.second = m_opt_status_value;
|
||||
|
||||
for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue;
|
||||
for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue;
|
||||
|
||||
const Preset& edited_preset = m_presets->get_edited_preset();
|
||||
const Preset& selected_preset = m_presets->get_selected_preset();
|
||||
const Preset* system_preset = m_presets->get_selected_preset_parent();
|
||||
for (auto& opt_key : m_presets->get_edited_preset().config.keys()) {
|
||||
if (edited_preset.config.option(opt_key)->phony)
|
||||
//ensure that osCurrentPhony is in the bitmask
|
||||
m_options_list[opt_key] |= osCurrentPhony;
|
||||
if (selected_preset.config.option(opt_key)->phony)
|
||||
m_options_list[opt_key] |= osInitPhony;
|
||||
if (system_preset && system_preset->config.option(opt_key)->phony)
|
||||
m_options_list[opt_key] |= osSystemPhony;
|
||||
}
|
||||
|
||||
//don't let option that were phony be resetable.
|
||||
for (auto opt_key : dirty_options)
|
||||
if( (m_options_list[opt_key] & osInitPhony) == 0)
|
||||
//ensure that osInitValue is not in the bitmask
|
||||
m_options_list[opt_key] &= ~osInitValue;
|
||||
for (auto opt_key : nonsys_options)
|
||||
if ((m_options_list[opt_key] & osSystemPhony) == 0)
|
||||
m_options_list[opt_key] &= ~osSystemValue;
|
||||
|
||||
decorate();
|
||||
|
||||
@ -1141,6 +1183,13 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
|
||||
wxGetApp().plater()->on_extruders_change(boost::any_cast<int>(value));
|
||||
}
|
||||
|
||||
//wxGetApp().preset_bundle->value_changed(opt_key);
|
||||
if (m_config->value_changed(opt_key, { wxGetApp().plater()->config() })) {
|
||||
update_dirty();
|
||||
//# Initialize UI components with the config values.
|
||||
reload_config();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@ -2956,6 +3005,7 @@ void Tab::load_current_preset()
|
||||
update_tab_ui();
|
||||
|
||||
// update show/hide tabs
|
||||
//merill note: this is a bit of anti-inheritance pattern
|
||||
if (m_type == Slic3r::Preset::TYPE_PRINTER) {
|
||||
const PrinterTechnology printer_technology = m_presets->get_edited_preset().printer_technology();
|
||||
if (printer_technology != static_cast<TabPrinter*>(this)->m_printer_technology)
|
||||
@ -3002,6 +3052,15 @@ void Tab::load_current_preset()
|
||||
on_presets_changed();
|
||||
if (m_type == Preset::TYPE_SLA_PRINT || m_type == Preset::TYPE_PRINT)
|
||||
update_frequently_changed_parameters();
|
||||
|
||||
//update width/spacing links
|
||||
if (m_type == Preset::TYPE_PRINT) {
|
||||
//verify that spacings are set
|
||||
if (m_config->update_phony({ wxGetApp().plater()->config() })) {
|
||||
update_dirty();
|
||||
reload_config();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue;
|
||||
|
@ -170,6 +170,7 @@ protected:
|
||||
wxColour m_sys_label_clr;
|
||||
wxColour m_modified_label_clr;
|
||||
wxColour m_default_text_clr;
|
||||
wxColour m_phony_text_clr;
|
||||
|
||||
// Tooltip text for reset buttons (for whole options group)
|
||||
wxString m_ttg_value_lock;
|
||||
@ -199,7 +200,13 @@ protected:
|
||||
bool m_show_incompatible_presets;
|
||||
|
||||
std::vector<Preset::Type> m_dependent_tabs;
|
||||
enum OptStatus { osSystemValue = 1, osInitValue = 2 };
|
||||
enum OptStatus {
|
||||
osSystemValue = 1,
|
||||
osInitValue = 2,
|
||||
osSystemPhony = 4,
|
||||
osInitPhony = 8,
|
||||
osCurrentPhony = 16,
|
||||
};
|
||||
std::map<std::string, int> m_options_list;
|
||||
int m_opt_status_value = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user