mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-12-27 09:59:48 -07:00
ENH: TimelapsePosPicker, make timelapsePos far away from the camera
By using Manhattan distance, a penalty function is constructed by weighting the distance from the safe position to the camera and the distance from the current position, incentivizing safe positions to move away from the camera. The isometric line of the integrated Manhattan distance changes from a circle to a trapezoidal shape, with the Euclidean distance toward the camera being half that away from the camera. This ensures that when selecting a safe position, points with the same Euclidean distance from the current position receive a smaller penalty if they are farther away from the camera. jira: none Change-Id: I3c256cfc0c33cecade86c254613063adeac59f91 (cherry picked from commit f86ca36b471dd99d4c1bd21c4e6db3ee10eb5a6d)
This commit is contained in:
parent
8863631c92
commit
eafe57d8c6
1 changed files with 31 additions and 8 deletions
|
|
@ -380,19 +380,42 @@ namespace Slic3r {
|
|||
|
||||
std::priority_queue<CandidatePoint> max_heap;
|
||||
|
||||
double min_distance = std::numeric_limits<double>::max();
|
||||
Point nearest_point = DefaultTimelapsePos;
|
||||
const double candidate_point_segment = scale_(5), weight_of_camera=1./3.;
|
||||
auto penaltyFunc = [&weight_of_camera](const Point &curr_post, const Point &CameraPos, const Point &candidatet) -> double {
|
||||
// move distance + Camera occlusion penalty function
|
||||
double ret_pen = (curr_post - candidatet).cwiseAbs().sum() - weight_of_camera * (CameraPos - candidatet).cwiseAbs().sum();
|
||||
return ret_pen;
|
||||
};
|
||||
|
||||
for (const auto& expoly : safe_areas) {
|
||||
Polygons polys = to_polygons(expoly);
|
||||
for (auto& poly : polys) {
|
||||
for (size_t idx = 0; idx < poly.points.size(); ++idx) {
|
||||
Line line(poly.points[idx], poly.points[next_idx_modulo(idx, poly.points)]);
|
||||
Point candidate;
|
||||
double dist = line.distance_to_squared(curr_pos, &candidate);
|
||||
max_heap.push({ dist,candidate });
|
||||
if (max_heap.size() > MAX_CANDIDATE_SIZE)
|
||||
max_heap.pop();
|
||||
double best_penalty = std::numeric_limits<double>::max();
|
||||
Point best_candidate = DefaultTimelapsePos; // the best candidate form current line
|
||||
//std::vector<Point> candidate_source;
|
||||
if ((poly.points[idx] - poly.points[next_idx_modulo(idx, poly.points)]).cwiseAbs().sum() < candidate_point_segment) {
|
||||
best_candidate = poly.points[idx]; // only check the start point if the line is short
|
||||
best_penalty = penaltyFunc(curr_pos, DefaultCameraPos, best_candidate);
|
||||
}else{
|
||||
Point direct_of_line = poly.points[next_idx_modulo(idx, poly.points)] - poly.points[idx];
|
||||
double length_L1 = direct_of_line.cwiseAbs().sum();
|
||||
int num_steps = static_cast<int>(length_L1 / candidate_point_segment); // for long line use 5mm segmentation to check
|
||||
// devide by length_L1 instead of steps, prevent lose accuracy for the step length
|
||||
direct_of_line.x() = static_cast<coord_t>(static_cast<double> (direct_of_line.x()) * candidate_point_segment / length_L1);
|
||||
direct_of_line.y() = static_cast<coord_t>(static_cast<double> (direct_of_line.y()) * candidate_point_segment / length_L1);
|
||||
Point candidate;
|
||||
for (int line_seg_i = 0; line_seg_i <= num_steps; ++line_seg_i) {
|
||||
candidate=poly.points[idx] + direct_of_line * line_seg_i;
|
||||
double dist = penaltyFunc(curr_pos, DefaultCameraPos, candidate);
|
||||
if (dist < best_penalty) {
|
||||
best_penalty = dist;
|
||||
best_candidate = candidate;
|
||||
}//only push the best point into heap for the whole line
|
||||
}
|
||||
}
|
||||
max_heap.push({best_penalty, best_candidate});
|
||||
if (max_heap.size() > MAX_CANDIDATE_SIZE) max_heap.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue