222{
225 if (
inpassable.empty() || (start - end).cast<
float>().norm() < 3.0) {
return Polyline{p0, p1}; }
226
229 if (inpassable.find(Pixel(x, y)) == inpassable.end() || start == end) {
230 start = Pixel(x, y);
231 return false;
232 }
233 return true;
234 });
235 }
236
239 if (inpassable.find(Pixel(x, y)) == inpassable.end() || start == end) {
240 end = Pixel(x, y);
241 return false;
242 }
243 return true;
244 });
245 }
246
249 search_box.min +=
Pixel(1, 1);
250
251 BoundingBox bounding_square(
Points{start,
end});
252 bounding_square.max +=
Pixel(5, 5);
253 bounding_square.min -=
Pixel(5, 5);
254 coord_t bounding_square_size = 2 * std::max(bounding_square.size().x(), bounding_square.size().y());
255 bounding_square.max.x() += (bounding_square_size - bounding_square.size().x()) / 2;
256 bounding_square.min.x() -= (bounding_square_size - bounding_square.size().x()) / 2;
257 bounding_square.max.y() += (bounding_square_size - bounding_square.size().y()) / 2;
258 bounding_square.min.y() -= (bounding_square_size - bounding_square.size().y()) / 2;
259
260
261 search_box.max = search_box.max.cwiseMin(bounding_square.max);
262 search_box.min = search_box.min.cwiseMax(bounding_square.min);
263
264 auto cell_query = [&](
Pixel pixel) {
265 return search_box.contains(pixel) && (pixel == start || pixel ==
end ||
inpassable.find(pixel) ==
inpassable.end());
266 };
267
268 JPSTracer<
Pixel,
decltype(cell_query)> tracer(end, cell_query);
269 using QNode = astar::QNode<JPSTracer<
Pixel,
decltype(cell_query)>>;
270
271 std::unordered_map<size_t, QNode> astar_cache{};
272 std::vector<Pixel, PointsAllocator<Pixel>> out_path;
273 std::vector<decltype(tracer)::Node> out_nodes;
274
275 if (!
astar::search_route(tracer, {start, {0, 0}}, std::back_inserter(out_nodes), astar_cache)) {
276
277
278 auto coordiante_func = [&astar_cache](size_t idx, size_t dim) { return float(astar_cache[idx].node.position[dim]); };
279 std::vector<size_t> keys;
280 keys.reserve(astar_cache.size());
281 for (const auto &pair : astar_cache) { keys.push_back(pair.first); }
282 KDTreeIndirect<2, float, decltype(coordiante_func)> kd_tree(coordiante_func, keys);
284
285 out_path.push_back(end);
287 out_path.push_back(astar_cache[closest_qnode].node.position);
288 closest_qnode = astar_cache[closest_qnode].parent;
289 }
290 } else {
291 for (const auto &node : out_nodes) { out_path.push_back(node.position); }
292 out_path.push_back(start);
293 }
294
295#ifdef DEBUG_FILES
296 auto scaled_points = [](
const Points &ps) {
298 for (
const Point &p : ps) { r.push_back(Point::new_scale(p.x(), p.y())); }
299 return r;
300 };
301 auto scaled_point = [](
const Point &p) {
return Point::new_scale(p.x(), p.y()); };
303 BoundingBox(scaled_point(search_box.min), scaled_point(search_box.max)));
304 for (
const auto &p :
inpassable) { svg.draw(scaled_point(p),
"black",
scale_(0.4)); }
305 for (
const auto &qn : astar_cache) { svg.draw(scaled_point(qn.second.node.position),
"blue",
scale_(0.3)); }
306 svg.draw(Polyline(scaled_points(out_path)),
"yellow",
scale_(0.25));
307 svg.draw(scaled_point(end),
"purple",
scale_(0.4));
308 svg.draw(scaled_point(start),
"green",
scale_(0.4));
309#endif
310
311 std::vector<Pixel, PointsAllocator<Pixel>> tmp_path;
312 tmp_path.reserve(out_path.size());
313
314 std::reverse(out_path.begin(), out_path.end());
315 {
316 tmp_path.push_back(out_path.front());
317 for (size_t i = 1; i < out_path.size() - 1; i++) {
318 if ((out_path[i] - out_path[i - 1]).cast<float>().normalized() != (out_path[i + 1] - out_path[i]).cast<float>().normalized()) {
319 tmp_path.push_back(out_path[i]);
320 }
321 }
322 tmp_path.push_back(out_path.back());
323 out_path = tmp_path;
324 }
325
326#ifdef DEBUG_FILES
327 svg.draw(Polyline(scaled_points(out_path)),
"orange",
scale_(0.20));
328#endif
329
330 tmp_path.clear();
331
332
333
334 {
335 tmp_path.push_back(out_path.front());
336 size_t index_of_last_stored_point = 0;
337 for (size_t i = 1; i < out_path.size(); i++) {
338 if (i - index_of_last_stored_point < 2) continue;
339 bool passable = true;
342 passable = false;
343 return false;
344 }
345 return true;
346 };
347 dda(tmp_path.back().x(), tmp_path.back().y(), out_path[i].x(), out_path[i].y(), store_obstacle);
348 if (!passable) {
349 tmp_path.push_back(out_path[i - 1]);
350 index_of_last_stored_point = i - 1;
351 }
352 }
353 tmp_path.push_back(out_path.back());
354 out_path = tmp_path;
355 }
356
357#ifdef DEBUG_FILES
358 svg.draw(Polyline(scaled_points(out_path)),
"red",
scale_(0.15));
359 svg.Close();
360#endif
361
362
363
365 out_path.front() = p0;
366 out_path.back() = p1;
367
368 return Polyline(out_path);
369}
Point unpixelize(const Pixel &p)
Definition JumpPointSearch.hpp:25
#define scale_(val)
Definition libslic3r.h:69
constexpr auto Unassigned
Definition AStar.hpp:59
bool search_route(const Tracer &tracer, const TracerNodeT< Tracer > &source, It out, NodeMap &&cached_nodes={})
Definition AStar.hpp:100
std::string debug_out_path(const char *name,...)
Definition utils.cpp:218
void dda(coord_t x0, coord_t y0, coord_t x1, coord_t y1, const PointFn &fn)
Definition JumpPointSearch.cpp:32
size_t find_closest_point(const KDTreeIndirect< D, CoordT, CoordFn > &kdtree, const PointType &point, FilterFn filter)
Definition KDTreeIndirect.hpp:266
std::vector< Point, PointsAllocator< Point > > Points
Definition Point.hpp:58
Kernel::Point_2 Point
Definition point_areas.cpp:20