diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 7bdef5a4ff..cec91c4ede 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -360,7 +360,7 @@ void Layer::simplify_support_entity_collection(ExtrusionEntityCollection* entity //BBS: method to simplify support path void Layer::simplify_support_path(ExtrusionPath * path) { - const auto print_config = this->object()->print()->config(); + const PrintConfig &print_config = this->object()->print()->config(); const bool spiral_mode = print_config.spiral_mode; const bool enable_arc_fitting = print_config.enable_arc_fitting; const auto scaled_resolution = scaled(print_config.resolution.value); @@ -375,7 +375,7 @@ void Layer::simplify_support_path(ExtrusionPath * path) //BBS: method to simplify support path void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath) { - const auto print_config = this->object()->print()->config(); + const PrintConfig &print_config = this->object()->print()->config(); const bool spiral_mode = print_config.spiral_mode; const bool enable_arc_fitting = print_config.enable_arc_fitting; const auto scaled_resolution = scaled(print_config.resolution.value); @@ -392,7 +392,7 @@ void Layer::simplify_support_multi_path(ExtrusionMultiPath* multipath) //BBS: method to simplify support path void Layer::simplify_support_loop(ExtrusionLoop* loop) { - const auto print_config = this->object()->print()->config(); + const PrintConfig &print_config = this->object()->print()->config(); const bool spiral_mode = print_config.spiral_mode; const bool enable_arc_fitting = print_config.enable_arc_fitting; const auto scaled_resolution = scaled(print_config.resolution.value); diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 6f868ba095..7780c0b63b 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -1074,7 +1074,7 @@ void LayerRegion::simplify_entity_collection(ExtrusionEntityCollection* entity_c void LayerRegion::simplify_path(ExtrusionPath* path) { - const auto print_config = this->layer()->object()->print()->config(); + const PrintConfig &print_config = this->layer()->object()->print()->config(); const bool spiral_mode = print_config.spiral_mode; const bool enable_arc_fitting = print_config.enable_arc_fitting; const auto scaled_resolution = scaled(print_config.resolution.value); @@ -1092,7 +1092,7 @@ void LayerRegion::simplify_path(ExtrusionPath* path) void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath) { - const auto print_config = this->layer()->object()->print()->config(); + const PrintConfig &print_config = this->layer()->object()->print()->config(); const bool spiral_mode = print_config.spiral_mode; const bool enable_arc_fitting = print_config.enable_arc_fitting; const auto scaled_resolution = scaled(print_config.resolution.value); @@ -1112,7 +1112,7 @@ void LayerRegion::simplify_multi_path(ExtrusionMultiPath* multipath) void LayerRegion::simplify_loop(ExtrusionLoop* loop) { - const auto print_config = this->layer()->object()->print()->config(); + const PrintConfig &print_config = this->layer()->object()->print()->config(); const bool spiral_mode = print_config.spiral_mode; const bool enable_arc_fitting = print_config.enable_arc_fitting; const auto scaled_resolution = scaled(print_config.resolution.value); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 5f5592cfce..2d11f975dc 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -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 &variant_list, const std::vector& self_index_list, FilamentIndexMap *index_map) +int Print::get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& 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::vectorextruder_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]; } } diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 3b7e889472..e9b3e0379b 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -987,6 +987,9 @@ void PrintObject::generate_support_material() this->_generate_support_material(); m_print->throw_if_canceled(); } + // Orca: the tree support collision/avoidance caches and support nodes are only used while this step runs + // (detect_overhangs() rebuilds them from scratch), so don't keep them resident until the next slice. + this->clear_tree_support_preview_cache(); this->set_done(posSupportMaterial); } } diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 14bd65c9cf..36f0afa1ba 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -1346,7 +1346,7 @@ void PrintObject::slice_volumes() if (min_growth < 0.f || elfoot > 0.f) { // Apply the negative XY compensation. (the ones that is <0) ExPolygons trimming; - static const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); + const float eps = float(scale_(m_config.slice_closing_radius.value) * 1.5); if (elfoot > 0.f) { ExPolygons expolygons_to_compensate = offset_ex(layer->merged(eps), -eps); lslices_elfoot_uncompensated[layer_id] = expolygons_to_compensate; diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index 519b6e826e..4da67f68a3 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1820,37 +1820,15 @@ coordf_t TreeSupport::get_radius(const SupportNode* node) return node->radius; } -ExPolygons TreeSupport::get_avoidance(coordf_t radius, size_t obj_layer_nr) +// Orca: these are hit up to several times per node per layer in drop_nodes(), so hand out a +// reference into the TreeSupportData cache instead of copying the ExPolygons out of it. +const ExPolygons& TreeSupport::get_avoidance(coordf_t radius, size_t obj_layer_nr) { -#if USE_SUPPORT_3D - if (m_model_volumes) { - bool on_build_plate = m_object_config->support_on_build_plate_only.value; - const Polygons& avoid_polys = m_model_volumes->getAvoidance(radius, obj_layer_nr, TreeSupport3D::TreeModelVolumes::AvoidanceType::FastSafe, on_build_plate, true); - ExPolygons expolys; - for (auto& poly : avoid_polys) - expolys.emplace_back(std::move(poly)); - return expolys; - } - return ExPolygons(); -#else return m_ts_data->get_avoidance(radius, obj_layer_nr); -#endif } -ExPolygons TreeSupport::get_collision(coordf_t radius, size_t layer_nr) +const ExPolygons& TreeSupport::get_collision(coordf_t radius, size_t layer_nr) { -#if USE_SUPPORT_3D - if (m_model_volumes) { - bool on_build_plate = m_object_config->support_on_build_plate_only.value; - const Polygons& collision_polys = m_model_volumes->getCollision(radius, layer_nr, true); - ExPolygons expolys; - for (auto& poly : collision_polys) - expolys.emplace_back(std::move(poly)); - return expolys; - } -#else return m_ts_data->get_collision(radius, layer_nr); -#endif - return ExPolygons(); } Polygons TreeSupport::get_collision_polys(coordf_t radius, size_t layer_nr) { @@ -2639,7 +2617,11 @@ void TreeSupport::draw_circles() #endif // SUPPORT_TREE_DEBUG_TO_SVG SupportLayerPtrs& ts_layers = m_object->support_layers(); - auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height < EPSILON; }); + // Orca: the vector owns its layers, so the dropped ones have to be deleted, not just unlinked. + // std::stable_partition (unlike std::remove_if) leaves exactly the dropped layers in the tail. + auto iter = std::stable_partition(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height >= EPSILON; }); + for (auto it = iter; it != ts_layers.end(); ++it) + delete *it; ts_layers.erase(iter, ts_layers.end()); for (int layer_nr = 0; layer_nr < ts_layers.size(); layer_nr++) { ts_layers[layer_nr]->upper_layer = layer_nr != ts_layers.size() - 1 ? ts_layers[layer_nr + 1] : nullptr; @@ -2882,7 +2864,7 @@ void TreeSupport::drop_nodes() //Insert a completely new node and let both original nodes fade. Point next_position = (node.position + neighbours[0]) / 2; //Average position of the two nodes. coordf_t next_radius = calc_radius(node.dist_mm_to_top+height_next); - auto avoid_layer = get_avoidance(next_radius, obj_layer_nr_next); + const ExPolygons& avoid_layer = get_avoidance(next_radius, obj_layer_nr_next); if (group_index == 0) { //Avoid collisions. @@ -3069,7 +3051,7 @@ void TreeSupport::drop_nodes() } #endif coordf_t next_radius = calc_radius(node.dist_mm_to_top + height_next); - auto avoidance_next = get_avoidance(next_radius, obj_layer_nr_next); + const ExPolygons& avoidance_next = get_avoidance(next_radius, obj_layer_nr_next); Point to_outside = projection_onto(avoidance_next, node.position); Point direction_to_outer = to_outside - node.position; @@ -3123,7 +3105,7 @@ void TreeSupport::drop_nodes() if (is_outside) { next_layer_vertex = candidate_vertex; } } } - auto next_collision = get_collision(0, obj_layer_nr_next); + const ExPolygons& next_collision = get_collision(0, obj_layer_nr_next); const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[obj_layer_nr_next], next_layer_vertex); // don't increase radius if next node will collide partially with the object (STUDIO-7883) to_outside = projection_onto(next_collision, next_layer_vertex); diff --git a/src/libslic3r/Support/TreeSupport.hpp b/src/libslic3r/Support/TreeSupport.hpp index bd5a154e26..e2b3921b82 100644 --- a/src/libslic3r/Support/TreeSupport.hpp +++ b/src/libslic3r/Support/TreeSupport.hpp @@ -511,9 +511,9 @@ private: coordf_t calc_branch_radius(coordf_t base_radius, coordf_t mm_to_top, double diameter_angle_scale_factor, bool use_min_distance=true); coordf_t calc_radius(coordf_t mm_to_top); coordf_t get_radius(const SupportNode* node); - ExPolygons get_avoidance(coordf_t radius, size_t obj_layer_nr); + const ExPolygons& get_avoidance(coordf_t radius, size_t obj_layer_nr); // layer's expolygon expanded by radius+m_xy_distance - ExPolygons get_collision(coordf_t radius, size_t layer_nr); + const ExPolygons& get_collision(coordf_t radius, size_t layer_nr); // get Polygons instead of ExPolygons Polygons get_collision_polys(coordf_t radius, size_t layer_nr);