diff --git a/src/libslic3r/Support/TreeSupport3D.cpp b/src/libslic3r/Support/TreeSupport3D.cpp index c62172cca..1995cf03d 100644 --- a/src/libslic3r/Support/TreeSupport3D.cpp +++ b/src/libslic3r/Support/TreeSupport3D.cpp @@ -209,7 +209,7 @@ static std::vector>> group_me } #endif -[[nodiscard]] static const std::vector generate_overhangs(const TreeSupportSettings &settings, const PrintObject &print_object, std::function throw_on_cancel) +[[nodiscard]] static const std::vector generate_overhangs(const TreeSupportSettings &settings, PrintObject &print_object, std::function throw_on_cancel) { const size_t num_raft_layers = settings.raft_layers.size(); const size_t num_object_layers = print_object.layer_count(); @@ -232,6 +232,20 @@ static std::vector>> group_me double support_tree_tip_diameter = 0.8; auto enforcer_overhang_offset = scaled(support_tree_tip_diameter); + // calc the extrudable expolygons of each layer + const coordf_t extrusion_width = config.line_width.value; + const coordf_t extrusion_width_scaled = scale_(extrusion_width); + tbb::parallel_for(tbb::blocked_range(0, print_object.layer_count()), + [&](const tbb::blocked_range& range) { + for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++) { + if (print_object.print()->canceled()) + break; + Layer* layer = print_object.get_layer(layer_nr); + // Filter out areas whose diameter that is smaller than extrusion_width, but we don't want to lose any details. + layer->lslices_extrudable = intersection_ex(layer->lslices, offset2_ex(layer->lslices, -extrusion_width_scaled / 2, extrusion_width_scaled)); + } + }); + size_t num_overhang_layers = support_auto ? num_object_layers : std::min(num_object_layers, std::max(size_t(support_enforce_layers), enforcers_layers.size())); tbb::parallel_for(tbb::blocked_range(1, num_overhang_layers), [&print_object, &config, &print_config, &enforcers_layers, &blockers_layers, @@ -259,9 +273,8 @@ static std::vector>> group_me lower_layer_offset = float(0.5 * external_perimeter_width); } else lower_layer_offset = scaled(lower_layer.height / tan_threshold); - overhangs = lower_layer_offset == 0 ? - diff(current_layer.lslices, lower_layer.lslices) : - diff(current_layer.lslices, offset(lower_layer.lslices, lower_layer_offset)); + Polygons lower_layer_offseted = offset(lower_layer.lslices_extrudable, lower_layer_offset); + overhangs = diff(current_layer.lslices_extrudable, lower_layer_offseted); if (lower_layer_offset == 0) { raw_overhangs = overhangs; raw_overhangs_calculated = true; @@ -4269,18 +4282,19 @@ static void generate_support_areas(Print &print, TreeSupport* tree_support, cons auto t_place = std::chrono::high_resolution_clock::now(); // ### draw these points as circles +#if 0 indexed_triangle_set branches = draw_branches(*print.get_object(processing.second.front()), volumes, config, move_bounds, throw_on_cancel); // Reduce memory footprint. After this point only slice_branches() will use volumes and from that only collisions with zero radius will be used. volumes.clear_all_but_object_collision(); slice_branches(*print.get_object(processing.second.front()), volumes, config, overhangs, move_bounds, branches, bottom_contacts, top_contacts, intermediate_layers, layer_storage, throw_on_cancel); - - // this new function may cause bad_function_call exception - //organic_draw_branches( - // *print.get_object(processing.second.front()), volumes, config, move_bounds, - // bottom_contacts, top_contacts, interface_placer, intermediate_layers, layer_storage, - // throw_on_cancel); - +#else + // this new function give correct result when raft is also enabled + organic_draw_branches( + *print.get_object(processing.second.front()), volumes, config, move_bounds, + bottom_contacts, top_contacts, interface_placer, intermediate_layers, layer_storage, + throw_on_cancel); +#endif remove_undefined_layers();