mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-10 03:51:49 +08:00
cubic spline segment size based on the length of string
This commit is contained in:
parent
1e05d09324
commit
fec3afa490
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "libslic3r/Utils.hpp"
|
#include "libslic3r/Utils.hpp"
|
||||||
|
|
||||||
#define DEBUG_FILES
|
//#define DEBUG_FILES
|
||||||
|
|
||||||
#ifdef DEBUG_FILES
|
#ifdef DEBUG_FILES
|
||||||
#include <boost/nowide/cstdio.hpp>
|
#include <boost/nowide/cstdio.hpp>
|
||||||
@ -1217,9 +1217,8 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
|
|||||||
while (next_layer < int(layers.size())) {
|
while (next_layer < int(layers.size())) {
|
||||||
std::optional<std::pair<size_t, size_t>> maybe_next_seam;
|
std::optional<std::pair<size_t, size_t>> maybe_next_seam;
|
||||||
float z_distance = float(po->get_layer(next_layer)->slice_z) - origin_position.z();
|
float z_distance = float(po->get_layer(next_layer)->slice_z) - origin_position.z();
|
||||||
float f = 2.71828f - logf(po->get_layer(next_layer)->height);
|
float max_distance = SeamPlacer::seam_align_tolerable_dist;
|
||||||
float max_distance = SeamPlacer::seam_align_tolerable_dist_factor * f * f;
|
if (fabs(next_layer - layer_idx) >= SeamPlacer::seam_align_min_seams_for_linear_projection){
|
||||||
if (fabs(next_layer - layer_idx) > 3){
|
|
||||||
Vec3f projected_position = origin_position + z_distance * surface_line_dir;
|
Vec3f projected_position = origin_position + z_distance * surface_line_dir;
|
||||||
maybe_next_seam = find_next_seam_in_layer(layers, projected_position, next_layer, max_distance,
|
maybe_next_seam = find_next_seam_in_layer(layers, projected_position, next_layer, max_distance,
|
||||||
comparator);
|
comparator);
|
||||||
@ -1246,9 +1245,7 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
|
|||||||
seam_string.push_back(maybe_next_seam.operator*());
|
seam_string.push_back(maybe_next_seam.operator*());
|
||||||
prev_point_index = seam_string.back();
|
prev_point_index = seam_string.back();
|
||||||
//String added, prev_point_index updated
|
//String added, prev_point_index updated
|
||||||
Vec3f line_dir = next_seam.position - origin_position;
|
surface_line_dir += (next_seam.position - origin_position).normalized();
|
||||||
surface_line_dir += line_dir / line_dir.z();
|
|
||||||
surface_line_dir /= surface_line_dir.z();
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1261,10 +1258,9 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
|
|||||||
while (next_layer >= 0) {
|
while (next_layer >= 0) {
|
||||||
std::optional<std::pair<size_t, size_t>> maybe_next_seam;
|
std::optional<std::pair<size_t, size_t>> maybe_next_seam;
|
||||||
float z_distance = float(po->get_layer(next_layer)->slice_z) - origin_position.z();
|
float z_distance = float(po->get_layer(next_layer)->slice_z) - origin_position.z();
|
||||||
float f = 2.71828f - logf(po->get_layer(next_layer)->height);
|
float max_distance = SeamPlacer::seam_align_tolerable_dist;
|
||||||
float max_distance = SeamPlacer::seam_align_tolerable_dist_factor * f * f;
|
if (fabs(next_layer - layer_idx) >= SeamPlacer::seam_align_min_seams_for_linear_projection){
|
||||||
if (fabs(next_layer - layer_idx) > 3){
|
Vec3f projected_position = origin_position + z_distance * (surface_line_dir / surface_line_dir.z());
|
||||||
Vec3f projected_position = origin_position + z_distance * surface_line_dir;
|
|
||||||
maybe_next_seam = find_next_seam_in_layer(layers, projected_position, next_layer, max_distance,
|
maybe_next_seam = find_next_seam_in_layer(layers, projected_position, next_layer, max_distance,
|
||||||
comparator);
|
comparator);
|
||||||
}
|
}
|
||||||
@ -1290,9 +1286,7 @@ std::vector<std::pair<size_t, size_t>> SeamPlacer::find_seam_string(const PrintO
|
|||||||
seam_string.push_back(maybe_next_seam.operator*());
|
seam_string.push_back(maybe_next_seam.operator*());
|
||||||
prev_point_index = seam_string.back();
|
prev_point_index = seam_string.back();
|
||||||
//String added, prev_point_index updated
|
//String added, prev_point_index updated
|
||||||
Vec3f line_dir = next_seam.position - origin_position;
|
surface_line_dir += (next_seam.position - origin_position).normalized();
|
||||||
surface_line_dir += line_dir / line_dir.z();
|
|
||||||
surface_line_dir /= surface_line_dir.z();
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1402,20 +1396,20 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
|
|||||||
weights.resize(seam_string.size());
|
weights.resize(seam_string.size());
|
||||||
|
|
||||||
//gather points positions and weights
|
//gather points positions and weights
|
||||||
// The algorithm uses only angle to compute penalty, to enforce snapping to sharp corners, if they are present
|
float total_length = 0.0f;
|
||||||
// after several experiments approach that gives best results is to snap the weight to one for sharp corners, and
|
Vec3f last_point_pos = layers[seam_string[0].first].points[seam_string[0].second].position;
|
||||||
// leave it small for others. However, this can result in non-smooth line over area with a lot of unaligned sharp corners.
|
|
||||||
for (size_t index = 0; index < seam_string.size(); ++index) {
|
for (size_t index = 0; index < seam_string.size(); ++index) {
|
||||||
Vec3f pos = layers[seam_string[index].first].points[seam_string[index].second].position;
|
Vec3f pos = layers[seam_string[index].first].points[seam_string[index].second].position;
|
||||||
|
total_length += (last_point_pos - pos).norm();
|
||||||
|
last_point_pos = pos;
|
||||||
observations[index] = pos.head<2>();
|
observations[index] = pos.head<2>();
|
||||||
observation_points[index] = pos.z();
|
observation_points[index] = pos.z();
|
||||||
weights[index] = std::min(1.0f,
|
weights[index] = comparator.weight(layers[seam_string[index].first].points[seam_string[index].second]);
|
||||||
comparator.weight(layers[seam_string[index].first].points[seam_string[index].second]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Curve Fitting
|
// Curve Fitting
|
||||||
size_t number_of_segments = std::max(size_t(1),
|
size_t number_of_segments = std::max(size_t(1),
|
||||||
size_t(observations.size() / SeamPlacer::seam_align_seams_per_segment));
|
size_t(total_length / SeamPlacer::seam_align_mm_per_segment));
|
||||||
auto curve = Geometry::fit_cubic_bspline(observations, observation_points, weights, number_of_segments);
|
auto curve = Geometry::fit_cubic_bspline(observations, observation_points, weights, number_of_segments);
|
||||||
|
|
||||||
// Do alignment - compute fitted point for each point in the string from its Z coord, and store the position into
|
// Do alignment - compute fitted point for each point in the string from its Z coord, and store the position into
|
||||||
|
@ -128,7 +128,7 @@ public:
|
|||||||
|
|
||||||
// arm length used during angles computation
|
// arm length used during angles computation
|
||||||
static constexpr float polygon_local_angles_arm_distance = 0.3f;
|
static constexpr float polygon_local_angles_arm_distance = 0.3f;
|
||||||
static constexpr float sharp_angle_snapping_threshold = 0.25f * float(PI);
|
static constexpr float sharp_angle_snapping_threshold = 0.3f * float(PI);
|
||||||
|
|
||||||
// max tolerable distance from the previous layer is overhang_distance_tolerance_factor * flow_width
|
// max tolerable distance from the previous layer is overhang_distance_tolerance_factor * flow_width
|
||||||
static constexpr float overhang_distance_tolerance_factor = 0.5f;
|
static constexpr float overhang_distance_tolerance_factor = 0.5f;
|
||||||
@ -143,13 +143,15 @@ public:
|
|||||||
static constexpr float enforcer_oversampling_distance = 0.2f;
|
static constexpr float enforcer_oversampling_distance = 0.2f;
|
||||||
|
|
||||||
// When searching for seam clusters for alignment:
|
// When searching for seam clusters for alignment:
|
||||||
|
static constexpr size_t seam_align_min_seams_for_linear_projection = 1;
|
||||||
// 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
|
// 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.3f;
|
static constexpr float seam_align_score_tolerance = 0.3f;
|
||||||
static constexpr float seam_align_tolerable_dist_factor = 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 = 3.0f;
|
||||||
// minimum number of seams needed in cluster to make alignment happen
|
// minimum number of seams needed in cluster to make alignment happen
|
||||||
static constexpr size_t seam_align_minimum_string_seams = 10;
|
static constexpr size_t seam_align_minimum_string_seams = 6;
|
||||||
// points covered by spline; determines number of splines for the given string
|
// millimeters covered by spline; determines number of splines for the given string
|
||||||
static constexpr size_t seam_align_seams_per_segment = 16;
|
static constexpr size_t seam_align_mm_per_segment = 8.0f;
|
||||||
|
|
||||||
//The following data structures hold all perimeter points for all PrintObject.
|
//The following data structures hold all perimeter points for all PrintObject.
|
||||||
std::unordered_map<const PrintObject*, PrintObjectSeamData> m_seam_per_object;
|
std::unordered_map<const PrintObject*, PrintObjectSeamData> m_seam_per_object;
|
||||||
|
@ -15,8 +15,8 @@ template<int Dimension, typename NumberType>
|
|||||||
struct PolynomialCurve {
|
struct PolynomialCurve {
|
||||||
Eigen::MatrixXf coefficients;
|
Eigen::MatrixXf coefficients;
|
||||||
|
|
||||||
Vec3f get_fitted_value(const NumberType value) const {
|
Vec<Dimension, NumberType> get_fitted_value(const NumberType& value) const {
|
||||||
auto result = Vec<Dimension, NumberType>::Zero();
|
Vec<Dimension, NumberType> result = Vec<Dimension, NumberType>::Zero();
|
||||||
size_t order = this->coefficients.rows() - 1;
|
size_t order = this->coefficients.rows() - 1;
|
||||||
auto x = NumberType(1.);
|
auto x = NumberType(1.);
|
||||||
for (size_t index = 0; index < order + 1; ++index, x *= value)
|
for (size_t index = 0; index < order + 1; ++index, x *= value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user