Initial partial implementation of presets in C++.
This commit is contained in:
parent
b58756f38b
commit
473233019c
@ -94,6 +94,7 @@ sub OnInit {
|
|||||||
Slic3r::debugf "wxWidgets version %s, Wx version %s\n", &Wx::wxVERSION_STRING, $Wx::VERSION;
|
Slic3r::debugf "wxWidgets version %s, Wx version %s\n", &Wx::wxVERSION_STRING, $Wx::VERSION;
|
||||||
|
|
||||||
$self->{notifier} = Slic3r::GUI::Notifier->new;
|
$self->{notifier} = Slic3r::GUI::Notifier->new;
|
||||||
|
$self->{preset_bundle} = Slic3r::GUI::PresetBundle->new;
|
||||||
|
|
||||||
# locate or create data directory
|
# locate or create data directory
|
||||||
# Unix: ~/.Slic3r
|
# Unix: ~/.Slic3r
|
||||||
|
@ -21,7 +21,7 @@ use File::Basename qw(basename);
|
|||||||
use List::Util qw(first);
|
use List::Util qw(first);
|
||||||
use Wx qw(:bookctrl :dialog :keycode :icon :id :misc :panel :sizer :treectrl :window
|
use Wx qw(:bookctrl :dialog :keycode :icon :id :misc :panel :sizer :treectrl :window
|
||||||
:button wxTheApp);
|
:button wxTheApp);
|
||||||
use Wx::Event qw(EVT_BUTTON EVT_CHOICE EVT_KEY_DOWN EVT_TREE_SEL_CHANGED);
|
use Wx::Event qw(EVT_BUTTON EVT_CHOICE EVT_KEY_DOWN EVT_CHECKBOX EVT_TREE_SEL_CHANGED);
|
||||||
use base qw(Wx::Panel Class::Accessor);
|
use base qw(Wx::Panel Class::Accessor);
|
||||||
|
|
||||||
# Index of the currently active preset.
|
# Index of the currently active preset.
|
||||||
@ -522,7 +522,7 @@ package Slic3r::GUI::Tab::Print;
|
|||||||
use base 'Slic3r::GUI::Tab';
|
use base 'Slic3r::GUI::Tab';
|
||||||
|
|
||||||
use List::Util qw(first);
|
use List::Util qw(first);
|
||||||
use Wx qw(:icon :dialog :id);
|
use Wx qw(:icon :dialog :id wxTheApp);
|
||||||
|
|
||||||
sub name { 'print' }
|
sub name { 'print' }
|
||||||
sub title { 'Print Settings' }
|
sub title { 'Print Settings' }
|
||||||
@ -530,49 +530,7 @@ sub title { 'Print Settings' }
|
|||||||
sub build {
|
sub build {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
$self->init_config_options(qw(
|
$self->{config}->apply(wxTheApp->{preset_bundle}->prints->preset(0)->config);
|
||||||
layer_height first_layer_height
|
|
||||||
perimeters spiral_vase
|
|
||||||
top_solid_layers bottom_solid_layers
|
|
||||||
extra_perimeters ensure_vertical_shell_thickness avoid_crossing_perimeters thin_walls overhangs
|
|
||||||
seam_position external_perimeters_first
|
|
||||||
fill_density fill_pattern external_fill_pattern
|
|
||||||
infill_every_layers infill_only_where_needed
|
|
||||||
solid_infill_every_layers fill_angle bridge_angle solid_infill_below_area
|
|
||||||
only_retract_when_crossing_perimeters infill_first
|
|
||||||
max_print_speed max_volumetric_speed
|
|
||||||
max_volumetric_extrusion_rate_slope_positive max_volumetric_extrusion_rate_slope_negative
|
|
||||||
perimeter_speed small_perimeter_speed external_perimeter_speed infill_speed
|
|
||||||
solid_infill_speed top_solid_infill_speed support_material_speed
|
|
||||||
support_material_xy_spacing
|
|
||||||
support_material_interface_speed bridge_speed gap_fill_speed
|
|
||||||
travel_speed
|
|
||||||
first_layer_speed
|
|
||||||
perimeter_acceleration infill_acceleration bridge_acceleration
|
|
||||||
first_layer_acceleration default_acceleration
|
|
||||||
skirts skirt_distance skirt_height min_skirt_length
|
|
||||||
brim_width
|
|
||||||
support_material support_material_threshold support_material_enforce_layers
|
|
||||||
raft_layers
|
|
||||||
support_material_pattern support_material_with_sheath support_material_spacing support_material_synchronize_layers support_material_angle
|
|
||||||
support_material_interface_layers support_material_interface_spacing support_material_interface_contact_loops
|
|
||||||
support_material_contact_distance support_material_buildplate_only dont_support_bridges
|
|
||||||
notes
|
|
||||||
complete_objects extruder_clearance_radius extruder_clearance_height
|
|
||||||
gcode_comments 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
|
|
||||||
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
|
|
||||||
));
|
|
||||||
$self->{config}->set('print_settings_id', '');
|
|
||||||
|
|
||||||
{
|
{
|
||||||
my $page = $self->add_options_page('Layers and perimeters', 'layers.png');
|
my $page = $self->add_options_page('Layers and perimeters', 'layers.png');
|
||||||
@ -776,7 +734,7 @@ sub build {
|
|||||||
$optgroup->append_single_option_line('clip_multipart_objects');
|
$optgroup->append_single_option_line('clip_multipart_objects');
|
||||||
$optgroup->append_single_option_line('elefant_foot_compensation');
|
$optgroup->append_single_option_line('elefant_foot_compensation');
|
||||||
$optgroup->append_single_option_line('xy_size_compensation');
|
$optgroup->append_single_option_line('xy_size_compensation');
|
||||||
$optgroup->append_single_option_line('threads') if $Slic3r::have_threads;
|
# $optgroup->append_single_option_line('threads') if $Slic3r::have_threads;
|
||||||
$optgroup->append_single_option_line('resolution');
|
$optgroup->append_single_option_line('resolution');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -831,6 +789,12 @@ sub build {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub reload_config {
|
||||||
|
my ($self) = @_;
|
||||||
|
# $self->_reload_compatible_printers_widget;
|
||||||
|
$self->SUPER::reload_config;
|
||||||
|
}
|
||||||
|
|
||||||
# Slic3r::GUI::Tab::Print::_update is called after a configuration preset is loaded or switched, or when a single option is modifed by the user.
|
# Slic3r::GUI::Tab::Print::_update is called after a configuration preset is loaded or switched, or when a single option is modifed by the user.
|
||||||
sub _update {
|
sub _update {
|
||||||
# $keys_modified is a reference to hash with modified keys set to 1, unmodified keys missing.
|
# $keys_modified is a reference to hash with modified keys set to 1, unmodified keys missing.
|
||||||
@ -1035,10 +999,11 @@ sub _update {
|
|||||||
for qw(wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe);
|
for qw(wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub hidden_options { !$Slic3r::have_threads ? qw(threads) : () }
|
#sub hidden_options { !$Slic3r::have_threads ? qw(threads) : () }
|
||||||
|
|
||||||
package Slic3r::GUI::Tab::Filament;
|
package Slic3r::GUI::Tab::Filament;
|
||||||
use base 'Slic3r::GUI::Tab';
|
use base 'Slic3r::GUI::Tab';
|
||||||
|
use Wx qw(wxTheApp);
|
||||||
|
|
||||||
sub name { 'filament' }
|
sub name { 'filament' }
|
||||||
sub title { 'Filament Settings' }
|
sub title { 'Filament Settings' }
|
||||||
@ -1046,15 +1011,7 @@ sub title { 'Filament Settings' }
|
|||||||
sub build {
|
sub build {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
$self->init_config_options(qw(
|
$self->{config}->apply(wxTheApp->{preset_bundle}->filaments->preset(0)->config);
|
||||||
filament_colour filament_diameter filament_type filament_soluble filament_notes filament_max_volumetric_speed extrusion_multiplier filament_density filament_cost
|
|
||||||
temperature first_layer_temperature bed_temperature 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
|
|
||||||
));
|
|
||||||
$self->{config}->set('filament_settings_id', '');
|
|
||||||
|
|
||||||
{
|
{
|
||||||
my $page = $self->add_options_page('Filament', 'spool.png');
|
my $page = $self->add_options_page('Filament', 'spool.png');
|
||||||
@ -1236,20 +1193,7 @@ sub build {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my (%params) = @_;
|
my (%params) = @_;
|
||||||
|
|
||||||
$self->init_config_options(qw(
|
$self->{config}->apply(wxTheApp->{preset_bundle}->printers->preset(0)->config);
|
||||||
bed_shape z_offset
|
|
||||||
gcode_flavor use_relative_e_distances
|
|
||||||
serial_port serial_speed
|
|
||||||
octoprint_host octoprint_apikey
|
|
||||||
use_firmware_retraction
|
|
||||||
use_volumetric_e variable_layer_height
|
|
||||||
single_extruder_multi_material start_gcode end_gcode before_layer_gcode layer_gcode toolchange_gcode
|
|
||||||
nozzle_diameter extruder_offset
|
|
||||||
retract_length retract_lift retract_speed deretract_speed retract_before_wipe retract_restart_extra retract_before_travel retract_layer_change wipe
|
|
||||||
retract_length_toolchange retract_restart_extra_toolchange
|
|
||||||
extruder_colour printer_notes
|
|
||||||
));
|
|
||||||
$self->{config}->set('printer_settings_id', '');
|
|
||||||
|
|
||||||
my $bed_shape_widget = sub {
|
my $bed_shape_widget = sub {
|
||||||
my ($parent) = @_;
|
my ($parent) = @_;
|
||||||
|
@ -28,6 +28,8 @@ if(WIN32)
|
|||||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB)
|
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -DBOOST_ALL_NO_LIB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DwxUSE_UNICODE -D_UNICODE -DUNICODE)
|
||||||
|
|
||||||
add_library(libslic3r STATIC
|
add_library(libslic3r STATIC
|
||||||
${LIBDIR}/libslic3r/BoundingBox.cpp
|
${LIBDIR}/libslic3r/BoundingBox.cpp
|
||||||
${LIBDIR}/libslic3r/BoundingBox.hpp
|
${LIBDIR}/libslic3r/BoundingBox.hpp
|
||||||
@ -164,6 +166,8 @@ add_library(libslic3r_gui STATIC
|
|||||||
${LIBDIR}/slic3r/GUI/3DScene.hpp
|
${LIBDIR}/slic3r/GUI/3DScene.hpp
|
||||||
${LIBDIR}/slic3r/GUI/GLShader.cpp
|
${LIBDIR}/slic3r/GUI/GLShader.cpp
|
||||||
${LIBDIR}/slic3r/GUI/GLShader.hpp
|
${LIBDIR}/slic3r/GUI/GLShader.hpp
|
||||||
|
${LIBDIR}/slic3r/GUI/Preset.cpp
|
||||||
|
${LIBDIR}/slic3r/GUI/Preset.hpp
|
||||||
${LIBDIR}/slic3r/GUI/GUI.cpp
|
${LIBDIR}/slic3r/GUI/GUI.cpp
|
||||||
${LIBDIR}/slic3r/GUI/GUI.hpp
|
${LIBDIR}/slic3r/GUI/GUI.hpp
|
||||||
)
|
)
|
||||||
@ -276,6 +280,7 @@ set(XS_XSP_FILES
|
|||||||
${XSP_DIR}/Geometry.xsp
|
${XSP_DIR}/Geometry.xsp
|
||||||
${XSP_DIR}/GUI.xsp
|
${XSP_DIR}/GUI.xsp
|
||||||
${XSP_DIR}/GUI_3DScene.xsp
|
${XSP_DIR}/GUI_3DScene.xsp
|
||||||
|
${XSP_DIR}/GUI_Preset.xsp
|
||||||
${XSP_DIR}/Layer.xsp
|
${XSP_DIR}/Layer.xsp
|
||||||
${XSP_DIR}/Line.xsp
|
${XSP_DIR}/Line.xsp
|
||||||
${XSP_DIR}/Model.xsp
|
${XSP_DIR}/Model.xsp
|
||||||
@ -460,13 +465,13 @@ if (SLIC3R_PRUSACONTROL)
|
|||||||
set(wxWidgets_UseAlienWx 1)
|
set(wxWidgets_UseAlienWx 1)
|
||||||
if (wxWidgets_UseAlienWx)
|
if (wxWidgets_UseAlienWx)
|
||||||
set(AlienWx_DEBUG 1)
|
set(AlienWx_DEBUG 1)
|
||||||
find_package(AlienWx REQUIRED COMPONENTS base)
|
find_package(AlienWx REQUIRED COMPONENTS base core adv)
|
||||||
include_directories(${AlienWx_INCLUDE_DIRS})
|
include_directories(${AlienWx_INCLUDE_DIRS})
|
||||||
#add_compile_options(${AlienWx_CXX_FLAGS})
|
#add_compile_options(${AlienWx_CXX_FLAGS})
|
||||||
add_definitions(${AlienWx_DEFINITIONS})
|
add_definitions(${AlienWx_DEFINITIONS})
|
||||||
set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES})
|
set(wxWidgets_LIBRARIES ${AlienWx_LIBRARIES})
|
||||||
else ()
|
else ()
|
||||||
find_package(wxWidgets REQUIRED COMPONENTS base)
|
find_package(wxWidgets REQUIRED COMPONENTS base core adv)
|
||||||
include(${wxWidgets_USE_FILE})
|
include(${wxWidgets_USE_FILE})
|
||||||
endif ()
|
endif ()
|
||||||
add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS)
|
add_definitions(-DSLIC3R_GUI -DSLIC3R_PRUS)
|
||||||
|
@ -282,6 +282,8 @@ for my $class (qw(
|
|||||||
Slic3r::Geometry::BoundingBoxf
|
Slic3r::Geometry::BoundingBoxf
|
||||||
Slic3r::Geometry::BoundingBoxf3
|
Slic3r::Geometry::BoundingBoxf3
|
||||||
Slic3r::GUI::_3DScene::GLVolume
|
Slic3r::GUI::_3DScene::GLVolume
|
||||||
|
Slic3r::GUI::Preset
|
||||||
|
Slic3r::GUI::PresetCollection
|
||||||
Slic3r::Layer
|
Slic3r::Layer
|
||||||
Slic3r::Layer::Region
|
Slic3r::Layer::Region
|
||||||
Slic3r::Layer::Support
|
Slic3r::Layer::Support
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
|
|
||||||
void set(const ConfigOption &option) {
|
void set(const ConfigOption &option) {
|
||||||
const ConfigOptionSingle<T>* other = dynamic_cast< const ConfigOptionSingle<T>* >(&option);
|
const ConfigOptionSingle<T>* other = dynamic_cast< const ConfigOptionSingle<T>* >(&option);
|
||||||
if (other != NULL) this->value = other->value;
|
if (other != nullptr) this->value = other->value;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,13 +71,15 @@ public:
|
|||||||
|
|
||||||
void set(const ConfigOption &option) {
|
void set(const ConfigOption &option) {
|
||||||
const ConfigOptionVector<T>* other = dynamic_cast< const ConfigOptionVector<T>* >(&option);
|
const ConfigOptionVector<T>* other = dynamic_cast< const ConfigOptionVector<T>* >(&option);
|
||||||
if (other != NULL) this->values = other->values;
|
if (other != nullptr) this->values = other->values;
|
||||||
};
|
};
|
||||||
|
|
||||||
T get_at(size_t i) const {
|
T& get_at(size_t i) {
|
||||||
assert(! this->values.empty());
|
assert(! this->values.empty());
|
||||||
return (i < this->values.size()) ? this->values[i] : this->values.front();
|
return (i < this->values.size()) ? this->values[i] : this->values.front();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const T& get_at(size_t i) const { return const_cast<ConfigOptionVector<T>*>(this)->get_at(i); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigOptionFloat : public ConfigOptionSingle<double>
|
class ConfigOptionFloat : public ConfigOptionSingle<double>
|
||||||
@ -434,12 +436,25 @@ public:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigOptionBools : public ConfigOptionVector<bool>
|
class ConfigOptionBools : public ConfigOptionVector<unsigned char>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void set(const ConfigOption &option) {
|
||||||
|
const ConfigOptionVector<unsigned char>* other = dynamic_cast<const ConfigOptionVector<unsigned char>*>(&option);
|
||||||
|
if (other != nullptr)
|
||||||
|
this->values = other->values;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool& get_at(size_t i) {
|
||||||
|
assert(! this->values.empty());
|
||||||
|
return *reinterpret_cast<bool*>(&((i < this->values.size()) ? this->values[i] : this->values.front()));
|
||||||
|
};
|
||||||
|
|
||||||
|
bool get_at(size_t i) const { return bool((i < this->values.size()) ? this->values[i] : this->values.front()); }
|
||||||
|
|
||||||
std::string serialize() const {
|
std::string serialize() const {
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
for (std::vector<bool>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
|
for (std::vector<unsigned char>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
|
||||||
if (it - this->values.begin() != 0) ss << ",";
|
if (it - this->values.begin() != 0) ss << ",";
|
||||||
ss << (*it ? "1" : "0");
|
ss << (*it ? "1" : "0");
|
||||||
}
|
}
|
||||||
@ -448,7 +463,7 @@ public:
|
|||||||
|
|
||||||
std::vector<std::string> vserialize() const {
|
std::vector<std::string> vserialize() const {
|
||||||
std::vector<std::string> vv;
|
std::vector<std::string> vv;
|
||||||
for (std::vector<bool>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
|
for (std::vector<unsigned char>::const_iterator it = this->values.begin(); it != this->values.end(); ++it) {
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
ss << (*it ? "1" : "0");
|
ss << (*it ? "1" : "0");
|
||||||
vv.push_back(ss.str());
|
vv.push_back(ss.str());
|
||||||
@ -702,6 +717,16 @@ public:
|
|||||||
t_config_option_keys keys() const;
|
t_config_option_keys keys() const;
|
||||||
void erase(const t_config_option_key &opt_key) { this->options.erase(opt_key); }
|
void erase(const t_config_option_key &opt_key) { this->options.erase(opt_key); }
|
||||||
|
|
||||||
|
std::string& opt_string(const t_config_option_key &opt_key, bool create = false) { return dynamic_cast<ConfigOptionString*>(this->optptr(opt_key, create))->value; }
|
||||||
|
const std::string& opt_string(const t_config_option_key &opt_key) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key); }
|
||||||
|
std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) { return dynamic_cast<ConfigOptionStrings*>(this->optptr(opt_key))->get_at(idx); }
|
||||||
|
const std::string& opt_string(const t_config_option_key &opt_key, unsigned int idx) const { return const_cast<DynamicConfig*>(this)->opt_string(opt_key, idx); }
|
||||||
|
|
||||||
|
double& opt_float(const t_config_option_key &opt_key) { return dynamic_cast<ConfigOptionFloat*>(this->optptr(opt_key))->value; }
|
||||||
|
const double& opt_float(const t_config_option_key &opt_key) const { return const_cast<DynamicConfig*>(this)->opt_float(opt_key); }
|
||||||
|
double& opt_float(const t_config_option_key &opt_key, unsigned int idx) { return dynamic_cast<ConfigOptionFloats*>(this->optptr(opt_key))->get_at(idx); }
|
||||||
|
const double& opt_float(const t_config_option_key &opt_key, unsigned int idx) const { return const_cast<DynamicConfig*>(this)->opt_float(opt_key, idx); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<t_config_option_key,ConfigOption*> t_options_map;
|
typedef std::map<t_config_option_key,ConfigOption*> t_options_map;
|
||||||
t_options_map options;
|
t_options_map options;
|
||||||
|
@ -57,6 +57,9 @@ REGISTER_CLASS(TriangleMesh, "TriangleMesh");
|
|||||||
REGISTER_CLASS(GLShader, "GUI::_3DScene::GLShader");
|
REGISTER_CLASS(GLShader, "GUI::_3DScene::GLShader");
|
||||||
REGISTER_CLASS(GLVolume, "GUI::_3DScene::GLVolume");
|
REGISTER_CLASS(GLVolume, "GUI::_3DScene::GLVolume");
|
||||||
REGISTER_CLASS(GLVolumeCollection, "GUI::_3DScene::GLVolume::Collection");
|
REGISTER_CLASS(GLVolumeCollection, "GUI::_3DScene::GLVolume::Collection");
|
||||||
|
REGISTER_CLASS(Preset, "GUI::Preset");
|
||||||
|
REGISTER_CLASS(PresetCollection, "GUI::PresetCollection");
|
||||||
|
REGISTER_CLASS(PresetBundle, "GUI::PresetBundle");
|
||||||
|
|
||||||
SV*
|
SV*
|
||||||
ConfigBase__as_hash(ConfigBase* THIS) {
|
ConfigBase__as_hash(ConfigBase* THIS) {
|
||||||
@ -138,8 +141,8 @@ ConfigOption_to_SV(const ConfigOption &opt, const ConfigOptionDef &def) {
|
|||||||
const ConfigOptionBools* optv = dynamic_cast<const ConfigOptionBools*>(&opt);
|
const ConfigOptionBools* optv = dynamic_cast<const ConfigOptionBools*>(&opt);
|
||||||
AV* av = newAV();
|
AV* av = newAV();
|
||||||
av_fill(av, optv->values.size()-1);
|
av_fill(av, optv->values.size()-1);
|
||||||
for (std::vector<bool>::const_iterator it = optv->values.begin(); it != optv->values.end(); ++it)
|
for (size_t i = 0; i < optv->values.size(); ++ i)
|
||||||
av_store(av, it - optv->values.begin(), newSViv(*it ? 1 : 0));
|
av_store(av, i, newSViv(optv->values[i] ? 1 : 0));
|
||||||
return newRV_noinc((SV*)av);
|
return newRV_noinc((SV*)av);
|
||||||
} else {
|
} else {
|
||||||
std::string serialized = opt.serialize();
|
std::string serialized = opt.serialize();
|
||||||
|
@ -704,7 +704,7 @@ void _3DScene::_glew_init()
|
|||||||
glewInit();
|
glewInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int hex_digit_to_int(const char c)
|
static inline int hex_digit_to_int(const char c)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
(c >= '0' && c <= '9') ? int(c - '0') :
|
(c >= '0' && c <= '9') ? int(c - '0') :
|
||||||
@ -712,7 +712,7 @@ inline int hex_digit_to_int(const char c)
|
|||||||
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::vector<float> parse_colors(const std::vector<std::string> &scolors)
|
static inline std::vector<float> parse_colors(const std::vector<std::string> &scolors)
|
||||||
{
|
{
|
||||||
std::vector<float> output(scolors.size() * 4, 1.f);
|
std::vector<float> output(scolors.size() * 4, 1.f);
|
||||||
for (size_t i = 0; i < scolors.size(); ++ i) {
|
for (size_t i = 0; i < scolors.size(); ++ i) {
|
||||||
|
323
xs/src/slic3r/GUI/Preset.cpp
Normal file
323
xs/src/slic3r/GUI/Preset.cpp
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
#include "Preset.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
|
#include <wx/image.h>
|
||||||
|
#include <wx/bmpcbox.h>
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Load a config file, return a C++ class Slic3r::DynamicPrintConfig with $keys initialized from the config file.
|
||||||
|
// In case of a "default" config item, return the default values.
|
||||||
|
DynamicPrintConfig& Preset::load(const std::vector<std::string> &keys)
|
||||||
|
{
|
||||||
|
// Set the configuration from the defaults.
|
||||||
|
Slic3r::FullPrintConfig defaults;
|
||||||
|
this->config.apply(defaults, keys.empty() ? defaults.keys() : keys);
|
||||||
|
|
||||||
|
if (! this->is_default) {
|
||||||
|
// Load the preset file, apply preset values on top of defaults.
|
||||||
|
try {
|
||||||
|
if (boost::algorithm::iends_with(this->file, ".gcode") || boost::algorithm::iends_with(this->file, ".g"))
|
||||||
|
this->config.load_from_gcode(this->file);
|
||||||
|
else
|
||||||
|
this->config.load(this->file);
|
||||||
|
} catch (const std::ifstream::failure&) {
|
||||||
|
throw std::runtime_error(std::string("The selected preset does not exist anymore: ") + this->file);
|
||||||
|
} catch (const std::runtime_error&) {
|
||||||
|
throw std::runtime_error(std::string("Failed loading the preset file: ") + this->file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->type == TYPE_PRINTER && std::find(keys.begin(), keys.end(), "nozzle_diameter") != keys.end()) {
|
||||||
|
// Loaded the Printer settings. Verify, that all extruder dependent values have enough values.
|
||||||
|
auto *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(this->config.option("nozzle_diameter"));
|
||||||
|
size_t num_extruders = nozzle_diameter->values.size();
|
||||||
|
auto *deretract_speed = dynamic_cast<ConfigOptionFloats*>(this->config.option("deretract_speed"));
|
||||||
|
deretract_speed->values.resize(num_extruders, deretract_speed->values.empty() ?
|
||||||
|
defaults.deretract_speed.values.front() : deretract_speed->values.front());
|
||||||
|
auto *extruder_colour = dynamic_cast<ConfigOptionStrings*>(this->config.option("extruder_colour"));
|
||||||
|
extruder_colour->values.resize(num_extruders, extruder_colour->values.empty() ?
|
||||||
|
defaults.extruder_colour.values.front() : extruder_colour->values.front());
|
||||||
|
auto *retract_before_wipe = dynamic_cast<ConfigOptionPercents*>(this->config.option("retract_before_wipe"));
|
||||||
|
retract_before_wipe->values.resize(num_extruders, retract_before_wipe->values.empty() ?
|
||||||
|
defaults.retract_before_wipe.values.front() : retract_before_wipe->values.front());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->loaded = true;
|
||||||
|
return this->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Preset::enable_compatible(const std::string &active_printer)
|
||||||
|
{
|
||||||
|
auto *compatible_printers = dynamic_cast<const ConfigOptionStrings*>(this->config.optptr("compatible_printers"));
|
||||||
|
this->is_visible = compatible_printers && ! compatible_printers->values.empty() &&
|
||||||
|
std::find(compatible_printers->values.begin(), compatible_printers->values.end(), active_printer) !=
|
||||||
|
compatible_printers->values.end();
|
||||||
|
return this->is_visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::string> &keys) :
|
||||||
|
m_type(type),
|
||||||
|
m_edited_preset(type, "", false)
|
||||||
|
{
|
||||||
|
// Insert just the default preset.
|
||||||
|
m_presets.emplace_back(Preset(type, "- default -", true));
|
||||||
|
m_presets.front().load(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetCollection::set_default_suppressed(bool default_suppressed)
|
||||||
|
{
|
||||||
|
if (m_default_suppressed != default_suppressed) {
|
||||||
|
m_default_suppressed = default_suppressed;
|
||||||
|
m_presets.front().is_visible = ! default_suppressed || m_presets.size() > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetCollection::enable_disable_compatible_to_printer(const std::string &active_printer)
|
||||||
|
{
|
||||||
|
size_t num_visible = 0;
|
||||||
|
for (size_t idx_preset = 1; idx_preset < m_presets.size(); ++ idx_preset)
|
||||||
|
if (m_presets[idx_preset].enable_compatible(active_printer))
|
||||||
|
++ num_visible;
|
||||||
|
if (num_visible == 0)
|
||||||
|
// Show the "-- default --" preset.
|
||||||
|
m_presets.front().is_visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string g_suffix_modified = " (modified)";
|
||||||
|
|
||||||
|
// Update the wxChoice UI component from this list of presets.
|
||||||
|
// Hide the
|
||||||
|
void PresetCollection::update_editor_ui(wxBitmapComboBox *ui)
|
||||||
|
{
|
||||||
|
if (ui == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t n_visible = this->num_visible();
|
||||||
|
size_t n_choice = size_t(ui->GetCount());
|
||||||
|
std::string name_selected = ui->GetStringSelection().ToUTF8();
|
||||||
|
if (boost::algorithm::iends_with(name_selected, g_suffix_modified))
|
||||||
|
// Remove the g_suffix_modified.
|
||||||
|
name_selected.erase(name_selected.end() - g_suffix_modified.size(), name_selected.end());
|
||||||
|
#if 0
|
||||||
|
if (std::abs(int(n_visible) - int(n_choice)) <= 1) {
|
||||||
|
// The number of items differs by at most one, update the choice.
|
||||||
|
size_t i_preset = 0;
|
||||||
|
size_t i_ui = 0;
|
||||||
|
while (i_preset < presets.size()) {
|
||||||
|
std::string name_ui = ui->GetString(i_ui).ToUTF8();
|
||||||
|
if (boost::algorithm::iends_with(name_ui, g_suffix_modified))
|
||||||
|
// Remove the g_suffix_modified.
|
||||||
|
name_ui.erase(name_ui.end() - g_suffix_modified.size(), name_ui.end());
|
||||||
|
while (this->presets[i_preset].name )
|
||||||
|
const Preset &preset = this->presets[i_preset];
|
||||||
|
if (preset)
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
// Otherwise fill in the list from scratch.
|
||||||
|
ui->Clear();
|
||||||
|
for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++ i) {
|
||||||
|
const Preset &preset = this->m_presets[i];
|
||||||
|
const wxBitmap *bmp = (i == 0 || preset.is_visible) ? m_bitmap_compatible : m_bitmap_incompatible;
|
||||||
|
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), (bmp == 0) ? wxNullBitmap : *bmp, (void*)i);
|
||||||
|
if (name_selected == preset.name)
|
||||||
|
ui->SetSelection(ui->GetCount() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PresetCollection::update_platter_ui(wxBitmapComboBox *ui)
|
||||||
|
{
|
||||||
|
if (ui == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size_t n_visible = this->num_visible();
|
||||||
|
size_t n_choice = size_t(ui->GetCount());
|
||||||
|
if (std::abs(int(n_visible) - int(n_choice)) <= 1) {
|
||||||
|
// The number of items differs by at most one, update the choice.
|
||||||
|
} else {
|
||||||
|
// Otherwise fill in the list from scratch.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PresetBundle::PresetBundle() :
|
||||||
|
prints(Preset::TYPE_PRINT, print_options()),
|
||||||
|
filaments(Preset::TYPE_FILAMENT, filament_options()),
|
||||||
|
printers(Preset::TYPE_PRINTER, printer_options()),
|
||||||
|
m_bitmapCompatible(new wxBitmap),
|
||||||
|
m_bitmapIncompatible(new wxBitmap)
|
||||||
|
{
|
||||||
|
// Create the ID config keys, as they are not part of the Static print config classes.
|
||||||
|
this->prints.preset(0).config.opt_string("print_settings_id", true);
|
||||||
|
this->filaments.preset(0).config.opt_string("filament_settings_id", true);
|
||||||
|
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->prints.preset(0).config.optptr("compatible_printers", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PresetBundle::~PresetBundle()
|
||||||
|
{
|
||||||
|
delete m_bitmapCompatible;
|
||||||
|
delete m_bitmapIncompatible;
|
||||||
|
for (std::pair<const std::string, wxBitmap*> &bitmap : m_mapColorToBitmap)
|
||||||
|
delete bitmap.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PresetBundle::load_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible)
|
||||||
|
{
|
||||||
|
bool loaded_compatible = m_bitmapCompatible ->LoadFile(wxString::FromUTF8(path_bitmap_compatible.c_str()));
|
||||||
|
bool loaded_incompatible = m_bitmapIncompatible->LoadFile(wxString::FromUTF8(path_bitmap_incompatible.c_str()));
|
||||||
|
if (loaded_compatible) {
|
||||||
|
prints .set_bitmap_compatible(m_bitmapCompatible);
|
||||||
|
filaments.set_bitmap_compatible(m_bitmapCompatible);
|
||||||
|
printers .set_bitmap_compatible(m_bitmapCompatible);
|
||||||
|
}
|
||||||
|
if (loaded_incompatible) {
|
||||||
|
prints .set_bitmap_compatible(m_bitmapIncompatible);
|
||||||
|
filaments.set_bitmap_compatible(m_bitmapIncompatible);
|
||||||
|
printers .set_bitmap_compatible(m_bitmapIncompatible);
|
||||||
|
}
|
||||||
|
return loaded_compatible && loaded_incompatible;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int hex_digit_to_int(const char c)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(c >= '0' && c <= '9') ? int(c - '0') :
|
||||||
|
(c >= 'A' && c <= 'F') ? int(c - 'A') + 10 :
|
||||||
|
(c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool parse_color(const std::string &scolor, unsigned char *rgb_out)
|
||||||
|
{
|
||||||
|
rgb_out[0] = rgb_out[1] = rgb_out[2] = 0;
|
||||||
|
const char *c = scolor.data() + 1;
|
||||||
|
if (scolor.size() != 7 || scolor.front() != '#')
|
||||||
|
return false;
|
||||||
|
for (size_t i = 0; i < 3; ++ i) {
|
||||||
|
int digit1 = hex_digit_to_int(*c ++);
|
||||||
|
int digit2 = hex_digit_to_int(*c ++);
|
||||||
|
if (digit1 == -1 || digit2 == -1)
|
||||||
|
return false;
|
||||||
|
rgb_out[i] = (unsigned char)(digit1 * 16 + digit2);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the colors preview at the platter extruder combo box.
|
||||||
|
void PresetBundle::update_platter_filament_ui_colors(wxBitmapComboBox *ui, unsigned int idx_extruder, unsigned int idx_filament)
|
||||||
|
{
|
||||||
|
unsigned char rgb[3];
|
||||||
|
std::string extruder_color = this->printers.get_edited_preset().config.opt_string("extruder_colour", idx_extruder);
|
||||||
|
if (! parse_color(extruder_color, rgb))
|
||||||
|
// Extruder color is not defined.
|
||||||
|
extruder_color.clear();
|
||||||
|
|
||||||
|
for (unsigned int ui_id = 0; ui_id < ui->GetCount(); ++ ui_id) {
|
||||||
|
if (! ui->HasClientUntypedData())
|
||||||
|
continue;
|
||||||
|
size_t filament_preset_id = size_t(ui->GetClientData(ui_id));
|
||||||
|
const Preset &filament_preset = filaments.preset(filament_preset_id);
|
||||||
|
// Assign an extruder color to the selected item if the extruder color is defined.
|
||||||
|
std::string filament_rgb = filament_preset.config.opt_string("filament_colour", 0);
|
||||||
|
std::string extruder_rgb = (int(ui_id) == ui->GetSelection() && ! extruder_color.empty()) ? extruder_color : filament_rgb;
|
||||||
|
wxBitmap *bitmap = nullptr;
|
||||||
|
if (filament_rgb == extruder_rgb) {
|
||||||
|
auto it = m_mapColorToBitmap.find(filament_rgb);
|
||||||
|
if (it == m_mapColorToBitmap.end()) {
|
||||||
|
// Create the bitmap.
|
||||||
|
parse_color(filament_rgb, rgb);
|
||||||
|
wxImage image(24, 16);
|
||||||
|
image.SetRGB(wxRect(0, 0, 24, 16), rgb[0], rgb[1], rgb[2]);
|
||||||
|
m_mapColorToBitmap[filament_rgb] = new wxBitmap(image);
|
||||||
|
} else {
|
||||||
|
bitmap = it->second;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::string bitmap_key = filament_rgb + extruder_rgb;
|
||||||
|
auto it = m_mapColorToBitmap.find(bitmap_key);
|
||||||
|
if (it == m_mapColorToBitmap.end()) {
|
||||||
|
// Create the bitmap.
|
||||||
|
wxImage image(24, 16);
|
||||||
|
parse_color(extruder_rgb, rgb);
|
||||||
|
image.SetRGB(wxRect(0, 0, 16, 16), rgb[0], rgb[1], rgb[2]);
|
||||||
|
parse_color(filament_rgb, rgb);
|
||||||
|
image.SetRGB(wxRect(16, 0, 8, 16), rgb[0], rgb[1], rgb[2]);
|
||||||
|
m_mapColorToBitmap[filament_rgb] = new wxBitmap(image);
|
||||||
|
} else {
|
||||||
|
bitmap = it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->SetItemBitmap(ui_id, *bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& PresetBundle::print_options()
|
||||||
|
{
|
||||||
|
const char *opts[] = {
|
||||||
|
"layer_height", "first_layer_height", "perimeters", "spiral_vase", "top_solid_layers", "bottom_solid_layers",
|
||||||
|
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||||
|
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "external_fill_pattern",
|
||||||
|
"infill_every_layers", "infill_only_where_needed", "solid_infill_every_layers", "fill_angle", "bridge_angle",
|
||||||
|
"solid_infill_below_area", "only_retract_when_crossing_perimeters", "infill_first", "max_print_speed",
|
||||||
|
"max_volumetric_speed", "max_volumetric_extrusion_rate_slope_positive", "max_volumetric_extrusion_rate_slope_negative",
|
||||||
|
"perimeter_speed", "small_perimeter_speed", "external_perimeter_speed", "infill_speed", "solid_infill_speed",
|
||||||
|
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
|
||||||
|
"bridge_speed", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
|
||||||
|
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
|
||||||
|
"min_skirt_length", "brim_width", "support_material", "support_material_threshold", "support_material_enforce_layers",
|
||||||
|
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||||
|
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
|
||||||
|
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
|
||||||
|
"support_material_buildplate_only", "dont_support_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||||
|
"extruder_clearance_height", "gcode_comments", "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", "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"
|
||||||
|
};
|
||||||
|
static std::vector<std::string> s_opts;
|
||||||
|
if (s_opts.empty())
|
||||||
|
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
|
||||||
|
return s_opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& PresetBundle::filament_options()
|
||||||
|
{
|
||||||
|
const char *opts[] = {
|
||||||
|
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
|
||||||
|
"extrusion_multiplier", "filament_density", "filament_cost", "temperature", "first_layer_temperature", "bed_temperature",
|
||||||
|
"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"
|
||||||
|
};
|
||||||
|
static std::vector<std::string> s_opts;
|
||||||
|
if (s_opts.empty())
|
||||||
|
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
|
||||||
|
return s_opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string>& PresetBundle::printer_options()
|
||||||
|
{
|
||||||
|
const char *opts[] = {
|
||||||
|
"bed_shape", "z_offset", "gcode_flavor", "use_relative_e_distances", "serial_port", "serial_speed",
|
||||||
|
"octoprint_host", "octoprint_apikey", "use_firmware_retraction", "use_volumetric_e", "variable_layer_height",
|
||||||
|
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
|
||||||
|
"nozzle_diameter", "extruder_offset", "retract_length", "retract_lift", "retract_speed", "deretract_speed",
|
||||||
|
"retract_before_wipe", "retract_restart_extra", "retract_before_travel", "retract_layer_change", "wipe",
|
||||||
|
"retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", "printer_notes"
|
||||||
|
};
|
||||||
|
static std::vector<std::string> s_opts;
|
||||||
|
if (s_opts.empty())
|
||||||
|
s_opts.assign(opts, opts + (sizeof(opts) / sizeof(opts[0])));
|
||||||
|
return s_opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
146
xs/src/slic3r/GUI/Preset.hpp
Normal file
146
xs/src/slic3r/GUI/Preset.hpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#ifndef slic3r_Preset_hpp_
|
||||||
|
#define slic3r_Preset_hpp_
|
||||||
|
|
||||||
|
#include "../../libslic3r/libslic3r.h"
|
||||||
|
#include "../../libslic3r/PrintConfig.hpp"
|
||||||
|
|
||||||
|
class wxBitmap;
|
||||||
|
class wxBitmapComboBox;
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
class Preset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
TYPE_INVALID,
|
||||||
|
TYPE_PRINT,
|
||||||
|
TYPE_FILAMENT,
|
||||||
|
TYPE_PRINTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
Preset(Type type, const std::string &name, bool is_default = false) : type(type), name(name), is_default(is_default) {}
|
||||||
|
|
||||||
|
Type type = TYPE_INVALID;
|
||||||
|
|
||||||
|
// The preset represents a "default" set of properties,
|
||||||
|
// pulled from the default values of the PrintConfig (see PrintConfigDef for their definitions).
|
||||||
|
bool is_default;
|
||||||
|
// External preset points to a configuration, which has been loaded but not imported
|
||||||
|
// into the Slic3r default configuration location.
|
||||||
|
bool is_external = false;
|
||||||
|
// Preset is visible, if it is compatible with the active Printer.
|
||||||
|
// Also the "default" preset is only visible, if it is the only preset in the list.
|
||||||
|
bool is_visible = true;
|
||||||
|
// Has this preset been modified?
|
||||||
|
bool is_dirty = false;
|
||||||
|
|
||||||
|
// Name of the preset, usually derived form the file name.
|
||||||
|
std::string name;
|
||||||
|
// File name of the preset. This could be a Print / Filament / Printer preset,
|
||||||
|
// or a Configuration file bundling the Print + Filament + Printer presets (in that case is_external will be true),
|
||||||
|
// or it could be a G-code (again, is_external will be true).
|
||||||
|
std::string file;
|
||||||
|
|
||||||
|
// Has this profile been loaded?
|
||||||
|
bool loaded = false;
|
||||||
|
|
||||||
|
// Configuration data, loaded from a file, or set from the defaults.
|
||||||
|
DynamicPrintConfig config;
|
||||||
|
|
||||||
|
// Load this profile for the following keys only.
|
||||||
|
// Throws std::runtime_error in case the file cannot be read.
|
||||||
|
DynamicPrintConfig& load(const std::vector<std::string> &keys);
|
||||||
|
|
||||||
|
// Set the is_dirty flag if the provided config is different from the active one.
|
||||||
|
bool set_dirty(const DynamicPrintConfig &config) { this->is_dirty = ! this->config.diff(config).empty(); }
|
||||||
|
void reset_dirty() { this->is_dirty = false; }
|
||||||
|
bool enable_compatible(const std::string &active_printer);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Collections of presets of the same type (one of the Print, Filament or Printer type).
|
||||||
|
class PresetCollection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Initialize the PresetCollection with the "- default -" preset.
|
||||||
|
PresetCollection(Preset::Type type, const std::vector<std::string> &keys);
|
||||||
|
|
||||||
|
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items.
|
||||||
|
void set_bitmap_compatible (const wxBitmap *bmp) { m_bitmap_compatible = bmp; }
|
||||||
|
void set_bitmap_incompatible(const wxBitmap *bmp) { m_bitmap_incompatible = bmp; }
|
||||||
|
|
||||||
|
// Enable / disable the "- default -" preset.
|
||||||
|
void set_default_suppressed(bool default_suppressed);
|
||||||
|
bool is_default_suppressed() const { return m_default_suppressed; }
|
||||||
|
|
||||||
|
// Select a preset. If an invalid index is provided, the first visible preset is selected.
|
||||||
|
Preset& select_preset(size_t idx);
|
||||||
|
// Return the selected preset, without the user modifications applied.
|
||||||
|
Preset& get_selected_preset() { return m_presets[m_idx_selected]; }
|
||||||
|
const Preset& get_selected_preset() const { return m_presets[m_idx_selected]; }
|
||||||
|
// Return the selected preset including the user modifications.
|
||||||
|
Preset& get_edited_preset() { return m_edited_preset; }
|
||||||
|
const Preset& get_edited_preset() const { return m_edited_preset; }
|
||||||
|
// Return a preset possibly with modifications.
|
||||||
|
Preset& preset(size_t idx) { return (int(idx) == m_idx_selected) ? m_edited_preset : m_presets[idx]; }
|
||||||
|
const Preset& preset(size_t idx) const { return const_cast<PresetCollection*>(this)->preset(idx); }
|
||||||
|
size_t size() const { return this->m_presets.size(); }
|
||||||
|
|
||||||
|
// For Print / Filament presets, disable those, which are not compatible with the printer.
|
||||||
|
void enable_disable_compatible_to_printer(const std::string &active_printer);
|
||||||
|
|
||||||
|
size_t num_visible() const { return std::count_if(m_presets.begin(), m_presets.end(), [](const Preset &preset){return preset.is_visible;}); }
|
||||||
|
void delete_preset(const size_t idx);
|
||||||
|
|
||||||
|
// Update the choice UI from the list of presets.
|
||||||
|
void update_editor_ui(wxBitmapComboBox *ui);
|
||||||
|
void update_platter_ui(wxBitmapComboBox *ui);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER.
|
||||||
|
Preset::Type m_type;
|
||||||
|
// List of presets, starting with the "- default -" preset.
|
||||||
|
std::vector<Preset> m_presets;
|
||||||
|
Preset m_edited_preset;
|
||||||
|
// Selected preset.
|
||||||
|
int m_idx_selected;
|
||||||
|
// Is the "- default -" preset suppressed?
|
||||||
|
bool m_default_suppressed = true;
|
||||||
|
// Compatible & incompatible marks, to be placed at the wxBitmapComboBox items.
|
||||||
|
const wxBitmap *m_bitmap_compatible = nullptr;
|
||||||
|
const wxBitmap *m_bitmap_incompatible = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Bundle of Print + Filament + Printer presets.
|
||||||
|
class PresetBundle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PresetBundle();
|
||||||
|
~PresetBundle();
|
||||||
|
|
||||||
|
bool load_bitmaps(const std::string &path_bitmap_compatible, const std::string &path_bitmap_incompatible);
|
||||||
|
|
||||||
|
PresetCollection prints;
|
||||||
|
PresetCollection filaments;
|
||||||
|
PresetCollection printers;
|
||||||
|
|
||||||
|
// Update the colors preview at the platter extruder combo box.
|
||||||
|
void update_platter_filament_ui_colors(wxBitmapComboBox *ui, unsigned int idx_extruder, unsigned int idx_filament);
|
||||||
|
|
||||||
|
static const std::vector<std::string>& print_options();
|
||||||
|
static const std::vector<std::string>& filament_options();
|
||||||
|
static const std::vector<std::string>& printer_options();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Indicator, that the preset is compatible with the selected printer.
|
||||||
|
wxBitmap *m_bitmapCompatible;
|
||||||
|
// Indicator, that the preset is NOT compatible with the selected printer.
|
||||||
|
wxBitmap *m_bitmapIncompatible;
|
||||||
|
// Caching color bitmaps for the
|
||||||
|
std::map<std::string, wxBitmap*> m_mapColorToBitmap;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif /* slic3r_Preset_hpp_ */
|
56
xs/xsp/GUI_Preset.xsp
Normal file
56
xs/xsp/GUI_Preset.xsp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
%module{Slic3r::XS};
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include <xsinit.h>
|
||||||
|
#include "slic3r/GUI/Preset.hpp"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%name{Slic3r::GUI::Preset} class Preset {
|
||||||
|
// owned by PresetCollection, no constructor/destructor
|
||||||
|
|
||||||
|
bool is_default() %code%{ RETVAL = THIS->is_default; %};
|
||||||
|
bool is_external() %code%{ RETVAL = THIS->is_external; %};
|
||||||
|
bool is_visible() %code%{ RETVAL = THIS->is_visible; %};
|
||||||
|
bool is_dirty() %code%{ RETVAL = THIS->is_dirty; %};
|
||||||
|
|
||||||
|
const char* name() %code%{ RETVAL = THIS->name.c_str(); %};
|
||||||
|
const char* file() %code%{ RETVAL = THIS->file.c_str(); %};
|
||||||
|
|
||||||
|
bool loaded() %code%{ RETVAL = THIS->loaded; %};
|
||||||
|
|
||||||
|
Ref<DynamicPrintConfig> config() %code%{ RETVAL = &THIS->config; %};
|
||||||
|
};
|
||||||
|
|
||||||
|
%name{Slic3r::GUI::PresetCollection} class PresetCollection {
|
||||||
|
|
||||||
|
Ref<Preset> preset(size_t idx) %code%{ RETVAL = &THIS->preset(idx); %};
|
||||||
|
size_t size() const;
|
||||||
|
size_t num_visible() const;
|
||||||
|
%{
|
||||||
|
|
||||||
|
SV*
|
||||||
|
PresetCollection::arrayref()
|
||||||
|
CODE:
|
||||||
|
AV* av = newAV();
|
||||||
|
av_fill(av, THIS->size()-1);
|
||||||
|
int i = 0;
|
||||||
|
for (size_t i = 0; i < THIS->size(); ++ i) {
|
||||||
|
Preset &preset = THIS->preset(i);
|
||||||
|
av_store(av, i++, perl_to_SV_ref(preset));
|
||||||
|
}
|
||||||
|
RETVAL = newRV_noinc((SV*)av);
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
%name{Slic3r::GUI::PresetBundle} class PresetBundle {
|
||||||
|
PresetBundle();
|
||||||
|
~PresetBundle();
|
||||||
|
|
||||||
|
Ref<PresetCollection> prints() %code%{ RETVAL = &THIS->prints; %};
|
||||||
|
Ref<PresetCollection> filaments() %code%{ RETVAL = &THIS->filaments; %};
|
||||||
|
Ref<PresetCollection> printers() %code%{ RETVAL = &THIS->printers; %};
|
||||||
|
};
|
@ -216,6 +216,13 @@ Ref<GLVolume> O_OBJECT_SLIC3R_T
|
|||||||
GLVolumeCollection* O_OBJECT_SLIC3R
|
GLVolumeCollection* O_OBJECT_SLIC3R
|
||||||
Ref<GLVolumeCollection> O_OBJECT_SLIC3R_T
|
Ref<GLVolumeCollection> O_OBJECT_SLIC3R_T
|
||||||
|
|
||||||
|
Preset* O_OBJECT_SLIC3R
|
||||||
|
Ref<Preset> O_OBJECT_SLIC3R_T
|
||||||
|
PresetCollection* O_OBJECT_SLIC3R
|
||||||
|
Ref<PresetCollection> O_OBJECT_SLIC3R_T
|
||||||
|
PresetBundle* O_OBJECT_SLIC3R
|
||||||
|
Ref<PresetBundle> O_OBJECT_SLIC3R_T
|
||||||
|
|
||||||
Axis T_UV
|
Axis T_UV
|
||||||
ExtrusionLoopRole T_UV
|
ExtrusionLoopRole T_UV
|
||||||
ExtrusionRole T_UV
|
ExtrusionRole T_UV
|
||||||
|
@ -196,6 +196,12 @@
|
|||||||
%typemap{Ref<GLVolume>}{simple};
|
%typemap{Ref<GLVolume>}{simple};
|
||||||
%typemap{GLVolumeCollection*};
|
%typemap{GLVolumeCollection*};
|
||||||
%typemap{Ref<GLVolumeCollection>}{simple};
|
%typemap{Ref<GLVolumeCollection>}{simple};
|
||||||
|
%typemap{Preset*};
|
||||||
|
%typemap{Ref<Preset>}{simple};
|
||||||
|
%typemap{PresetCollection*};
|
||||||
|
%typemap{Ref<PresetCollection>}{simple};
|
||||||
|
%typemap{PresetBundle*};
|
||||||
|
%typemap{Ref<PresetBundle>}{simple};
|
||||||
|
|
||||||
%typemap{PrintRegionPtrs*};
|
%typemap{PrintRegionPtrs*};
|
||||||
%typemap{PrintObjectPtrs*};
|
%typemap{PrintObjectPtrs*};
|
||||||
|
Loading…
Reference in New Issue
Block a user