Organic supports: Improving smoothing / collision avoidance convergence

This commit is contained in:
Vojtech Bubnik 2023-01-31 15:55:35 +01:00
parent b173927ad1
commit 49caab98cb

View File

@ -3557,7 +3557,7 @@ static void organic_smooth_branches_avoid_collisions(
throw_on_cancel(); throw_on_cancel();
static constexpr const double collision_extra_gap = 0.1; static constexpr const double collision_extra_gap = 0.1;
static constexpr const double max_nudge_collision_avoidance = 0.2; static constexpr const double max_nudge_collision_avoidance = 0.5;
static constexpr const double max_nudge_smoothing = 0.2; static constexpr const double max_nudge_smoothing = 0.2;
static constexpr const size_t num_iter = 100; // 1000; static constexpr const size_t num_iter = 100; // 1000;
for (size_t iter = 0; iter < num_iter; ++ iter) { for (size_t iter = 0; iter < num_iter; ++ iter) {
@ -3574,12 +3574,12 @@ static void organic_smooth_branches_avoid_collisions(
for (uint32_t layer_id = collision_sphere.layer_begin; layer_id != collision_sphere.layer_end; ++ layer_id) { for (uint32_t layer_id = collision_sphere.layer_begin; layer_id != collision_sphere.layer_end; ++ layer_id) {
double dz = (layer_id - collision_sphere.element.state.layer_idx) * slicing_params.layer_height; double dz = (layer_id - collision_sphere.element.state.layer_idx) * slicing_params.layer_height;
if (double r2 = sqr(collision_sphere.radius) - sqr(dz); r2 > 0) { if (double r2 = sqr(collision_sphere.radius) - sqr(dz); r2 > 0) {
if (const LayerCollisionCache &layer_collision_cache_item = layer_collision_cache[layer_id]; ! layer_collision_cache.empty()) { if (const LayerCollisionCache &layer_collision_cache_item = layer_collision_cache[layer_id]; ! layer_collision_cache_item.empty()) {
size_t hit_idx_out; size_t hit_idx_out;
Vec2d hit_point_out; Vec2d hit_point_out;
double dist = sqrt(AABBTreeLines::squared_distance_to_indexed_lines( if (double dist = sqrt(AABBTreeLines::squared_distance_to_indexed_lines(
layer_collision_cache_item.lines, layer_collision_cache_item.aabbtree_lines, Vec2d(to_2d(collision_sphere.position).cast<double>()), layer_collision_cache_item.lines, layer_collision_cache_item.aabbtree_lines, Vec2d(to_2d(collision_sphere.position).cast<double>()),
hit_idx_out, hit_point_out, r2)); hit_idx_out, hit_point_out, r2)); dist >= 0.) {
double collision_depth = sqrt(r2) - dist; double collision_depth = sqrt(r2) - dist;
if (collision_depth > collision_sphere.last_collision_depth) { if (collision_depth > collision_sphere.last_collision_depth) {
collision_sphere.last_collision_depth = collision_depth; collision_sphere.last_collision_depth = collision_depth;
@ -3588,6 +3588,7 @@ static void organic_smooth_branches_avoid_collisions(
} }
} }
} }
}
if (collision_sphere.last_collision_depth > 0) { if (collision_sphere.last_collision_depth > 0) {
// Collision detected to be removed. // Collision detected to be removed.
// Nudge the circle center away from the collision. // Nudge the circle center away from the collision.
@ -3628,7 +3629,14 @@ static void organic_smooth_branches_avoid_collisions(
throw_on_cancel(); throw_on_cancel();
} }
}); });
// printf("iteration: %d, moved: %d\n", int(iter), int(num_moved)); #if 0
std::vector<double> stat;
for (CollisionSphere& collision_sphere : collision_spheres)
if (!collision_sphere.locked)
stat.emplace_back(collision_sphere.last_collision_depth);
std::sort(stat.begin(), stat.end());
printf("iteration: %d, moved: %d, collision depth: min %lf, max %lf, median %lf\n", int(iter), int(num_moved), stat.front(), stat.back(), stat[stat.size() / 2]);
#endif
if (num_moved == 0) if (num_moved == 0)
break; break;
} }
@ -3644,7 +3652,8 @@ static void organic_smooth_branches_avoid_collisions(
const TreeSupportSettings &config, const TreeSupportSettings &config,
std::vector<SupportElements> &move_bounds, std::vector<SupportElements> &move_bounds,
const std::vector<std::pair<SupportElement*, int>> &elements_with_link_down, const std::vector<std::pair<SupportElement*, int>> &elements_with_link_down,
const std::vector<size_t> &linear_data_layers) const std::vector<size_t> &linear_data_layers,
std::function<void()> throw_on_cancel)
{ {
TriangleMesh mesh = print_object.model_object()->raw_mesh(); TriangleMesh mesh = print_object.model_object()->raw_mesh();
mesh.transform(print_object.trafo_centered()); mesh.transform(print_object.trafo_centered());