tweaked parameters,
fixed minor bugs
This commit is contained in:
parent
c72687c96c
commit
ad819850f9
2 changed files with 28 additions and 34 deletions
|
@ -156,7 +156,7 @@ std::vector<HitInfo> raycast_visibility(const AABBTreeIndirect::Tree<3, float> &
|
|||
// Prepare random samples per ray
|
||||
// std::random_device rnd_device;
|
||||
// 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 };
|
||||
|
||||
auto gen = [&dist, &mersenne_engine]() {
|
||||
|
@ -174,15 +174,19 @@ std::vector<HitInfo> raycast_visibility(const AABBTreeIndirect::Tree<3, float> &
|
|||
|
||||
BOOST_LOG_TRIVIAL(debug)
|
||||
<< "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> { },
|
||||
[&](tbb::blocked_range<size_t> r, std::vector<HitInfo> init) {
|
||||
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]);
|
||||
//place the ray origin on the bounding sphere
|
||||
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);
|
||||
|
||||
// apply the local direction via Frame struct - the local_dir is with respect to +Z being forward
|
||||
Frame f;
|
||||
f.set_from_z(global_ray_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;
|
||||
}
|
||||
|
||||
// structure to store global information about the model - occlusion hits, enforcers, blockers
|
||||
struct GlobalModelInfo {
|
||||
std::vector<HitInfo> geometry_raycast_hits;
|
||||
KDTreeIndirect<3, float, HitInfoCoordinateFunctor> raycast_hits_tree;
|
||||
|
@ -311,7 +316,7 @@ struct GlobalModelInfo {
|
|||
if (closest_point_index == raycast_hits_tree.npos
|
||||
||
|
||||
(position - geometry_raycast_hits[closest_point_index].position).norm()
|
||||
> SeamPlacer::seam_align_tolerable_dist) {
|
||||
> SeamPlacer::considered_area_radius) {
|
||||
return 0;
|
||||
}
|
||||
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) {
|
||||
float visibility = calculate_point_visibility(divided_mesh.vertices[i]);
|
||||
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);
|
||||
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),
|
||||
|
@ -576,9 +581,9 @@ void gather_global_model_info(GlobalModelInfo &result, const PrintObject *po) {
|
|||
struct DefaultSeamComparator {
|
||||
float compute_angle_penalty(float ccw_angle) const {
|
||||
if (ccw_angle >= 0) {
|
||||
return PI - ccw_angle;
|
||||
return PI * PI - ccw_angle * ccw_angle;
|
||||
} else {
|
||||
return (PI - ccw_angle) * 1.1f;
|
||||
return (PI * PI - ccw_angle * ccw_angle) * 0.8f;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -593,12 +598,12 @@ struct DefaultSeamComparator {
|
|||
}
|
||||
|
||||
//avoid overhangs
|
||||
if (a.overhang > 0.2f && b.overhang < a.overhang) {
|
||||
if (a.overhang > 0.3f && b.overhang < a.overhang) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (a.visibility + 0.01) * compute_angle_penalty(a.local_ccw_angle) <
|
||||
(b.visibility + 0.01) * compute_angle_penalty(b.local_ccw_angle);
|
||||
return (a.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(a.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 {
|
||||
|
@ -611,12 +616,12 @@ struct DefaultSeamComparator {
|
|||
}
|
||||
|
||||
//avoid overhangs
|
||||
if (a.overhang > 0.2f && b.overhang < a.overhang) {
|
||||
if (a.overhang > 0.3f && b.overhang < a.overhang) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (a.visibility + 0.01) * compute_angle_penalty(a.local_ccw_angle) * 0.8f <=
|
||||
(b.visibility + 0.01) * compute_angle_penalty(b.local_ccw_angle);
|
||||
return (a.visibility + SeamPlacer::expected_hits_per_area) * compute_angle_penalty(a.local_ccw_angle) * 0.8f <=
|
||||
(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
|
||||
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(),
|
||||
[&](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
|
||||
* (1.2 * PI
|
||||
- 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));
|
||||
return comparator.is_first_better(m_perimeter_points_per_object[po][left.first][left.second],
|
||||
m_perimeter_points_per_object[po][right.first][right.second]);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
std::vector<Vec2f> coefficients = polyfit(points, 4);
|
||||
std::vector<Vec2f> coefficients = polyfit(points, 3);
|
||||
for (const auto &pair : seam_string) {
|
||||
float current_height = m_perimeter_points_per_object[po][pair.first][pair.second].position.z();
|
||||
Vec3f seam_pos = get_fitted_point(coefficients, current_height);
|
||||
|
|
|
@ -97,21 +97,21 @@ public:
|
|||
using SeamCandidatesTree =
|
||||
KDTreeIndirect<3, float, SeamPlacerImpl::SeamCandidateCoordinateFunctor>;
|
||||
// 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
|
||||
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
|
||||
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
|
||||
// in this case, forward direction means towards the center of the mesh
|
||||
static constexpr float cosine_hemisphere_sampling_power = 4.0f;
|
||||
|
||||
// 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
|
||||
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:
|
||||
// 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;
|
||||
// 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 = 6;
|
||||
static constexpr size_t seam_align_tolerable_skips = 4;
|
||||
// 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:
|
||||
// Map of PrintObjects (PO) -> vector of layers of PO -> vector of perimeter points of the given layer
|
||||
|
|
Loading…
Reference in a new issue