mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 12:56:03 +08:00
tweaked parameters,
fixed minor bugs
This commit is contained in:
parent
c72687c96c
commit
ad819850f9
@ -156,7 +156,7 @@ std::vector<HitInfo> raycast_visibility(const AABBTreeIndirect::Tree<3, float> &
|
|||||||
// Prepare random samples per ray
|
// Prepare random samples per ray
|
||||||
// std::random_device rnd_device;
|
// std::random_device rnd_device;
|
||||||
// use fixed seed, we can backtrack potential issues easier
|
// use fixed seed, we can backtrack potential issues easier
|
||||||
std::mt19937 mersenne_engine { 12345 };
|
std::mt19937 mersenne_engine { 131 };
|
||||||
std::uniform_real_distribution<float> dist { 0, 1 };
|
std::uniform_real_distribution<float> dist { 0, 1 };
|
||||||
|
|
||||||
auto gen = [&dist, &mersenne_engine]() {
|
auto gen = [&dist, &mersenne_engine]() {
|
||||||
@ -174,15 +174,19 @@ std::vector<HitInfo> raycast_visibility(const AABBTreeIndirect::Tree<3, float> &
|
|||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "SeamPlacer: raycast visibility for " << ray_count << " rays: start";
|
<< "SeamPlacer: raycast visibility for " << ray_count << " rays: start";
|
||||||
// raycast visibility
|
|
||||||
std::vector<HitInfo> hit_points = tbb::parallel_reduce(tbb::blocked_range<size_t>(0, ray_count),
|
std::vector<HitInfo> hit_points = tbb::parallel_reduce(tbb::blocked_range<size_t>(0, ray_count),
|
||||||
std::vector<HitInfo> { },
|
std::vector<HitInfo> { },
|
||||||
[&](tbb::blocked_range<size_t> r, std::vector<HitInfo> init) {
|
[&](tbb::blocked_range<size_t> r, std::vector<HitInfo> init) {
|
||||||
for (size_t index = r.begin(); index < r.end(); ++index) {
|
for (size_t index = r.begin(); index < r.end(); ++index) {
|
||||||
|
//generate global ray direction
|
||||||
Vec3f global_ray_dir = sample_sphere_uniform(global_dir_random_samples[index]);
|
Vec3f global_ray_dir = sample_sphere_uniform(global_dir_random_samples[index]);
|
||||||
|
//place the ray origin on the bounding sphere
|
||||||
Vec3f ray_origin = (vision_sphere_center - global_ray_dir * vision_sphere_raidus);
|
Vec3f ray_origin = (vision_sphere_center - global_ray_dir * vision_sphere_raidus);
|
||||||
|
// compute local ray direction as cosine hemisphere sample - the rays dont aim directly to the middle
|
||||||
Vec3f local_dir = sample_power_cosine_hemisphere(local_dir_random_samples[index], SeamPlacer::cosine_hemisphere_sampling_power);
|
Vec3f local_dir = sample_power_cosine_hemisphere(local_dir_random_samples[index], SeamPlacer::cosine_hemisphere_sampling_power);
|
||||||
|
|
||||||
|
// apply the local direction via Frame struct - the local_dir is with respect to +Z being forward
|
||||||
Frame f;
|
Frame f;
|
||||||
f.set_from_z(global_ray_dir);
|
f.set_from_z(global_ray_dir);
|
||||||
Vec3f final_ray_dir = (f.to_world(local_dir));
|
Vec3f final_ray_dir = (f.to_world(local_dir));
|
||||||
@ -282,6 +286,7 @@ std::vector<float> calculate_polygon_angles_at_vertices(const Polygon &polygon,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// structure to store global information about the model - occlusion hits, enforcers, blockers
|
||||||
struct GlobalModelInfo {
|
struct GlobalModelInfo {
|
||||||
std::vector<HitInfo> geometry_raycast_hits;
|
std::vector<HitInfo> geometry_raycast_hits;
|
||||||
KDTreeIndirect<3, float, HitInfoCoordinateFunctor> raycast_hits_tree;
|
KDTreeIndirect<3, float, HitInfoCoordinateFunctor> raycast_hits_tree;
|
||||||
@ -311,7 +316,7 @@ struct GlobalModelInfo {
|
|||||||
if (closest_point_index == raycast_hits_tree.npos
|
if (closest_point_index == raycast_hits_tree.npos
|
||||||
||
|
||
|
||||||
(position - geometry_raycast_hits[closest_point_index].position).norm()
|
(position - geometry_raycast_hits[closest_point_index].position).norm()
|
||||||
> SeamPlacer::seam_align_tolerable_dist) {
|
> SeamPlacer::considered_area_radius) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto nearby_points = find_nearby_points(raycast_hits_tree, position, SeamPlacer::considered_area_radius);
|
auto nearby_points = find_nearby_points(raycast_hits_tree, position, SeamPlacer::considered_area_radius);
|
||||||
@ -354,7 +359,7 @@ struct GlobalModelInfo {
|
|||||||
for (size_t i = 0; i < divided_mesh.vertices.size(); ++i) {
|
for (size_t i = 0; i < divided_mesh.vertices.size(); ++i) {
|
||||||
float visibility = calculate_point_visibility(divided_mesh.vertices[i]);
|
float visibility = calculate_point_visibility(divided_mesh.vertices[i]);
|
||||||
float normalized = visibility
|
float normalized = visibility
|
||||||
/ (SeamPlacer::expected_hits_per_area * PI * SeamPlacer::considered_area_radius);
|
/ (SeamPlacer::expected_hits_per_area * SeamPlacer::considered_area_radius);
|
||||||
Vec3f color = vis_to_rgb(normalized);
|
Vec3f color = vis_to_rgb(normalized);
|
||||||
fprintf(fp, "v %f %f %f %f %f %f\n",
|
fprintf(fp, "v %f %f %f %f %f %f\n",
|
||||||
divided_mesh.vertices[i](0), divided_mesh.vertices[i](1), divided_mesh.vertices[i](2),
|
divided_mesh.vertices[i](0), divided_mesh.vertices[i](1), divided_mesh.vertices[i](2),
|
||||||
@ -576,9 +581,9 @@ void gather_global_model_info(GlobalModelInfo &result, const PrintObject *po) {
|
|||||||
struct DefaultSeamComparator {
|
struct DefaultSeamComparator {
|
||||||
float compute_angle_penalty(float ccw_angle) const {
|
float compute_angle_penalty(float ccw_angle) const {
|
||||||
if (ccw_angle >= 0) {
|
if (ccw_angle >= 0) {
|
||||||
return PI - ccw_angle;
|
return PI * PI - ccw_angle * ccw_angle;
|
||||||
} else {
|
} else {
|
||||||
return (PI - ccw_angle) * 1.1f;
|
return (PI * PI - ccw_angle * ccw_angle) * 0.8f;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -593,12 +598,12 @@ struct DefaultSeamComparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//avoid overhangs
|
//avoid overhangs
|
||||||
if (a.overhang > 0.2f && b.overhang < a.overhang) {
|
if (a.overhang > 0.3f && b.overhang < a.overhang) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (a.visibility + 0.01) * compute_angle_penalty(a.local_ccw_angle) <
|
return (a.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(a.local_ccw_angle) <
|
||||||
(b.visibility + 0.01) * compute_angle_penalty(b.local_ccw_angle);
|
(b.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(b.local_ccw_angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_first_not_much_worse(const SeamCandidate &a, const SeamCandidate &b) const {
|
bool is_first_not_much_worse(const SeamCandidate &a, const SeamCandidate &b) const {
|
||||||
@ -611,12 +616,12 @@ struct DefaultSeamComparator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//avoid overhangs
|
//avoid overhangs
|
||||||
if (a.overhang > 0.2f && b.overhang < a.overhang) {
|
if (a.overhang > 0.3f && b.overhang < a.overhang) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (a.visibility + 0.01) * compute_angle_penalty(a.local_ccw_angle) * 0.8f <=
|
return (a.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(a.local_ccw_angle) * 0.8f <=
|
||||||
(b.visibility + 0.01) * compute_angle_penalty(b.local_ccw_angle);
|
(b.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(b.local_ccw_angle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -691,9 +696,6 @@ tbb::parallel_for(tbb::blocked_range<size_t>(0, m_perimeter_points_per_object[po
|
|||||||
if (layer_idx > 0) { //calculate overhang
|
if (layer_idx > 0) { //calculate overhang
|
||||||
perimeter_point.overhang = calculate_layer_overhang(layer_idx-1);
|
perimeter_point.overhang = calculate_layer_overhang(layer_idx-1);
|
||||||
}
|
}
|
||||||
if (layer_idx < m_perimeter_points_per_object[po].size() - 1) { //calculate higher_layer_overhang
|
|
||||||
perimeter_point.higher_layer_overhang = calculate_layer_overhang(layer_idx+1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -776,19 +778,11 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const Comparator &comp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sort them by visiblity, before aligning
|
//sort them and then align starting with the best candidates
|
||||||
std::sort(seams.begin(), seams.end(),
|
std::sort(seams.begin(), seams.end(),
|
||||||
[&](const std::pair<size_t, size_t> &left, const std::pair<size_t, size_t> &right) {
|
[&](const std::pair<size_t, size_t> &left, const std::pair<size_t, size_t> &right) {
|
||||||
return m_perimeter_points_per_object[po][left.first][left.second].visibility
|
return comparator.is_first_better(m_perimeter_points_per_object[po][left.first][left.second],
|
||||||
* (1.2 * PI
|
m_perimeter_points_per_object[po][right.first][right.second]);
|
||||||
- std::abs(
|
|
||||||
m_perimeter_points_per_object[po][left.first][left.second].local_ccw_angle
|
|
||||||
- 0.2 * PI))
|
|
||||||
< m_perimeter_points_per_object[po][right.first][right.second].visibility
|
|
||||||
* (1.2 * PI
|
|
||||||
- std::abs(
|
|
||||||
m_perimeter_points_per_object[po][right.first][right.second].local_ccw_angle
|
|
||||||
- 0.2 * PI));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -850,7 +844,7 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const Comparator &comp
|
|||||||
m_perimeter_points_per_object[po][seam_string[index].first][seam_string[index].second].position;
|
m_perimeter_points_per_object[po][seam_string[index].first][seam_string[index].second].position;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vec2f> coefficients = polyfit(points, 4);
|
std::vector<Vec2f> coefficients = polyfit(points, 3);
|
||||||
for (const auto &pair : seam_string) {
|
for (const auto &pair : seam_string) {
|
||||||
float current_height = m_perimeter_points_per_object[po][pair.first][pair.second].position.z();
|
float current_height = m_perimeter_points_per_object[po][pair.first][pair.second].position.z();
|
||||||
Vec3f seam_pos = get_fitted_point(coefficients, current_height);
|
Vec3f seam_pos = get_fitted_point(coefficients, current_height);
|
||||||
|
@ -97,21 +97,21 @@ public:
|
|||||||
using SeamCandidatesTree =
|
using SeamCandidatesTree =
|
||||||
KDTreeIndirect<3, float, SeamPlacerImpl::SeamCandidateCoordinateFunctor>;
|
KDTreeIndirect<3, float, SeamPlacerImpl::SeamCandidateCoordinateFunctor>;
|
||||||
// Rough estimates of hits of the mesh during raycasting per surface circle defined by considered_area_radius
|
// Rough estimates of hits of the mesh during raycasting per surface circle defined by considered_area_radius
|
||||||
static constexpr float expected_hits_per_area = 600.0f;
|
static constexpr float expected_hits_per_area = 400.0f;
|
||||||
// area considered when computing number of rays and then gathering visiblity info from the hits
|
// area considered when computing number of rays and then gathering visiblity info from the hits
|
||||||
static constexpr float considered_area_radius = 3.0f;
|
static constexpr float considered_area_radius = 4.0f;
|
||||||
// quadric error limit of quadric decimation function used on the mesh before raycasting
|
// quadric error limit of quadric decimation function used on the mesh before raycasting
|
||||||
static constexpr float raycasting_decimation_target_error = 0.3f;
|
static constexpr float raycasting_decimation_target_error = 0.1f;
|
||||||
|
|
||||||
// cosine sampling power represents how prefered are forward directions when raycasting from given spot
|
// cosine sampling power represents how prefered are forward directions when raycasting from given spot
|
||||||
// in this case, forward direction means towards the center of the mesh
|
// in this case, forward direction means towards the center of the mesh
|
||||||
static constexpr float cosine_hemisphere_sampling_power = 4.0f;
|
static constexpr float cosine_hemisphere_sampling_power = 4.0f;
|
||||||
|
|
||||||
// arm length used during angles computation
|
// arm length used during angles computation
|
||||||
static constexpr float polygon_local_angles_arm_distance = 0.6f;
|
static constexpr float polygon_local_angles_arm_distance = 1.0f;
|
||||||
|
|
||||||
// If enforcer or blocker is closer to the seam candidate than this limit, the seam candidate is set to Blocer or Enforcer
|
// If enforcer or blocker is closer to the seam candidate than this limit, the seam candidate is set to Blocer or Enforcer
|
||||||
static constexpr float enforcer_blocker_sqr_distance_tolerance = 0.2f;
|
static constexpr float enforcer_blocker_sqr_distance_tolerance = 0.1f;
|
||||||
|
|
||||||
// When searching for seam clusters for alignment:
|
// When searching for seam clusters for alignment:
|
||||||
// seam_align_tolerable_dist - if seam is closer to the previous seam position projected to the current layer than this value,
|
// seam_align_tolerable_dist - if seam is closer to the previous seam position projected to the current layer than this value,
|
||||||
@ -119,9 +119,9 @@ public:
|
|||||||
static constexpr float seam_align_tolerable_dist = 1.0f;
|
static constexpr float seam_align_tolerable_dist = 1.0f;
|
||||||
// if the seam of the current layer is too far away, and the closest seam candidate is not very good, layer is skipped.
|
// 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
|
// this param limits the number of allowed skips
|
||||||
static constexpr size_t seam_align_tolerable_skips = 6;
|
static constexpr size_t seam_align_tolerable_skips = 4;
|
||||||
// minimum number of seams needed in cluster to make alignemnt happen
|
// minimum number of seams needed in cluster to make alignemnt happen
|
||||||
static constexpr size_t seam_align_minimum_string_seams = 5;
|
static constexpr size_t seam_align_minimum_string_seams = 4;
|
||||||
|
|
||||||
//The following data structures hold all perimeter points for all PrintObject. The structure is as follows:
|
//The following data structures hold all perimeter points for all PrintObject. The structure is as follows:
|
||||||
// Map of PrintObjects (PO) -> vector of layers of PO -> vector of perimeter points of the given layer
|
// Map of PrintObjects (PO) -> vector of layers of PO -> vector of perimeter points of the given layer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user