#ifndef slic3r_AvoidCrossingPerimeters_hpp_ #define slic3r_AvoidCrossingPerimeters_hpp_ #include "../libslic3r.h" #include "../ExPolygon.hpp" #include "../EdgeGrid.hpp" namespace Slic3r { // Forward declarations. class GCode; class Layer; class MotionPlanner; class Point; class Print; class PrintObject; struct PrintInstance; using PrintObjectPtrs = std::vector; class AvoidCrossingPerimeters { public: // this flag triggers the use of the external configuration space bool use_external_mp; bool use_external_mp_once; // just for the next travel move // this flag disables avoid_crossing_perimeters just for the next travel move // we enable it by default for the first travel move in print bool disable_once; AvoidCrossingPerimeters() : use_external_mp(false), use_external_mp_once(false), disable_once(true) {} virtual ~AvoidCrossingPerimeters() = default; void reset() { m_external_mp.reset(); m_layer_mp.reset(); } void init_external_mp(const Print &print); void init_layer_mp(const ExPolygons &islands) { m_layer_mp = Slic3r::make_unique(islands); } virtual Polyline travel_to(const GCode &gcodegen, const Point &point); protected: // For initializing the regions to avoid. static Polygons collect_contours_all_layers(const PrintObjectPtrs &objects); std::unique_ptr m_external_mp; std::unique_ptr m_layer_mp; }; class AvoidCrossingPerimeters2 : public AvoidCrossingPerimeters { protected: struct Intersection { size_t border_idx; size_t line_idx; Point point_transformed; Point point; Intersection(size_t border_idx, size_t line_idx, const Point &point_transformed, const Point &point) : border_idx(border_idx), line_idx(line_idx), point_transformed(point_transformed), point(point){}; inline bool operator<(const Intersection &other) const { return this->point_transformed.x() < other.point_transformed.x(); } }; enum class Direction { Forward, Backward }; private: static ExPolygons get_boundary(const Layer &layer); static ExPolygons get_boundary_external(const Layer &layer); static Direction get_shortest_direction( const Lines &lines, const size_t start_idx, const size_t end_idx, const Point &intersection_first, const Point &intersection_last); static Polyline simplify_travel(const EdgeGrid::Grid &edge_grid, const Polyline &travel); static Polyline avoid_perimeters(const Polygons &boundaries, const EdgeGrid::Grid &grid, const Point &start, const Point &end); Polygons m_boundaries; Polygons m_boundaries_external; BoundingBox m_bbox; BoundingBox m_bbox_external; EdgeGrid::Grid m_grid; EdgeGrid::Grid m_grid_external; public: AvoidCrossingPerimeters2() : AvoidCrossingPerimeters() {} virtual ~AvoidCrossingPerimeters2() = default; virtual Polyline travel_to(const GCode &gcodegen, const Point &point) override; void init_layer(const Layer &layer); }; } // namespace Slic3r #endif // slic3r_AvoidCrossingPerimeters_hpp_