Skip to content

Commit

Permalink
Add some spacing settings at the side of width
Browse files Browse the repository at this point in the history
 - 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
  • Loading branch information
remi durand committed Apr 25, 2021
1 parent 1d40530 commit 715d58d
Show file tree
Hide file tree
Showing 18 changed files with 673 additions and 79 deletions.
43 changes: 34 additions & 9 deletions resources/ui_layout/print.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 18 additions & 2 deletions src/libslic3r/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
}

Expand Down Expand Up @@ -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;
}

Expand Down
18 changes: 17 additions & 1 deletion src/libslic3r/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -266,6 +273,7 @@ class ConfigOptionSingle : public ConfigOption {
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
Expand Down Expand Up @@ -340,6 +348,7 @@ class ConfigOptionVector : public ConfigOptionVectorBase
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.
Expand Down Expand Up @@ -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(); }
Expand Down Expand Up @@ -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(); }
Expand Down Expand Up @@ -943,6 +954,7 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
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(); }
Expand Down Expand Up @@ -1427,6 +1439,7 @@ class ConfigOptionEnum : public ConfigOptionSingle<T>
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
Expand Down Expand Up @@ -1511,6 +1524,7 @@ class ConfigOptionEnumGeneric : public ConfigOptionInt
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
Expand Down Expand Up @@ -1658,7 +1672,9 @@ class ConfigOptionDef
// 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.
Expand Down
4 changes: 2 additions & 2 deletions src/libslic3r/Fill/FillAdaptive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 5 additions & 5 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/libslic3r/GCodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
Expand Down
8 changes: 4 additions & 4 deletions src/libslic3r/PerimeterGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.
Expand Down Expand Up @@ -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) {
Expand All @@ -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();
Expand Down
24 changes: 20 additions & 4 deletions src/libslic3r/Preset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.") };
Expand Down
Loading

0 comments on commit 715d58d

Please sign in to comment.