FIX: tree support bottom interface layers were not correct

The bottom interface layers were not right when "independent support layer height" is enabled.
This commit ensures there are always 2 bottom interface layers and the gap
is not less than specified. However, the gap may be slightly larger.

Jira: STUDIO-3842, STUDIO-2138
Github: #2127

Change-Id: Ifd8fbc4c7bc6dd92f2534fdd0179458a9e93c79a
(cherry picked from commit edcdad162e)
This commit is contained in:
Arthur 2023-08-04 22:29:56 +08:00 committed by Noisyfox
parent b3be5bb161
commit de24d0ac2f

View file

@ -1471,6 +1471,7 @@ void TreeSupport::generate_toolpaths()
SupportLayer* ts_layer = m_object->get_support_layer(layer_id); SupportLayer* ts_layer = m_object->get_support_layer(layer_id);
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
m_support_material_interface_flow = support_material_interface_flow(m_object, ts_layer->height); // update flow using real support layer height
coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing(); coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing();
coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing); coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing);
ts_layer->support_fills.no_sort = false; ts_layer->support_fills.no_sort = false;
@ -1934,9 +1935,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<SupportNode*>>& con
const PrintObjectConfig& object_config = m_object->config(); const PrintObjectConfig& object_config = m_object->config();
BOOST_LOG_TRIVIAL(info) << "draw_circles for object: " << m_object->model_object()->name; BOOST_LOG_TRIVIAL(info) << "draw_circles for object: " << m_object->model_object()->name;
// coconut: previously std::unordered_map in m_collision_cache is not multi-thread safe which may cause programs stuck, here we change to tbb::concurrent_unordered_map tbb::parallel_for(tbb::blocked_range<size_t>(0, m_object->layer_count()),
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_object->layer_count()),
[&](const tbb::blocked_range<size_t>& range) [&](const tbb::blocked_range<size_t>& range)
{ {
for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++) for (size_t layer_nr = range.begin(); layer_nr < range.end(); layer_nr++)
@ -1998,7 +1997,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<SupportNode*>>& con
has_polygon_node = true; has_polygon_node = true;
} }
else { else {
Polygon circle; Polygon circle(branch_circle);
double scale = calc_branch_radius(branch_radius, node.dist_mm_to_top, diameter_angle_scale_factor) / branch_radius; double scale = calc_branch_radius(branch_radius, node.dist_mm_to_top, diameter_angle_scale_factor) / branch_radius;
double moveX = node.movement.x() / (scale * branch_radius_scaled); double moveX = node.movement.x() / (scale * branch_radius_scaled);
@ -2011,14 +2010,14 @@ void TreeSupport::draw_circles(const std::vector<std::vector<SupportNode*>>& con
scale * (1 + moveX * moveX * vsize_inv),scale * (0 + moveX * moveY * vsize_inv), scale * (1 + moveX * moveX * vsize_inv),scale * (0 + moveX * moveY * vsize_inv),
scale * (0 + moveX * moveY * vsize_inv),scale * (1 + moveY * moveY * vsize_inv), scale * (0 + moveX * moveY * vsize_inv),scale * (1 + moveY * moveY * vsize_inv),
}; };
int i = 0;
for (auto vertex: branch_circle.points) { for (auto vertex: branch_circle.points) {
vertex = Point(matrix[0] * vertex.x() + matrix[1] * vertex.y(), matrix[2] * vertex.x() + matrix[3] * vertex.y()); vertex = Point(matrix[0] * vertex.x() + matrix[1] * vertex.y(), matrix[2] * vertex.x() + matrix[3] * vertex.y());
circle.append(node.position + vertex); circle.points[i++] = node.position + vertex;
} }
} else { } else {
for (auto iter = branch_circle.points.begin(); iter != branch_circle.points.end(); iter++) { for (int i = 0;i< circle.points.size(); i++) {
Point corner = (*iter) * scale; circle.points[i] = circle.points[i] * scale + node.position;
circle.append(node.position + corner);
} }
} }
if (layer_nr == 0 && m_raft_layers == 0) { if (layer_nr == 0 && m_raft_layers == 0) {
@ -2107,16 +2106,22 @@ void TreeSupport::draw_circles(const std::vector<std::vector<SupportNode*>>& con
{ {
if (layer_nr >= bottom_interface_layers + bottom_gap_layers) if (layer_nr >= bottom_interface_layers + bottom_gap_layers)
{ {
for (size_t i = 0; i <= bottom_gap_layers; i++) // find the lowest interface layer
// TODO the gap may not be exact when "independent support layer height" is enabled
size_t layer_nr_next = layer_nr;
for (size_t i = 0; i < bottom_interface_layers && layer_nr_next>0; i++) {
layer_nr_next = m_ts_data->layer_heights[layer_nr_next].next_layer_nr;
}
for (size_t i = 0; i <= bottom_gap_layers && i<=layer_nr_next; i++)
{ {
const Layer* below_layer = m_object->get_layer(layer_nr - bottom_interface_layers - i); const Layer* below_layer = m_object->get_layer(layer_nr_next - i);
ExPolygons bottom_interface = intersection_ex(base_areas, below_layer->lslices); ExPolygons bottom_interface = intersection_ex(base_areas, below_layer->lslices);
floor_areas.insert(floor_areas.end(), bottom_interface.begin(), bottom_interface.end()); floor_areas.insert(floor_areas.end(), bottom_interface.begin(), bottom_interface.end());
} }
} }
if (floor_areas.empty() == false) { if (floor_areas.empty() == false) {
floor_areas = std::move(diff_ex(floor_areas, avoid_region_interface)); //floor_areas = std::move(diff_ex(floor_areas, avoid_region_interface));
floor_areas = std::move(offset2_ex(floor_areas, contact_dist_scaled, -contact_dist_scaled)); //floor_areas = std::move(offset2_ex(floor_areas, contact_dist_scaled, -contact_dist_scaled));
base_areas = std::move(diff_ex(base_areas, offset_ex(floor_areas, 10))); base_areas = std::move(diff_ex(base_areas, offset_ex(floor_areas, 10)));
} }
} }
@ -2238,6 +2243,8 @@ void TreeSupport::draw_circles(const std::vector<std::vector<SupportNode*>>& con
// 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) { 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) {
Polylines pl_out = intersection_pl(to_polylines(expoly), ExPolygon(poly));
if (pl_out.empty()) return false;
float min_dist = std::numeric_limits<float>::max(); float min_dist = std::numeric_limits<float>::max();
float max_dist = 0; float max_dist = 0;
for (auto from : poly.points) { for (auto from : poly.points) {
@ -3045,8 +3052,8 @@ std::vector<LayerHeightData> TreeSupport::plan_layer_heights(std::vector<std::ve
break; break;
} }
} }
BOOST_LOG_TRIVIAL(trace) << "plan_layer_heights print_z, height, layer_nr->next_layer_nr: " << layer_heights[i].print_z << " " << layer_heights[i].height << " " BOOST_LOG_TRIVIAL(info) << "plan_layer_heights print_z, height, layer_nr->next_layer_nr: " << layer_heights[i].print_z << " " << layer_heights[i].height << " "
<< i << "->" << layer_heights[i].next_layer_nr << std::endl; << i << "->" << layer_heights[i].next_layer_nr;
} }
return layer_heights; return layer_heights;