diff options
author | supermerill <merill@free.fr> | 2022-07-24 19:27:15 +0300 |
---|---|---|
committer | supermerill <merill@free.fr> | 2022-07-24 19:27:15 +0300 |
commit | 25751573af5dbd8b6f973a3d13b873bfdeda3788 (patch) | |
tree | 995c1cfa43cd15946362fd9d31e8ff6281229989 | |
parent | b0ade4e6429e4d187fb4e8cc5b0b5290a1210629 (diff) | |
parent | 95a11fa59fd50405daa3df8c2454de2dad7f56ce (diff) |
test for #2938debug_ubuntu
-rw-r--r-- | src/libslic3r/AppConfig.cpp | 10 | ||||
-rw-r--r-- | src/libslic3r/Config.cpp | 7 | ||||
-rw-r--r-- | src/libslic3r/Flow.cpp | 60 | ||||
-rw-r--r-- | src/libslic3r/Flow.hpp | 13 | ||||
-rw-r--r-- | src/libslic3r/GCode.cpp | 2 | ||||
-rw-r--r-- | src/libslic3r/GCode/WipeTower.cpp | 17 | ||||
-rw-r--r-- | src/libslic3r/GCode/WipeTower.hpp | 4 | ||||
-rw-r--r-- | src/libslic3r/Preset.cpp | 19 | ||||
-rw-r--r-- | src/libslic3r/Print.cpp | 2 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.cpp | 118 | ||||
-rw-r--r-- | src/libslic3r/PrintConfig.hpp | 2 | ||||
-rw-r--r-- | src/libslic3r/Utils.hpp | 3 | ||||
-rw-r--r-- | src/libslic3r/utils.cpp | 5 | ||||
-rw-r--r-- | src/slic3r/GUI/BackgroundSlicingProcess.cpp | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/GalleryDialog.cpp | 16 | ||||
-rw-r--r-- | src/slic3r/GUI/PhysicalPrinterDialog.cpp | 16 | ||||
-rw-r--r-- | src/slic3r/GUI/PresetHints.cpp | 10 | ||||
-rw-r--r-- | src/slic3r/Utils/Http.cpp | 3 | ||||
-rw-r--r-- | src/slic3r/Utils/Http.hpp | 4 | ||||
-rw-r--r-- | src/slic3r/Utils/OctoPrint.cpp | 18 | ||||
-rw-r--r-- | src/slic3r/Utils/OctoPrint.hpp | 5 |
21 files changed, 247 insertions, 91 deletions
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index cf7bf21d1..7bc749643 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -655,6 +655,7 @@ void AppConfig::init_ui_layout() { //copy all resources that aren't in datadir or newer std::string current_name = get("ui_layout"); bool find_current = false; + std::string error_message; for (const auto& layout : resources_map) { auto it_datadir_layout = datadir_map.find(layout.first); if (it_datadir_layout != datadir_map.end()) { @@ -665,7 +666,8 @@ void AppConfig::init_ui_layout() { boost::filesystem::remove_all(file.path()); } for (boost::filesystem::directory_entry& file : boost::filesystem::directory_iterator(layout.second.path)) { - boost::filesystem::copy_file(file.path(), it_datadir_layout->second.path / file.path().filename()); + if (copy_file_inner(file.path(), it_datadir_layout->second.path / file.path().filename(), error_message)) + throw FileIOError(error_message); } //update for saving it_datadir_layout->second.version = layout.second.version; @@ -679,7 +681,8 @@ void AppConfig::init_ui_layout() { std::time_t datadir_last_mod = boost::filesystem::last_write_time(datadir_path); if (datadir_last_mod < resources_last_mod) { boost::filesystem::remove_all(datadir_path); - boost::filesystem::copy_file(resources_file.path(), datadir_path); + if (copy_file_inner(resources_file.path(), datadir_path, error_message)) + throw FileIOError(error_message); } } @@ -688,7 +691,8 @@ void AppConfig::init_ui_layout() { // Doesn't exists, copy boost::filesystem::create_directory(data_dir_path / layout.second.path.filename()); for (boost::filesystem::directory_entry& file : boost::filesystem::directory_iterator(layout.second.path)) { - boost::filesystem::copy_file(file.path(), data_dir_path / layout.second.path.filename() / file.path().filename()); + if (copy_file_inner(file.path(), data_dir_path / layout.second.path.filename() / file.path().filename(), error_message)) + throw FileIOError(error_message); } //update for saving datadir_map[layout.first] = layout.second; diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index e2b13c9a7..c603e316a 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -838,8 +838,11 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key, double rati // Get stored option value. const ConfigOption *raw_opt = this->option(opt_key); assert(raw_opt != nullptr); - if (raw_opt->type() != coFloatOrPercent) - throw ConfigurationError("ConfigBase::get_abs_value(): opt_key is not of coFloatOrPercent"); + if (raw_opt->type() != coFloatOrPercent) { + if(raw_opt->type() != coPercent) + throw ConfigurationError("ConfigBase::get_abs_value(): opt_key is not of coFloatOrPercent"); + return static_cast<const ConfigOptionPercent*>(raw_opt)->get_abs_value(ratio_over); + } // Compute absolute value. return static_cast<const ConfigOptionFloatOrPercent*>(raw_opt)->get_abs_value(ratio_over); } diff --git a/src/libslic3r/Flow.cpp b/src/libslic3r/Flow.cpp index a0323a52c..15b443481 100644 --- a/src/libslic3r/Flow.cpp +++ b/src/libslic3r/Flow.cpp @@ -148,20 +148,20 @@ const ConfigOptionFloatOrPercent* Flow::extrusion_option(const std::string& opt_ } // external_perimeter_extrusion_width default is perimeter_extrusion_width - if (opt->value == 0. && boost::starts_with(opt_key, "external_perimeter_extrusion_width")) { - // The role specific extrusion width value was set to zero, try the role non-specific extrusion width. - opt = config.option<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"); - if (opt == nullptr) - throw_on_missing_variable(opt_key, "perimeter_extrusion_width"); - } + //if (opt->value == 0. && boost::starts_with(opt_key, "external_perimeter_extrusion_width")) { + // // The role specific extrusion width value was set to zero, try the role non-specific extrusion width. + // opt = config.option<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"); + // if (opt == nullptr) + // throw_on_missing_variable(opt_key, "perimeter_extrusion_width"); + //} // top_infill_extrusion_width default is solid_infill_extrusion_width - if (opt->value == 0. && boost::starts_with(opt_key, "top_infill_extrusion_width")) { - // The role specific extrusion width value was set to zero, try the role non-specific extrusion width. - opt = config.option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width"); - if (opt == nullptr) - throw_on_missing_variable(opt_key, "perimeter_extrusion_width"); - } + //if (opt->value == 0. && boost::starts_with(opt_key, "top_infill_extrusion_width")) { + // // The role specific extrusion width value was set to zero, try the role non-specific extrusion width. + // opt = config.option<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width"); + // if (opt == nullptr) + // throw_on_missing_variable(opt_key, "solid_infill_extrusion_width"); + //} if (opt->value == 0.) { // The role specific extrusion width value was set to zero, try the role non-specific extrusion width. @@ -179,6 +179,42 @@ double Flow::extrusion_width(const std::string& opt_key, const ConfigOptionResol return extrusion_width(opt_key, config.option<ConfigOptionFloatOrPercent>(opt_key), config, first_printing_extruder); } +Flow Flow::new_from_config(FlowRole role, const DynamicConfig& print_config, float nozzle_diameter, float layer_height, float filament_max_overlap, bool first_layer) { + + ConfigOptionFloatOrPercent config_width; + // Get extrusion width from configuration. + float overlap = 1.f; + // (might be an absolute value, or a percent value, or zero for auto) + if (role == frExternalPerimeter) { + config_width = print_config.opt<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width"); + overlap = (float)print_config.get_abs_value("external_perimeter_overlap", 1.); + } else if (role == frPerimeter) { + config_width = print_config.opt<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"); + overlap = (float)print_config.get_abs_value("perimeter_overlap", 1.); + } else if (role == frInfill) { + config_width = print_config.opt<ConfigOptionFloatOrPercent>("infill_extrusion_width"); + } else if (role == frSolidInfill) { + config_width = print_config.opt<ConfigOptionFloatOrPercent>("solid_infill_extrusion_width"); + overlap = (float)print_config.get_abs_value("solid_infill_overlap", 1.); + } else if (role == frTopSolidInfill) { + config_width = print_config.opt<ConfigOptionFloatOrPercent>("top_infill_extrusion_width"); + overlap = (float)print_config.get_abs_value("solid_infill_overlap", 1.); + } else { + throw Slic3r::InvalidArgument("Unknown role"); + } + if (first_layer && print_config.get_abs_value("first_layer_extrusion_width", 1) > 0) { + config_width = print_config.opt<ConfigOptionFloatOrPercent>("first_layer_extrusion_width"); + } + + if (config_width.value == 0) + config_width = print_config.opt<ConfigOptionFloatOrPercent>("extrusion_width"); + + // Get the configured nozzle_diameter for the extruder associated to the flow role requested. + // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right. + return Flow::new_from_config_width(role, config_width, nozzle_diameter, layer_height, std::min(overlap, filament_max_overlap)); + //bridge ? (float)m_config.bridge_flow_ratio.get_abs_value(1) : 0.0f); +} + // This constructor builds a Flow object from an extrusion width config setting // and other context properties. Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float spacing_ratio, float bridge_flow_ratio) diff --git a/src/libslic3r/Flow.hpp b/src/libslic3r/Flow.hpp index 4be0ea8a0..d0d5448cd 100644 --- a/src/libslic3r/Flow.hpp +++ b/src/libslic3r/Flow.hpp @@ -108,10 +108,6 @@ public: Flow with_cross_section(float area) const; Flow with_flow_ratio(double ratio) const { return this->with_cross_section(this->mm3_per_mm() * ratio); } - static Flow bridging_flow(float dmr, float nozzle_diameter) { return Flow { dmr, dmr, bridge_extrusion_spacing(dmr), nozzle_diameter, 0, true }; } - - static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent& width, float nozzle_diameter, float height, float spacing_ratio); - // Spacing of extrusions with rounded extrusion model. static float rounded_rectangle_extrusion_spacing(float width, float height); // Width of extrusions with rounded extrusion model. @@ -119,7 +115,7 @@ public: // Spacing of round thread extrusions. static float bridge_extrusion_spacing(float dmr); - // Sane extrusion width defautl based on nozzle diameter. + // Sane extrusion width default based on nozzle diameter. // The defaults were derived from manual Prusa MK3 profiles. static float auto_extrusion_width(FlowRole role, float nozzle_diameter); @@ -130,8 +126,13 @@ public: static double extrusion_width(const std::string &opt_key, const ConfigOptionResolver &config, const unsigned int first_printing_extruder = 0); static const ConfigOptionFloatOrPercent* extrusion_option(const std::string& opt_key, const ConfigOptionResolver& config); + // like PrintRegion::flow() but with print settings from a DynamicConfig + static Flow new_from_config(FlowRole role, const DynamicConfig& print_config, float nozzle_diameter, float layer_height, float filament_max_overlap, bool first_layer); -/// old constructors + //low level constructor + static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent& width, float nozzle_diameter, float height, float spacing_ratio); + static Flow bridging_flow(float dmr, float nozzle_diameter) { return Flow{ dmr, dmr, bridge_extrusion_spacing(dmr), nozzle_diameter, 0, true }; } +/// old constructors don't use them. They are used by the good constructors from PrintRegion or the default_flow(). static Flow new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent& width, float nozzle_diameter, float height, float spacing_ratio, float bridge_flow_ratio); // Create a flow from the spacing of extrusion lines. // This method is used exclusively to calculate new flow of 100% infill, where the extrusion width was allowed to scale diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index fda78df69..8ef419ed0 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3287,6 +3287,8 @@ void GCode::append_full_config(const Print &print, std::string &str) "printhost_apikey", "printhost_cafile", "printhost_client_cert", + "printhost_client_cert_enabled", + "printhost_client_cert_password", "printhost_port" }; assert(std::is_sorted(banned_keys.begin(), banned_keys.end())); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 3f9fa3791..815b419e8 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -615,9 +615,10 @@ WipeTower::ToolChangeResult WipeTower::construct_tcr(WipeTowerWriter& writer, -WipeTower::WipeTower(const PrintConfig& config, const PrintObjectConfig& object_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) : +WipeTower::WipeTower(const PrintConfig& config, const PrintObjectConfig& default_object_config, const PrintRegionConfig& default_region_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool) : m_config(&config), - m_object_config(&object_config), + m_object_config(&default_object_config), + m_region_config(&default_region_config), m_semm(config.single_extruder_multi_material.value), m_wipe_tower_pos(config.wipe_tower_x, config.wipe_tower_y), m_wipe_tower_width(float(config.wipe_tower_width)), @@ -1396,7 +1397,17 @@ WipeTower::ToolChangeResult WipeTower::finish_layer() // brim (first layer only) if (first_layer) { box_coordinates box = wt_box; - const Slic3r::Flow brim_flow = Flow::new_from_config_width(FlowRole::frPerimeter, m_object_config->first_layer_extrusion_width, m_nozzle_diameter, m_layer_height, 1,0); //don't care of spacing and bridge + //same as print::brimflow() + PrintRegionConfig brim_region_config = *m_region_config; + brim_region_config.parent = m_object_config; + const Slic3r::Flow brim_flow = + Flow::new_from_config_width( + frPerimeter, + *Flow::extrusion_option("brim_extrusion_width", brim_region_config), + (float)m_nozzle_diameter, + (float)m_layer_height, + (m_current_tool < m_config->nozzle_diameter.values.size()) ? m_object_config->get_computed_value("filament_max_overlap", m_current_tool) : 1 + ); const coordf_t spacing = brim_flow.spacing(); // How many perimeters shall the brim have? size_t loops_num = (m_wipe_tower_brim_width + spacing / 2) / spacing; diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 7230a6590..632fce037 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -15,6 +15,7 @@ namespace Slic3r class WipeTowerWriter; class PrintConfig; class PrintObjectConfig; +class PrintRegionConfig; enum GCodeFlavor : unsigned char; @@ -126,7 +127,7 @@ public: // y -- y coordinates of wipe tower in mm ( left bottom corner ) // width -- width of wipe tower in mm ( default 60 mm - leave as it is ) // wipe_area -- space available for one toolchange in mm - WipeTower(const PrintConfig& config, const PrintObjectConfig& object_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool); + WipeTower(const PrintConfig& config, const PrintObjectConfig& default_object_config, const PrintRegionConfig& default_region_config, const std::vector<std::vector<float>>& wiping_matrix, size_t initial_tool); // Set the extruder properties. void set_extruder(size_t idx); @@ -263,6 +264,7 @@ private: const PrintConfig* m_config; const PrintObjectConfig* m_object_config; + const PrintRegionConfig* m_region_config; bool m_semm = true; // Are we using a single extruder multimaterial printer? Vec2f m_wipe_tower_pos; // Left front corner of the wipe tower in mm. float m_wipe_tower_width; // Width of the wipe tower. diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 5b1ab812f..e222b8e8b 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1782,6 +1782,8 @@ static std::vector<std::string> s_PhysicalPrinter_opts { "printhost_apikey", "printhost_cafile", "printhost_client_cert", + "printhost_client_cert_enabled", + "printhost_client_cert_password", "printhost_port", "printhost_authorization_type", // HTTP digest authentization (RFC 2617) @@ -1828,14 +1830,15 @@ const std::set<std::string>& PhysicalPrinter::get_preset_names() const bool PhysicalPrinter::has_empty_config() const { - return config.opt_string("print_host" ).empty() && - config.opt_string("printhost_apikey" ).empty() && - config.opt_string("printhost_cafile" ).empty() && - config.opt_string("printhost_client_cert").empty() && - config.opt_string("printhost_port" ).empty() && - config.opt_string("printhost_user" ).empty() && - config.opt_string("printhost_password").empty() && - config.opt_string("printhost_port" ).empty(); + return config.opt_string("print_host" ).empty() && + config.opt_string("printhost_apikey" ).empty() && + config.opt_string("printhost_cafile" ).empty() && + config.opt_string("printhost_client_cert" ).empty() && + config.opt_string("printhost_client_cert_password" ).empty() && + config.opt_string("printhost_port" ).empty() && + config.opt_string("printhost_user" ).empty() && + config.opt_string("printhost_password" ).empty() && + config.opt_string("printhost_port" ).empty(); } // temporary workaround for compatibility with older Slicer diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 333b33d01..b2f4ed9bf 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -1533,7 +1533,7 @@ void Print::_make_wipe_tower() this->throw_if_canceled(); // Initialize the wipe tower. - WipeTower wipe_tower(m_config, m_default_object_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder()); + WipeTower wipe_tower(m_config, m_default_object_config, m_default_region_config, wipe_volumes, m_wipe_tower_data.tool_ordering.first_extruder()); //wipe_tower.set_retract(); diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index a0f1759a4..5f4c7df26 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -474,6 +474,7 @@ void PrintConfigDef::init_common_params() def->cli = ConfigOptionDef::nocli; def->set_default_value(new ConfigOptionString("")); + // for repetier def = this->add("printhost_port", coString); def->label = L("Printer"); def->tooltip = L("Name of the printer"); @@ -482,6 +483,7 @@ void PrintConfigDef::init_common_params() def->cli = ConfigOptionDef::nocli; def->set_default_value(new ConfigOptionString("")); + // only if there isn't a native SSL support def = this->add("printhost_cafile", coString); def->label = L("HTTPS CA File"); def->category = OptionCategory::general; @@ -494,20 +496,35 @@ void PrintConfigDef::init_common_params() def = this->add("printhost_client_cert", coString); def->label = L("Client Certificate File"); def->category = OptionCategory::general; - def->tooltip = L("Custom Client certificate file can be specified for 2-way ssl authentication, in p12/pfx format. " + def->tooltip = L("A Client certificate file for use with 2-way ssl authentication, in p12/pfx format. " "If left blank, no client certificate is used."); def->mode = comAdvancedE | comSuSi; def->set_default_value(new ConfigOptionString("")); - // Options used by physical printers - + def = this->add("printhost_client_cert_enabled", coBool); + def->label = L("Enable 2-way ssl authentication"); + def->category = OptionCategory::general; + def->tooltip = L("Use this option to enable 2-way ssl authentication with you printer."); + def->mode = comAdvancedE | comSuSi; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("printhost_client_cert_password", coString); + def->label = L("Client Certificate Password"); + def->category = OptionCategory::general; + def->tooltip = L("Password for client certificate for 2-way ssl authentication. " + "Leave blank if no password is needed"); + def->mode = comAdvanced | comSuSi; + def->set_default_value(new ConfigOptionString("")); + + // For PrusaLink def = this->add("printhost_user", coString); def->label = L("User"); // def->tooltip = L(""); def->mode = comAdvancedE | comPrusa; def->cli = ConfigOptionDef::nocli; def->set_default_value(new ConfigOptionString("")); - + + // For PrusaLink def = this->add("printhost_password", coString); def->label = L("Password"); // def->tooltip = L(""); @@ -530,6 +547,7 @@ void PrintConfigDef::init_common_params() def->mode = comAdvancedE | comPrusa; def->set_default_value(new ConfigOptionStrings{}); + // For PrusaLink def = this->add("printhost_authorization_type", coEnum); def->label = L("Authorization Type"); // def->tooltip = L(""); @@ -7292,6 +7310,8 @@ std::unordered_set<std::string> prusa_export_to_remove_keys = { "print_retract_lift", "print_temperature", "printhost_client_cert", +"printhost_client_cert_enabled", +"printhost_client_cert_password", "remaining_times_type", "retract_lift_first_layer", "retract_lift_top", @@ -7791,11 +7811,11 @@ const TYPE* find_option(const t_config_option_key &opt_key, DynamicPrintConfig* return nullptr; } -std::set<const DynamicPrintConfig*> DynamicPrintConfig::update_phony(const std::vector<DynamicPrintConfig*> config_collection) { +std::set<const DynamicPrintConfig*> DynamicPrintConfig::update_phony(const std::vector<DynamicPrintConfig*> config_collection, bool exclude_default_extrusion /*= false*/) { std::set<const DynamicPrintConfig*> something_changed; //update width/spacing links const char* widths[] = { "", "external_perimeter_", "perimeter_", "infill_", "solid_infill_", "top_infill_", "support_material_", "first_layer_", "skirt_" }; - for (size_t i = 0; i < sizeof(widths) / sizeof(widths[i]); ++i) { + for (size_t i = exclude_default_extrusion?1:0; i < sizeof(widths) / sizeof(widths[i]); ++i) { std::string key_width(widths[i]); key_width += "extrusion_width"; std::string key_spacing(widths[i]); @@ -8002,9 +8022,13 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (flow.width() < flow.height()) flow.with_height(flow.width()); - spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (flow.width() < flow.height()) flow.with_height(flow.width()); + spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8014,9 +8038,13 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (flow.width() < flow.height()) flow.with_height(flow.width()); - spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow flow = Flow::new_from_config_width(FlowRole::frPerimeter, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (flow.width() < flow.height()) flow.with_height(flow.width()); + spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8027,10 +8055,14 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option && perimeter_overlap_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow flow = Flow::new_from_config_width(FlowRole::frExternalPerimeter, width_option->value == 0 ? *default_width_option : *width_option , max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); - flow = flow.with_spacing_ratio(std::min(flow.spacing_ratio(), (float)perimeter_overlap_option->get_abs_value(1))); - spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow flow = Flow::new_from_config_width(FlowRole::frExternalPerimeter, width_option->value == 0 ? *default_width_option : *width_option , max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); + flow = flow.with_spacing_ratio(std::min(flow.spacing_ratio(), (float)perimeter_overlap_option->get_abs_value(1))); + spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8041,10 +8073,14 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option && external_perimeter_overlap_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow ext_perimeter_flow = Flow::new_from_config_width(FlowRole::frPerimeter, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (ext_perimeter_flow.width() < ext_perimeter_flow.height()) ext_perimeter_flow = ext_perimeter_flow.with_height(ext_perimeter_flow.width()); - ext_perimeter_flow = ext_perimeter_flow.with_spacing_ratio(std::min(ext_perimeter_flow.spacing_ratio() * 0.5f, float(external_perimeter_overlap_option->get_abs_value(0.5)))); - spacing_option->value = (width_option->percent) ? std::round(100 * ext_perimeter_flow.spacing() / max_nozzle_diameter) : (std::round(ext_perimeter_flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow ext_perimeter_flow = Flow::new_from_config_width(FlowRole::frPerimeter, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (ext_perimeter_flow.width() < ext_perimeter_flow.height()) ext_perimeter_flow = ext_perimeter_flow.with_height(ext_perimeter_flow.width()); + ext_perimeter_flow = ext_perimeter_flow.with_spacing_ratio(std::min(ext_perimeter_flow.spacing_ratio() * 0.5f, float(external_perimeter_overlap_option->get_abs_value(0.5)))); + spacing_option->value = (width_option->percent) ? std::round(100 * ext_perimeter_flow.spacing() / max_nozzle_diameter) : (std::round(ext_perimeter_flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8054,9 +8090,13 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow flow = Flow::new_from_config_width(FlowRole::frInfill, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); - spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow flow = Flow::new_from_config_width(FlowRole::frInfill, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); + spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8067,10 +8107,14 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow flow = Flow::new_from_config_width(FlowRole::frSolidInfill, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); - flow = flow.with_spacing_ratio(std::min(flow.spacing_ratio(), float(solid_infill_overlap_option->get_abs_value(1.)))); - spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow flow = Flow::new_from_config_width(FlowRole::frSolidInfill, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); + flow = flow.with_spacing_ratio(std::min(flow.spacing_ratio(), float(solid_infill_overlap_option->get_abs_value(1.)))); + spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8080,9 +8124,13 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co if (width_option) { width_option->set_phony(false); spacing_option->set_phony(true); - Flow flow = Flow::new_from_config_width(FlowRole::frTopSolidInfill, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); - if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); - spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + if (width_option->value == 0) + spacing_option->value = 0; + else { + Flow flow = Flow::new_from_config_width(FlowRole::frTopSolidInfill, width_option->value == 0 ? *default_width_option : *width_option, max_nozzle_diameter, layer_height_option->value, overlap_ratio, 0); + if (flow.width() < flow.height()) flow = flow.with_height(flow.width()); + spacing_option->value = (width_option->percent) ? std::round(100 * flow.spacing() / max_nozzle_diameter) : (std::round(flow.spacing() * 10000) / 10000); + } spacing_option->percent = width_option->percent; something_changed = true; } @@ -8126,6 +8174,16 @@ std::set<const DynamicPrintConfig*> DynamicPrintConfig::value_changed(const t_co } } } + //update phony counterpark of 0-set fields + // now they show 0, no need to update them + //if (opt_key == "extrusion_width" || opt_key == "extrusion_spacing") { + // for (auto conf : config_collection) { + // if (conf->option("extrusion_width")) + // if (!conf->update_phony(config_collection, true).empty()) + // return { conf }; + // } + // return {}; + //} if(something_changed) return { this }; return {}; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 4cad48c6e..e616aabd6 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -392,7 +392,7 @@ public: /// <param name="opt_key">name of the changed option</param> /// <return> configs that have at least a change</param> std::set<const DynamicPrintConfig*> value_changed(const t_config_option_key& opt_key, const std::vector<DynamicPrintConfig*> config_collection); - std::set<const DynamicPrintConfig*> update_phony(const std::vector<DynamicPrintConfig*> config_collection); + std::set<const DynamicPrintConfig*> update_phony(const std::vector<DynamicPrintConfig*> config_collection, bool exclude_default_extrusion = false); }; void handle_legacy_sla(DynamicPrintConfig& config); diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index f109ced06..4390f70fd 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -100,7 +100,8 @@ enum CopyFileResult { FAIL_CHECK_TARGET_NOT_OPENED }; // Copy a file, adjust the access attributes, so that the target is writable. -CopyFileResult copy_file_inner(const std::string &from, const std::string &to, std::string& error_message); +CopyFileResult copy_file_inner(const std::string& from, const std::string& to, std::string& error_message); +CopyFileResult copy_file_inner(const boost::filesystem::path& from, const boost::filesystem::path& to, std::string& error_message); // Copy file to a temp file first, then rename it to the final file name. // If with_check is true, then the content of the copied file is compared to the content // of the source file before renaming. diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 5969b7ee3..66d7a54f6 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -764,6 +764,11 @@ CopyFileResult copy_file_inner(const std::string& from, const std::string& to, s { const boost::filesystem::path source(from); const boost::filesystem::path target(to); + return copy_file_inner(source, target, error_message); +} + +CopyFileResult copy_file_inner(const boost::filesystem::path& source, const boost::filesystem::path& target, std::string& error_message) +{ static const auto perms = boost::filesystem::owner_read | boost::filesystem::owner_write | boost::filesystem::group_read | boost::filesystem::others_read; // aka 644 // Make sure the file has correct permission both before and after we copy over it. diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 8f430c4ee..14c1db6cd 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -731,7 +731,9 @@ void BackgroundSlicingProcess::finalize_gcode() // collide with the G-code viewer memory mapping of the unprocessed G-code. G-code viewer maps unprocessed G-code, because m_gcode_result // is calculated for the unprocessed G-code and it references lines in the memory mapped G-code file by line numbers. // export_path may be changed by the post-processing script as well if the post processing script decides so, see GH #6042. - bool post_processed = run_post_process_scripts(output_path, true, "File", export_path, m_fff_print->full_print_config()); + DynamicPrintConfig conf_for_script = m_fff_print->full_print_config(); + conf_for_script.apply(m_fff_print->physical_printer_config()); // add physical printer options for use in the script. + bool post_processed = run_post_process_scripts(output_path, true, "File", export_path, conf_for_script); auto remove_post_processed_temp_file = [post_processed, &output_path]() { if (post_processed) try { diff --git a/src/slic3r/GUI/GalleryDialog.cpp b/src/slic3r/GUI/GalleryDialog.cpp index 9178eef13..ad9ad2aa7 100644 --- a/src/slic3r/GUI/GalleryDialog.cpp +++ b/src/slic3r/GUI/GalleryDialog.cpp @@ -473,7 +473,9 @@ void GalleryDialog::change_thumbnail() png_path.replace_extension("png"); fs::path current = fs::path(into_u8(input_files.Item(0))); - fs::copy_file(current, png_path, fs::copy_option::overwrite_if_exists); + std::string error_msg; + if (copy_file_inner(current, png_path, error_msg)) + throw FileIOError(error_msg); } catch (fs::filesystem_error const& e) { std::cerr << e.what() << '\n'; @@ -560,9 +562,11 @@ bool GalleryDialog::load_files(const wxArrayString& input_files) try { fs::path current = fs::path(input_file); - if (!fs::exists(dest_dir / current.filename())) - fs::copy_file(current, dest_dir / current.filename()); - else { + if (!fs::exists(dest_dir / current.filename())) { + std::string error_msg; + if (copy_file_inner(current, dest_dir / current.filename(), error_msg)) + throw FileIOError(error_msg); + } else { std::string filename = current.stem().string(); int file_idx = 0; @@ -584,7 +588,9 @@ bool GalleryDialog::load_files(const wxArrayString& input_files) } if (file_idx > 0) { filename += " (" + std::to_string(file_idx) + ")." + (is_gallery_file(input_file, ".stl") ? "stl" : "obj"); - fs::copy_file(current, dest_dir / filename); + std::string error_msg; + if (copy_file_inner(current, dest_dir / filename, error_msg)) + throw FileIOError(error_msg); } } } diff --git a/src/slic3r/GUI/PhysicalPrinterDialog.cpp b/src/slic3r/GUI/PhysicalPrinterDialog.cpp index 9200b7ddf..dc0c39ab1 100644 --- a/src/slic3r/GUI/PhysicalPrinterDialog.cpp +++ b/src/slic3r/GUI/PhysicalPrinterDialog.cpp @@ -322,7 +322,7 @@ void PhysicalPrinterDialog::update_printers() void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgroup) { m_optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value) { - if (opt_key == "host_type" || opt_key == "printhost_authorization_type") + if (opt_key == "host_type" || opt_key == "printhost_authorization_type" || opt_key == "printhost_client_cert_enabled") this->update(); if (opt_key == "print_host") this->update_printhost_buttons(); @@ -408,6 +408,10 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr port_line.append_widget(print_host_printers); m_optgroup->append_line(port_line); + option = m_optgroup->get_option("printhost_client_cert_enabled"); + option.opt.width = Field::def_width_wider(); + m_optgroup->append_single_option_line(option); + option = m_optgroup->get_option("printhost_client_cert"); option.opt.width = Field::def_width_wider(); Line client_cert_line = m_optgroup->create_single_option_line(option); @@ -441,6 +445,10 @@ void PhysicalPrinterDialog::build_printhost_settings(ConfigOptionsGroup* m_optgr }; m_optgroup->append_line(clientcert_hint); + option = m_optgroup->get_option("printhost_client_cert_password"); + option.opt.width = Field::def_width_wider(); + m_optgroup->append_single_option_line(option); + const auto ca_file_hint = _u8L("HTTPS CA file is optional. It is only needed if you use HTTPS with a self-signed certificate."); if (Http::ca_file_supported()) { @@ -586,6 +594,11 @@ void PhysicalPrinterDialog::update(bool printer_change) m_optgroup->hide_field("printhost_apikey"); m_optgroup->hide_field("printhost_cafile"); } + + // Hide client cert options if disabled + const bool enable_client_authentication = m_config->option<ConfigOptionBool>("printhost_client_cert_enabled")->value; + m_optgroup->show_field("printhost_client_cert", enable_client_authentication); + m_optgroup->show_field("printhost_client_cert_password", enable_client_authentication); } else { m_optgroup->set_value("host_type", int(PrintHostType::htOctoPrint), false); @@ -614,6 +627,7 @@ void PhysicalPrinterDialog::update(bool printer_change) } this->Layout(); + this->Fit(); } void PhysicalPrinterDialog::update_host_type(bool printer_change) diff --git a/src/slic3r/GUI/PresetHints.cpp b/src/slic3r/GUI/PresetHints.cpp index e4b9f0f36..7c285d6c7 100644 --- a/src/slic3r/GUI/PresetHints.cpp +++ b/src/slic3r/GUI/PresetHints.cpp @@ -171,6 +171,7 @@ static const ConfigOptionFloatOrPercent& first_positive(const ConfigOptionFloatO return (v1 != nullptr && v1->value > 0) ? *v1 : ((v2.value > 0) ? v2 : v3); } +//TODO since 2.4: check the flow computation (and try to simplify them) std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle &preset_bundle) { // Find out, to which nozzle index is the current filament profile assigned. @@ -419,16 +420,15 @@ std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle& pre } float filament_max_overlap = (float)filament_config.get_computed_value("filament_max_overlap", 0); - Flow external_perimeter_flow = Flow::new_from_config_width( - frExternalPerimeter, - *print_config.opt<ConfigOptionFloatOrPercent>("external_perimeter_extrusion_width"), + Flow external_perimeter_flow = Flow::new_from_config(frExternalPerimeter, + print_config, nozzle_diameter, layer_height, filament_max_overlap, false); - Flow perimeter_flow = Flow::new_from_config_width( + Flow perimeter_flow = Flow::new_from_config( frPerimeter, - *print_config.opt<ConfigOptionFloatOrPercent>("perimeter_extrusion_width"), + print_config, nozzle_diameter, layer_height, filament_max_overlap, diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index 5fbe94e51..9bab91860 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -522,10 +522,11 @@ Http& Http::ca_file(const std::string &name) return *this; } -Http& Http::client_cert(const std::string &name) +Http& Http::client_cert(const std::string &name, const std::string &password) { curl_easy_setopt(p->curl, CURLOPT_SSLCERT, name.c_str()); curl_easy_setopt(p->curl, CURLOPT_SSLCERTTYPE, "P12"); + curl_easy_setopt(p->curl, CURLOPT_KEYPASSWD, password.c_str()); return *this; } diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index a73edd11d..438b8d31e 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -79,8 +79,8 @@ public: // specifically, this is supported with OpenSSL and NOT supported with Windows and OS X native certificate store. // See also ca_file_supported(). Http& ca_file(const std::string &filename); - // Set a client certificate for usage with 2-way ssl authentication - Http& client_cert(const std::string &filename); + // Set a client certificate for usage with 2-way ssl authentication (password for key is optional) + Http& client_cert(const std::string &filename, const std::string &password = ""); // Add a HTTP multipart form field Http& form_add(const std::string &name, const std::string &contents); // Add a HTTP multipart form file data contents, `name` is the name of the part diff --git a/src/slic3r/Utils/OctoPrint.cpp b/src/slic3r/Utils/OctoPrint.cpp index fc7796873..89e3bd814 100644 --- a/src/slic3r/Utils/OctoPrint.cpp +++ b/src/slic3r/Utils/OctoPrint.cpp @@ -99,6 +99,8 @@ OctoPrint::OctoPrint(DynamicPrintConfig *config) : m_apikey(config->opt_string("printhost_apikey")), m_cafile(config->opt_string("printhost_cafile")), m_client_cert(config->opt_string("printhost_client_cert")), + m_client_cert_password(config->opt_string("printhost_client_cert_password")), + m_client_cert_enabled(config->opt_bool("printhost_client_cert_enabled")), m_ssl_revoke_best_effort(config->opt_bool("printhost_ssl_ignore_revoke")) {} @@ -273,12 +275,12 @@ void OctoPrint::set_auth(Http &http) const { http.header("X-Api-Key", m_apikey); - if (!m_cafile.empty()) { - http.ca_file(m_cafile); + if (!get_cafile().empty()) { + http.ca_file(get_cafile()); } - if (! m_client_cert.empty()) { - http.client_cert(m_client_cert); + if (! get_client_cert().empty() && get_client_cert_enabled()) { + http.client_cert(get_client_cert(), get_client_cert_password()); } } @@ -373,8 +375,8 @@ void SL1Host::set_auth(Http &http) const http.ca_file(get_cafile()); } - if (! get_client_cert().empty()) { - http.client_cert(get_client_cert()); + if (!get_client_cert().empty() && get_client_cert_enabled()) { + http.client_cert(get_client_cert(), get_client_cert_password()); } } @@ -421,8 +423,8 @@ void PrusaLink::set_auth(Http& http) const http.ca_file(get_cafile()); } - if (! get_client_cert().empty()) { - http.client_cert(get_client_cert()); + if (! get_client_cert().empty() && get_client_cert_enabled()) { + http.client_cert(get_client_cert(), get_client_cert_password()); } } diff --git a/src/slic3r/Utils/OctoPrint.hpp b/src/slic3r/Utils/OctoPrint.hpp index e84f9a9af..a70eaacb6 100644 --- a/src/slic3r/Utils/OctoPrint.hpp +++ b/src/slic3r/Utils/OctoPrint.hpp @@ -33,6 +33,9 @@ public: const std::string& get_apikey() const { return m_apikey; } const std::string& get_cafile() const { return m_cafile; } const std::string& get_client_cert() const { return m_client_cert; } + const std::string& get_client_cert_password() const { return m_client_cert_password; } + const bool get_client_cert_enabled() const { return m_client_cert_enabled; } + protected: virtual bool validate_version_text(const boost::optional<std::string> &version_text) const; @@ -44,6 +47,8 @@ private: std::string m_cafile; bool m_ssl_revoke_best_effort; std::string m_client_cert; + std::string m_client_cert_password; + bool m_client_cert_enabled; virtual void set_auth(Http &http) const; std::string make_url(const std::string &path) const; |