mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-09 10:16:50 +00:00
Merge branch 'main' into feat/plugin-feature
Resolve five conflicts, all of which needed both sides rather than a pick: - BackgroundSlicingProcess: ours was a pure tabs->spaces reformat of base, so keep main's per-filament volume/nozzle map read-back (its only change here). - GUI_App: main's #12506 else-if attached to an `if` this branch deleted; re-expressed onto the same-agent early-return path (the agent factory caches per id, so pointer equality is the same predicate). - MainFrame: both sides relocated Sync Presets independently; keep main's push_notification plus the branch's Plugins menu items. - Tab: the "TODO: Orca: Support hybrid" blocks were unchanged base, not a branch decision; take main's enabled Hybrid to match the already auto-merged siblings. - test_config: union of both sides' cases (6 plugin + 9 multi-nozzle).
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "calib.hpp"
|
||||
|
||||
@@ -38,6 +39,7 @@ class SupportLayer;
|
||||
class TreeSupportData;
|
||||
class TreeSupport;
|
||||
class ExtrusionLayers;
|
||||
namespace MultiNozzleUtils { class NozzleGroupResultBase; class LayeredNozzleGroupResult; }
|
||||
|
||||
#define MAX_OUTER_NOZZLE_DIAMETER 4
|
||||
// BBS: move from PrintObjectSlice.cpp
|
||||
@@ -426,7 +428,7 @@ public:
|
||||
// (layer height, first layer height, raft settings, print nozzle diameter etc).
|
||||
const SlicingParameters& slicing_parameters() const { return m_slicing_params; }
|
||||
// Orca: XYZ shrinkage compensation has introduced the const Vec3d &object_shrinkage_compensation parameter to the function below
|
||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation);
|
||||
static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation, std::vector<int> variant_index = std::vector<int>());
|
||||
|
||||
size_t num_printing_regions() const throw() { return m_shared_regions->all_regions.size(); }
|
||||
const PrintRegion& printing_region(size_t idx) const throw() { return *m_shared_regions->all_regions[idx].get(); }
|
||||
@@ -497,7 +499,7 @@ public:
|
||||
// If ! m_slicing_params.valid, recalculate.
|
||||
void update_slicing_parameters();
|
||||
|
||||
static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders);
|
||||
static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders, std::vector<int>& variant_index);
|
||||
|
||||
private:
|
||||
void make_perimeters();
|
||||
@@ -780,6 +782,7 @@ struct WipeTowerData
|
||||
number_of_toolchanges = -1;
|
||||
depth = 0.f;
|
||||
brim_width = 0.f;
|
||||
height = 0.f;
|
||||
rib_offset = Vec2f::Zero();
|
||||
wipe_tower_mesh_data = std::nullopt;
|
||||
}
|
||||
@@ -1016,15 +1019,50 @@ public:
|
||||
const WipeTowerData& wipe_tower_data(size_t filaments_cnt = 0) const;
|
||||
const ToolOrdering& tool_ordering() const { return m_tool_ordering; }
|
||||
|
||||
void update_filament_maps_to_config(std::vector<int> f_maps);
|
||||
void update_filament_maps_to_config(std::vector<int> f_maps, std::vector<int> f_volume_maps = std::vector<int>{}, std::vector<int> f_nozzle_maps = std::vector<int>{});
|
||||
// Write-back for a selector (per-layer planned) grouping result. When a filament actually
|
||||
// migrates between nozzle variants, rebuilds the per-slot filament arrays so it holds one
|
||||
// slot per variant and recomputes the extruder retract overrides against the expanded
|
||||
// slots — update_filament_maps_to_config's single-slot rebuild cannot represent a
|
||||
// migration. A result without migration reduces to a single grouping and takes the
|
||||
// three-map write-back like the static paths.
|
||||
void update_to_config_by_nozzle_group_result(const MultiNozzleUtils::LayeredNozzleGroupResult& group_result);
|
||||
void apply_config_for_render(const DynamicConfig &config);
|
||||
|
||||
// 1 based group ids
|
||||
std::vector<int> get_filament_maps() const;
|
||||
FilamentMapMode get_filament_map_mode() const;
|
||||
std::vector<int> get_filament_volume_maps() const;
|
||||
std::vector<int> get_filament_nozzle_maps() const;
|
||||
// get the group label of filament
|
||||
size_t get_extruder_id(unsigned int filament_id) const;
|
||||
|
||||
// The region every extruder can reach,
|
||||
// i.e. the intersection of all per-extruder printable areas. Falls back to the full printable_area
|
||||
// for single-nozzle printers and whenever extruder_printable_area is not populated (all current
|
||||
// single/dual profiles), so the wipe-tower-center clamp is byte-identical to full-bed clamping there.
|
||||
Polygons get_extruder_shared_printable_polygon() const;
|
||||
|
||||
// Logical (extruder, nozzle) grouping result produced by ToolOrdering during reorder.
|
||||
// Consumed by GCode via get_layered_nozzle_group_result()->get_nozzle_id(filament, layer) etc.
|
||||
void set_nozzle_group_result(std::shared_ptr<MultiNozzleUtils::NozzleGroupResultBase> result) { m_nozzle_group_result = result; }
|
||||
std::shared_ptr<MultiNozzleUtils::NozzleGroupResultBase> get_nozzle_group_result() const { return m_nozzle_group_result; }
|
||||
std::shared_ptr<MultiNozzleUtils::LayeredNozzleGroupResult> get_layered_nozzle_group_result() const;
|
||||
|
||||
// True only when the project opts into the per-layer filament selector
|
||||
// (enable_filament_dynamic_map) in auto-for-flush mode on a multi-extruder machine. Gates the
|
||||
// dynamic (per-layer) regroup branch in ToolOrdering::reorder_extruders_for_minimum_flush_volume,
|
||||
// the sequential (by-object) plan stitching in Print::process, and GCode's use of the cached
|
||||
// sequential plans. No profile sets the flag, so the static grouping path (byte-identical
|
||||
// output) is the only one taken unless the user enables the selector.
|
||||
bool is_dynamic_group_reorder() const;
|
||||
|
||||
// Per-object tool orderings planned by the sequential (by-object) selector regroup with
|
||||
// cross-object nozzle-status threading. GCode export must consume these exact plans: a fresh
|
||||
// per-object construction would re-plan from a different seed and diverge from the published
|
||||
// stitched result. Empty on the static path.
|
||||
const std::map<const PrintObject*, ToolOrdering>& sequential_dynamic_orderings() const { return m_sequential_dynamic_orderings; }
|
||||
|
||||
const std::vector<std::vector<DynamicPrintConfig>>& get_extruder_filament_info() const { return m_extruder_filament_info; }
|
||||
void set_extruder_filament_info(const std::vector<std::vector<DynamicPrintConfig>>& filament_info) { m_extruder_filament_info = filament_info; }
|
||||
|
||||
@@ -1050,6 +1088,18 @@ public:
|
||||
*/
|
||||
std::vector<std::set<int>> get_physical_unprintable_filaments(const std::vector<unsigned int>& used_filaments) const;
|
||||
|
||||
/**
|
||||
* @brief Determines the forbidden nozzle volume types for each used filament
|
||||
*
|
||||
* A filament may declare the extruder variants it supports. Every volume type offered by the
|
||||
* printer's extruders that the filament does not support is forbidden for that filament.
|
||||
* Hybrid volumes are ignored on both sides, and filaments declaring no variants are unrestricted.
|
||||
*
|
||||
* @param used_filaments Totally used filaments when slicing
|
||||
* @return A map from used filament index to the set of nozzle volume types it cannot print on
|
||||
*/
|
||||
std::map<int, std::set<NozzleVolumeType>> get_filament_unprintable_flow(const std::vector<unsigned int> &used_filaments) const;
|
||||
|
||||
std::vector<double> get_extruder_printable_height() const;
|
||||
std::vector<Polygons> get_extruder_printable_polygons() const;
|
||||
std::vector<Polygons> get_extruder_unprintable_polygons() const;
|
||||
@@ -1133,7 +1183,12 @@ public:
|
||||
bool is_all_objects_are_short() const {
|
||||
return std::all_of(this->objects().begin(), this->objects().end(), [&](PrintObject* obj) { return obj->height() < scale_(this->config().nozzle_height.value); });
|
||||
}
|
||||
|
||||
|
||||
// Post-slicing config-slot resolvers: map a (filament, layer) pair to the index of its
|
||||
// per-(extruder x volume type) column in the expanded variant arrays, cached by grouping context.
|
||||
int get_filament_config_indx(int filament_id, int layer_id);
|
||||
int get_nozzle_config_index(int filament_id, int layer_id);
|
||||
|
||||
// Orca: Implement prusa's filament shrink compensation approach
|
||||
// Returns if all used filaments have same shrinkage compensations.
|
||||
bool has_same_shrinkage_compensations() const;
|
||||
@@ -1143,6 +1198,57 @@ public:
|
||||
std::tuple<float, float> object_skirt_offset(double margin_height = 0) const;
|
||||
|
||||
protected:
|
||||
struct FilamentIndexKey
|
||||
{
|
||||
int filament_id;
|
||||
ExtruderType extruder;
|
||||
NozzleVolumeType nozzle_volume_type;
|
||||
|
||||
bool operator==(const FilamentIndexKey &other) const
|
||||
{
|
||||
return filament_id == other.filament_id && extruder == other.extruder && nozzle_volume_type == other.nozzle_volume_type;
|
||||
}
|
||||
};
|
||||
|
||||
struct PrintIndexKey
|
||||
{
|
||||
int filament_id;
|
||||
int extruder_id;
|
||||
ExtruderType extruder;
|
||||
NozzleVolumeType nozzle_volume_type;
|
||||
|
||||
bool operator==(const PrintIndexKey &other) const
|
||||
{
|
||||
return filament_id == other.filament_id && extruder_id == other.extruder_id && extruder == other.extruder && nozzle_volume_type == other.nozzle_volume_type;
|
||||
}
|
||||
};
|
||||
|
||||
struct FilamentIndexKeyHash
|
||||
{
|
||||
std::size_t operator()(const FilamentIndexKey &k) const
|
||||
{
|
||||
size_t h1 = std::hash<int>{}(k.filament_id);
|
||||
size_t h2 = std::hash<int>{}(static_cast<int>(k.extruder));
|
||||
size_t h3 = std::hash<int>{}(static_cast<int>(k.nozzle_volume_type));
|
||||
return h1 ^ (h2 << 8) ^ (h3 << 12);
|
||||
}
|
||||
};
|
||||
struct PrintIndexKeyHash
|
||||
{
|
||||
std::size_t operator()(const PrintIndexKey &k) const
|
||||
{
|
||||
size_t h1 = std::hash<int>{}(k.filament_id);
|
||||
size_t h2 = std::hash<int>{}(k.extruder_id);
|
||||
size_t h3 = std::hash<int>{}(static_cast<int>(k.extruder));
|
||||
size_t h4 = std::hash<int>{}(static_cast<int>(k.nozzle_volume_type));
|
||||
return h1 ^ (h2 << 8) ^ (h3 << 12) ^ (h4 << 16);
|
||||
}
|
||||
};
|
||||
using FilamentIndexMap = std::unordered_map<FilamentIndexKey, int, FilamentIndexKeyHash>;
|
||||
using PrintIndexMap = std::unordered_map<PrintIndexKey, int, PrintIndexKeyHash>;
|
||||
int get_config_index(int filament_id, int layer_id, const std::vector<std::string> &variant_list, const std::vector<int>& self_index_list, FilamentIndexMap &index_map);
|
||||
int get_config_index(int filament_id, int layer_id, const std::vector<std::string> &variant_list, const std::vector<int>& self_index_list, PrintIndexMap &index_map);
|
||||
|
||||
// Invalidates the step, and its depending steps in Print.
|
||||
bool invalidate_step(PrintStep step);
|
||||
|
||||
@@ -1156,6 +1262,16 @@ private:
|
||||
void _make_skirt();
|
||||
void _make_wipe_tower();
|
||||
void finalize_first_layer_convex_hull();
|
||||
void update_filament_self_index_cache();
|
||||
// Deduplicates, per filament, the (extruder type x volume type) variants the grouping
|
||||
// result routes it through; filaments the plan never routes get their default-map
|
||||
// assignment so the slot resolution never depends on the (mutable) filament_map. config
|
||||
// must carry extruder_type; returns false when it does not. Both the slice-time write-back
|
||||
// and the apply-time reproduction call this with m_ori_full_print_config so the two
|
||||
// expansions resolve identical slots.
|
||||
bool collect_filament_variant_uses(const MultiNozzleUtils::LayeredNozzleGroupResult& group_result,
|
||||
const DynamicPrintConfig& config,
|
||||
std::unordered_map<int, std::vector<FilamentVariantUse>>& uses) const;
|
||||
|
||||
// Islands of objects and their supports extruded at the 1st layer.
|
||||
Polygons first_layer_islands() const;
|
||||
@@ -1174,7 +1290,7 @@ private:
|
||||
PrintRegionPtrs m_print_regions;
|
||||
|
||||
//SoftFever
|
||||
bool m_isBBLPrinter;
|
||||
bool m_isBBLPrinter = false;
|
||||
|
||||
// Ordered collections of extrusion paths to build skirt loops and brim.
|
||||
ExtrusionEntityCollection m_skirt;
|
||||
@@ -1196,6 +1312,24 @@ private:
|
||||
|
||||
std::vector<std::vector<DynamicPrintConfig>> m_extruder_filament_info;
|
||||
|
||||
// Logical (extruder, nozzle) grouping result, set by ToolOrdering during reorder.
|
||||
std::shared_ptr<MultiNozzleUtils::NozzleGroupResultBase> m_nozzle_group_result;
|
||||
|
||||
// Sequential (by-object) selector plans, keyed by object; see sequential_dynamic_orderings().
|
||||
// Rebuilt (or cleared) on every process().
|
||||
std::map<const PrintObject*, ToolOrdering> m_sequential_dynamic_orderings;
|
||||
|
||||
// Used to cache filament parameter information
|
||||
FilamentIndexMap m_filament_index_map;
|
||||
// Used to cache printer and process parameter information
|
||||
PrintIndexMap m_nozzle_index_map;
|
||||
// Orca: filament ids already reported as missing a nozzle-group entry this slice. get_config_index()
|
||||
// falls back per-filament/per-layer in the g-code hot path, so this dedupes its log to once per
|
||||
// filament instead of flooding thousands of identical error lines. Cleared with the caches each slice.
|
||||
std::set<int> m_missing_nozzle_group_logged;
|
||||
// save the config value of "filament_self_index"
|
||||
std::vector<int> m_filament_self_index;
|
||||
|
||||
// Following section will be consumed by the GCodeGenerator.
|
||||
ToolOrdering m_tool_ordering;
|
||||
WipeTowerData m_wipe_tower_data {m_tool_ordering};
|
||||
|
||||
Reference in New Issue
Block a user