mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 18:45:55 +08:00
Merge branch 'master' of https://github.com/Prusa-Development/PrusaSlicerPrivate into et_transformations
This commit is contained in:
commit
d3b7cdfeca
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user