Merge some BS1.7 changes:

internal_solid_infill_pattern
This commit is contained in:
SoftFever
2023-08-08 18:34:21 +08:00
parent 7ece35931e
commit bcbbbf35db
95 changed files with 44122 additions and 693 deletions

View File

@@ -33,8 +33,6 @@
namespace Slic3r
{
#define unscale_(val) ((val) * SCALING_FACTOR)
#define FIRST_LAYER_EXPANSION 1.2
inline unsigned int round_divide(unsigned int dividend, unsigned int divisor) //!< Return dividend divided by divisor rounded to the nearest integer
{
@@ -734,6 +732,7 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
const coordf_t max_bridge_length = scale_(config.max_bridge_length.value);
const bool bridge_no_support = max_bridge_length > 0;
const bool support_critical_regions_only = config.support_critical_regions_only.value;
const bool config_remove_small_overhangs = config.support_remove_small_overhang.value;
const int enforce_support_layers = config.enforce_support_layers.value;
const double area_thresh_well_supported = SQ(scale_(6));
const double length_thresh_well_supported = scale_(6);
@@ -870,9 +869,11 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
}
}
ExPolygons curr_polys;
std::vector<const ExPolygon*> curr_poly_ptrs;
for (const ExPolygon& expoly : layer->lslices) {
if (!offset_ex(expoly, -extrusion_width_scaled / 2).empty()) {
curr_polys.emplace_back(expoly);
curr_poly_ptrs.emplace_back(&expoly);
}
}
@@ -885,28 +886,30 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
overhang_areas.end());
ExPolygons overhangs_sharp_tail;
if (is_auto(stype) && g_config_support_sharp_tails)
{
// BBS detect sharp tail
const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails;
auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height;
for (ExPolygon& expoly : layer->lslices) {
for (const ExPolygon* expoly : curr_poly_ptrs) {
bool is_sharp_tail = false;
// 1. nothing below
// this is a sharp tail region if it's small but non-ignorable
if (!overlaps(offset_ex(expoly, 0.5 * extrusion_width_scaled), lower_polys)) {
is_sharp_tail = expoly.area() < area_thresh_well_supported && !offset_ex(expoly, -0.1 * extrusion_width_scaled).empty();
if (!overlaps(offset_ex(*expoly, 0.5 * extrusion_width_scaled), lower_polys)) {
is_sharp_tail = expoly->area() < area_thresh_well_supported && !offset_ex(*expoly, -0.1 * extrusion_width_scaled).empty();
}
if (is_sharp_tail) {
ExPolygons overhang = diff_ex({ expoly }, lower_layer->lslices);
layer->sharp_tails.push_back(expoly);
layer->sharp_tails_height.insert({ &expoly, layer->height });
ExPolygons overhang = diff_ex({ *expoly }, lower_polys);
layer->sharp_tails.push_back(*expoly);
layer->sharp_tails_height.insert({ expoly, layer->height });
append(overhang_areas, overhang);
if (!overhang.empty())
if (!overhang.empty()) {
has_sharp_tails = true;
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
SVG svg(format("SVG/sharp_tail_orig_%.02f.svg", layer->print_z), m_object->bounding_box());
if (svg.is_opened()) svg.draw(overhang, "red");
#endif
}
}
}
}
@@ -953,15 +956,12 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
Layer* layer = m_object->get_layer(layer_nr);
SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
Layer* lower_layer = layer->lower_layer;
// skip if:
// 1) if the current layer is already detected as sharp tails
// 2) lower layer has no sharp tails
if (!lower_layer || layer->sharp_tails.empty() == false || lower_layer->sharp_tails.empty() == true)
if (!lower_layer)
continue;
// BBS detect sharp tail
const ExPolygons& lower_layer_sharptails = lower_layer->sharp_tails;
auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height;
const auto& lower_layer_sharptails_height = lower_layer->sharp_tails_height;
for (ExPolygon& expoly : layer->lslices) {
bool is_sharp_tail = false;
float accum_height = layer->height;
@@ -992,13 +992,13 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
}
// 2.3 check whether sharp tail exceed the max height
for (auto& lower_sharp_tail_height : lower_layer_sharptails_height) {
for (const auto& lower_sharp_tail_height : lower_layer_sharptails_height) {
if (lower_sharp_tail_height.first->overlaps(expoly)) {
accum_height += lower_sharp_tail_height.second;
break;
}
}
if (accum_height >= sharp_tail_max_support_height) {
if (accum_height > sharp_tail_max_support_height) {
is_sharp_tail = false;
break;
}
@@ -1024,8 +1024,8 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
if (!overhang.empty())
has_sharp_tails = true;
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
SVG svg(get_svg_filename(std::to_string(layer->print_z), "sharp_tail"), m_object->bounding_box());
if (svg.is_opened()) svg.draw(overhang, "yellow");
SVG svg(format("SVG/sharp_tail_%.02f.svg",layer->print_z), m_object->bounding_box());
if (svg.is_opened()) svg.draw(overhang, "red");
#endif
}
@@ -1050,7 +1050,7 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
auto blockers = m_object->slice_support_blockers();
m_object->project_and_append_custom_facets(false, EnforcerBlockerType::ENFORCER, enforcers);
m_object->project_and_append_custom_facets(false, EnforcerBlockerType::BLOCKER, blockers);
if (is_auto(stype) && g_config_remove_small_overhangs) {
if (is_auto(stype) && config_remove_small_overhangs) {
if (blockers.size() < m_object->layer_count())
blockers.resize(m_object->layer_count());
for (auto& cluster : overhangClusters) {
@@ -1066,18 +1066,25 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
if (!cluster.is_sharp_tail && !cluster.is_cantilever) {
// 2. check overhang cluster size is smaller than 3.0 * fw_scaled
auto erode1 = offset_ex(cluster.merged_poly, -1.5 * extrusion_width_scaled);
cluster.is_small_overhang = area(erode1) < SQ(scale_(0.1));
auto erode1 = offset_ex(cluster.merged_poly, -1 * extrusion_width_scaled);
Point bbox_sz = get_extents(erode1).size();
if (bbox_sz.x() < 2 * extrusion_width_scaled || bbox_sz.y() < 2 * extrusion_width_scaled) {
cluster.is_small_overhang = true;
}
}
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
const Layer* layer1 = m_object->get_layer(cluster.min_layer);
BoundingBox bbox = cluster.merged_bbox;
bbox.merge(get_extents(layer1->lslices));
SVG svg(format("SVG/overhangCluster_%s_%s_tail=%s_cantilever=%s_small=%s.svg", cluster.min_layer, layer1->print_z, cluster.is_sharp_tail, cluster.is_cantilever, cluster.is_small_overhang), bbox);
SVG svg(format("SVG/overhangCluster_%s-%s_%s-%s_tail=%s_cantilever=%s_small=%s.svg",
cluster.min_layer, cluster.max_layer, layer1->print_z, m_object->get_layer(cluster.max_layer)->print_z,
cluster.is_sharp_tail, cluster.is_cantilever, cluster.is_small_overhang), bbox);
if (svg.is_opened()) {
svg.draw(layer1->lslices, "red");
svg.draw(cluster.merged_poly, "blue");
svg.draw_text(bbox.min + Point(scale_(0), scale_(2)), "lslices", "red", 2);
svg.draw_text(bbox.min + Point(scale_(0), scale_(2)), "overhang", "blue", 2);
}
#endif
@@ -1100,7 +1107,7 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
auto layer = m_object->get_layer(layer_nr);
auto lower_layer = layer->lower_layer;
if (support_critical_regions_only) {
if (support_critical_regions_only && is_auto(stype)) {
ts_layer->overhang_areas.clear();
if (lower_layer == nullptr)
ts_layer->overhang_areas = layer->sharp_tails;
@@ -1112,7 +1119,9 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
if (layer_nr < blockers.size()) {
Polygons& blocker = blockers[layer_nr];
ts_layer->overhang_areas = diff_ex(ts_layer->overhang_areas, offset_ex(blocker, scale_(radius_sample_resolution)));
// Arthur: union_ is a must because after mirroring, the blocker polygons are in left-hand coordinates, ie clockwise,
// which are not valid polygons, and will be removed by offset_ex. union_ can make these polygons right.
ts_layer->overhang_areas = diff_ex(ts_layer->overhang_areas, offset_ex(union_(blocker), scale_(radius_sample_resolution)));
}
if (max_bridge_length > 0 && ts_layer->overhang_areas.size() > 0 && lower_layer) {
@@ -1124,16 +1133,24 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
for (auto &area : ts_layer->overhang_areas) {
ts_layer->overhang_types.emplace(&area, SupportLayer::Detected);
}
// enforcers
if (layer_nr < enforcers.size()) {
// enforcers now follow same logic as normal support. See STUDIO-3692
if (layer_nr < enforcers.size() && lower_layer) {
float no_interface_offset = std::accumulate(layer->regions().begin(), layer->regions().end(), FLT_MAX,
[](float acc, const LayerRegion* layerm) { return std::min(acc, float(layerm->flow(frExternalPerimeter).scaled_width())); });
Polygons lower_layer_polygons = (layer_nr == 0) ? Polygons() : to_polygons(lower_layer->lslices);
Polygons& enforcer = enforcers[layer_nr];
// coconut: enforcer can't do offset2_ex, otherwise faces with angle near 90 degrees can't have enforcers, which
// is not good. For example: tails of animals needs extra support except the lowest tip.
//enforcer = std::move(offset2_ex(enforcer, -0.1 * extrusion_width_scaled, 0.1 * extrusion_width_scaled));
enforcer = offset(enforcer, 0.1 * extrusion_width_scaled);
for (const Polygon& poly : enforcer) {
ts_layer->overhang_areas.emplace_back(poly);
ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), SupportLayer::Enforced);
if (!enforcer.empty()) {
Polygons enforcer_polygons = diff(intersection(layer->lslices, enforcer),
// Inflate just a tiny bit to avoid intersection of the overhang areas with the object.
expand(lower_layer_polygons, 0.05f * no_interface_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
// coconut: enforcer can't do offset2_ex, otherwise faces with angle near 90 degrees can't have enforcers, which
// is not good. For example: tails of animals needs extra support except the lowest tip.
//enforcer = std::move(offset2_ex(enforcer, -0.1 * extrusion_width_scaled, 0.1 * extrusion_width_scaled));
enforcer_polygons = offset(enforcer_polygons, 0.1 * extrusion_width_scaled);
for (const Polygon& poly : enforcer_polygons) {
ts_layer->overhang_areas.emplace_back(poly);
ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), SupportLayer::Enforced);
}
}
}
@@ -1143,13 +1160,15 @@ void TreeSupport::detect_overhangs(bool detect_first_sharp_tail_only)
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
for (const SupportLayer* layer : m_object->support_layers()) {
if (layer->overhang_areas.empty())
if (layer->overhang_areas.empty() && (blockers.size()<=layer->id() || blockers[layer->id()].empty()))
continue;
SVG svg(format("SVG/overhang_areas_%s.svg", layer->print_z), m_object->bounding_box());
if (svg.is_opened()) {
svg.draw_outline(m_object->get_layer(layer->id())->lslices, "yellow");
svg.draw(layer->overhang_areas, "red");
svg.draw(layer->overhang_areas, "orange");
if (blockers.size() > layer->id())
svg.draw(blockers[layer->id()], "red");
for (auto& overhang : layer->overhang_areas) {
double aarea = overhang.area()/ area_thresh_well_supported;
auto pt = get_extents(overhang).center();
@@ -1959,7 +1978,8 @@ coordf_t TreeSupport::calc_branch_radius(coordf_t base_radius, coordf_t mm_to_to
return radius;
}
ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const ExPolygons &avoid_region) {
template<typename RegionType> // RegionType could be ExPolygons or Polygons
ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const RegionType&avoid_region) {
ExPolygons expolys_out;
for (auto expoly : expolys) {
auto expolys_avoid = diff_ex(expoly, avoid_region);
@@ -1977,6 +1997,82 @@ ExPolygons avoid_object_remove_extra_small_parts(ExPolygons &expolys, const ExPo
return expolys_out;
}
Polygons TreeSupport::get_trim_support_regions(
const PrintObject& object,
SupportLayer* support_layer_ptr,
const coordf_t gap_extra_above,
const coordf_t gap_extra_below,
const coordf_t gap_xy)
{
static const double sharp_tail_xy_gap = 0.2f;
static const double no_overlap_xy_gap = 0.2f;
double gap_xy_scaled = scale_(gap_xy);
SupportLayer& support_layer = *support_layer_ptr;
auto m_print_config = object.print()->config();
size_t idx_object_layer_overlapping = size_t(-1);
auto is_layers_overlap = [](const SupportLayer& support_layer, const Layer& object_layer, coordf_t bridging_height = 0.f) -> bool {
if (std::abs(support_layer.print_z - object_layer.print_z) < EPSILON)
return true;
coordf_t object_lh = bridging_height > EPSILON ? bridging_height : object_layer.height;
if (support_layer.print_z < object_layer.print_z && support_layer.print_z > object_layer.print_z - object_lh)
return true;
if (support_layer.print_z > object_layer.print_z && support_layer.bottom_z() < object_layer.print_z - EPSILON)
return true;
return false;
};
// Find the overlapping object layers including the extra above / below gap.
coordf_t z_threshold = support_layer.bottom_z() - gap_extra_below + EPSILON;
idx_object_layer_overlapping = Layer::idx_higher_or_equal(
object.layers().begin(), object.layers().end(), idx_object_layer_overlapping,
[z_threshold](const Layer* layer) { return layer->print_z >= z_threshold; });
// Collect all the object layers intersecting with this layer.
Polygons polygons_trimming;
size_t i = idx_object_layer_overlapping;
for (; i < object.layers().size(); ++i) {
const Layer& object_layer = *object.layers()[i];
if (object_layer.bottom_z() > support_layer.print_z + gap_extra_above - EPSILON)
break;
bool is_overlap = is_layers_overlap(support_layer, object_layer);
for (const ExPolygon& expoly : object_layer.lslices) {
// BBS
bool is_sharptail = !intersection_ex({ expoly }, object_layer.sharp_tails).empty();
coordf_t trimming_offset = is_sharptail ? scale_(sharp_tail_xy_gap) :
is_overlap ? gap_xy_scaled :
scale_(no_overlap_xy_gap);
polygons_append(polygons_trimming, offset({ expoly }, trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
}
}
if (!m_slicing_params.soluble_interface && m_object_config->thick_bridges) {
// Collect all bottom surfaces, which will be extruded with a bridging flow.
for (; i < object.layers().size(); ++i) {
const Layer& object_layer = *object.layers()[i];
bool some_region_overlaps = false;
for (LayerRegion* region : object_layer.regions()) {
coordf_t bridging_height = region->region().bridging_height_avg(m_print_config);
if (object_layer.print_z - bridging_height > support_layer.print_z + gap_extra_above - EPSILON)
break;
some_region_overlaps = true;
bool is_overlap = is_layers_overlap(support_layer, object_layer, bridging_height);
coordf_t trimming_offset = is_overlap ? gap_xy_scaled : scale_(no_overlap_xy_gap);
polygons_append(polygons_trimming,
offset(region->fill_surfaces.filter_by_type(stBottomBridge), trimming_offset, SUPPORT_SURFACES_OFFSET_PARAMETERS));
}
if (!some_region_overlaps)
break;
}
}
return polygons_trimming;
}
void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_nodes)
{
const PrintObjectConfig &config = m_object->config();
@@ -1985,6 +2081,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
int bottom_gap_layers = round(m_slicing_params.gap_object_support / m_slicing_params.layer_height);
const coordf_t branch_radius = config.tree_support_branch_diameter.value / 2;
const coordf_t branch_radius_scaled = scale_(branch_radius);
bool on_buildplate_only = config.support_on_build_plate_only.value;
Polygon branch_circle; //Pre-generate a circle with correct diameter so that we don't have to recompute those (co)sines every time.
// Use square support if there are too many nodes per layer because circle support needs much longer time to compute
@@ -2122,7 +2219,8 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
}
area.emplace_back(ExPolygon(circle));
// merge overhang to get a smoother interface surface
if (top_interface_layers > 0 && node.support_roof_layers_below > 0) {
// Do not merge when buildplate_only is on, because some underneath nodes may have been deleted.
if (top_interface_layers > 0 && node.support_roof_layers_below > 0 && !on_buildplate_only) {
ExPolygons overhang_expanded;
if (node.overhang->contour.size() > 100 || node.overhang->holes.size()>1)
overhang_expanded.emplace_back(*node.overhang);
@@ -2174,7 +2272,8 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
roof_1st_layer = std::move(offset2_ex(roof_1st_layer, contact_dist_scaled, -contact_dist_scaled));
// avoid object
auto avoid_region_interface = m_ts_data->get_collision(m_ts_data->m_xy_distance, layer_nr);
//ExPolygons avoid_region_interface = m_ts_data->get_collision(m_ts_data->m_xy_distance, layer_nr);
Polygons avoid_region_interface = get_trim_support_regions(*m_object, ts_layer, m_slicing_params.gap_object_support, m_slicing_params.gap_support_object, m_ts_data->m_xy_distance);
if (has_circle_node) {
roof_areas = avoid_object_remove_extra_small_parts(roof_areas, avoid_region_interface);
roof_1st_layer = avoid_object_remove_extra_small_parts(roof_1st_layer, avoid_region_interface);
@@ -2251,7 +2350,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
}
});
#if 1
if (with_lightning_infill)
{
const bool global_lightning_infill = true;
@@ -2323,7 +2422,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
else if (!with_infill) {
// move the holes to contour so they can be well supported
// check if poly's contour intersects with expoly's contour
// check if poly's contour intersects with expoly's contour
auto intersects_contour = [](Polygon poly, ExPolygon expoly, Point& pt_on_poly, Point& pt_on_expoly, Point& pt_far_on_poly, float dist_thresh = 0.01) {
float min_dist = std::numeric_limits<float>::max();
float max_dist = 0;
@@ -2436,7 +2535,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
}
}
}
#endif
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
for (int layer_nr = m_object->layer_count() - 1; layer_nr >= 0; layer_nr--) {
@@ -2731,20 +2830,17 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
node_ = (node.dist_mm_to_top >= neighbour->dist_mm_to_top && p_node->parent) ? p_node : neighbour;
else
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(m_ts_data->get_avoidance(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_->parent,
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;
get_max_move_dist(next_node);
next_node->is_merged = true;
contact_nodes[layer_nr_next].push_back(next_node);
// make sure the trees are all connected
if (node.parent) node.parent->child = next_node;
if (neighbour->parent) neighbour->parent->child = next_node;
// Make sure the next pass doesn't drop down either of these (since that already happened).
node.merged_neighbours.push_front(neighbour);
to_delete.insert(neighbour);
to_delete.insert(p_node);
}
@@ -2977,7 +3073,7 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
}
}
}
#if 0
#if 1
// delete nodes with no children (means either it's a single layer nodes, or the branch has been deleted but not completely)
for (size_t layer_nr = contact_nodes.size() - 1; layer_nr > 0; layer_nr--){
auto layer_contact_nodes = contact_nodes[layer_nr];
@@ -3053,16 +3149,8 @@ void TreeSupport::smooth_nodes(std::vector<std::vector<Node *>> &contact_nodes)
}
}
}
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
// save tree structure for viewing in python
struct TreeNode {
Vec3f pos;
std::vector<int> children; // index of children in the storing vector
TreeNode(Point pt, float z) {
pos = { float(unscale_(pt.x())),float(unscale_(pt.y())),z };
}
};
std::vector<TreeNode> tree_nodes;
auto& tree_nodes = m_ts_data->tree_nodes;
std::map<Node*, int> ptr2idx;
std::map<int, Node*> idx2ptr;
for (int layer_nr = 0; layer_nr < contact_nodes.size(); layer_nr++) {
@@ -3078,12 +3166,16 @@ void TreeSupport::smooth_nodes(std::vector<std::vector<Node *>> &contact_nodes)
Node* p_node = idx2ptr[i];
if (p_node->child)
tree_node.children.push_back(ptr2idx[p_node->child]);
if(p_node->parent)
tree_node.parents.push_back(ptr2idx[p_node->parent]);
}
#ifdef SUPPORT_TREE_DEBUG_TO_SVG
nlohmann::json jj;
for (size_t i = 0; i < tree_nodes.size(); i++) {
nlohmann::json j;
j["pos"] = tree_nodes[i].pos;
j["children"] = tree_nodes[i].children;
j["linked"] = !(tree_nodes[i].pos.z() > 0.205 && tree_nodes[i].children.empty());
jj.push_back(j);
}
@@ -3356,12 +3448,14 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<TreeSupport::N
Point candidate = overhang_bounds.center();
if (!overhang_part.contains(candidate))
move_inside_expoly(overhang_part, candidate);
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;
curr_nodes.emplace_back(contact_node);
continue;
if (!(config.support_on_build_plate_only && is_inside_ex(m_ts_data->m_layer_outlines_below[layer_nr], candidate))) {
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;
curr_nodes.emplace_back(contact_node);
continue;
}
}
overhang_bounds.inflated(half_overhang_distance);
@@ -3413,7 +3507,8 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<TreeSupport::N
curr_nodes.emplace_back(contact_node);
}
}
if (ts_layer->overhang_types[&overhang_part] == SupportLayer::Detected) {
// add supports at corners for both auto and manual overhangs, github #2008
if (/*ts_layer->overhang_types[&overhang_part] == SupportLayer::Detected*/1) {
// add points at corners
auto &points = overhang_part.contour.points;
int nSize = points.size();
@@ -3589,7 +3684,6 @@ const ExPolygons& TreeSupportData::calculate_avoidance(const RadiusLayerPair& ke
const auto& radius = key.radius;
const auto& layer_nr = key.layer_nr;
BOOST_LOG_TRIVIAL(debug) << "calculate_avoidance on radius=" << radius << ", layer=" << layer_nr<<", recursion="<<key.recursions;
std::pair<tbb::concurrent_unordered_map<RadiusLayerPair, ExPolygons, RadiusLayerPairHash, RadiusLayerPairEquality>::iterator,bool> ret;
constexpr auto max_recursion_depth = 100;
if (key.recursions <= max_recursion_depth*2) {
if (layer_nr == 0) {
@@ -3616,14 +3710,15 @@ const ExPolygons& TreeSupportData::calculate_avoidance(const RadiusLayerPair& ke
const ExPolygons &collision = get_collision(radius, layer_nr);
avoidance_areas.insert(avoidance_areas.end(), collision.begin(), collision.end());
avoidance_areas = std::move(union_ex(avoidance_areas));
ret = m_avoidance_cache.insert({key, std::move(avoidance_areas)});
auto ret = m_avoidance_cache.insert({ key, std::move(avoidance_areas) });
//assert(ret.second);
return ret.first->second;
} else {
ExPolygons avoidance_areas = std::move(offset_ex(m_layer_outlines_below[layer_nr], scale_(m_xy_distance + radius)));
ret = m_avoidance_cache.insert({key, std::move(avoidance_areas)});
auto ret = m_avoidance_cache.insert({ key, std::move(avoidance_areas) });
assert(ret.second);
return ret.first->second;
}
return ret.first->second;
}
} //namespace Slic3r