From f27605eac166d36b79f4db8890cd38f19adc1fc2 Mon Sep 17 00:00:00 2001 From: Rodrigo Faselli <162915171+RF47@users.noreply.github.com> Date: Tue, 27 Jan 2026 19:12:18 -0300 Subject: [PATCH 1/2] 3d honeycomb bug fix (with infill combination) improve bridge direction (#12062) * fill 3d honeycomb bugfix * fix bridges Co-Authored-By: tome9111991 <57866234+tome9111991@users.noreply.github.com> * Fix typo * cleaning * Remove bridging angle adjustment for ip3DHoneycomb * Adjust layer height scaling for infill consistency * PR comments --------- Co-authored-by: tome9111991 <57866234+tome9111991@users.noreply.github.com> --- src/libslic3r/Fill/Fill3DHoneycomb.cpp | 6 ++++-- src/libslic3r/PrintObject.cpp | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/libslic3r/Fill/Fill3DHoneycomb.cpp b/src/libslic3r/Fill/Fill3DHoneycomb.cpp index de4aaeacd3..6429a81073 100644 --- a/src/libslic3r/Fill/Fill3DHoneycomb.cpp +++ b/src/libslic3r/Fill/Fill3DHoneycomb.cpp @@ -224,7 +224,9 @@ void Fill3DHoneycomb::_fill_surface_single( // This means that the resultant infill won't be an ideal truncated octahedron, // but it should look better than the equivalent quantised version - coordf_t layerHeight = scale_(thickness_layers); + //Orca: uses a fixed layer height to avoid inconsistent bridges and variable layer height artifacts. + //coordf_t layerHeight = scale_(thickness_layers); + coordf_t layerHeight = scale_(1.0); // ceiling to an integer value of layers per Z // (with a little nudge in case it's close to perfect) coordf_t layersPerModule = floor((gridSize * 2) / (zScale * layerHeight) + 0.05); @@ -300,4 +302,4 @@ void Fill3DHoneycomb::_fill_surface_single( } } -} // namespace Slic3r \ No newline at end of file +} // namespace Slic3r diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 4b4237dca1..fc68fce76b 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -2615,13 +2615,16 @@ void PrintObject::bridge_over_infill() auto determine_bridging_angle = [](const Polygons &bridged_area, const Lines &anchors, InfillPattern dominant_pattern, double infill_direction) { AABBTreeLines::LinesDistancer lines_tree(anchors); + // Orca: since 3D Honeycomb was "fixed" by forcing coordf_t layerHeight = scale_(1.0), this is no longer needed. + // CorssHatch also does not need fixed angle. + // // Check it the infill that require a fixed infill angle. - switch (dominant_pattern) { - case ip3DHoneycomb: - case ipCrossHatch: - return (infill_direction + 45.0) * 2.0 * M_PI / 360.; - default: break; - } + //switch (dominant_pattern) { + //case ip3DHoneycomb: + //case ipCrossHatch: + // return (infill_direction + 45.0) * 2.0 * M_PI / 360.; + //default: break; + //} std::map counted_directions; for (const Polygon &p : bridged_area) { From c37132768a9420d20b85103075135eb9315ed3ae Mon Sep 17 00:00:00 2001 From: SoftFever Date: Sun, 1 Feb 2026 00:06:39 +0800 Subject: [PATCH 2/2] Make the generic filament the default fallback instead of using filaments sorted alphabetically by name. (#12124) --- src/libslic3r/Preset.cpp | 10 ++++++---- src/libslic3r/Preset.hpp | 31 ++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index a1d5f576cb..f230a11087 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1388,7 +1388,7 @@ void PresetCollection::load_presets( } if (presets_loaded.size() > 0) m_presets.insert(m_presets.end(), std::make_move_iterator(presets_loaded.begin()), std::make_move_iterator(presets_loaded.end())); - std::sort(m_presets.begin() + m_num_default_presets, m_presets.end()); + sort_presets(); //BBS: add config related logs BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": loaded %1% presets from %2%, type %3%")%presets_loaded.size() %dir %Preset::get_type_string(m_type); //this->select_preset(first_visible_idx()); @@ -1583,7 +1583,7 @@ void PresetCollection::load_project_embedded_presets(std::vector& proje } m_presets.insert(m_presets.end(), std::make_move_iterator(presets_loaded.begin()), std::make_move_iterator(presets_loaded.end())); - std::sort(m_presets.begin() + m_num_default_presets, m_presets.end()); + sort_presets(); //don't select it here //this->select_preset(first_visible_idx()); unlock(); @@ -1976,7 +1976,7 @@ void PresetCollection::update_after_user_presets_loaded() lock(); std::string selected_name = get_selected_preset_name(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", before sort, type %1%, selected_idx %2%, selected_name %3%") %m_type %m_idx_selected %selected_name; - std::sort(m_presets.begin() + m_num_default_presets, m_presets.end()); + sort_presets(); this->select_preset_by_name(selected_name, false); unlock(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", after sort, type %1%, selected_idx %2%") %m_type %m_idx_selected; @@ -3129,7 +3129,9 @@ std::vector PresetCollection::merge_presets(PresetCollection &&othe if (preset.is_default || preset.is_external) continue; Preset key(m_type, preset.name); - auto it = std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key); + auto it = (m_type == Preset::TYPE_FILAMENT) + ? std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key, filament_preset_less) + : std::lower_bound(m_presets.begin() + m_num_default_presets, m_presets.end(), key); if (it == m_presets.end() || it->name != preset.name) { if (preset.vendor != nullptr) { // Re-assign a pointer to the vendor structure in the new PresetBundle. diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index 6afda07426..e1c3f57f33 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,8 @@ #define ORCA_JSON_KEY_RENAMED_FROM "renamed_from" +static constexpr const char* GENERIC_PREFIX = "Generic "; + namespace Slic3r { class AppConfig; @@ -764,13 +767,39 @@ protected: void set_custom_preset_alias(Preset &preset); private: + // Comparator that sorts "Generic " prefixed presets before others, then alphabetically within each group. + static bool filament_preset_less(const Preset &a, const Preset &b) { + bool a_generic = boost::starts_with(a.name, GENERIC_PREFIX); + bool b_generic = boost::starts_with(b.name, GENERIC_PREFIX); + if (a_generic != b_generic) + return a_generic; // generics first + return a.name < b.name; + } + + // Sort presets: filament presets use generic-first ordering, others sort alphabetically. + void sort_presets() { + if (m_type == Preset::TYPE_FILAMENT) + std::sort(m_presets.begin() + m_num_default_presets, m_presets.end(), filament_preset_less); + else + std::sort(m_presets.begin() + m_num_default_presets, m_presets.end()); + } + // Find a preset position in the sorted list of presets. // The "-- default -- " preset is always the first, so it needs // to be handled differently. // If a preset does not exist, an iterator is returned indicating where to insert a preset with the same name. std::deque::iterator find_preset_internal(const std::string &name, bool from_orca_lib_only = false) { - auto it = Slic3r::lower_bound_by_predicate(m_presets.begin() + m_num_default_presets, m_presets.end(), [&name](const auto& l) { return l.name < name; }); + auto it = Slic3r::lower_bound_by_predicate(m_presets.begin() + m_num_default_presets, m_presets.end(), + [&name, this](const auto& l) { + if (m_type == Preset::TYPE_FILAMENT) { + bool l_generic = boost::starts_with(l.name, GENERIC_PREFIX); + bool name_generic = boost::starts_with(name, GENERIC_PREFIX); + if (l_generic && !name_generic) return true; + if (!l_generic && name_generic) return false; + } + return l.name < name; + }); if (it == m_presets.end() || it->name != name) { // Preset has not been not found in the sorted list of non-default presets. Try the defaults. for (size_t i = 0; i < m_num_default_presets; ++ i)