Merge branch 'vb_tr_SuggestedTreeSupportFixes'

This commit is contained in:
Vojtech Bubnik 2023-02-10 12:39:42 +01:00
commit f982a91e7b
2 changed files with 49 additions and 7 deletions

View file

@ -520,14 +520,54 @@ void TreeModelVolumes::calculateCollision(const coord_t radius, const LayerIndex
// 2) Sum over top / bottom ranges.
const bool last = outline_idx == layer_outline_indices.size();
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) {
for (LayerIndex layer_idx = range.begin(); layer_idx != range.end(); ++layer_idx) {
Polygons collisions;
for (int i = -z_distance_bottom_layers; i <= z_distance_top_layers; ++ i) {
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]);
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);
auto &dst = data[layer_idx - (min_layer_last + 1)];
@ -644,6 +684,8 @@ void TreeModelVolumes::calculateAvoidance(const std::vector<RadiusLayerPair> &ke
BOOST_LOG_TRIVIAL(debug) << "Calculation requested for value already calculated?";
continue;
}
if ((task.to_model && !to_model) || (!task.to_model && !to_build_plate))
continue;
if (! task.holefree() || task.radius < m_increase_until_radius + m_current_min_xy_dist_delta)
avoidance_tasks.emplace_back(task);
}

View file

@ -576,7 +576,8 @@ static std::optional<std::pair<Point, size_t>> polyline_sample_next_point_at_dis
double next_distance = current_distance;
// Get points so that at least min_points are added and they each are current_distance away from each other. If that is impossible, decrease current_distance a bit.
// The input are lines, that means that the line from the last to the first vertex does not have to exist, so exclude all points that are on this line!
while ((next_point = polyline_sample_next_point_at_distance(part.points, current_point, current_index, next_distance))) {
while ((next_point = polyline_sample_next_point_at_distance(part.points, current_point, current_index, next_distance)) &&
next_point->second < coord_t(part.size()) - 1) {
// Not every point that is distance away, is valid, as it may be much closer to another point. This is especially the case when the overhang is very thin.
// So this ensures that the points are actually a certain distance from each other.
// This assurance is only made on a per polygon basis, as different but close polygon may not be able to use support below the other polygon.
@ -916,7 +917,7 @@ static void generate_initial_areas(
//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 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.
// + 10 * mesh_config.support_line_width;
;
@ -1079,9 +1080,8 @@ static void generate_initial_areas(
Polygons overhang_regular;
{
const Polygons &overhang_raw = overhangs[layer_idx + z_distance_delta];
overhang_regular = mesh_group_settings.support_offset == 0 ?
overhang_raw :
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);
// 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_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);
//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