mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-14 07:52:56 +00:00
Integrations up to commit b3c41fda41.
- libslic3r: vendor FilamentMixer; MixedFilamentManager (auto-gen, resolve,
serialize; manual-pattern / gradient / pointillism); 19 new PrintConfig
keys; PresetBundle owns the canonical manager with 3MF + AppConfig
roundtrip and AMS-safe strip+restore; Print owns the slicing-time copy
with PrintApply auto-regen on color change; TriangleSelector::
shift_states_above + filament-id remap; inset_idx propagation through
ExtrusionPath/Loop/MultiPath copy/assign.
- Slicing: virtual filament IDs in painted regions (same-physical channels
collapse when mixed_filament_region_collapse is on); ByObject
collect_filament_data expands mixed slots; pair-cadence + whole-object +
3+component Local-Z plan generators; LocalZOrderOptimizer utility.
- GCode + ToolOrdering: LayerTools resolves virtual IDs through wall /
infill / sparse / solid queries; SameLayerPointillisme in process_layer
(uniform-segment + grouped per-perimeter-index splitters); WipeTower2
Local-Z reservation + sub-layer G-code emission; per-layer infill
filament override.
- PartPlate: get_extruders* expand virtual slots into physical components;
CLI path rebuilds a local manager from full_config.
- GUI: five widget files extracted from FS Plater.cpp (~5000 LOC) —
MixedMixPreview, MixedGradientSelector + WeightsDialog,
MixedFilamentColorMapPanel, MixedFilamentColorMatchDialog (ΔE₀₀ recipe
search), MixedFilamentConfigPanel; Sidebar Mixed Filaments panel
(drag-reorder, enable/delete, Add Gradient/Pattern/Color); Tab exposure
of mixed-filament / dithering / per-layer infill-override settings +
ConfigManipulation visibility and slot-validation rules;
BBLMixedFilamentBroken / BBLSingleExtruderMixedFilamentRisk
notifications + slice gate; WipeTowerDialog edits physical P×P
sub-matrix; bounds-safe extruder_id guards in 3DScene / GLCanvas3D /
GLGizmoMmuSegmentation; change_filament merge guard and
on_filaments_delete is_mixed_before_delete propagation.
- Tests: 4 Catch2 tests for 3MF roundtrip (auto/custom persistence,
PresetBundle string path, total_filaments stability); full-pipeline
slice E2E deferred — TODO in file.
Co-authored-by: Rad <radugheorghiu96@gmail.com>
Co-authored-by: Justin Hayes <justinh@rahb.ca>
Co-authored-by: Calogero Guagenti <calogeroguagenti@gmail.com>
Co-authored-by: xSil3nt <ahmedshazin21@gmail.com>
Co-authored-by: ratdoux <62392831+ratdoux@users.noreply.github.com>
Co-authored-by: Rad <radugheorghiu96@gmail.com>
Co-authored-by: Justin Hayes <justinh@rahb.ca>
Co-authored-by: Calogero Guagenti <calogeroguagenti@gmail.com>
Co-authored-by: xSil3nt <ahmedshazin21@gmail.com>
Co-authored-by: ratdoux <62392831+ratdoux@users.noreply.github.com>
73 lines
2.6 KiB
C++
73 lines
2.6 KiB
C++
#ifndef slic3r_LocalZOrderOptimizer_hpp_
|
|
#define slic3r_LocalZOrderOptimizer_hpp_
|
|
|
|
#include <algorithm>
|
|
#include <numeric>
|
|
#include <vector>
|
|
|
|
namespace Slic3r {
|
|
namespace LocalZOrderOptimizer {
|
|
|
|
inline bool bucket_contains_extruder(const std::vector<unsigned int> &extruders, int extruder_id)
|
|
{
|
|
return extruder_id >= 0 &&
|
|
std::find(extruders.begin(), extruders.end(), static_cast<unsigned int>(extruder_id)) != extruders.end();
|
|
}
|
|
|
|
inline std::vector<unsigned int> order_bucket_extruders(std::vector<unsigned int> extruders,
|
|
int current_extruder,
|
|
int preferred_last_extruder = -1)
|
|
{
|
|
extruders.erase(std::unique(extruders.begin(), extruders.end()), extruders.end());
|
|
if (extruders.empty())
|
|
return extruders;
|
|
|
|
if (current_extruder >= 0) {
|
|
auto current_it = std::find(extruders.begin(), extruders.end(), static_cast<unsigned int>(current_extruder));
|
|
if (current_it != extruders.end())
|
|
std::rotate(extruders.begin(), current_it, extruders.end());
|
|
}
|
|
|
|
if (preferred_last_extruder >= 0 && extruders.size() > 1 && static_cast<int>(extruders.front()) != preferred_last_extruder) {
|
|
auto preferred_it = std::find(extruders.begin() + 1, extruders.end(), static_cast<unsigned int>(preferred_last_extruder));
|
|
if (preferred_it != extruders.end())
|
|
std::rotate(preferred_it, preferred_it + 1, extruders.end());
|
|
}
|
|
|
|
return extruders;
|
|
}
|
|
|
|
inline std::vector<size_t> order_pass_group(const std::vector<std::vector<unsigned int>> &group_extruders, int current_extruder)
|
|
{
|
|
std::vector<size_t> remaining(group_extruders.size());
|
|
std::iota(remaining.begin(), remaining.end(), size_t(0));
|
|
|
|
std::vector<size_t> ordered;
|
|
ordered.reserve(group_extruders.size());
|
|
|
|
int active_extruder = current_extruder;
|
|
while (!remaining.empty()) {
|
|
auto next_it = std::find_if(remaining.begin(), remaining.end(), [&](size_t idx) {
|
|
return bucket_contains_extruder(group_extruders[idx], active_extruder);
|
|
});
|
|
if (next_it == remaining.end())
|
|
next_it = remaining.begin();
|
|
|
|
const size_t next_idx = *next_it;
|
|
ordered.push_back(next_idx);
|
|
|
|
const std::vector<unsigned int> ordered_bucket = order_bucket_extruders(group_extruders[next_idx], active_extruder);
|
|
if (!ordered_bucket.empty())
|
|
active_extruder = static_cast<int>(ordered_bucket.back());
|
|
|
|
remaining.erase(next_it);
|
|
}
|
|
|
|
return ordered;
|
|
}
|
|
|
|
} // namespace LocalZOrderOptimizer
|
|
} // namespace Slic3r
|
|
|
|
#endif
|