From 48dbaf51dfc40a7ddbefd4077443512f4e76ada7 Mon Sep 17 00:00:00 2001 From: supermerill Date: Tue, 4 Jun 2024 10:07:17 +0200 Subject: [PATCH 01/10] Also use offset for only_retract_when_crossing_perimeters supermerill/SuperSlicer#4294 --- src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 2f663166cc5..8d885fa5325 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6373,7 +6373,7 @@ Polyline GCode::travel_to(std::string &gcode, const Point &point, ExtrusionRole bool needs_retraction = this->needs_retraction(travel, role); if (m_config.only_retract_when_crossing_perimeters && !(m_config.enforce_retract_first_layer && m_layer_index == 0)) - needs_retraction = needs_retraction && this->can_cross_perimeter(travel, false); + needs_retraction = needs_retraction && this->can_cross_perimeter(travel, true); // Re-allow avoid_crossing_perimeters for the next travel moves m_avoid_crossing_perimeters.reset_once_modifiers(); From c3c2244faa915907f96985f4c0cd3760cd9d1a87 Mon Sep 17 00:00:00 2001 From: supermerill Date: Tue, 4 Jun 2024 20:59:20 +0200 Subject: [PATCH 02/10] use the right optgroup when creating the frequent tabs. --- resources/ui_layout/default/freq_fff.ui | 2 +- src/slic3r/GUI/GUI_App.cpp | 4 +-- src/slic3r/GUI/OptionsGroup.cpp | 7 ++-- src/slic3r/GUI/OptionsGroup.hpp | 2 +- src/slic3r/GUI/Plater.cpp | 30 ++++++++-------- src/slic3r/GUI/Tab.cpp | 48 +++++++++++++++++-------- src/slic3r/GUI/Tab.hpp | 15 +++++--- 7 files changed, 70 insertions(+), 38 deletions(-) diff --git a/resources/ui_layout/default/freq_fff.ui b/resources/ui_layout/default/freq_fff.ui index fcf53c32c19..d80283f490e 100644 --- a/resources/ui_layout/default/freq_fff.ui +++ b/resources/ui_layout/default/freq_fff.ui @@ -1,5 +1,5 @@ #logs -page:print: +page:Frequent settings: group:freq_settings_event:no_title:no_search: line: setting:simple:script:enum$none$None$bp$Support on build plate only$se$For support enforcers only$ev$Everywhere:depends$support_material$support_material_auto$support_material_buildplate_only:label$Supports:tooltip$Select what kind of support do you need:full_width:s_support_fff diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 368ffc964bc..ab46ddf558c 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -873,7 +873,7 @@ bool GUI_App::init_opengl() if (boost::contains(gpu_vendor, "Apple") || boost::contains(gpu_vendor, "APPLE")) { assert(false); // apple gpu are only in _M_ARM64 } - } catch (std::exception &ex) {} + } catch (std::exception &) {} #endif app_config->set_hardware_type(AppConfig::HardwareType(hard_cpu + hard_gpu)); } @@ -2652,7 +2652,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu) associate_gcode_files(); } #endif // _WIN32 - } catch (std::exception &e) {} + } catch (std::exception &) {} } if (app_layout_changed) { // hide full main_sizer for mainFrame diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index facaefc6734..b2cdbb82276 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -126,11 +126,14 @@ OptionsGroup::OptionsGroup( wxWindow* _parent, const wxString& title, m_use_custom_ctrl(is_tab_opt), staticbox(title!=""), extra_column(extra_clmn) { + assert(Tab::fake_build || m_parent); } wxWindow* OptionsGroup::ctrl_parent() const { - return this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast(this->custom_ctrl) : (this->stb ? static_cast(this->stb) : this->parent()); + wxWindow* ret_val = this->custom_ctrl && m_use_custom_ctrl_as_parent ? static_cast(this->custom_ctrl) : (this->stb ? static_cast(this->stb) : this->parent()); + assert(ret_val); + return ret_val; } bool OptionsGroup::is_legend_line() @@ -190,7 +193,7 @@ void OptionsGroup::show_field(const t_config_option_key& opt_key, bool show/* = void OptionsGroup::append_line(const Line& line) { - m_lines.emplace_back(line); + m_lines.push_back(line); if (line.full_width && ( line.widget != nullptr || diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 56de96f7dcb..e0a0252d02d 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -135,7 +135,7 @@ class OptionsGroup { /// Returns a copy of the pointer of the parent wxWindow. /// Accessor function is because users are not allowed to change the parent /// but defining it as const means a lot of const_casts to deal with wx functions. - inline wxWindow* parent() const { return m_parent; } + inline wxWindow* parent() const { assert(m_parent); return m_parent; } wxWindow* ctrl_parent() const; diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e28ded9cdbd..f95f146b174 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -343,7 +343,7 @@ class FreqChangedParams : public OG_Settings void FreqChangedParams::msw_rescale() { - m_og->msw_rescale(); + if(m_og) m_og->msw_rescale(); for(auto& entry : m_og_other) entry.second->msw_rescale(); @@ -353,7 +353,7 @@ void FreqChangedParams::msw_rescale() void FreqChangedParams::sys_color_changed() { - m_og->sys_color_changed(); + if(m_og) m_og->sys_color_changed(); for (auto& entry : m_og_other) entry.second->sys_color_changed(); @@ -389,16 +389,17 @@ void FreqChangedParams::init() assert(tab_freq_fff == nullptr || dynamic_cast(tab_freq_fff)); if (tab_freq_fff && dynamic_cast(tab_freq_fff)) { - // std::vector pages; + static_cast(tab_freq_fff)->set_freq_parent(m_og->parent()); tab_freq_fff->build(); - // if(tab_freq_fff != nullptr) pages = - // tab_freq_fff->create_pages(Preset::type_name(tab_freq_fff->type())+".ui", -1, tab_freq_fff->type()); if (tab_freq_fff->get_page_count() > 0) { + assert(tab_freq_fff->get_page_count() == 1); + assert(tab_freq_fff->get_page(0)); + assert(tab_freq_fff->get_page(0)->m_optgroups.size() == 1); + m_og = (tab_freq_fff->get_page(0)->m_optgroups[0]); m_og->set_config(config); m_og->hide_labels(); m_og->m_on_change = Tab::set_or_add(m_og->m_on_change, [tab_freq_fff, this](t_config_option_key opt_key, boost::any value) - // m_og->m_on_change = [tab_print, this](t_config_option_key opt_key, boost::any value) { const Option *opt_def = this->m_og->get_option_def(opt_key); if (opt_def && !opt_def->opt.is_script) { @@ -470,10 +471,9 @@ void FreqChangedParams::init() line_for_purge->append_widget(wiping_dialog_btn); } - for (const Line &l : page->m_optgroups[0]->get_lines()) { m_og->append_line(l); } - // current_group->m_on_change = on_change; m_og->activate(); + assert(m_og->sizer); m_sizer->Add(m_og->sizer, 0, wxEXPAND); } } @@ -483,12 +483,14 @@ void FreqChangedParams::init() Tab* tab_freq_sla = wxGetApp().get_tab(Preset::TYPE_FREQUENT_SLA, false); assert(tab_freq_sla == nullptr || dynamic_cast(tab_freq_sla)); if (tab_freq_sla && dynamic_cast(tab_freq_sla)) { + static_cast(tab_freq_sla)->set_freq_parent(m_parent); tab_freq_sla->build(); - // if (tab_freq_sla != nullptr) pages = - // tab_freq_sla->create_pages(Preset::type_name(tab_freq_sla->type())+".ui", -1, tab_freq_sla->type()); if (tab_freq_sla->get_page_count() > 0) { + assert(tab_freq_fff->get_page_count() == 1); + assert(tab_freq_fff->get_page(0)); + assert(tab_freq_fff->get_page(0)->m_optgroups.size() == 1); std::shared_ptr m_og_sla = m_og_other[ptSLA] = - std::make_shared(m_parent, ""); + (tab_freq_sla->get_page(0)->m_optgroups[0]); m_og_sla->set_config(config); m_og_sla->hide_labels(); m_og_sla->m_on_change = Tab::set_or_add(m_og_sla->m_on_change, [tab_freq_sla, @@ -512,8 +514,8 @@ void FreqChangedParams::init() l.append_widget(empty_widget); } } - for (const Line &l : page->m_optgroups[0]->get_lines()) { m_og_sla->append_line(l); } m_og_sla->activate(); + assert(m_og_sla->sizer); m_sizer->Add(m_og_sla->sizer, 0, wxEXPAND); } } @@ -533,7 +535,7 @@ void FreqChangedParams::Show(bool visible) { void FreqChangedParams::Show(PrinterTechnology tech) { - m_og->Show( (tech & PrinterTechnology::ptFFF) != 0); + if(m_og) m_og->Show( (tech & PrinterTechnology::ptFFF) != 0); for (auto& entry : m_og_other) entry.second->Show( (entry.first & tech) != 0); @@ -1155,7 +1157,7 @@ void Sidebar::jump_to_option(size_t selected) } } - wxGetApp().get_tab(opt.type)->activate_option(opt.opt_key_with_idx(), boost::nowide::narrow(opt.category)); + wxGetApp().get_tab(opt.type, false)->activate_option(opt.opt_key_with_idx(), boost::nowide::narrow(opt.category)); // Switch to the Settings NotePad // wxGetApp().mainframe->select_tab(MainFrame::ETabType::LastSettings); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index da99d32c599..c16edfe4dd5 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -467,33 +467,42 @@ void Tab::load_initial_data() m_tt_non_system_script = has_parent ? &m_tt_value_unlock_script : &m_ttg_white_bullet_ns; } -Slic3r::GUI::PageShp Tab::create_options_page(const wxString& title, const std::string& icon) +int Tab::get_icon_id(const wxString& title, const std::string& icon) { // Index of icon in an icon list $self->{icons}. - auto icon_idx = 0; + int icon_idx = 0; if (!icon.empty()) { icon_idx = (m_icon_index.find(icon) == m_icon_index.end()) ? -1 : m_icon_index.at(icon); if (icon_idx == -1 && m_icons) { // Add a new icon to the icon list. m_scaled_icons_list.push_back(ScalableBitmap(this, icon)); m_icons->Add(m_scaled_icons_list.back().bmp()); - icon_idx = ++m_icon_count; + icon_idx = ++m_icon_count; m_icon_index[icon] = icon_idx; } if (m_category_icon.find(title) == m_category_icon.end()) { // Add new category to the category_to_icon list. m_category_icon[title] = icon; + } } - } + return icon_idx; +} + +Slic3r::GUI::PageShp Tab::create_options_page(const wxString& title, const std::string& icon) +{ + assert((this->type() & Preset::Type::TYPE_FREQUENT) == 0); + assert(Tab::fake_build || m_page_view); // Initialize the page. - PageShp page(new Page(this, m_page_view, title, icon_idx)); -// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); -#ifdef __WINDOWS__ -// page->SetDoubleBuffered(true); -#endif //__WINDOWS__ + PageShp page(new Page(this, m_page_view, title, get_icon_id(title, icon))); + return page; +} - //page->set_config(m_config); +Slic3r::GUI::PageShp TabFrequent::create_options_page(const wxString &title, const std::string &icon) { + assert(!m_page_view); + assert(m_freq_parent); + // Initialize the page. + PageShp page(new Page(this, m_freq_parent, title, get_icon_id(title, icon))); return page; } @@ -1247,12 +1256,12 @@ Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/ std::pair Tab::get_custom_ctrl_with_blinking_ptr(const t_config_option_key& opt_key, int opt_index/* = -1*/) { - if (!m_active_page) + if (!m_active_page && m_pages.empty()) return {nullptr, nullptr}; std::pair ret = {nullptr, nullptr}; - for (auto opt_group : m_active_page->m_optgroups) { + for (auto opt_group : m_active_page ? m_active_page->m_optgroups : m_pages.front()->m_optgroups) { ret = opt_group->get_custom_ctrl_with_blinking_ptr(opt_key, opt_index); if (ret.first && ret.second) break; @@ -1508,6 +1517,14 @@ void Tab::activate_option(const std::string& opt_key, const wxString& category) m_highlighter.init(get_custom_ctrl_with_blinking_ptr(opt_key)); } +void TabFrequent::activate_option(const std::string &opt_key, const wxString &category){ + wxGetApp().plater()->collapse_sidebar(false); + wxGetApp().mainframe->select_tab(MainFrame::ETabType::Plater3D); + // no act btns -> no blink arrow + //std::pair ctrl = get_custom_ctrl_with_blinking_ptr(opt_key); + //m_highlighter.init(ctrl); +} + void Tab::cache_config_diff(const std::vector& selected_options) { m_cache_config.apply_only(m_presets->get_edited_preset().config, selected_options); @@ -1807,7 +1824,7 @@ std::vector Tab::create_pages(std::string setting_type_nam } if(logs) Slic3r::slic3r_log->info("settings gui") << "create page " << label.c_str() <<" : "<< params[params.size() - 1] << "\n"; - pages.push_back(create_options_page(label, params[params.size() - 1])); + pages.push_back(this->create_options_page(label, params[params.size() - 1])); current_page = pages.back(); } else if (boost::starts_with(full_line, "end_page")) @@ -3185,13 +3202,16 @@ void TabPrinter::init() // For DiffPresetDialog we use options list which is saved in Searcher class. // Options for the Searcher is added in the moment of pages creation. - // So, build first of all printer pages for non-selected printer technology... + // So, fake-build first of all printer pages for non-selected printer technology... + // //FIXME: split into PRINTERSLA and PRINTERFFF + Tab::fake_build = true; std::string def_preset_name = "- default " + std::string(m_printer_technology == ptSLA ? "FFF" : "SLA") + " -"; m_config = &m_presets->find_preset(def_preset_name)->config; m_config_base = m_config; m_printer_technology != ptSLA ? build_sla() : build_fff(); if (m_printer_technology == ptSLA) m_extruders_count_old = 0;// revert this value + Tab::fake_build = false; // ... and than for selected printer technology load_initial_data(); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 29d587c479f..95df5c82cb1 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -122,7 +122,7 @@ class Page// : public wxScrolledWindow //DynamicPrintConfig* m_config; wxBoxSizer* vsizer() const { return m_vsizer; } - wxWindow* parent() const { return m_parent; } + wxWindow* parent() const { assert(m_parent); return m_parent; } const wxString& title() const { return m_title; } size_t iconID() const { return m_iconID; } //void set_config(DynamicPrintConfig* config_in) { m_config = config_in; } @@ -384,6 +384,7 @@ class Tab: public wxPanel // 3. propagate changed configuration to the Plater when (m_update_cnt == 0) only std::atomic_int16_t m_update_cnt = 0; + static inline bool fake_build = false; public: Tab(wxBookCtrlBase* parent, const wxString& title, Preset::Type type); ~Tab() {} @@ -433,10 +434,12 @@ class Tab: public wxPanel void update_undo_buttons(); void on_roll_back_value(const bool to_sys = false); - - PageShp create_options_page(const wxString& title, const std::string& icon); + + int get_icon_id(const wxString& title, const std::string &icon); + virtual PageShp create_options_page(const wxString &title, const std::string &icon); static wxString translate_category(const wxString& title, Preset::Type preset_type); + virtual void OnActivate(); virtual void on_preset_loaded() {} virtual void init() = 0; @@ -475,7 +478,7 @@ class Tab: public wxPanel void on_value_change(const std::string& opt_key, const boost::any& value); void update_wiping_button_visibility(); - void activate_option(const std::string& opt_key, const wxString& category); + virtual void activate_option(const std::string& opt_key, const wxString& category); void cache_config_diff(const std::vector& selected_options); void apply_config_from_cache(); @@ -510,6 +513,7 @@ class Tab: public wxPanel class TabFrequent : public Tab { MultiPtrPrintConfig m_multi_conf; + wxWindow * m_freq_parent = nullptr; public: TabFrequent(wxBookCtrlBase* parent, const wxString &title, Preset::Type tab_type) : Tab(parent, title, tab_type) {} @@ -524,6 +528,9 @@ class TabFrequent : public Tab PrinterTechnology get_printer_technology() const override { return (m_type & Preset::Type::TYPE_TECHNOLOGY) == Preset::Type::TYPE_FFF ? PrinterTechnology::ptFFF : (m_type & Preset::Type::TYPE_TECHNOLOGY) == Preset::Type::TYPE_SLA ? PrinterTechnology::ptSLA : PrinterTechnology::ptAny; } + virtual void activate_option(const std::string& opt_key, const wxString& category) override; + void set_freq_parent(wxWindow * freq_parent) { m_freq_parent = freq_parent;} + virtual PageShp create_options_page(const wxString &title, const std::string &icon) override; }; class TabPrint : public Tab From e4f5507db3866fe5b2e07ed22f47db41e4ca4f1a Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 5 Jun 2024 10:26:40 +0200 Subject: [PATCH 03/10] variable width path: allow reverse. --- src/libslic3r/GCode.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 8d885fa5325..682c4c4e355 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -5114,9 +5114,15 @@ std::string GCode::extrude_multi_path(const ExtrusionMultiPath &multipath, const //reverse to get a shorter point (hopefully there is still no feature that choose a point that need no perimeter crossing before). // extrude along the reversedpath for (size_t idx_path = multipath.paths.size() - 1; idx_path < multipath.paths.size(); --idx_path) { - assert(multipath.paths[idx_path].can_reverse()); - //extrude_path will reverse the path by itself, no need to copy it do to it here. - gcode += extrude_path(multipath.paths[idx_path], description, speed); + //it's possible to have un-reverseable paths into a reversable multipath: this means that only the whole thing can be reversed, and not individual apths. + if (multipath.paths[idx_path].can_reverse()) { + // extrude_path will reverse the path by itself, no need to copy it do to it here. + gcode += extrude_path(multipath.paths[idx_path], description, speed); + } else { + ExtrusionPath path = multipath.paths[idx_path]; + path.reverse(); + gcode += extrude_path(path, description, speed); + } } } else { // extrude along the path From 6c8a446da91839b81c62dc82fa13c1fd69bf0a52 Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 5 Jun 2024 14:11:31 +0200 Subject: [PATCH 04/10] fix brim on first support layer (when it's not on the bed) supermerill/SuperSlicer#4300 --- src/libslic3r/GCode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 682c4c4e355..f3b090fe97f 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -3441,7 +3441,7 @@ LayerResult GCode::process_layer( //extrude object-only skirt (for sequential) //TODO: use it also for wiping like the other one (as they are exlusiev) if (single_object_instance_idx != size_t(-1) && !layers.front().object()->skirt().empty() - && extruder_id == layer_tools.extruders.front()) { + && extruder_id == layer_tools.extruders.front() && object_layer) { const PrintObject *print_object = layers.front().object(); //object skirt & brim use the object settings. @@ -3459,7 +3459,7 @@ LayerResult GCode::process_layer( } //extrude object-only brim (for sequential) if (single_object_instance_idx != size_t(-1) && !layers.front().object()->brim().empty() - && extruder_id == layer_tools.extruders.front()) { + && extruder_id == layer_tools.extruders.front() && object_layer) { const PrintObject* print_object = layers.front().object(); //object skirt & brim use the object settings. From adcfd97d23bb0cb9b03fa34c653d635b36e52f71 Mon Sep 17 00:00:00 2001 From: supermerill Date: Wed, 5 Jun 2024 14:12:12 +0200 Subject: [PATCH 05/10] Fix Slider refresh data was sending gcode data when refreshing for a preview. --- src/slic3r/GUI/GUI_Preview.cpp | 74 ++++++++++++++++------------------ src/slic3r/GUI/GUI_Preview.hpp | 2 +- 2 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 9c492156c92..0b834ad3fe1 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -686,7 +686,7 @@ void Preview::check_layers_slider_values(std::vector& ticks_f m_schedule_background_process(); } -void Preview::update_layers_slider(const std::vector& layers_z, bool keep_z_range) +void Preview::update_layers_slider(const std::vector& layers_z, bool show_gcode_data, bool keep_z_range) { //lock rendering while updating { @@ -708,7 +708,7 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee // Detect and set manipulation mode for double slider update_layers_slider_mode(); - + Plater* plater = wxGetApp().plater(); CustomGCode::Info ticks_info_from_model = plater->model().custom_gcode_per_print_z; if (wxGetApp().is_editor()) @@ -742,47 +742,40 @@ void Preview::update_layers_slider(const std::vector& layers_z, bool kee } m_layers_slider->SetSelectionSpan(idx_low, idx_high); m_layers_slider->SetTicksValues(ticks_info_from_model); - - bool sla_print_technology = plater->printer_technology() == ptSLA; + bool sequential_print = wxGetApp().preset_bundle->fff_prints.get_edited_preset().config.opt_bool("complete_objects"); + bool sla_print_technology = plater->printer_technology() == ptSLA; m_layers_slider->SetDrawMode(sla_print_technology, sequential_print); - if (sla_print_technology) - m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times); - else { - if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { - //do not fetch uncomplete data - m_layers_slider->SetLayersTimes({}, 0); + if (show_gcode_data) { + if (sla_print_technology) { + m_layers_slider->SetLayersTimes(plater->sla_print().print_statistics().layers_times); } else { - auto print_mode_stat = m_gcode_result->print_statistics.modes.front(); - m_layers_slider->SetLayersTimes(print_mode_stat.layers_times, print_mode_stat.time); + if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { + // do not fetch uncomplete data + m_layers_slider->SetLayersTimes({}, 0); + } else { + auto print_mode_stat = m_gcode_result->print_statistics.modes.front(); + m_layers_slider->SetLayersTimes(print_mode_stat.layers_times, print_mode_stat.time); + } } - } // create area array - //area not computed for sla_print_technology //TODO - if (!sla_print_technology){ - if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { - //do not fetch uncomplete data - m_layers_slider->SetLayersAreas({}); - } else { - const std::vector> &layerz_to_area = plater->fff_print().print_statistics().layer_area_stats; - std::vector areas; - for(auto [z, area] : layerz_to_area) - areas.push_back(area); - m_layers_slider->SetLayersAreas(areas); - assert(areas.size() == m_gcode_result->print_statistics.modes.front().layers_times.size()); - //auto objects = plater->fff_print().objects(); - //for (auto object : objects) { - // for (auto layer : object->layers()) { - // assert(layer->print_z > 100); - // coord_t layer_z = 100*(coord_t(layer->print_z + 50)/100); - // int32_t area = layerz_to_area[layer_z]; - // for (auto poly : layer->lslices) { - // area += poly.area(); - // } - // layerz_to_area[layer_z] = area; - // } - //} + // area not computed for sla_print_technology //TODO + if (!sla_print_technology) { + if (plater->fff_print().print_statistics().is_computing_gcode || !plater->fff_print().finished()) { + // do not fetch uncomplete data + m_layers_slider->SetLayersAreas({}); + } else { + const std::vector> &layerz_to_area = + plater->fff_print().print_statistics().layer_area_stats; + std::vector areas; + for (auto [z, area] : layerz_to_area) areas.push_back(area); + m_layers_slider->SetLayersAreas(areas); + assert(areas.size() == m_gcode_result->print_statistics.modes.front().layers_times.size()); + } } + } else { + m_layers_slider->SetLayersTimes({}, 0); + m_layers_slider->SetLayersAreas({}); } // Suggest the auto color change, if model looks like sign @@ -1066,6 +1059,7 @@ void Preview::load_print_as_fff(bool keep_z_range) m_canvas->set_items_show(true, true); m_canvas->set_selected_extruder(0); + bool gcode_not_extrusions = false; if (current_force_state == ForceState::ForceGcode || (gcode_preview_data_valid && current_force_state != ForceState::ForceExtrusions)) { // Load the real G-code preview. if (current_force_state == ForceState::NoForce) @@ -1077,6 +1071,7 @@ void Preview::load_print_as_fff(bool keep_z_range) Refresh(); zs = m_canvas->get_gcode_layers_zs(); m_loaded = true; + gcode_not_extrusions = true; } else if (wxGetApp().is_editor()) { // Load the initial preview based on slices, not the final G-code. @@ -1087,6 +1082,7 @@ void Preview::load_print_as_fff(bool keep_z_range) m_left_sizer->Layout(); Refresh(); zs = m_canvas->get_volumes_print_zs(true); + gcode_not_extrusions = false; } if (!zs.empty() && !m_keep_current_preview_type) { @@ -1116,7 +1112,7 @@ void Preview::load_print_as_fff(bool keep_z_range) hide_layers_slider(); m_canvas_widget->Refresh(); } else { - update_layers_slider(zs, keep_z_range); + update_layers_slider(zs, gcode_not_extrusions, keep_z_range); } } } @@ -1163,7 +1159,7 @@ void Preview::load_print_as_sla() Refresh(); if (n_layers > 0) - update_layers_slider(zs); + update_layers_slider(zs, true); m_loaded = true; } diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 3bc93bb9aee..f9535f0aadb 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -214,7 +214,7 @@ Preview(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrintConfig* config, void check_layers_slider_values(std::vector& ticks_from_model, const std::vector& layers_z); void reset_layers_slider(); - void update_layers_slider(const std::vector& layers_z, bool keep_z_range = false); + void update_layers_slider(const std::vector& layers_z, bool show_gcode_data = false, bool keep_z_range = false); void update_layers_slider_mode(); // update vertical DoubleSlider after keyDown in canvas void update_layers_slider_from_canvas(wxKeyEvent& event); From 542f67e18e9a1d7985ca283f2e8b4078553b13e8 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 10 Jun 2024 15:06:07 +0200 Subject: [PATCH 06/10] Fix crash when wipe into collapsed area supermerill/SuperSlicer#4301 --- src/libslic3r/GCode.cpp | 61 +++++++++++++++++++++------- src/libslic3r/GCode/SeamPlacer.cpp | 2 +- src/libslic3r/MultiPoint.cpp | 8 +++- src/libslic3r/MultiPoint.hpp | 2 +- src/libslic3r/PerimeterGenerator.cpp | 4 +- src/libslic3r/Polygon.cpp | 8 +++- src/libslic3r/Polygon.hpp | 2 +- src/libslic3r/Polyline.hpp | 2 +- src/slic3r/GUI/3DBed.cpp | 2 +- 9 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index f3b090fe97f..e2e49552080 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4188,7 +4188,7 @@ namespace check_wipe { const Point* closest = poly_to_test.closest_point(external_polygon.front()); // because sqrt(2) = 1.42 and it's the worst case if (closest->distance_to(external_polygon.front()) < coordf_t(wipe_inside_depth * 1.43)) { - Point pt_proj = poly_to_test.point_projection(reference); + Point pt_proj = poly_to_test.point_projection(reference).first; Point pt_temp; if (pt_proj.distance_to(reference) < threshold || poly_to_test.intersection(Line{ reference , external_polygon.front() }, &pt_temp)) { //ok @@ -4932,26 +4932,59 @@ std::string GCode::extrude_loop(const ExtrusionLoop &original_loop, const std::s if (!polys.empty()) { // if multiple polygon, keep only our nearest. if (polys.size() > 1) { + Point nearest_pt; + size_t nearest_pt_idx; size_t nearest_poly_idx = size_t(-1); coordf_t best_dist_sqr = dist * dist * 100; for (int idx_poly = 0; idx_poly < polys.size(); ++idx_poly) { Polygon &poly = polys[idx_poly]; - for (int idxpt = 0; idxpt < poly.points.size(); ++idxpt) { - if (coordf_t test_dist = pt_inside.distance_to_square(poly.points[idxpt]); - test_dist < best_dist_sqr) { - nearest_poly_idx = idx_poly; - best_dist_sqr = test_dist; + // use projection + auto [near_pt, near_idx] = poly.point_projection(pt_inside); + if (coordf_t test_dist = pt_inside.distance_to_square(near_pt); + test_dist < best_dist_sqr) { + nearest_poly_idx = idx_poly; + best_dist_sqr = test_dist; + nearest_pt = near_pt; + nearest_pt_idx = near_idx; + } + } + if (nearest_poly_idx == size_t(-1)) { + // too far away, try with lower offset + polys = offset(original_polygon, -dist / 2); + assert(!polys.empty()); + if (!polys.empty()) { + for (int idx_poly = 0; idx_poly < polys.size(); ++idx_poly) { + Polygon &poly = polys[idx_poly]; + auto [near_pt, near_idx] = poly.point_projection(pt_inside); + if (coordf_t test_dist = pt_inside.distance_to_square(near_pt); + test_dist < best_dist_sqr) { + nearest_poly_idx = idx_poly; + best_dist_sqr = test_dist; + nearest_pt = near_pt; + nearest_pt_idx = near_idx; + } } } + // if fail again (weird) reuse our initial poly + } + assert(nearest_poly_idx < polys.size()); + if (nearest_poly_idx < polys.size()) { + if (nearest_poly_idx < polys.size() - 1) + polys.erase(polys.begin() + nearest_poly_idx + 1, polys.end()); + if (nearest_poly_idx > 0 ) + polys.erase(polys.begin(), polys.begin() + nearest_poly_idx); + assert(polys.size() == 1); + assert(nearest_pt_idx < polys.front().points.size()); + if (nearest_pt_idx < polys.front().points.size() && + !polys.front().points[nearest_pt_idx].coincides_with_epsilon(nearest_pt)) { + polys.front().points.insert(polys.front().points.begin() + nearest_pt_idx, nearest_pt); + } + assert(polys.front().closest_point(pt_inside) != nullptr && + std::abs(polys.front().closest_point(pt_inside)->distance_to_square(pt_inside) - + best_dist_sqr) < SCALED_EPSILON); + } else { + polys = { original_polygon }; } - if (nearest_poly_idx + 1 < polys.size()) - polys.erase(polys.begin() + nearest_poly_idx + 1, polys.end()); - if (nearest_poly_idx > 0) - polys.erase(polys.begin(), polys.begin() + nearest_poly_idx); - assert(polys.size() == 1); - assert(polys.front().closest_point(pt_inside) != nullptr && - std::abs(polys.front().closest_point(pt_inside)->distance_to_square(pt_inside) - - best_dist_sqr) < EPSILON); } // This offset may put point so close that they coincides. diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 8dd1457d904..1b1f198de1a 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -1754,7 +1754,7 @@ std::tuple> get_seam_from_modifier(const Layer& layer, double test_lambda_z = std::abs(layer.print_z - test_lambda_pos.z()); Point xy_lambda(scale_(test_lambda_pos.x()), scale_(test_lambda_pos.y())); - Point nearest = polygon.point_projection(xy_lambda); + Point nearest = polygon.point_projection(xy_lambda).first; Vec3d polygon_3dpoint{ unscaled(nearest.x()), unscaled(nearest.y()), (double)layer.print_z }; double test_lambda_dist = (polygon_3dpoint - test_lambda_pos).norm(); double sphere_radius = po->model_object()->instance_bounding_box(0, true).size().x() / 2; diff --git a/src/libslic3r/MultiPoint.cpp b/src/libslic3r/MultiPoint.cpp index 506e36f2a94..313c96f6497 100644 --- a/src/libslic3r/MultiPoint.cpp +++ b/src/libslic3r/MultiPoint.cpp @@ -186,7 +186,8 @@ bool MultiPoint::intersections(const Line &line, Points *intersections) const } // Projection of a point onto the polygon. -Point MultiPoint::point_projection(const Point &point) const { +std::pair MultiPoint::point_projection(const Point &point) const { + size_t pt_idx = size_t(-1); Point proj = point; double dmin = std::numeric_limits::max(); if (!this->points.empty()) { @@ -197,11 +198,13 @@ Point MultiPoint::point_projection(const Point &point) const { if (d < dmin) { dmin = d; proj = pt0; + pt_idx = i; } d = pt1.distance_to(point); if (d < dmin) { dmin = d; proj = pt1; + pt_idx = i + 1; } Vec2d v1(coordf_t(pt1(0) - pt0(0)), coordf_t(pt1(1) - pt0(1))); coordf_t div = dot(v1); @@ -214,12 +217,13 @@ Point MultiPoint::point_projection(const Point &point) const { if (d < dmin) { dmin = d; proj = foot; + pt_idx = i; } } } } } - return proj; + return {proj, pt_idx}; } std::vector MultiPoint::_douglas_peucker(const std::vector& pts, const double tolerance) diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp index 51cf2648981..c65e9807cba 100644 --- a/src/libslic3r/MultiPoint.hpp +++ b/src/libslic3r/MultiPoint.hpp @@ -92,7 +92,7 @@ class MultiPoint bool first_intersection(const Line& line, Point* intersection) const; bool intersections(const Line &line, Points *intersections) const; // Projection of a point onto the lines defined by the points. - virtual Point point_projection(const Point &point) const; + virtual std::pair point_projection(const Point &point) const; static Points _douglas_peucker(const Points& points, const double tolerance); static Points _douglas_peucker_plus(const Points& points, const double tolerance, const double min_length); diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index acc6cf6ab50..3f9b0130ddf 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -3889,7 +3889,7 @@ PerimeterGenerator::_get_nearest_point(const PerimeterGeneratorLoops &children, //don't check the last point, as it's used to go outter, can't use it to go inner. for (size_t idx_point = 1; idx_point < myPolylines.paths[idx_poly].polyline.size()-1; idx_point++) { const Point &p = myPolylines.paths[idx_poly].polyline.get_points()[idx_point]; - Point nearest_p = child.polygon.point_projection(p); + Point nearest_p = child.polygon.point_projection(p).first; coord_t dist = (coord_t)nearest_p.distance_to(p); //if no projection, go to next if (dist == 0) continue; @@ -3917,7 +3917,7 @@ PerimeterGenerator::_get_nearest_point(const PerimeterGeneratorLoops &children, //lastly, try to check from one of his points for (size_t idx_point = 0; idx_point < child.polygon.size(); idx_point++) { const Point &p = child.polygon.points[idx_point]; - Point nearest_p = myPolylines.paths[idx_poly].polyline.point_projection(p); + Point nearest_p = myPolylines.paths[idx_poly].polyline.point_projection(p).first; coord_t dist = (coord_t)nearest_p.distance_to(p); //if no projection, go to next if (dist == 0) continue; diff --git a/src/libslic3r/Polygon.cpp b/src/libslic3r/Polygon.cpp index c10dcb55a6b..0142461b57a 100644 --- a/src/libslic3r/Polygon.cpp +++ b/src/libslic3r/Polygon.cpp @@ -262,8 +262,9 @@ std::vector Polygon::convex_points_idx(double angle) const } // Projection of a point onto the polygon. -Point Polygon::point_projection(const Point &point) const +std::pair Polygon::point_projection(const Point &point) const { + size_t pt_idx = size_t(-1); Point proj = point; double dmin = std::numeric_limits::max(); if (! this->points.empty()) { @@ -274,11 +275,13 @@ Point Polygon::point_projection(const Point &point) const if (d < dmin) { dmin = d; proj = pt0; + pt_idx = i; } d = (point - pt1).cast().norm(); if (d < dmin) { dmin = d; proj = pt1; + pt_idx = (i + 1 == this->points.size()) ? 0 : i + 1; } Vec2d v1(coordf_t(pt1(0) - pt0(0)), coordf_t(pt1(1) - pt0(1))); coordf_t div = v1.squaredNorm(); @@ -291,12 +294,13 @@ Point Polygon::point_projection(const Point &point) const if (d < dmin) { dmin = d; proj = foot; + pt_idx = i; } } } } } - return proj; + return {proj, pt_idx}; } std::vector Polygon::parameter_by_length() const diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 137c4f69115..833d1ffdf71 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -72,7 +72,7 @@ class Polygon : public MultiPoint std::vector concave_points_idx(double angle = PI) const; std::vector convex_points_idx(double angle = PI) const; // Projection of a point onto the polygon. - Point point_projection(const Point &point) const; + std::pair point_projection(const Point &point) const override; std::vector parameter_by_length() const; /// remove points that are (almost) on an existing line from previous & next point. /// return number of point removed diff --git a/src/libslic3r/Polyline.hpp b/src/libslic3r/Polyline.hpp index 06ffb8ea164..e19cbd35709 100644 --- a/src/libslic3r/Polyline.hpp +++ b/src/libslic3r/Polyline.hpp @@ -340,7 +340,7 @@ class PolylineOrArc : /*public*/ Polyline { int find_point(const Point& point) const { return Polyline::find_point(point); } int find_point(const Point& point, const double scaled_epsilon) const { return Polyline::find_point(point, scaled_epsilon); } int closest_point_index(const Point& point) const { return Polyline::closest_point_index(point); } - Point point_projection(const Point& point) const { return Polyline::point_projection(point); } + std::pair point_projection(const Point& point) const { return Polyline::point_projection(point); } virtual void reverse() override; diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp index 15f3b9f58fe..25c31bfd64b 100644 --- a/src/slic3r/GUI/3DBed.cpp +++ b/src/slic3r/GUI/3DBed.cpp @@ -264,7 +264,7 @@ bool Bed3D::contains(const Point& point) const Point Bed3D::point_projection(const Point& point) const { - return m_polygon.point_projection(point); + return m_polygon.point_projection(point).first; } void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture) From f5cc8db19e6b025825aa0dfec992f251613ab344 Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 10 Jun 2024 16:11:34 +0200 Subject: [PATCH 07/10] Fix seam notch for outer perimeters. supermerill/SuperSlicer/#4305 --- src/libslic3r/GCode.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index e2e49552080..213ccee2774 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4316,10 +4316,10 @@ void GCode::seam_notch(const ExtrusionLoop& original_loop, if (next_point == start_point || prev_point == end_point) { throw Slic3r::SlicingError(_(L("Error while writing gcode: two points are at the same position. Please send the .3mf project to the dev team for debugging. Extrude loop: seam notch."))); } + if(building_paths.size() == 1) + assert(is_full_loop_ccw == Polygon(building_paths.front().polyline.get_points()).is_counter_clockwise()); double angle = PI / 2; - if (is_hole_loop ? is_full_loop_ccw : (!is_full_loop_ccw)) { - // swap points - next_point = *(building_paths.back().polyline.get_points().end() - 2); + if (is_hole_loop ? (is_full_loop_ccw) : (!is_full_loop_ccw)) { angle *= -1; } Vec2d vec_start = next_point.cast() - start_point.cast(); @@ -4335,9 +4335,9 @@ void GCode::seam_notch(const ExtrusionLoop& original_loop, //use a vec that is the mean between the two. vec_start = (vec_start + vec_end) / 2; - Point moved_start = (start_point.cast() + vec_start * notch_value).cast();; + Point moved_start = (start_point.cast() + vec_start * notch_value).cast(); moved_start.rotate(angle, start_point); - Point moved_end = (end_point.cast() + vec_start * notch_value).cast();; + Point moved_end = (end_point.cast() + vec_start * notch_value).cast(); moved_end.rotate(angle, end_point); //check if the current angle isn't too sharp @@ -4552,7 +4552,7 @@ void GCode::seam_notch(const ExtrusionLoop& original_loop, }; create_new_extrusion(notch_extrusion_end, building_paths.back(), check_length_clipped(p2)?0.75f:0.f, building_paths.back().last_point(), p2); create_new_extrusion(notch_extrusion_end, building_paths.back(), check_length_clipped(p1) ? 0.5f : 0.f, p2, p1); - create_new_extrusion(notch_extrusion_end, building_paths.back(), 0.f, p1, moved_end); + create_new_extrusion(notch_extrusion_end, building_paths.back(), 0.f, p1, moved_end); // 0 instead of 25%, to remove a bit of material at the nd, for oozing and pressure reduction. } else { create_new_extrusion(notch_extrusion_end, building_paths.back(), 0.5f, building_paths.back().last_point(), moved_end); } From 44afda57b66224a4728da6b09e0461818827d5ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Wed, 3 Jan 2024 23:55:02 +0100 Subject: [PATCH 08/10] Replace some deprecated boost functions. Actually, all those deprecated functions were internally called those new functions. So there isn't any risk to use them directly. --- src/libslic3r/PrintBase.cpp | 2 +- src/libslic3r/utils.cpp | 2 +- src/slic3r/GUI/RemovableDriveManager.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/PrintBase.cpp b/src/libslic3r/PrintBase.cpp index 29bdc1301d0..60e40644cb8 100644 --- a/src/libslic3r/PrintBase.cpp +++ b/src/libslic3r/PrintBase.cpp @@ -123,7 +123,7 @@ std::string PrintBase::output_filename(const std::string &format, const std::str filepath = filename + extension; } if (filepath.extension().empty()) - filepath = boost::filesystem::change_extension(filepath, default_ext); + filepath.replace_extension(default_ext); return filepath.string(); } catch (std::runtime_error &err) { throw Slic3r::PlaceholderParserError(L("Failed processing of the output_filename_format template.") + "\n" + err.what()); diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 71089ceea64..6eac962b20e 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -836,7 +836,7 @@ CopyFileResult copy_file_inner(const boost::filesystem::path& source, const boos // That may happen when copying on some exotic file system, for example Linux on Chrome. copy_file_linux(source, target, ec); #else // __linux__ - boost::filesystem::copy_file(source, target, boost::filesystem::copy_option::overwrite_if_exists, ec); + boost::filesystem::copy_file(source, target, boost::filesystem::copy_options::overwrite_existing, ec); #endif // __linux__ if (ec) { error_message = ec.message(); diff --git a/src/slic3r/GUI/RemovableDriveManager.cpp b/src/slic3r/GUI/RemovableDriveManager.cpp index 5fb8b013210..2f8ac96a1a2 100644 --- a/src/slic3r/GUI/RemovableDriveManager.cpp +++ b/src/slic3r/GUI/RemovableDriveManager.cpp @@ -202,7 +202,7 @@ namespace search_for_drives_internal stat(path.c_str(), &buf); uid_t uid = buf.st_uid; if (getuid() == uid) - out.emplace_back(DriveData{ boost::filesystem::basename(boost::filesystem::path(path)), path }); + out.emplace_back(DriveData{ boost::filesystem::path(path).stem().string(), path }); } } } From 6672c1383577fef97fa38932893b3be04debdb3f Mon Sep 17 00:00:00 2001 From: supermerill Date: Mon, 10 Jun 2024 19:13:03 +0200 Subject: [PATCH 09/10] fix bad support grid (introduced by fill_aligned_z, caa4a0) supermerill/SuperSlicer#4306 --- src/libslic3r/Fill/Fill3DHoneycomb.cpp | 2 +- src/libslic3r/Fill/FillAdaptive.cpp | 2 +- src/libslic3r/Fill/FillBase.cpp | 79 +++++++++++++------------- src/libslic3r/Fill/FillBase.hpp | 18 +++--- src/libslic3r/Fill/FillGyroid.cpp | 2 +- src/libslic3r/Fill/FillHoneycomb.cpp | 2 +- src/libslic3r/Fill/FillLightning.cpp | 2 +- src/libslic3r/Fill/FillPlanePath.cpp | 2 +- src/libslic3r/Fill/FillRectilinear.cpp | 5 +- src/libslic3r/Print.hpp | 3 +- 10 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/src/libslic3r/Fill/Fill3DHoneycomb.cpp index eb852658b76..0d668adae99 100644 --- a/src/libslic3r/Fill/Fill3DHoneycomb.cpp +++ b/src/libslic3r/Fill/Fill3DHoneycomb.cpp @@ -170,7 +170,7 @@ void Fill3DHoneycomb::_fill_surface_single( if (params.connection == icNotConnected || polylines.size() <= 1) append(polylines_out, chain_polylines(std::move(polylines))); else - this->connect_infill(std::move(polylines), expolygon, polylines_out, this->get_spacing(), params); + this->connect_infill(std::move(polylines), expolygon, polylines_out, scale_t(this->get_spacing()), params); } } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp index d46bf192242..52412405c9c 100644 --- a/src/libslic3r/Fill/FillAdaptive.cpp +++ b/src/libslic3r/Fill/FillAdaptive.cpp @@ -1405,7 +1405,7 @@ void Filler::_fill_surface_single( if (params.connection == InfillConnection::icNotConnected || all_polylines_with_hooks.size() <= 1) append(polylines_out, chain_polylines(std::move(all_polylines_with_hooks))); else - connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, this->get_spacing(), params); + connect_infill(std::move(all_polylines_with_hooks), expolygon, polylines_out, scale_t(this->get_spacing()), params); #ifdef ADAPTIVE_CUBIC_INFILL_DEBUG_OUTPUT { diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 5a18e1e555c..57179471fd2 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -630,13 +630,13 @@ Points getFrontier(Polylines& polylines, const Point& p1, const Point& p2, const /// return the connected polylines in polylines_out. Can output polygons (stored as polylines with first_point = last_point). /// complexity: worst: N(infill_ordered.points) x N(boundary.points) /// typical: N(infill_ordered) x ( N(boundary.points) + N(infill_ordered.points) ) -void connect_infill(const Polylines& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const double spacing, const FillParams& params) { +void connect_infill(const Polylines& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const coord_t spacing, const FillParams& params) { //TODO: fallback to the quick & dirty old algorithm when n(points) is too high. Polylines polylines_frontier = to_polylines(((Polygons)boundary)); Polylines polylines_blocker; - coord_t clip_size = scale_(spacing) * 2; + coord_t clip_size = (spacing) * 2; for (const Polyline& polyline : infill_ordered) { if (polyline.length() > 2.01 * clip_size) { polylines_blocker.push_back(polyline); @@ -656,8 +656,8 @@ void connect_infill(const Polylines& infill_ordered, const ExPolygon& boundary, Points& pts_end = polylines_connected_first.back().points; const Point& last_point = pts_end.back(); const Point& first_point = polyline.points.front(); - if (last_point.distance_to(first_point) < scale_(spacing) * 10) { - Points pts_frontier = getFrontier(polylines_frontier, last_point, first_point, scale_(spacing), polylines_blocker, scale_(ideal_length) * 2); + if (last_point.distance_to(first_point) < (spacing) * 10) { + Points pts_frontier = getFrontier(polylines_frontier, last_point, first_point, (spacing), polylines_blocker, (ideal_length) * 2); if (!pts_frontier.empty()) { // The lines can be connected. pts_end.insert(pts_end.end(), pts_frontier.begin(), pts_frontier.end()); @@ -682,7 +682,7 @@ void connect_infill(const Polylines& infill_ordered, const ExPolygon& boundary, const Point& first_point = polyline.points.front(); Polylines before = polylines_frontier; - Points pts_frontier = getFrontier(polylines_frontier, last_point, first_point, scale_(spacing), polylines_blocker); + Points pts_frontier = getFrontier(polylines_frontier, last_point, first_point, (spacing), polylines_blocker); if (!pts_frontier.empty()) { // The lines can be connected. pts_end.insert(pts_end.end(), pts_frontier.begin(), pts_frontier.end()); @@ -719,7 +719,7 @@ void connect_infill(const Polylines& infill_ordered, const ExPolygon& boundary, Points pts_frontier = getFrontier(polylines_frontier, switch_id1 ? polylines_connected[idx1].first_point() : polylines_connected[idx1].last_point(), switch_id2 ? polylines_connected[min_idx].last_point() : polylines_connected[min_idx].first_point(), - scale_(spacing), polylines_blocker); + (spacing), polylines_blocker); if (!pts_frontier.empty()) { if (switch_id1) polylines_connected[idx1].reverse(); if (switch_id2) polylines_connected[min_idx].reverse(); @@ -733,7 +733,7 @@ void connect_infill(const Polylines& infill_ordered, const ExPolygon& boundary, //try to create some loops if possible for (Polyline& polyline : polylines_connected) { - Points pts_frontier = getFrontier(polylines_frontier, polyline.last_point(), polyline.first_point(), scale_(spacing), polylines_blocker); + Points pts_frontier = getFrontier(polylines_frontier, polyline.last_point(), polyline.first_point(), (spacing), polylines_blocker); if (!pts_frontier.empty()) { polyline.points.insert(polyline.points.end(), pts_frontier.begin(), pts_frontier.end()); polyline.points.insert(polyline.points.begin(), polyline.points.back()); @@ -1054,7 +1054,7 @@ namespace PrusaSimpleConnect { } } - void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_src, Polylines &polylines_out, const double spacing, const FillParams ¶ms) + void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary_src, Polylines &polylines_out, const coord_t spacing, const FillParams ¶ms) { assert(!infill_ordered.empty()); assert(!boundary_src.contour.points.empty()); @@ -1133,16 +1133,16 @@ namespace PrusaSimpleConnect { // Mark the points and segments of split boundary as consumed if they are very close to some of the infill line. { - // @supermerill used 2. * scale_(spacing) - const double clip_distance = 3. * scale_(spacing); - const double distance_colliding = 1.1 * scale_(spacing); + // @supermerill used 2. * (spacing) + const double clip_distance = 3. * (spacing); + const double distance_colliding = 1.1 * (spacing); mark_boundary_segments_touching_infill(boundary, boundary_data, bbox, infill_ordered, clip_distance, distance_colliding); } // Connection from end of one infill line to the start of another infill line. - //const float length_max = scale_(spacing); - // const float length_max = scale_((2. / params.density) * spacing); - const coord_t length_max = scale_((1000. / params.density) * spacing); + //const float length_max = (spacing); + // const float length_max = ((2. / params.density) * spacing); + const coord_t length_max = ((1000. / params.density) * spacing); std::vector merged_with(infill_ordered.size()); for (size_t i = 0; i < merged_with.size(); ++i) merged_with[i] = i; @@ -2170,7 +2170,7 @@ void mark_boundary_segments_touching_infill( assert(validate_boundary_intersections(boundary_intersections)); } -void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary_src, Polylines& polylines_out, const double spacing, const FillParams& params) +void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary_src, Polylines& polylines_out, const coord_t spacing, const FillParams& params) { assert(!boundary_src.contour.points.empty()); auto polygons_src = reserve_vector(boundary_src.holes.size() + 1); @@ -2183,7 +2183,7 @@ void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary_src, P connect_infill(std::move(infill_ordered), polygons_src, get_extents(boundary_src.contour), polylines_out, spacing, params); } -void connect_infill(Polylines&& infill_ordered, const Polygons& boundary_src, const BoundingBox& bbox, Polylines& polylines_out, const double spacing, const FillParams& params) +void connect_infill(Polylines&& infill_ordered, const Polygons& boundary_src, const BoundingBox& bbox, Polylines& polylines_out, const coord_t spacing, const FillParams& params) { auto polygons_src = reserve_vector(boundary_src.size()); for (const Polygon& polygon : boundary_src) @@ -2286,7 +2286,7 @@ static inline void mark_boundary_segments_overlapping_infill( // Infill lines, either completely inside the boundary, or touching the boundary. const Polylines &infill, // Spacing (width) of the infill lines. - const double spacing) + const coord_t spacing) { for (ContourIntersectionPoint &cp : graph.map_infill_end_point_to_boundary) { const Points &contour = graph.boundary[cp.contour_idx]; @@ -2361,7 +2361,7 @@ static inline void mark_boundary_segments_overlapping_infill( } } -BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, const double spacing) +BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, const coord_t spacing) { BoundaryInfillGraph out; out.boundary.assign(boundary_src.size(), Points()); @@ -2485,12 +2485,12 @@ BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered // Mark the points and segments of split out.boundary as consumed if they are very close to some of the infill line. { - // @supermerill used 2. * scale_(spacing) - const double clip_distance = 1.7 * scale_(spacing); + // @supermerill used 2. * (spacing) + const double clip_distance = 1.7 * (spacing); // Allow a bit of overlap. This value must be slightly higher than the overlap of FillAdaptive, otherwise // the anchors of the adaptive infill will mask the other side of the perimeter line. // (see connect_lines_using_hooks() in FillAdaptive.cpp) - const double distance_colliding = 0.8 * scale_(spacing); + const double distance_colliding = 0.8 * (spacing); mark_boundary_segments_touching_infill(out.boundary, out.boundary_params, boundary_intersection_points, bbox, infill_ordered, clip_distance, distance_colliding); } } @@ -2498,7 +2498,7 @@ BoundaryInfillGraph create_boundary_infill_graph(const Polylines &infill_ordered return out; } -void connect_infill(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms) +void connect_infill(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const coord_t spacing, const FillParams ¶ms) { assert(! infill_ordered.empty()); assert(params.anchor_length >= 0.); @@ -2545,13 +2545,13 @@ void connect_infill(Polylines &&infill_ordered, const std::vector::max(); }; - const double line_half_width = 0.5 * scale_(spacing); + const double line_half_width = 0.5 * (spacing); #if 0 // Connection from end of one infill line to the start of another infill line. - //const double length_max = scale_(spacing); -// const auto length_max = double(scale_((2. / params.density) * spacing)); - const auto length_max = double(scale_((1000. / params.density) * spacing)); + //const double length_max = (spacing); +// const auto length_max = double(((2. / params.density) * spacing)); + const auto length_max = double(((1000. / params.density) * spacing)); struct ConnectionCost { ConnectionCost(size_t idx_first, double cost, bool reversed) : idx_first(idx_first), cost(cost), reversed(reversed) {} size_t idx_first; @@ -2746,7 +2746,7 @@ void connect_infill(Polylines &&infill_ordered, const std::vector evaluate_support_arches(Polylines &infill, BoundaryInfillGraph &graph, const double spacing, const FillParams ¶ms) +static inline std::vector evaluate_support_arches(Polylines &infill, BoundaryInfillGraph &graph, const FillParams ¶ms) { std::vector arches(graph.map_infill_end_point_to_boundary.size() * 2); @@ -3161,13 +3159,15 @@ static inline std::vector evaluate_support_arches(Polylines &inf } // end namespace FakePerimeterConnect // Both the poly_with_offset and polylines_out are rotated, so the infill lines are strictly vertical. -void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms) +void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const coord_t line_spacing, const FillParams ¶ms) { // assert(! infill_ordered.empty()); assert(params.anchor_length >= 0.); assert(params.anchor_length_max >= 0.01f); assert(params.anchor_length_max >= params.anchor_length); + coord_t spacing = line_spacing * params.density; + FakePerimeterConnect::BoundaryInfillGraph graph = FakePerimeterConnect::create_boundary_infill_graph(infill_ordered, boundary_src, bbox, spacing); #ifdef INFILL_DEBUG_OUTPUT @@ -3176,15 +3176,14 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector 0) ? params.max_sparse_infill_spacing : spacing) / params.density; + const double line_half_width = 0.5 * spacing; const double min_arch_length = 1.3 * line_spacing; const double trim_length = line_half_width * 0.3; // After mark_boundary_segments_touching_infill() marks boundary segments overlapping trimmed infill lines, // there are possibly some very short boundary segments unmarked, but overlapping the untrimmed infill lines fully. // Mark those short boundary segments. - mark_boundary_segments_overlapping_infill(graph, infill_ordered, scale_(spacing)); + mark_boundary_segments_overlapping_infill(graph, infill_ordered, spacing); #ifdef INFILL_DEBUG_OUTPUT export_partial_infill_to_svg(debug_out_path("connect_base_support-marked-%03d.svg", iRun), graph, infill_ordered, polylines_out); @@ -3240,7 +3239,7 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector arches = FakePerimeterConnect::evaluate_support_arches(infill_ordered, graph, spacing, params); + const std::vector arches = FakePerimeterConnect::evaluate_support_arches(infill_ordered, graph, params); static const double cost_low = line_spacing * 1.3; static const double cost_high = line_spacing * 2.; static const double cost_veryhigh = line_spacing * 3.; @@ -3616,16 +3615,16 @@ void Fill::connect_base_support(Polylines &&infill_ordered, const std::vector(boundary_src.size()); for (const Polygon &polygon : boundary_src) polygons_src.emplace_back(&polygon); - connect_base_support(std::move(infill_ordered), polygons_src, bbox, polylines_out, spacing, params); + connect_base_support(std::move(infill_ordered), polygons_src, bbox, polylines_out, line_spacing, params); } -void Fill::connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const double spacing, const FillParams& params) { +void Fill::connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const coord_t spacing, const FillParams& params) { if (params.anchor_length_max == 0) { PrusaSimpleConnect::connect_infill(std::move(infill_ordered), boundary, polylines_out, spacing, params); } else { @@ -3633,7 +3632,7 @@ void Fill::connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, } } -void Fill::connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, const Polygons& polygons_src, Polylines& polylines_out, const double spacing, const FillParams& params) { +void Fill::connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, const Polygons& polygons_src, Polylines& polylines_out, const coord_t spacing, const FillParams& params) { if (params.anchor_length_max == 0) { PrusaSimpleConnect::connect_infill(std::move(infill_ordered), boundary, polylines_out, spacing, params); } else { diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index c6a876de601..9d37d1c3286 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -215,26 +215,26 @@ class Fill } public: - static void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const double spacing, const FillParams& params); + static void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const coord_t spacing, const FillParams& params); //for rectilinear - static void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, const Polygons& polygons_src, Polylines& polylines_out, const double spacing, const FillParams& params); + static void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, const Polygons& polygons_src, Polylines& polylines_out, const coord_t spacing, const FillParams& params); - static void connect_base_support(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms); - static void connect_base_support(Polylines &&infill_ordered, const Polygons &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const double spacing, const FillParams ¶ms); + static void connect_base_support(Polylines &&infill_ordered, const std::vector &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const coord_t line_spacing, const FillParams ¶ms); + static void connect_base_support(Polylines &&infill_ordered, const Polygons &boundary_src, const BoundingBox &bbox, Polylines &polylines_out, const coord_t line_spacing, const FillParams ¶ms); static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance, const double factor_max = 1.2); }; namespace FakePerimeterConnect { - void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const double spacing, const FillParams& params); - void connect_infill(Polylines&& infill_ordered, const Polygons& boundary, const BoundingBox& bbox, Polylines& polylines_out, const double spacing, const FillParams& params); - void connect_infill(Polylines&& infill_ordered, const std::vector& boundary, const BoundingBox& bbox, Polylines& polylines_out, double spacing, const FillParams& params); + void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const coord_t spacing, const FillParams& params); + void connect_infill(Polylines&& infill_ordered, const Polygons& boundary, const BoundingBox& bbox, Polylines& polylines_out, const coord_t spacing, const FillParams& params); + void connect_infill(Polylines&& infill_ordered, const std::vector& boundary, const BoundingBox& bbox, Polylines& polylines_out, coord_t spacing, const FillParams& params); } namespace PrusaSimpleConnect { - void connect_infill(Polylines& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const double spacing, const FillParams& params); + void connect_infill(Polylines& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const coord_t spacing, const FillParams& params); } namespace NaiveConnect { - void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const double spacing, const FillParams& params); + void connect_infill(Polylines&& infill_ordered, const ExPolygon& boundary, Polylines& polylines_out, const coord_t spacing, const FillParams& params); } // composite filler diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index c276b76b28d..1f8b7821fbb 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -192,7 +192,7 @@ void FillGyroid::_fill_surface_single( if (params.connection == icNotConnected){ append(polylines_out, chain_polylines(polylines)); } else { - this->connect_infill(chain_polylines(polylines), expolygon, polylines_out, this->get_spacing(), params); + this->connect_infill(chain_polylines(polylines), expolygon, polylines_out, scale_t(this->get_spacing()), params); } // new paths must be rotated back if (std::abs(infill_angle) >= EPSILON) { diff --git a/src/libslic3r/Fill/FillHoneycomb.cpp b/src/libslic3r/Fill/FillHoneycomb.cpp index 41dd02d62c2..b320e1652d5 100644 --- a/src/libslic3r/Fill/FillHoneycomb.cpp +++ b/src/libslic3r/Fill/FillHoneycomb.cpp @@ -82,7 +82,7 @@ void FillHoneycomb::_fill_surface_single( if (params.connection == icNotConnected || all_polylines.size() <= 1) append(polylines_out, chain_polylines(std::move(all_polylines))); else - connect_infill(std::move(all_polylines), expolygon, polylines_out, this->get_spacing(), params); + connect_infill(std::move(all_polylines), expolygon, polylines_out, scale_t(this->get_spacing()), params); } } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillLightning.cpp b/src/libslic3r/Fill/FillLightning.cpp index d02353c8ff4..1548b858cf9 100644 --- a/src/libslic3r/Fill/FillLightning.cpp +++ b/src/libslic3r/Fill/FillLightning.cpp @@ -19,7 +19,7 @@ void Filler::_fill_surface_single( if (params.dont_connect() || fill_lines.size() <= 1) { append(polylines_out, chain_polylines(std::move(fill_lines))); } else - connect_infill(std::move(fill_lines), expolygon, polylines_out, this->get_spacing(), params); + connect_infill(std::move(fill_lines), expolygon, polylines_out, scale_t(this->get_spacing()), params); } void GeneratorDeleter::operator()(Generator *p) { diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index 086fbd4e391..d5b17d443cc 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -67,7 +67,7 @@ void FillPlanePath::_fill_surface_single( if (params.dont_connect() || params.density > 0.5 || all_poly.size() <= 1) chained = chain_polylines(std::move(all_poly)); else - connect_infill(std::move(all_poly), expolygon, chained, this->get_spacing(), params); + connect_infill(std::move(all_poly), expolygon, chained, scale_t(this->get_spacing()), params); // paths must be repositioned and rotated back for (Polyline &pl : chained) { pl.translate(double(shift.x()), double(shift.y())); diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 3c571e79e93..76984b8dbd6 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -3162,7 +3162,7 @@ bool FillRectilinear::fill_surface_by_multilines(const Surface *surface, FillPar fill_lines = chain_polylines(std::move(fill_lines)); append(polylines_out, std::move(fill_lines)); } else - connect_infill(std::move(fill_lines), surface->expolygon, poly_with_offset_base.polygons_outer, polylines_out, this->get_spacing(), params); + connect_infill(std::move(fill_lines), surface->expolygon, poly_with_offset_base.polygons_outer, polylines_out, scale_t(this->get_spacing()), params); return true; } @@ -3242,8 +3242,9 @@ Polylines FillSupportBase::fill_surface(const Surface *surface, const FillParams coord_t line_spacing = _line_spacing_for_density(params); // Create infill lines, keep them vertical. make_fill_lines(poly_with_offset, rotate_vector.second.rotated(- rotate_vector.first), 0, 0, line_spacing, 0, fill_lines, params); + // Both the poly_with_offset and polylines_out are rotated, so the infill lines are strictly vertical. - connect_base_support(std::move(fill_lines), poly_with_offset.polygons_outer, poly_with_offset.bounding_box_outer(), polylines_out, this->get_spacing(), params); + connect_base_support(std::move(fill_lines), poly_with_offset.polygons_outer, poly_with_offset.bounding_box_outer(), polylines_out, _line_spacing_for_density(params), params); // Rotate back by rotate_vector.first const double cos_a = cos(rotate_vector.first); const double sin_a = sin(rotate_vector.first); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 3ba0ef55b1a..a353f0b8d0f 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -441,8 +441,7 @@ class PrintObject : public PrintObjectBaseWithState Date: Mon, 10 Jun 2024 19:28:09 +0200 Subject: [PATCH 10/10] Fix deactivate seam visibility search if disabled. --- src/libslic3r/Fill/Fill.cpp | 2 +- src/libslic3r/Fill/FillPlanePath.cpp | 2 +- src/libslic3r/GCode/SeamPlacer.cpp | 8 ++++++-- src/libslic3r/SupportMaterial.cpp | 12 ++++++------ 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 9f3b3848ea5..6577395f17e 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -939,7 +939,7 @@ void Layer::make_ironing() fill.init_spacing(ironing_params.line_spacing, fill_params); fill.can_angle_cross = region_config.fill_angle_cross.value; fill.angle = float(ironing_params.angle); - fill.link_max_length = (coord_t)scale_(3. * fill.get_spacing()); + fill.link_max_length = scale_t(3. * fill.get_spacing()); double extrusion_height = ironing_params.height * fill.get_spacing() / nozzle_dmr; //FIXME FLOW decide if it's good // note: don't use filament_max_overlap, as it's a top surface diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index d5b17d443cc..4d828b8fad6 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -15,7 +15,7 @@ void FillPlanePath::_fill_surface_single( { expolygon.rotate(- direction.first); - coord_t distance_between_lines = coord_t(scale_(this->get_spacing()) / params.density); + coord_t distance_between_lines = scale_t(this->get_spacing() / params.density); // align infill across layers using the object's bounding box // Rotated bounding box of the whole object. diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp index 1b1f198de1a..5ec022a55e3 100644 --- a/src/libslic3r/GCode/SeamPlacer.cpp +++ b/src/libslic3r/GCode/SeamPlacer.cpp @@ -784,8 +784,9 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po, throw_if_canceled(); BOOST_LOG_TRIVIAL(debug) << "SeamPlacer: build AABB tree: end"; + bool has_seam_visibility = po->config().seam_visibility.value && po->config().seam_position.value == SeamPosition::spCost; result.mesh_samples_visibility = raycast_visibility(raycasting_tree, triangle_set, result.mesh_samples, - negative_volumes_start_index, !po->config().seam_visibility.value); + negative_volumes_start_index, !has_seam_visibility); throw_if_canceled(); #ifdef DEBUG_FILES result.debug_export(triangle_set); @@ -840,7 +841,10 @@ struct SeamComparator { travel_importance = (float)po.config().seam_travel_cost.get_abs_value(1.f); angle_importance = (float)po.config().seam_angle_cost.get_abs_value(1.f); } - visibility_importance = po.config().seam_visibility.value ? 1.f : 0.f; + visibility_importance = (po.config().seam_visibility.value && + po.config().seam_position.value == SeamPosition::spCost) ? + 1.f : + 0.f; } // Standard comparator, must respect the requirements of comparators (e.g. give same result on same inputs) for sorting usage diff --git a/src/libslic3r/SupportMaterial.cpp b/src/libslic3r/SupportMaterial.cpp index 8993cd9bcde..be84a97c838 100644 --- a/src/libslic3r/SupportMaterial.cpp +++ b/src/libslic3r/SupportMaterial.cpp @@ -3417,7 +3417,7 @@ static inline void fill_expolygon_generate_paths( float density, ExtrusionRole role, const Flow &flow, - coordf_t spacing) + double spacing) { assert(!fill_params.use_arachne); FillParams new_params = fill_params; @@ -3440,7 +3440,7 @@ static inline void fill_expolygons_generate_paths( float density, ExtrusionRole role, const Flow &flow, - coordf_t spacing) + double spacing) { for (ExPolygon& expoly : expolygons) fill_expolygon_generate_paths(dst, std::move(expoly), filler, fill_params, density, role, flow, spacing); @@ -3453,7 +3453,7 @@ static inline void fill_expolygons_generate_paths( float density, ExtrusionRole role, const Flow &flow, - coordf_t spacing, + double spacing, const PrintRegionConfig& region_config) { FillParams fill_params; @@ -4401,7 +4401,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( //filler->layer_id = support_layer_id; // don't do that, or the filler will rotate thigns from that layerid filler->z = support_layer.print_z; float supp_density = m_support_params.interface_density; - coordf_t filler_spacing; + double filler_spacing; //if first layer and solid first layer : draw concentric with 100% density if (support_layer.id() == 0 && layer_ex.layer->bottom_z <= 0) { filler = filler_first_layer_ptr.get(); @@ -4441,7 +4441,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( // Base interface layers under soluble interfaces if ( ! base_interface_layer.empty() && ! base_interface_layer.polygons_to_extrude().empty()) { Fill *filler = filler_base_interface.get(); - coordf_t filler_spacing = filler->get_spacing(); + double filler_spacing = filler->get_spacing(); //FIXME Bottom interfaces are extruded with the briding flow. Some bridging layers have its height slightly reduced, therefore // the bridging flow does not quite apply. Reduce the flow to area of an ellipse? (A = pi * a * b) assert(! base_interface_layer.layer->bridging); @@ -4465,7 +4465,7 @@ void PrintObjectSupportMaterial::generate_toolpaths( // Base support or flange. if (! base_layer.empty() && ! base_layer.polygons_to_extrude().empty()) { Fill *filler = filler_support.get(); - coordf_t filler_spacing = m_support_params.support_material_flow.spacing(); + double filler_spacing = m_support_params.support_material_flow.spacing(); // We don't use $base_flow->spacing because we need a constant spacing // value that guarantees that all layers are correctly aligned. assert(! base_layer.layer->bridging);