SeamPlacer - fix search radius estimation for visibility computation (use exp distribution)
slightly tune parameters
This commit is contained in:
parent
bd4b63e67d
commit
745c5ecd9b
2 changed files with 23 additions and 13 deletions
|
@ -178,7 +178,7 @@ std::vector<float> raycast_visibility(const AABBTreeIndirect::Tree<3, float> &ra
|
||||||
// FIXME: This AABBTTreeIndirect query will not compile for float ray origin and
|
// FIXME: This AABBTTreeIndirect query will not compile for float ray origin and
|
||||||
// direction.
|
// direction.
|
||||||
Vec3d final_ray_dir_d = final_ray_dir.cast<double>();
|
Vec3d final_ray_dir_d = final_ray_dir.cast<double>();
|
||||||
Vec3d ray_origin_d = (center + normal * 1.0f).cast<double>(); // start above surface.
|
Vec3d ray_origin_d = (center + normal * 0.01f).cast<double>(); // start above surface.
|
||||||
bool hit = AABBTreeIndirect::intersect_ray_first_hit(triangles.vertices,
|
bool hit = AABBTreeIndirect::intersect_ray_first_hit(triangles.vertices,
|
||||||
triangles.indices, raycasting_tree, ray_origin_d, final_ray_dir_d, hitpoint);
|
triangles.indices, raycasting_tree, ray_origin_d, final_ray_dir_d, hitpoint);
|
||||||
if (hit && its_face_normal(triangles, hitpoint.id).dot(final_ray_dir) <= 0) {
|
if (hit && its_face_normal(triangles, hitpoint.id).dot(final_ray_dir) <= 0) {
|
||||||
|
@ -188,10 +188,10 @@ std::vector<float> raycast_visibility(const AABBTreeIndirect::Tree<3, float> &ra
|
||||||
bool casting_from_negative_volume = samples.triangle_indices[s_idx]
|
bool casting_from_negative_volume = samples.triangle_indices[s_idx]
|
||||||
>= negative_volumes_start_index;
|
>= negative_volumes_start_index;
|
||||||
|
|
||||||
Vec3d ray_origin_d = (center + normal * 1.0f).cast<double>(); // start above surface.
|
Vec3d ray_origin_d = (center + normal * 0.01f).cast<double>(); // start above surface.
|
||||||
if (casting_from_negative_volume) { // if casting from negative volume face, invert direction, change start pos
|
if (casting_from_negative_volume) { // if casting from negative volume face, invert direction, change start pos
|
||||||
final_ray_dir = -1.0 * final_ray_dir;
|
final_ray_dir = -1.0 * final_ray_dir;
|
||||||
ray_origin_d = (center - normal * 1.0f).cast<double>();
|
ray_origin_d = (center - normal * 0.01f).cast<double>();
|
||||||
}
|
}
|
||||||
Vec3d final_ray_dir_d = final_ray_dir.cast<double>();
|
Vec3d final_ray_dir_d = final_ray_dir.cast<double>();
|
||||||
bool some_hit = AABBTreeIndirect::intersect_ray_all_hits(triangles.vertices,
|
bool some_hit = AABBTreeIndirect::intersect_ray_all_hits(triangles.vertices,
|
||||||
|
@ -455,14 +455,13 @@ void process_perimeter_polygon(const Polygon &orig_polygon, float z_coord, const
|
||||||
}
|
}
|
||||||
|
|
||||||
Polygon polygon = orig_polygon;
|
Polygon polygon = orig_polygon;
|
||||||
bool was_clockwise = polygon.make_counter_clockwise();
|
|
||||||
|
|
||||||
std::vector<float> lengths { };
|
std::vector<float> lengths { };
|
||||||
for (size_t point_idx = 0; point_idx < polygon.size() - 1; ++point_idx) {
|
for (size_t point_idx = 0; point_idx < polygon.size() - 1; ++point_idx) {
|
||||||
lengths.push_back(std::max((unscale(polygon[point_idx]) - unscale(polygon[point_idx + 1])).norm(), 0.001));
|
lengths.push_back((unscale(polygon[point_idx]) - unscale(polygon[point_idx + 1])).norm());
|
||||||
}
|
}
|
||||||
lengths.push_back(std::max((unscale(polygon[0]) - unscale(polygon[polygon.size() - 1])).norm(), 0.001));
|
lengths.push_back(std::max((unscale(polygon[0]) - unscale(polygon[polygon.size() - 1])).norm(), 0.1));
|
||||||
|
|
||||||
|
bool was_clockwise = polygon.make_counter_clockwise();
|
||||||
std::vector<float> local_angles = calculate_polygon_angles_at_vertices(polygon, lengths,
|
std::vector<float> local_angles = calculate_polygon_angles_at_vertices(polygon, lengths,
|
||||||
SeamPlacer::polygon_local_angles_arm_distance);
|
SeamPlacer::polygon_local_angles_arm_distance);
|
||||||
|
|
||||||
|
@ -640,8 +639,20 @@ void compute_global_occlusion(GlobalModelInfo &result, const PrintObject *po,
|
||||||
result.mesh_samples_coordinate_functor = CoordinateFunctor(&result.mesh_samples.positions);
|
result.mesh_samples_coordinate_functor = CoordinateFunctor(&result.mesh_samples.positions);
|
||||||
result.mesh_samples_tree = KDTreeIndirect<3, float, CoordinateFunctor>(result.mesh_samples_coordinate_functor,
|
result.mesh_samples_tree = KDTreeIndirect<3, float, CoordinateFunctor>(result.mesh_samples_coordinate_functor,
|
||||||
result.mesh_samples.positions.size());
|
result.mesh_samples.positions.size());
|
||||||
result.mesh_samples_radius = sqrt(
|
|
||||||
10.0f * (result.mesh_samples.total_area / SeamPlacer::raycasting_visibility_samples_count) / PI);
|
// The following code determines search area for random visibility samples on the mesh when calculating visibility of each perimeter point
|
||||||
|
// number of random samples in the given radius (area) is approximately poisson distribution
|
||||||
|
// 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 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:
|
||||||
|
// P(S > samples in A) = e^-(samples/(density*A)); express A:
|
||||||
|
float search_area = samples / (-logf(probability) * density);
|
||||||
|
float search_radius = sqrt(search_area / PI);
|
||||||
|
result.mesh_samples_radius = search_radius;
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug)
|
BOOST_LOG_TRIVIAL(debug)
|
||||||
<< "SeamPlacer: Compute visiblity sample points: end";
|
<< "SeamPlacer: Compute visiblity sample points: end";
|
||||||
|
@ -1090,7 +1101,6 @@ void SeamPlacer::calculate_overhangs_and_layer_embedding(const PrintObject *po)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
bool should_compute_layer_embedding = regions_with_perimeter > 1;
|
bool should_compute_layer_embedding = regions_with_perimeter > 1;
|
||||||
layers[layer_idx].points[0].perimeter.end_index < layers[layer_idx].points.size() - 1;
|
|
||||||
std::unique_ptr<PerimeterDistancer> current_layer_distancer = std::make_unique<PerimeterDistancer>(po->layers()[layer_idx]);
|
std::unique_ptr<PerimeterDistancer> current_layer_distancer = std::make_unique<PerimeterDistancer>(po->layers()[layer_idx]);
|
||||||
|
|
||||||
for (SeamCandidate &perimeter_point : layers[layer_idx].points) {
|
for (SeamCandidate &perimeter_point : layers[layer_idx].points) {
|
||||||
|
|
|
@ -133,8 +133,8 @@ public:
|
||||||
static constexpr float overhang_distance_tolerance_factor = 0.5f;
|
static constexpr float overhang_distance_tolerance_factor = 0.5f;
|
||||||
|
|
||||||
// determines angle importance compared to visibility ( neutral value is 1.0f. )
|
// determines angle importance compared to visibility ( neutral value is 1.0f. )
|
||||||
static constexpr float angle_importance_aligned = 1.0f;
|
static constexpr float angle_importance_aligned = 0.5f;
|
||||||
static constexpr float angle_importance_nearest = 2.0f; // use much higher angle importance for nearest mode, to combat the visiblity info noise
|
static constexpr float angle_importance_nearest = 1.0f; // use much higher angle importance for nearest mode, to combat the visiblity info noise
|
||||||
|
|
||||||
// If enforcer or blocker is closer to the seam candidate than this limit, the seam candidate is set to Blocker or Enforcer
|
// If enforcer or blocker is closer to the seam candidate than this limit, the seam candidate is set to Blocker or Enforcer
|
||||||
static constexpr float enforcer_blocker_distance_tolerance = 0.35f;
|
static constexpr float enforcer_blocker_distance_tolerance = 0.35f;
|
||||||
|
@ -143,7 +143,7 @@ public:
|
||||||
|
|
||||||
// When searching for seam clusters for alignment:
|
// 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
|
// 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.45f;
|
static constexpr float seam_align_score_tolerance = 0.27f;
|
||||||
// seam_align_tolerable_dist - if next layer closest point is too far away, skip layer
|
// seam_align_tolerable_dist - if next layer closest point is too far away, skip layer
|
||||||
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.
|
||||||
|
|
Loading…
Add table
Reference in a new issue