mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-01-31 16:08:43 +03:00
PRUSA 2.7.0
This commit is contained in:
@@ -36,6 +36,9 @@
|
||||
#include "libslic3r.h"
|
||||
#include "Utils.hpp"
|
||||
#include "PlaceholderParser.hpp"
|
||||
#include "GCode/Thumbnails.hpp"
|
||||
|
||||
#include "PresetBundle.hpp"
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
@@ -186,29 +189,6 @@ VendorProfile VendorProfile::from_ini(const ptree &tree, const boost::filesystem
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Malformed variants field: `%2%`") % id % variants_field;
|
||||
}
|
||||
//B19
|
||||
section.second.get<std::string>("email", "");
|
||||
const auto emails_field = section.second.get<std::string>("email", "");
|
||||
std::vector<std::string> emails;
|
||||
if (Slic3r::unescape_strings_cstyle(emails_field, emails)) {
|
||||
for (const std::string &email_name : emails) {
|
||||
if (model.email(email_name) == nullptr)
|
||||
model.emails.emplace_back(VendorProfile::PrinterEmail(email_name));
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Malformed variants field: `%2%`") % id % emails_field;
|
||||
}
|
||||
section.second.get<std::string>("skype", "");
|
||||
const auto skypes_field = section.second.get<std::string>("skype", "");
|
||||
std::vector<std::string> skypes;
|
||||
if (Slic3r::unescape_strings_cstyle(skypes_field, skypes)) {
|
||||
for (const std::string &skype_name : skypes) {
|
||||
if (model.skype(skype_name) == nullptr)
|
||||
model.skypes.emplace_back(VendorProfile::PrinterSkype(skype_name));
|
||||
}
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(error) << boost::format("Vendor bundle: `%1%`: Malformed skypes field: `%2%`") % id % skypes_field;
|
||||
}
|
||||
auto default_materials_field = section.second.get<std::string>("default_materials", "");
|
||||
if (default_materials_field.empty())
|
||||
default_materials_field = section.second.get<std::string>("default_filaments", "");
|
||||
@@ -474,13 +454,15 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"support_tree_angle", "support_tree_angle_slow", "support_tree_branch_diameter", "support_tree_branch_diameter_angle", "support_tree_branch_diameter_double_wall",
|
||||
"support_tree_top_rate", "support_tree_branch_distance", "support_tree_tip_diameter",
|
||||
"dont_support_bridges", "thick_bridges", "notes", "complete_objects", "extruder_clearance_radius",
|
||||
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "perimeter_extruder",
|
||||
"extruder_clearance_height", "gcode_comments", "gcode_label_objects", "output_filename_format", "post_process", "gcode_substitutions", "gcode_binary","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", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "resolution", "gcode_resolution", "arc_fitting",
|
||||
"wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
//w12
|
||||
"elefant_foot_compensation", "xy_size_compensation", "xy_contour_compensation", "xy_hole_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "xy_contour_compensation", "xy_hole_compensation", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_cone_angle", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
||||
"mmu_segmented_region_interlocking_depth", "wipe_tower_extruder", "wipe_tower_no_sparse_layers", "wipe_tower_extra_spacing", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"perimeter_generator", "wall_transition_length", "wall_transition_filter_deviation", "wall_transition_angle",
|
||||
@@ -505,7 +487,8 @@ static std::vector<std::string> s_Preset_filament_options {
|
||||
"overhang_fan_speed_0", "overhang_fan_speed_1", "overhang_fan_speed_2", "overhang_fan_speed_3",
|
||||
// Retract overrides
|
||||
"filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
|
||||
"filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe", "filament_retract_length_toolchange", "filament_retract_restart_extra_toolchange",
|
||||
"filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe", "filament_retract_length_toolchange", "filament_retract_restart_extra_toolchange", "filament_travel_ramping_lift",
|
||||
"filament_travel_slope", "filament_travel_max_lift", "filament_travel_lift_before_obstacle",
|
||||
// Profile compatibility
|
||||
"filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits",
|
||||
//B15
|
||||
@@ -545,8 +528,6 @@ static std::vector<std::string> s_Preset_printer_options {
|
||||
"default_print_profile", "inherits",
|
||||
"remaining_times", "silent_mode",
|
||||
"machine_limits_usage", "thumbnails", "thumbnails_format",
|
||||
//Y18
|
||||
"bed_exclude_area",
|
||||
//Y16
|
||||
"chamber_temperature", "auxiliary_fan", "chamber_fan"
|
||||
};
|
||||
@@ -805,7 +786,7 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const D
|
||||
// when comparing profiles for equality. Ignore them.
|
||||
for (const char *key : { "compatible_prints", "compatible_prints_condition",
|
||||
"compatible_printers", "compatible_printers_condition", "inherits",
|
||||
"print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id",
|
||||
"print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id", "filament_vendor",
|
||||
"printer_model", "printer_variant", "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile",
|
||||
//FIXME remove the print host keys?
|
||||
"print_host", "printhost_apikey", "printhost_cafile" })
|
||||
@@ -818,7 +799,7 @@ static bool profile_print_params_same(const DynamicPrintConfig &cfg_old, const D
|
||||
// and select it, losing previous modifications.
|
||||
// Only a single profile could be edited at at the same time, which introduces complexity when loading
|
||||
// filament profiles for multi-extruder printers.
|
||||
std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
ExternalPreset PresetCollection::load_external_preset(
|
||||
// Path to the profile source file (a G-code, an AMF or 3MF file, a config file)
|
||||
const std::string &path,
|
||||
// Name of the profile, derived from the source file name.
|
||||
@@ -841,7 +822,7 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
const Preset &edited = this->get_edited_preset();
|
||||
if ((edited.name == original_name || edited.name == inherits) && profile_print_params_same(edited.config, cfg))
|
||||
// Just point to that already selected and edited profile.
|
||||
return std::make_pair(&(*this->find_preset_internal(edited.name)), false);
|
||||
return ExternalPreset(&(*this->find_preset_internal(edited.name)), false);
|
||||
}
|
||||
// Is there a preset already loaded with the name stored inside the config?
|
||||
std::deque<Preset>::iterator it = this->find_preset_internal(original_name);
|
||||
@@ -851,11 +832,11 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
it = this->find_preset_renamed(original_name);
|
||||
found = it != m_presets.end();
|
||||
}
|
||||
if (found && profile_print_params_same(it->config, cfg)) {
|
||||
// The preset exists and it matches the values stored inside config.
|
||||
if (found && profile_print_params_same(it->config, cfg) && it->is_visible) {
|
||||
// The preset exists and is visible and it matches the values stored inside config.
|
||||
if (select == LoadAndSelect::Always)
|
||||
this->select_preset(it - m_presets.begin());
|
||||
return std::make_pair(&(*it), false);
|
||||
return ExternalPreset(&(*it), false);
|
||||
}
|
||||
if (! found && select != LoadAndSelect::Never && ! inherits.empty()) {
|
||||
// Try to use a system profile as a base to select the system profile
|
||||
@@ -867,19 +848,25 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
// The system preset exists and it matches the values stored inside config.
|
||||
if (select == LoadAndSelect::Always)
|
||||
this->select_preset(it - m_presets.begin());
|
||||
return std::make_pair(&(*it), false);
|
||||
return ExternalPreset(&(*it), false);
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
if (select != LoadAndSelect::Never) {
|
||||
const size_t idx = it - m_presets.begin();
|
||||
// The newly selected preset can be activated AND have to be make as visible.
|
||||
bool is_installed = !m_presets[idx].is_visible;
|
||||
// Select the existing preset and override it with new values, so that
|
||||
// the differences will be shown in the preset editor against the referenced profile.
|
||||
this->select_preset(it - m_presets.begin());
|
||||
this->select_preset(idx);
|
||||
|
||||
// update dirty state only if it's needed
|
||||
if (!profile_print_params_same(it->config, cfg)) {
|
||||
// The source config may contain keys from many possible preset types. Just copy those that relate to this preset.
|
||||
|
||||
// Following keys are not used neither by the UI nor by the slicing core, therefore they are not important
|
||||
// Erase them from config appl to avoid redundant "dirty" parameter in loaded preset.
|
||||
for (const char* key : { "print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id",
|
||||
// Erase them from config apply to avoid redundant "dirty" parameter in loaded preset.
|
||||
for (const char* key : { "print_settings_id", "filament_settings_id", "sla_print_settings_id", "sla_material_settings_id", "printer_settings_id", "filament_vendor",
|
||||
"printer_model", "printer_variant", "default_print_profile", "default_filament_profile", "default_sla_print_profile", "default_sla_material_profile" })
|
||||
keys.erase(std::remove(keys.begin(), keys.end(), key), keys.end());
|
||||
|
||||
@@ -888,7 +875,8 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
// Don't save the newly loaded project as a "saved into project" state.
|
||||
//update_saved_preset_from_current_preset();
|
||||
assert(this->get_edited_preset().is_dirty);
|
||||
return std::make_pair(&(*it), this->get_edited_preset().is_dirty);
|
||||
}
|
||||
return ExternalPreset(&(*it), this->get_edited_preset().is_dirty, is_installed);
|
||||
}
|
||||
if (inherits.empty()) {
|
||||
// Update the "inherits" field.
|
||||
@@ -919,7 +907,7 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
// The preset exists and it matches the values stored inside config.
|
||||
if (select == LoadAndSelect::Always)
|
||||
this->select_preset(it - m_presets.begin());
|
||||
return std::make_pair(&(*it), false);
|
||||
return ExternalPreset(&(*it), false);
|
||||
}
|
||||
// Form another profile name.
|
||||
}
|
||||
@@ -929,7 +917,7 @@ std::pair<Preset*, bool> PresetCollection::load_external_preset(
|
||||
if (this->m_idx_selected != size_t(-1) && &this->get_selected_preset() == &preset)
|
||||
this->get_edited_preset().is_external = true;
|
||||
|
||||
return std::make_pair(&preset, false);
|
||||
return ExternalPreset(&preset, false);
|
||||
}
|
||||
|
||||
Preset& PresetCollection::load_preset(const std::string &path, const std::string &name, DynamicPrintConfig &&config, bool select)
|
||||
@@ -1350,9 +1338,6 @@ static const std::set<std::string> independent_from_extruder_number_options = {
|
||||
"filament_ramming_parameters",
|
||||
"gcode_substitutions",
|
||||
"post_process",
|
||||
"thumbnails",
|
||||
//Y18
|
||||
"bed_exclude_area",
|
||||
};
|
||||
|
||||
bool PresetCollection::is_independent_from_extruder_number_option(const std::string& opt_key)
|
||||
@@ -1376,6 +1361,15 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
|
||||
} else if (opt_key == "default_filament_profile") {
|
||||
// Ignore this field, it is not presented to the user, therefore showing a "modified" flag for this parameter does not help.
|
||||
// Also the length of this field may differ, which may lead to a crash if the block below is used.
|
||||
} else if (opt_key == "thumbnails") {
|
||||
// "thumbnails" can not contain extensions in old config but they are valid and use PNG extension by default
|
||||
// So, check if "thumbnails" is really changed
|
||||
// We will compare full thumbnails instead of exactly config values
|
||||
auto [thumbnails, er] = GCodeThumbnails::make_and_check_thumbnail_list(config_this);
|
||||
auto [thumbnails_new, er_new] = GCodeThumbnails::make_and_check_thumbnail_list(config_other);
|
||||
if (thumbnails != thumbnails_new || er != er_new)
|
||||
// if those strings are actually the same, erase them from the list of dirty oprions
|
||||
diff.emplace_back(opt_key);
|
||||
} else {
|
||||
switch (other_opt->type()) {
|
||||
case coInts: add_correct_opts_to_diff<ConfigOptionInts >(opt_key, diff, config_other, config_this); break;
|
||||
@@ -1387,6 +1381,12 @@ inline t_config_option_keys deep_diff(const ConfigBase &config_this, const Confi
|
||||
case coFloatsOrPercents: add_correct_opts_to_diff<ConfigOptionFloatsOrPercents >(opt_key, diff, config_other, config_this); break;
|
||||
default: diff.emplace_back(opt_key); break;
|
||||
}
|
||||
// "nozzle_diameter" is a vector option which contain info about diameter for each nozzle
|
||||
// But in the same time size of this vector indicates about count of extruders,
|
||||
// So, we need to add it to the diff if its size is changed.
|
||||
if (opt_key == "nozzle_diameter" &&
|
||||
static_cast<const ConfigOptionFloats*>(this_opt)->size() != static_cast<const ConfigOptionFloats*>(other_opt)->size())
|
||||
diff.emplace_back(opt_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1399,7 +1399,14 @@ bool PresetCollection::is_dirty(const Preset *edited, const Preset *reference)
|
||||
{
|
||||
if (edited != nullptr && reference != nullptr) {
|
||||
// Only compares options existing in both configs.
|
||||
if (! reference->config.equals(edited->config))
|
||||
bool is_dirty = !reference->config.equals(edited->config);
|
||||
if (is_dirty && edited->type != Preset::TYPE_FILAMENT) {
|
||||
// for non-filaments preset check deep difference for compared configs
|
||||
// there can be cases (as for thumbnails), when configs can logically equal
|
||||
// even when their values are not equal.
|
||||
is_dirty = !deep_diff(edited->config, reference->config).empty();
|
||||
}
|
||||
if (is_dirty)
|
||||
return true;
|
||||
// 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.
|
||||
@@ -1810,7 +1817,8 @@ std::string PhysicalPrinter::get_preset_name(std::string name)
|
||||
// *** PhysicalPrinterCollection ***
|
||||
// -----------------------------------
|
||||
|
||||
PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector<std::string>& keys)
|
||||
PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector<std::string>& keys, PresetBundle* preset_bundle)
|
||||
:m_preset_bundle_owner(preset_bundle)
|
||||
{
|
||||
// Default config for a physical printer containing all key/value pairs of PhysicalPrinter::printer_options().
|
||||
for (const std::string &key : keys) {
|
||||
@@ -1821,6 +1829,27 @@ PhysicalPrinterCollection::PhysicalPrinterCollection( const std::vector<std::str
|
||||
}
|
||||
}
|
||||
|
||||
static void update_preset_names_if_were_renamed(std::set<std::string>& preset_names, const PrinterPresetCollection& printer_presets)
|
||||
{
|
||||
std::set<std::string> new_names;
|
||||
|
||||
bool was_renamed{ false };
|
||||
for (const std::string& preset_name : preset_names) {
|
||||
const Preset* preset = printer_presets.find_preset(preset_name);
|
||||
if (preset)
|
||||
new_names.emplace(preset_name);
|
||||
else {
|
||||
if (const std::string* new_name = printer_presets.get_preset_name_renamed(preset_name)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "Printer preset present " << preset_name << "was renamed to: " << *new_name << std::endl;
|
||||
new_names.emplace(*new_name);
|
||||
was_renamed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (was_renamed)
|
||||
preset_names = new_names;
|
||||
}
|
||||
// Load all printers found in dir_path.
|
||||
// Throws an exception on error.
|
||||
void PhysicalPrinterCollection::load_printers(
|
||||
@@ -1839,10 +1868,13 @@ void PhysicalPrinterCollection::load_printers(
|
||||
std::string name = dir_entry.path().filename().string();
|
||||
// Remove the .ini suffix.
|
||||
name.erase(name.size() - 4);
|
||||
if (this->find_printer(name, false)) {
|
||||
if (PhysicalPrinter* found_printer = this->find_printer(name, false)) {
|
||||
// This happens when there's is a preset (most likely legacy one) with the same name as a system preset
|
||||
// that's already been loaded from a bundle.
|
||||
BOOST_LOG_TRIVIAL(warning) << "Printer already present, not loading: " << name;
|
||||
// But some of used printer_preset might have been renamed.
|
||||
// Check it and replace with new name(s) if it's needed
|
||||
update_preset_names_if_were_renamed(found_printer->preset_names, m_preset_bundle_owner->printers);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
@@ -1856,6 +1888,9 @@ void PhysicalPrinterCollection::load_printers(
|
||||
substitutions.push_back({ name, Preset::TYPE_PHYSICAL_PRINTER, PresetConfigSubstitutions::Source::UserFile, printer.file, std::move(config_substitutions) });
|
||||
printer.update_from_config(config);
|
||||
printer.loaded = true;
|
||||
// Some of used printer_preset might have been renamed.
|
||||
// Check it and replace with new name(s) if it's needed
|
||||
update_preset_names_if_were_renamed(printer.preset_names, m_preset_bundle_owner->printers);
|
||||
}
|
||||
catch (const std::ifstream::failure& err) {
|
||||
throw Slic3r::RuntimeError(std::string("The selected preset cannot be loaded: ") + printer.file + "\n\tReason: " + err.what());
|
||||
@@ -1887,6 +1922,9 @@ void PhysicalPrinterCollection::load_printer(const std::string& path, const std:
|
||||
it->file = path;
|
||||
it->config = std::move(config);
|
||||
it->loaded = true;
|
||||
// Some of used printer_preset might have been renamed.
|
||||
// Check it and replace with new name(s) if it's needed
|
||||
update_preset_names_if_were_renamed(it->preset_names, m_preset_bundle_owner->printers);
|
||||
if (select)
|
||||
this->select_printer(*it);
|
||||
|
||||
@@ -2142,6 +2180,9 @@ void PhysicalPrinterCollection::select_printer(const std::string& full_name)
|
||||
m_selected_preset = *it->preset_names.begin();
|
||||
else
|
||||
m_selected_preset = it->get_preset_name(full_name);
|
||||
// Check if selected preset wasn't renamed and replace it with new name
|
||||
if (const std::string* new_name = m_preset_bundle_owner->printers.get_preset_name_renamed(m_selected_preset))
|
||||
m_selected_preset = *new_name;
|
||||
}
|
||||
|
||||
void PhysicalPrinterCollection::select_printer(const std::string& printer_name, const std::string& preset_name)
|
||||
@@ -2361,6 +2402,15 @@ namespace PresetUtils {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool compare_vendor_profile_printers(const VendorProfile& vp_old, const VendorProfile& vp_new, std::vector<std::string>& new_printers)
|
||||
{
|
||||
for (const VendorProfile::PrinterModel& model : vp_new.models)
|
||||
{
|
||||
if (std::find_if(vp_old.models.begin(), vp_old.models.end(), [model](const VendorProfile::PrinterModel& pm) { return pm.id == model.id; }) == vp_old.models.end())
|
||||
new_printers.push_back(model.name);
|
||||
}
|
||||
return new_printers.empty();
|
||||
}
|
||||
} // namespace PresetUtils
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
Reference in New Issue
Block a user