mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-14 03:11:19 +00:00
Take the print config by reference while simplifying extrusions
simplify_path, simplify_multi_path and simplify_loop each copied the whole PrintConfig, 10520 bytes with around 200 heap owning members, once per extrusion entity, from inside the parallel_for over all layers. LayerRegion.cpp already binds a reference a few hundred lines above. Three more sites in Layer.cpp do the same thing. The tree support changes in the same area: draw_circles() dropped layers from an owning vector without deleting them, so every re-slice leaked the layers above the topmost overhang. std::stable_partition rather than std::remove_if, because remove_if leaves moved-from duplicates of kept pointers in the tail and deleting those would be a double free. The collision and avoidance accessors returned ExPolygons by value out of a cache that hands them out by reference, several times per node per layer. The preview cache is released when the support step finishes instead of at the start of the next slice; nothing reads it in between. set_shared_object() now releases the layers the object still owns before it starts aliasing another object's. Both clear functions are no-ops once the alias is set, so this cannot free the sharee's layers. PrintObjectSlice.cpp: eps was a function local static inside a parallel_for, so slice_closing_radius was latched once per process. This one changes output for projects that override it per object, or on a re-slice after editing it. The old behaviour was undefined: whichever object won the race set it for the session.
This commit is contained in:
+13
-11
@@ -2604,6 +2604,11 @@ void Print::auto_assign_extruders(ModelObject* model_object) const
|
||||
|
||||
void PrintObject::set_shared_object(PrintObject *object)
|
||||
{
|
||||
// Orca: from now on m_layers / m_support_layers only alias the shared object's layers, so release the
|
||||
// ones this object still owns (it may have sliced itself before it became shareable again).
|
||||
// Both are no-ops once m_shared_object is set, so this cannot free layers owned by another object.
|
||||
clear_support_layers();
|
||||
clear_layers();
|
||||
m_shared_object = object;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, found shared object from %2%")%this%m_shared_object;
|
||||
}
|
||||
@@ -4329,9 +4334,9 @@ bool Print::is_dynamic_group_reorder() const
|
||||
return true;
|
||||
}
|
||||
|
||||
int Print::get_filament_config_indx(int filament_id, int layer_id, bool use_cache)
|
||||
int Print::get_filament_config_indx(int filament_id, int layer_id)
|
||||
{
|
||||
return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, use_cache ? &m_filament_index_map : nullptr);
|
||||
return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, m_filament_index_map);
|
||||
}
|
||||
|
||||
void Print::update_filament_self_index_cache()
|
||||
@@ -4374,7 +4379,7 @@ int Print::get_nozzle_config_index(int filament_id, int layer_id)
|
||||
return get_config_index(filament_id, layer_id, m_default_region_config.print_extruder_variant.values, m_default_region_config.print_extruder_id.values, m_nozzle_index_map);
|
||||
}
|
||||
|
||||
int Print::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 Print::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)
|
||||
{
|
||||
auto group_result = get_layered_nozzle_group_result();
|
||||
// Orca: defensive — when no grouping producer has published a result yet, fall back to the
|
||||
@@ -4385,8 +4390,7 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vector<std
|
||||
if (!nozzle_info.has_value()) {
|
||||
// Orca: this fallback runs per-filament/per-layer in the g-code hot path — log once per filament
|
||||
// (reset each slice) instead of flooding thousands of identical lines that bury the real error.
|
||||
// Without the cache, the log set is left alone too; the cached caller reports the same filament.
|
||||
if (index_map && m_missing_nozzle_group_logged.insert(filament_id).second)
|
||||
if (m_missing_nozzle_group_logged.insert(filament_id).second)
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__
|
||||
<< boost::format(", Line %1%: could not found group_nozzle_info corresponding to filament_id %2%, layer_id %3% (further occurrences for this filament suppressed)") % __LINE__ % filament_id %
|
||||
layer_id;
|
||||
@@ -4395,17 +4399,15 @@ int Print::get_config_index(int filament_id, int layer_id, const std::vector<std
|
||||
|
||||
ExtruderType extruder_type = ExtruderType(m_config.extruder_type.get_at(nozzle_info->extruder_id));
|
||||
NozzleVolumeType nozzle_volume_type = nozzle_info->volume_type;
|
||||
if (!index_map)
|
||||
return get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list);
|
||||
|
||||
FilamentIndexKey key{filament_id, extruder_type, nozzle_volume_type};
|
||||
auto iter = index_map->find(key);
|
||||
if (iter == index_map->end()) {
|
||||
auto iter = index_map.find(key);
|
||||
if (iter == index_map.end()) {
|
||||
int index = get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list);
|
||||
(*index_map)[key] = index;
|
||||
index_map[key] = index;
|
||||
return index;
|
||||
} else {
|
||||
return iter->second;
|
||||
return index_map[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user