First implementation of the "compatible_printers_condition"

for the print and filament profiles.
Added documentation for building the boost library for Slic3r on Linux.
This commit is contained in:
bubnikv 2017-12-18 15:07:38 +01:00
parent bb61de8379
commit 6b81f43206
7 changed files with 63 additions and 18 deletions

View File

@ -302,3 +302,14 @@ Debugging the C++ code works fine using the latest Eclipse for C++ and the gdb o
It is yet a bit more complicated. The Strawberry MINGW is compiled for a different C++ exception passing model (SJLJ) than the other MINGWs, so one cannot simply combine MINGWs on Windows. For an unknown reason the nice debugger of the QT Creator hangs when debugging the C++ compiled by the Strawberry MINGW. Mabe it is because of the different exception passing models.
And to disable optimization of the C/C++ code, one has to manually modify Config_heavy.pl in the Perl central installation. The SLIC3R_DEBUG environment variable did not override all the -O2 and -O3 flags that the perl build adds the gcc execution line.
----------------------------------------------------------------------
Building boost.
One may save compilation time by compiling just what Slic3r needs.
./bootstrap.sh --with-libraries=system,filesystem,thread,log,locale,regex
The -fPIC flag is required on Linux to make the static libraries rellocatable,
so they could be embedded into a shared library.
./bjam -a link=static variant=release threading=multi cxxflags=-fPIC cflags=-fPIC
To install on Linux to /usr/local/..., run the line above with the additional install keyword and with sudo.

View File

@ -150,6 +150,8 @@ sub save_preset {
# Save the preset into Slic3r::data_dir/presets/section_name/preset_name.ini
eval { $self->{presets}->save_current_preset($name); };
Slic3r::GUI::catch_error($self) and return;
# Mark the print & filament enabled if they are compatible with the currently selected preset.
wxTheApp->{preset_bundle}->update_compatible_with_printer(0);
# Add the new item into the UI component, remove dirty flags and activate the saved item.
$self->update_tab_ui;
# Update the selection boxes at the platter.
@ -285,12 +287,12 @@ sub select_preset {
my $new_printer_preset = $presets->find_preset($new_printer_name, 1);
my $print_presets = wxTheApp->{preset_bundle}->print;
my $print_preset_dirty = $print_presets->current_is_dirty;
my $print_preset_compatible = $print_presets->get_edited_preset->is_compatible_with_printer($new_printer_name);
my $print_preset_compatible = $print_presets->get_edited_preset->is_compatible_with_printer($new_printer_preset);
$canceled = $print_preset_dirty && ! $print_preset_compatible &&
! $self->may_discard_current_dirty_preset($print_presets, $new_printer_name);
my $filament_presets = wxTheApp->{preset_bundle}->filament;
my $filament_preset_dirty = $filament_presets->current_is_dirty;
my $filament_preset_compatible = $filament_presets->get_edited_preset->is_compatible_with_printer($new_printer_name);
my $filament_preset_compatible = $filament_presets->get_edited_preset->is_compatible_with_printer($new_printer_preset);
if (! $canceled) {
$canceled = $filament_preset_dirty && ! $filament_preset_compatible &&
! $self->may_discard_current_dirty_preset($filament_presets, $new_printer_name);
@ -442,6 +444,7 @@ sub _load_key_value {
$self->{config}->set($opt_key, $value);
# Mark the print & filament enabled if they are compatible with the currently selected preset.
if ($opt_key eq 'compatible_printers') {
# $opt_key eq 'compatible_printers_condition') {
wxTheApp->{preset_bundle}->update_compatible_with_printer(0);
}
$self->{presets}->update_dirty_ui($self->{presets_choice});
@ -838,6 +841,10 @@ sub build {
widget => $self->_compatible_printers_widget,
);
$optgroup->append_line($line);
my $option = $optgroup->get_option('compatible_printers_condition');
$option->full_width(1);
$optgroup->append_single_option_line($option);
}
}
}
@ -1207,6 +1214,10 @@ sub build {
widget => $self->_compatible_printers_widget,
);
$optgroup->append_line($line);
my $option = $optgroup->get_option('compatible_printers_condition');
$option->full_width(1);
$optgroup->append_single_option_line($option);
}
}
}

View File

@ -139,6 +139,13 @@ PrintConfigDef::PrintConfigDef()
def->label = "Compatible printers";
def->default_value = new ConfigOptionStrings();
def = this->add("compatible_printers_condition", coString);
def->label = "Compatible printers condition";
def->tooltip = "A boolean expression using the configuration values of an active printer profile. "
"If this expression evaluates to true, this profile is considered compatible "
"with the active printer profile.";
def->default_value = new ConfigOptionString();
def = this->add("complete_objects", coBool);
def->label = "Complete individual objects";
def->tooltip = "When printing multiple objects or copies, this feature will complete "

View File

@ -21,6 +21,7 @@
#include "../../libslic3r/libslic3r.h"
#include "../../libslic3r/Utils.hpp"
#include "../../libslic3r/PlaceholderParser.hpp"
namespace Slic3r {
@ -141,16 +142,26 @@ std::string Preset::label() const
return this->name + (this->is_dirty ? g_suffix_modified : "");
}
bool Preset::is_compatible_with_printer(const std::string &active_printer) const
bool Preset::is_compatible_with_printer(const Preset &active_printer) const
{
auto *condition = dynamic_cast<const ConfigOptionString*>(this->config.option("compatible_printers_condition"));
if (condition != nullptr && ! condition->value.empty()) {
try {
return PlaceholderParser::evaluate_boolean_expression(condition->value, active_printer.config);
} catch (const std::runtime_error &err) {
//FIXME in case of an error, return "compatible with everything".
printf("Preset::is_compatible_with_printer - parsing error of compatible_printers_condition %s:\n%s\n", active_printer.name.c_str(), err.what());
return true;
}
}
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(this->config.option("compatible_printers"));
return this->is_default || active_printer.empty() ||
return this->is_default || active_printer.name.empty() ||
compatible_printers == nullptr || compatible_printers->values.empty() ||
std::find(compatible_printers->values.begin(), compatible_printers->values.end(), active_printer) !=
std::find(compatible_printers->values.begin(), compatible_printers->values.end(), active_printer.name) !=
compatible_printers->values.end();
}
bool Preset::update_compatible_with_printer(const std::string &active_printer)
bool Preset::update_compatible_with_printer(const Preset &active_printer)
{
return this->is_compatible = is_compatible_with_printer(active_printer);
}
@ -180,7 +191,7 @@ const std::vector<std::string>& Preset::print_options()
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "bridge_flow_ratio", "clip_multipart_objects",
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
"wipe_tower_width", "wipe_tower_per_color_wipe",
"compatible_printers"
"compatible_printers", "compatible_printers_condition"
};
return s_opts;
}
@ -193,7 +204,7 @@ const std::vector<std::string>& Preset::filament_options()
"first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed", "max_fan_speed", "bridge_fan_speed",
"disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed", "start_filament_gcode",
"end_filament_gcode",
"compatible_printers"
"compatible_printers", "compatible_printers_condition"
};
return s_opts;
}
@ -395,7 +406,7 @@ void PresetCollection::set_default_suppressed(bool default_suppressed)
}
}
void PresetCollection::update_compatible_with_printer(const std::string &active_printer, bool select_other_if_incompatible)
void PresetCollection::update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible)
{
for (size_t idx_preset = 1; idx_preset < m_presets.size(); ++ idx_preset) {
bool selected = idx_preset == m_idx_selected;
@ -490,9 +501,11 @@ std::vector<std::string> PresetCollection::current_dirty_options() const
// The "compatible_printers" option key is handled differently from the others:
// It is not mandatory. If the key is missing, it means it is compatible with any printer.
// If the key exists and it is empty, it means it is compatible with no printer.
const char compatible_printers[] = "compatible_printers";
if (this->get_selected_preset().config.has(compatible_printers) != this->get_edited_preset().config.has(compatible_printers))
changed.emplace_back(compatible_printers);
std::initializer_list<const char*> optional_keys { "compatible_printers", "compatible_printers_condition" };
for (auto &opt_key : optional_keys) {
if (this->get_selected_preset().config.has(opt_key) != this->get_edited_preset().config.has(opt_key))
changed.emplace_back(opt_key);
}
return changed;
}

View File

@ -79,9 +79,9 @@ public:
void set_dirty(bool dirty = true) { this->is_dirty = dirty; }
void reset_dirty() { this->is_dirty = false; }
bool is_compatible_with_printer(const std::string &active_printer) const;
bool is_compatible_with_printer(const Preset &active_printer) const;
// Mark this preset as compatible if it is compatible with active_printer.
bool update_compatible_with_printer(const std::string &active_printer);
bool update_compatible_with_printer(const Preset &active_printer);
// Resize the extruder specific fields, initialize them with the content of the 1st extruder.
void set_num_extruders(unsigned int n) { set_num_extruders(this->config, n); }
@ -180,7 +180,7 @@ public:
size_t size() const { return this->m_presets.size(); }
// For Print / Filament presets, disable those, which are not compatible with the printer.
void update_compatible_with_printer(const std::string &active_printer, bool select_other_if_incompatible);
void update_compatible_with_printer(const Preset &active_printer, bool select_other_if_incompatible);
size_t num_visible() const { return std::count_if(m_presets.begin(), m_presets.end(), [](const Preset &preset){return preset.is_visible;}); }

View File

@ -47,7 +47,9 @@ PresetBundle::PresetBundle() :
this->printers.preset(0).config.opt_string("print_settings_id", true);
// Create the "compatible printers" keys, as they are not part of the Static print config classes.
this->filaments.preset(0).config.optptr("compatible_printers", true);
this->filaments.preset(0).config.optptr("compatible_printers_condition", true);
this->prints.preset(0).config.optptr("compatible_printers", true);
this->prints.preset(0).config.optptr("compatible_printers_condition", true);
this->prints .load_bitmap_default("cog.png");
this->filaments.load_bitmap_default("spool.png");
@ -537,8 +539,8 @@ void PresetBundle::update_multi_material_filament_presets()
void PresetBundle::update_compatible_with_printer(bool select_other_if_incompatible)
{
this->prints.update_compatible_with_printer(this->printers.get_selected_preset().name, select_other_if_incompatible);
this->filaments.update_compatible_with_printer(this->printers.get_selected_preset().name, select_other_if_incompatible);
this->prints.update_compatible_with_printer(this->printers.get_edited_preset(), select_other_if_incompatible);
this->filaments.update_compatible_with_printer(this->printers.get_edited_preset(), select_other_if_incompatible);
if (select_other_if_incompatible) {
// Verify validity of the current filament presets.
for (std::string &filament_name : this->filament_presets) {

View File

@ -15,7 +15,8 @@
bool visible() %code%{ RETVAL = THIS->is_visible; %};
bool dirty() %code%{ RETVAL = THIS->is_dirty; %};
bool compatible() %code%{ RETVAL = THIS->is_compatible; %};
bool is_compatible_with_printer(char *active_printer) const;
bool is_compatible_with_printer(Preset *active_printer)
%code%{ RETVAL = THIS->is_compatible_with_printer(*active_printer); %};
const char* name() %code%{ RETVAL = THIS->name.c_str(); %};
const char* file() %code%{ RETVAL = THIS->file.c_str(); %};