diff --git a/src/libslic3r/TreeSupport.cpp b/src/libslic3r/TreeSupport.cpp index 17aeec301..c7975be53 100644 --- a/src/libslic3r/TreeSupport.cpp +++ b/src/libslic3r/TreeSupport.cpp @@ -2189,7 +2189,7 @@ void TreeSupport::draw_circles(const std::vector>& contact_no const PrintObjectConfig& object_config = m_object->config(); BOOST_LOG_TRIVIAL(info) << "draw_circles for object: " << m_object->model_object()->name; - tbb::parallel_for(tbb::blocked_range(0, m_object->layer_count(), m_object->layer_count()), + tbb::parallel_for(tbb::blocked_range(0, m_object->layer_count()), [&](const tbb::blocked_range& range) { for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++) @@ -2850,8 +2850,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nodes) node_ = p_node->parent ? p_node : neighbour; // Make sure the next pass doesn't drop down either of these (since that already happened). node_->merged_neighbours.push_front(node_ == p_node ? neighbour : p_node); - //const bool to_buildplate = !is_inside_ex(get_collision(0, layer_nr_next), next_position); - const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr_next], next_position); + const bool to_buildplate = !is_inside_ex(get_collision(0, layer_nr_next), next_position); Node * next_node = new Node(next_position, node_->distance_to_top + 1, layer_nr_next, node_->support_roof_layers_below-1, to_buildplate, node_, print_z_next, height_next); next_node->movement = next_position - node.position; @@ -2894,11 +2893,26 @@ void TreeSupport::drop_nodes(std::vector>& contact_nodes) } if (node.type == ePolygon) { // polygon node do not merge or move - const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr], p_node->position); - Node * next_node = new Node(p_node->position, p_node->distance_to_top + 1, layer_nr_next, p_node->support_roof_layers_below - 1, to_buildplate, - p_node, print_z_next, height_next); - next_node->max_move_dist = 0; - contact_nodes[layer_nr_next].emplace_back(next_node); + const bool to_buildplate = true; + // keep only the part that won't be removed by the next layer + ExPolygons overhangs_next = diff_clipped({ node.overhang }, get_collision_polys(0, layer_nr_next)); + // find the biggest overhang if there are many + float area_biggest = -1; + int index_biggest = -1; + for (int i = 0; i < overhangs_next.size(); i++) { + float a=area(overhangs_next[i]); + if (a > area_biggest) { + area_biggest = a; + index_biggest = i; + } + } + if (index_biggest >= 0) { + Node* next_node = new Node(p_node->position, p_node->distance_to_top + 1, layer_nr_next, p_node->support_roof_layers_below - 1, to_buildplate, + p_node, print_z_next, height_next); + next_node->max_move_dist = 0; + next_node->overhang = std::move(overhangs_next[index_biggest]); + contact_nodes[layer_nr_next].emplace_back(next_node); + } continue; } @@ -3031,7 +3045,7 @@ void TreeSupport::drop_nodes(std::vector>& contact_nodes) } } - const bool to_buildplate = !is_inside_ex(m_ts_data->m_layer_outlines[layer_nr], next_layer_vertex); + const bool to_buildplate = !is_inside_ex(get_collision(0, layer_nr_next), next_layer_vertex); Node * next_node = new Node(next_layer_vertex, node.distance_to_top + 1, layer_nr_next, node.support_roof_layers_below - 1, to_buildplate, p_node, print_z_next, height_next); next_node->movement = movement; @@ -3493,14 +3507,12 @@ void TreeSupport::generate_contact_points(std::vector m_support_params.thresh_big_overhang) { - Point candidate = overhang_bounds.center(); - if (!overhang_part.contains(candidate)) - move_inside_expoly(overhang_part, candidate); - if (!(config.support_on_build_plate_only && is_inside_ex(m_ts_data->m_layer_outlines_below[layer_nr], candidate))) { + if (!overlaps({ overhang_part }, m_ts_data->m_layer_outlines_below[layer_nr-1])) { + Point candidate = overhang_bounds.center(); Node* contact_node = new Node(candidate, -z_distance_top_layers, layer_nr, support_roof_layers + z_distance_top_layers, true, Node::NO_PARENT, print_z, height, z_distance_top); contact_node->type = ePolygon; - contact_node->overhang=overhang_part; + contact_node->overhang = overhang_part; contact_node->radius = unscale_(overhang_bounds.radius()); curr_nodes.emplace_back(contact_node); continue;