Skip to content

Commit

Permalink
Refactoring of StaticPrintConfig & derived classes:
Browse files Browse the repository at this point in the history
1) Using boost::preprocessor to reduce code duplicities when defining
   new configuration values.
2) Implemented static hash() and operator== on StaticPrintConfig derived
   classes to support hash tables of instances thereof.
  • Loading branch information
bubnikv committed Apr 26, 2021
1 parent 5783cc6 commit d1cfdcb
Show file tree
Hide file tree
Showing 7 changed files with 622 additions and 891 deletions.
124 changes: 81 additions & 43 deletions src/libslic3r/Config.hpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/libslic3r/GCode/CoolingBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ std::vector<PerExtruderAdjustments> CoolingBuffer::parse_layer_gcode(const std::
PerExtruderAdjustments *adjustment = &per_extruder_adjustments[map_extruder_to_per_extruder_adjustment[current_extruder]];
const char *line_start = gcode.c_str();
const char *line_end = line_start;
const char extrusion_axis = config.get_extrusion_axis()[0];
const char extrusion_axis = get_extrusion_axis(config)[0];
// Index of an existing CoolingLine of the current adjustment, which holds the feedrate setting command
// for a sequence of extrusion moves.
size_t active_speed_modifier = size_t(-1);
Expand Down
4 changes: 2 additions & 2 deletions src/libslic3r/GCodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ namespace Slic3r {
void GCodeReader::apply_config(const GCodeConfig &config)
{
m_config = config;
m_extrusion_axis = m_config.get_extrusion_axis()[0];
m_extrusion_axis = get_extrusion_axis(m_config)[0];
}

void GCodeReader::apply_config(const DynamicPrintConfig &config)
{
m_config.apply(config, true);
m_extrusion_axis = m_config.get_extrusion_axis()[0];
m_extrusion_axis = get_extrusion_axis(m_config)[0];
}

const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair<const char*, const char*> &command)
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/GCodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Slic3r {
void GCodeWriter::apply_print_config(const PrintConfig &print_config)
{
this->config.apply(print_config, true);
m_extrusion_axis = this->config.get_extrusion_axis();
m_extrusion_axis = get_extrusion_axis(this->config);
m_single_extruder_multi_material = print_config.single_extruder_multi_material.value;
bool is_marlin = print_config.gcode_flavor.value == gcfMarlinLegacy || print_config.gcode_flavor.value == gcfMarlinFirmware;
m_max_acceleration = std::lrint((is_marlin && print_config.machine_limits_usage.value == MachineLimitsUsage::EmitToGCode) ?
Expand Down
88 changes: 44 additions & 44 deletions src/libslic3r/PrintConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3608,7 +3608,7 @@ std::string DynamicPrintConfig::validate()
FullPrintConfig fpc;
fpc.apply(*this, true);
// Verify this print options through the FullPrintConfig.
return fpc.validate();
return Slic3r::validate(fpc);
}
default:
//FIXME no validation on SLA data?
Expand All @@ -3617,135 +3617,135 @@ std::string DynamicPrintConfig::validate()
}

//FIXME localize this function.
std::string FullPrintConfig::validate()
std::string validate(const FullPrintConfig &cfg)
{
// --layer-height
if (this->get_abs_value("layer_height") <= 0)
if (cfg.get_abs_value("layer_height") <= 0)
return "Invalid value for --layer-height";
if (fabs(fmod(this->get_abs_value("layer_height"), SCALING_FACTOR)) > 1e-4)
if (fabs(fmod(cfg.get_abs_value("layer_height"), SCALING_FACTOR)) > 1e-4)
return "--layer-height must be a multiple of print resolution";

// --first-layer-height
if (first_layer_height.value <= 0)
if (cfg.first_layer_height.value <= 0)
return "Invalid value for --first-layer-height";

// --filament-diameter
for (double fd : this->filament_diameter.values)
for (double fd : cfg.filament_diameter.values)
if (fd < 1)
return "Invalid value for --filament-diameter";

// --nozzle-diameter
for (double nd : this->nozzle_diameter.values)
for (double nd : cfg.nozzle_diameter.values)
if (nd < 0.005)
return "Invalid value for --nozzle-diameter";

// --perimeters
if (this->perimeters.value < 0)
if (cfg.perimeters.value < 0)
return "Invalid value for --perimeters";

// --solid-layers
if (this->top_solid_layers < 0)
if (cfg.top_solid_layers < 0)
return "Invalid value for --top-solid-layers";
if (this->bottom_solid_layers < 0)
if (cfg.bottom_solid_layers < 0)
return "Invalid value for --bottom-solid-layers";

if (this->use_firmware_retraction.value &&
this->gcode_flavor.value != gcfSmoothie &&
this->gcode_flavor.value != gcfRepRapSprinter &&
this->gcode_flavor.value != gcfRepRapFirmware &&
this->gcode_flavor.value != gcfMarlinLegacy &&
this->gcode_flavor.value != gcfMarlinFirmware &&
this->gcode_flavor.value != gcfMachinekit &&
this->gcode_flavor.value != gcfRepetier)
if (cfg.use_firmware_retraction.value &&
cfg.gcode_flavor.value != gcfSmoothie &&
cfg.gcode_flavor.value != gcfRepRapSprinter &&
cfg.gcode_flavor.value != gcfRepRapFirmware &&
cfg.gcode_flavor.value != gcfMarlinLegacy &&
cfg.gcode_flavor.value != gcfMarlinFirmware &&
cfg.gcode_flavor.value != gcfMachinekit &&
cfg.gcode_flavor.value != gcfRepetier)
return "--use-firmware-retraction is only supported by Marlin, Smoothie, RepRapFirmware, Repetier and Machinekit firmware";

if (this->use_firmware_retraction.value)
for (unsigned char wipe : this->wipe.values)
if (cfg.use_firmware_retraction.value)
for (unsigned char wipe : cfg.wipe.values)
if (wipe)
return "--use-firmware-retraction is not compatible with --wipe";

// --gcode-flavor
if (! print_config_def.get("gcode_flavor")->has_enum_value(this->gcode_flavor.serialize()))
if (! print_config_def.get("gcode_flavor")->has_enum_value(cfg.gcode_flavor.serialize()))
return "Invalid value for --gcode-flavor";

// --fill-pattern
if (! print_config_def.get("fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
if (! print_config_def.get("fill_pattern")->has_enum_value(cfg.fill_pattern.serialize()))
return "Invalid value for --fill-pattern";

// --top-fill-pattern
if (! print_config_def.get("top_fill_pattern")->has_enum_value(this->top_fill_pattern.serialize()))
if (! print_config_def.get("top_fill_pattern")->has_enum_value(cfg.top_fill_pattern.serialize()))
return "Invalid value for --top-fill-pattern";

// --bottom-fill-pattern
if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(this->bottom_fill_pattern.serialize()))
if (! print_config_def.get("bottom_fill_pattern")->has_enum_value(cfg.bottom_fill_pattern.serialize()))
return "Invalid value for --bottom-fill-pattern";

// --fill-density
if (fabs(this->fill_density.value - 100.) < EPSILON &&
! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize()))
if (fabs(cfg.fill_density.value - 100.) < EPSILON &&
! print_config_def.get("top_fill_pattern")->has_enum_value(cfg.fill_pattern.serialize()))
return "The selected fill pattern is not supposed to work at 100% density";

// --infill-every-layers
if (this->infill_every_layers < 1)
if (cfg.infill_every_layers < 1)
return "Invalid value for --infill-every-layers";

// --skirt-height
if (this->skirt_height < 0)
if (cfg.skirt_height < 0)
return "Invalid value for --skirt-height";

// --bridge-flow-ratio
if (this->bridge_flow_ratio <= 0)
if (cfg.bridge_flow_ratio <= 0)
return "Invalid value for --bridge-flow-ratio";

// extruder clearance
if (this->extruder_clearance_radius <= 0)
if (cfg.extruder_clearance_radius <= 0)
return "Invalid value for --extruder-clearance-radius";
if (this->extruder_clearance_height <= 0)
if (cfg.extruder_clearance_height <= 0)
return "Invalid value for --extruder-clearance-height";

// --extrusion-multiplier
for (double em : this->extrusion_multiplier.values)
for (double em : cfg.extrusion_multiplier.values)
if (em <= 0)
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 ((cfg.perimeter_acceleration != 0. || cfg.infill_acceleration != 0. || cfg.bridge_acceleration != 0. || cfg.first_layer_acceleration != 0.) &&
cfg.default_acceleration == 0.)
return "Invalid zero value for --default-acceleration when using other acceleration settings";

// --spiral-vase
if (this->spiral_vase) {
if (cfg.spiral_vase) {
// Note that we might want to have more than one perimeter on the bottom
// solid layers.
if (this->perimeters > 1)
if (cfg.perimeters > 1)
return "Can't make more than one perimeter when spiral vase mode is enabled";
else if (this->perimeters < 1)
else if (cfg.perimeters < 1)
return "Can't make less than one perimeter when spiral vase mode is enabled";
if (this->fill_density > 0)
if (cfg.fill_density > 0)
return "Spiral vase mode can only print hollow objects, so you need to set Fill density to 0";
if (this->top_solid_layers > 0)
if (cfg.top_solid_layers > 0)
return "Spiral vase mode is not compatible with top solid layers";
if (this->support_material || this->support_material_enforce_layers > 0)
if (cfg.support_material || cfg.support_material_enforce_layers > 0)
return "Spiral vase mode is not compatible with support material";
}

// extrusion widths
{
double max_nozzle_diameter = 0.;
for (double dmr : this->nozzle_diameter.values)
for (double dmr : cfg.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" };
for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++ i) {
std::string key(widths[i]);
key += "_extrusion_width";
if (this->get_abs_value(key, max_nozzle_diameter) > 10. * max_nozzle_diameter)
if (cfg.get_abs_value(key, max_nozzle_diameter) > 10. * max_nozzle_diameter)
return std::string("Invalid extrusion width (too large): ") + key;
}
}

// Out of range validation of numeric values.
for (const std::string &opt_key : this->keys()) {
const ConfigOption *opt = this->optptr(opt_key);
for (const std::string &opt_key : cfg.keys()) {
const ConfigOption *opt = cfg.optptr(opt_key);
assert(opt != nullptr);
const ConfigOptionDef *optdef = print_config_def.get(opt_key);
assert(optdef != nullptr);
Expand Down
Loading

0 comments on commit d1cfdcb

Please sign in to comment.