Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_transformations

This commit is contained in:
enricoturri1966 2023-02-13 07:50:03 +01:00
commit d3b7cdfeca
2 changed files with 54 additions and 14 deletions

View File

@ -505,7 +505,7 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
// 1) Calculate offsets of collision areas in parallel. // 1) Calculate offsets of collision areas in parallel.
std::vector<Polygons> collision_areas_offsetted(max_required_layer + 1 - min_layer_bottom); std::vector<Polygons> collision_areas_offsetted(max_required_layer + 1 - min_layer_bottom);
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_bottom, max_required_layer + 1), tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_bottom, max_required_layer + 1),
[&outlines, &machine_border = m_machine_border, offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel] [&outlines, &machine_border = std::as_const(m_machine_border), offset_value = radius + xy_distance, min_layer_bottom, &collision_areas_offsetted, &throw_on_cancel]
(const tbb::blocked_range<LayerIndex> &range) { (const tbb::blocked_range<LayerIndex> &range) {
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) { for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++ layer_idx) {
Polygons collision_areas = machine_border; Polygons collision_areas = machine_border;
@ -520,14 +520,54 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
// 2) Sum over top / bottom ranges. // 2) Sum over top / bottom ranges.
const bool last = outline_idx == layer_outline_indices.size(); const bool last = outline_idx == layer_outline_indices.size();
tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_last + 1, max_layer_idx + 1), tbb::parallel_for(tbb::blocked_range<LayerIndex>(min_layer_last + 1, max_layer_idx + 1),
[&collision_areas_offsetted, &anti_overhang = m_anti_overhang, min_layer_bottom, radius, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel] [&collision_areas_offsetted, &outlines, &machine_border = m_machine_border, &anti_overhang = m_anti_overhang, min_layer_bottom, radius,
xy_distance, z_distance_bottom_layers, z_distance_top_layers, min_resolution = m_min_resolution, &data, min_layer_last, last, &throw_on_cancel]
(const tbb::blocked_range<LayerIndex>& range) { (const tbb::blocked_range<LayerIndex>& range) {
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) { for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) {
Polygons collisions; Polygons collisions;
for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) { for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) {
int j = layer_idx + i - min_layer_bottom; int j = layer_idx + i - min_layer_bottom;
if (j >= 0 && j < int(collision_areas_offsetted.size())) if (j >= 0 && j < int(collision_areas_offsetted.size()) && i <= 0)
append(collisions, collision_areas_offsetted[j]); append(collisions, collision_areas_offsetted[j]);
else if (j >= 0 && layer_idx + i < int(outlines.size()) && i > 0) {
Polygons collision_areas_original = machine_border;
append(collision_areas_original, outlines[layer_idx + i]);
// If just the collision (including the xy distance) of the layers above is accumulated, it leads to the
// following issue:
// Example: assuming the z distance is 2 layer
// + = xy_distance
// - = model
// o = overhang of the area two layers above that should result in tips on this layer
//
// +-----+
// +-----+
// +-----+
// o +-----+
// If just the collision above is accumulated the overhang will get overwritten by the xy_distance of the
// layer below the overhang...
//
// This only causes issues if the overhang area is thinner than xy_distance
// Just accumulating areas of the model above without the xy distance is also problematic, as then support
// may get closer to the model (on the diagonal downwards) than the user intended. Example (s = support):
// +-----+
// +-----+
// +-----+
// s+-----+
// technically the calculation below is off by one layer, as the actual distance between plastic one layer
// down is 0 not layer height, as this layer is filled with said plastic. But otherwise a part of the
// overhang that is expected to be supported is overwritten by the remaining part of the xy distance of the
// layer below the to be supported area.
coord_t required_range_x =
(xy_distance - ((i - (z_distance_top_layers == 1 ? 0.5 : 0)) * xy_distance / z_distance_top_layers));
// the conditional -0.5 ensures that plastic can never touch on the diagonal
// downward when the z_distance_top_layers = 1. It is assumed to be better to
// not support an overhang<90 degree than to risk fusing to it.
collision_areas_original = offset(union_ex(collision_areas_original), radius + required_range_x, ClipperLib::jtMiter, 1.2);
append(collisions, collision_areas_original);
}
} }
collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions); collisions = last && layer_idx < int(anti_overhang.size()) ? union_(collisions, offset(union_ex(anti_overhang[layer_idx]), radius, ClipperLib::jtMiter, 1.2)) : union_(collisions);
auto &dst = data[layer_idx - (min_layer_last + 1)]; auto &dst = data[layer_idx - (min_layer_last + 1)];
@ -644,7 +684,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector<RadiusLayerPair> &ke
BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?"; BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?";
continue; continue;
} }
if (! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta) if ((task.to_model ? to_model : to_build_plate) &&
(! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta))
avoidance_tasks.emplace_back(task); avoidance_tasks.emplace_back(task);
} }

View File

@ -496,15 +496,15 @@ static std::optional<std::pair<Point, size_t>> polyline_sample_next_point_at_dis
Vec2d xf = p0f - foot_pt; Vec2d xf = p0f - foot_pt;
// Squared distance of "start_pt" from the ray (p0, p1). // Squared distance of "start_pt" from the ray (p0, p1).
double l2_from_line = xf.squaredNorm(); double l2_from_line = xf.squaredNorm();
double det = dist2 - l2_from_line; // Squared distance of an intersection point of a circle with center at the foot point.
if (double l2_intersection = dist2 - l2_from_line;
if (det > - SCALED_EPSILON) { l2_intersection > - SCALED_EPSILON) {
// The ray (p0, p1) touches or intersects a circle centered at "start_pt" with radius "dist". // The ray (p0, p1) touches or intersects a circle centered at "start_pt" with radius "dist".
// Distance of the circle intersection point from the foot point. // Distance of the circle intersection point from the foot point.
double dist_circle_intersection = std::sqrt(std::max(0., det)); l2_intersection = std::max(l2_intersection, 0.);
if ((v - foot_pt).cast<double>().norm() > dist_circle_intersection) { if ((v - foot_pt).cast<double>().squaredNorm() >= l2_intersection) {
// Intersection of the circle with the segment (p0, p1) is on the right side (close to p1) from the foot point. // Intersection of the circle with the segment (p0, p1) is on the right side (close to p1) from the foot point.
Point p = p0 + (foot_pt + v * (dist_circle_intersection / sqrt(l2v))).cast<coord_t>(); Point p = p0 + (foot_pt + v * sqrt(l2_intersection / l2v)).cast<coord_t>();
validate_range(p); validate_range(p);
return std::pair<Point, size_t>{ p, i - 1 }; return std::pair<Point, size_t>{ p, i - 1 };
} }
@ -916,7 +916,7 @@ static void generate_initial_areas(
//FIXME Vojtech: This is not sufficient for support enforcers to work. //FIXME Vojtech: This is not sufficient for support enforcers to work.
//FIXME There is no account for the support overhang angle. //FIXME There is no account for the support overhang angle.
//FIXME There is no account for the width of the collision regions. //FIXME There is no account for the width of the collision regions.
const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0) const coord_t extra_outset = std::max(coord_t(0), mesh_config.min_radius - mesh_config.support_line_width / 2) + (min_xy_dist ? mesh_config.support_line_width / 2 : 0)
//FIXME this is a heuristic value for support enforcers to work. //FIXME this is a heuristic value for support enforcers to work.
// + 10 * mesh_config.support_line_width; // + 10 * mesh_config.support_line_width;
; ;
@ -1079,9 +1079,8 @@ static void generate_initial_areas(
Polygons overhang_regular; Polygons overhang_regular;
{ {
const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta]; const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta];
overhang_regular = mesh_group_settings.support_offset == 0 ? // When support_offset = 0 safe_offset_inc will only be the difference between overhang_raw and relevant_forbidden, that has to be calculated anyway.
overhang_raw : overhang_regular = safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1);
safe_offset_inc(overhang_raw, mesh_group_settings.support_offset, relevant_forbidden, mesh_config.min_radius * 1.75 + mesh_config.xy_min_distance, 0, 1);
//check_self_intersections(overhang_regular, "overhang_regular1"); //check_self_intersections(overhang_regular, "overhang_regular1");
// offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang // offset ensures that areas that could be supported by a part of a support line, are not considered unsupported overhang