SeamPlacer: Removed skipping mechanics in alignment

improved snapping to sharp angles
reduced curling on smooth surfaces
Rear is now aligned
This commit is contained in:
PavelMikus 2022-06-20 17:41:05 +02:00
parent 07dfcdd94c
commit 732586de7c
2 changed files with 26 additions and 34 deletions

View file

@ -332,7 +332,6 @@ struct GlobalModelInfo {
return std::abs(orig_to_point.dot(plane_normal));
};
float total_weight = 0;
float total_visibility = 0;
for (size_t i = 0; i < points.size(); ++i) {
@ -561,7 +560,7 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const
break;
}
viable_points_indices.push_back(last_enforced_idx);
if (abs(result.points[last_enforced_idx].local_ccw_angle) > 0.3 * PI) {
if (abs(result.points[last_enforced_idx].local_ccw_angle) > SeamPlacer::sharp_angle_snapping_threshold) {
orig_large_angle_points_indices.push_back(last_enforced_idx);
}
last_enforced_idx = next_index(last_enforced_idx);
@ -654,7 +653,7 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po,
// to compute ideal search radius (area), we use exponential distribution (complementary distr to poisson)
// parameters of exponential distribution to compute area that will have with probability="probability" more than given number of samples="samples"
float probability = 0.9f;
float samples = 3;
float samples = 4;
float density = SeamPlacer::raycasting_visibility_samples_count / result.mesh_samples.total_area;
// exponential probability distrubtion function is : f(x) = P(X > x) = e^(l*x) where l is the rate parameter (computed as 1/u where u is mean value)
// probability that sampled area A with S samples contains more than samples count:
@ -718,7 +717,7 @@ void gather_enforcers_blockers(GlobalModelInfo &result, const PrintObject *po) {
struct SeamComparator {
SeamPosition setup;
float angle_importance;
SeamComparator(SeamPosition setup) :
explicit SeamComparator(SeamPosition setup) :
setup(setup) {
angle_importance = setup == spNearest ? SeamPlacer::angle_importance_nearest : SeamPlacer::angle_importance_aligned;
}
@ -750,10 +749,7 @@ struct SeamComparator {
return false;
}
if (setup == SeamPosition::spRear) {
if (a.position.y() == b.position.y()) {
return a.position.x() > b.position.x();
}
if (setup == SeamPosition::spRear && a.position.y() != b.position.y()) {
return a.position.y() > b.position.y();
}
@ -816,10 +812,7 @@ struct SeamComparator {
}
if (setup == SeamPosition::spRear) {
if (a.position.y() == b.position.y()) {
return a.position.x() > b.position.x();
}
return a.position.y() > b.position.y();
return a.position.y() + SeamPlacer::seam_align_score_tolerance * 5.0f > b.position.y();
}
float penalty_a = a.visibility
@ -843,6 +836,10 @@ struct SeamComparator {
return gauss(ccw_angle, 0.0f, 1.0f, 3.0f) +
1.0f / (2 + std::exp(-ccw_angle));
}
float weight(const SeamCandidate &a) const {
return a.visibility + angle_importance * compute_angle_penalty(a.local_ccw_angle) / (1.0f + angle_importance);
}
};
#ifdef DEBUG_FILES
@ -1214,13 +1211,12 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
int seam_index = start_seam.second;
//initialize searching for seam string - cluster of nearby seams on previous and next layers
int skips = SeamPlacer::seam_align_tolerable_skips / 2;
int next_layer = layer_idx + 1;
std::pair<size_t, size_t> prev_point_index = start_seam;
std::vector<std::pair<size_t, size_t>> seam_string { start_seam };
//find seams or potential seams in forward direction; there is a budget of skips allowed
while (skips >= 0 && next_layer < int(layers.size())) {
while (next_layer < int(layers.size())) {
auto maybe_next_seam = find_next_seam_in_layer(layers, prev_point_index, next_layer,
float(po->get_layer(next_layer)->slice_z), comparator);
if (maybe_next_seam.has_value()) {
@ -1240,17 +1236,15 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
prev_point_index = seam_string.back();
//String added, prev_point_index updated
} else {
// Layer skipped, reduce number of available skips
skips--;
break;
}
next_layer++;
}
//do additional check in back direction
next_layer = layer_idx - 1;
skips = SeamPlacer::seam_align_tolerable_skips / 2;
prev_point_index = std::pair<size_t, size_t>(layer_idx, seam_index);
while (skips >= 0 && next_layer >= 0) {
while (next_layer >= 0) {
auto maybe_next_seam = find_next_seam_in_layer(layers, prev_point_index, next_layer,
float(po->get_layer(next_layer)->slice_z), comparator);
if (maybe_next_seam.has_value()) {
@ -1269,8 +1263,7 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
prev_point_index = seam_string.back();
//String added, prev_point_index updated
} else {
// Layer skipped, reduce number of available skips
skips--;
break;
}
next_layer--;
}
@ -1385,10 +1378,8 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
Vec3f pos = layers[seam_string[index].first].points[seam_string[index].second].position;
observations[index] = pos.head<2>();
observation_points[index] = pos.z();
weights[index] =
(comparator.compute_angle_penalty(
layers[seam_string[index].first].points[seam_string[index].second].local_ccw_angle)
< comparator.compute_angle_penalty(0.4f * float(PI))) ? 1.0f : 0.1f;
weights[index] = std::min(1.0f,
comparator.weight(layers[seam_string[index].first].points[seam_string[index].second]));
}
// Curve Fitting
@ -1400,7 +1391,10 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
// Perimeter structure of the point; also set flag aligned to true
for (size_t index = 0; index < seam_string.size(); ++index) {
const auto &pair = seam_string[index];
const float t = weights[index];
const float t =
abs(layers[pair.first].points[pair.second].local_ccw_angle)
> SeamPlacer::sharp_angle_snapping_threshold
? 1.0 : 0.0f;
Vec3f current_pos = layers[pair.first].points[pair.second].position;
Vec2f fitted_pos = curve.get_fitted_value(current_pos.z());
@ -1504,7 +1498,7 @@ void SeamPlacer::init(const Print &print, std::function<void(void)> throw_if_can
<< "SeamPlacer: pick_seam_point : end";
}
throw_if_canceled_func();
if (configured_seam_preference == spAligned) {
if (configured_seam_preference == spAligned || configured_seam_preference == spRear) {
BOOST_LOG_TRIVIAL(debug)
<< "SeamPlacer: align_seam_points : start";
align_seam_points(po, comparator);

View file

@ -128,6 +128,7 @@ public:
// arm length used during angles computation
static constexpr float polygon_local_angles_arm_distance = 0.3f;
static constexpr float sharp_angle_snapping_threshold = 0.3 * PI;
// max tolerable distance from the previous layer is overhang_distance_tolerance_factor * flow_width
static constexpr float overhang_distance_tolerance_factor = 0.5f;
@ -143,16 +144,13 @@ public:
// When searching for seam clusters for alignment:
// following value describes, how much worse score can point have and still be picked into seam cluster instead of original seam point on the same layer
static constexpr float seam_align_score_tolerance = 0.27f;
// seam_align_tolerable_dist - if next layer closest point is too far away, skip layer
static constexpr float seam_align_tolerable_dist = 0.4f;
// if the seam of the current layer is too far away, and the closest seam candidate is not very good, layer is skipped.
// this param limits the number of allowed skips
static constexpr size_t seam_align_tolerable_skips = 4;
static constexpr float seam_align_score_tolerance = 0.3f;
// seam_align_tolerable_dist - if next layer closest point is too far away, break aligned string
static constexpr float seam_align_tolerable_dist = 1.0f;
// minimum number of seams needed in cluster to make alignment happen
static constexpr size_t seam_align_minimum_string_seams = 6;
static constexpr size_t seam_align_minimum_string_seams = 10;
// points covered by spline; determines number of splines for the given string
static constexpr size_t seam_align_seams_per_segment = 8;
static constexpr size_t seam_align_seams_per_segment = 16;
//The following data structures hold all perimeter points for all PrintObject.
std::unordered_map<const PrintObject*, PrintObjectSeamData> m_seam_per_object;