// // Created by ylzha on 2025/2/25. // //#ifndef DBRIDGE_HPP //#define DBRIDGE_HPP #ifndef slic3r_Bridge_hpp_ #define slic3r_Bridge_hpp_ // 防止头文件被重复包含的预处理器指令 //#pragma once #include "../libslic3r.h" //#include //#include //#include #include //#include //#include //#include //#include //#include //#include //#include #include "FillBase.hpp" namespace bg = boost::geometry; //#include namespace Slic3r{ class Surface; //namespace bg = boost::geometry; // 定义点类型 typedef bg::model::d2::point_xy Point_t; //定义线段 typedef bg::model::segment Segment; // 定义多边形类型 typedef bg::model::polygon Polygon_t; // 多边形集合 typedef bg::model::multi_polygon MultiPolygon; // 定义环类型 typedef bg::model::ring Ring; // 定义折线类型(用于表示直线) //typedef bg::model::linestring Linestring; // 定义多边形的外边界和内边界 struct PolygonBoundaries { Ring outerBoundary; // 外边界 std::vector innerBoundaries; // 内边界(可能有多个) }; struct IdIndex { size_t id{}; size_t index{}; // 定义小于运算符 bool operator<(const IdIndex& other) const { return id < other.id; } IdIndex(const size_t id, const size_t index) : id(id), index(index) {} bool operator==(const IdIndex& ii) const { return id == ii.id && index == ii.index; } }; //环路径树结构中节点类型 struct RingNode { IdIndex id; Ring ring; //当前环 int orientation{}; //方向 -1 向内 1 向外 std::vector children; //子节点集 RingNode* parent; //父节点 bool isHide{ false }; //在最终路径中是否呈现 false 呈现 true 不呈现 // 构造函数,方便初始化 RingNode(const IdIndex id, const Ring& ring, const int orientation = 0) : id(id), ring(ring), orientation(orientation), parent(nullptr) { } // 重载==运算符方便比较 bool operator==(const RingNode& other) const { return id.id == other.id.id && id.index == other.id.index; } }; //桥接映射 struct BridgeMap { Point_t from; Point_t to; Point_t from2; Point_t to2; IdIndex from_ii; IdIndex to_ii; BridgeMap(Point_t from, Point_t to, Point_t from2, Point_t to2,IdIndex from_ii, IdIndex to_ii) : from(from), to(to), from2(from2), to2(to2),from_ii(from_ii), to_ii(to_ii) { } }; //合并映射 struct MergeMap { IdIndex ii1; //环1 IdIndex ii2; //环2 std::vector nodes; //产生的环集 // 构造函数 MergeMap(const IdIndex& i1, const IdIndex& i2, const std::vector& nodeList) : ii1(i1), ii2(i2), nodes(nodeList) { } }; //struct PointHash_t { // std::size_t operator()(const Point_t& p) const { // std::size_t seed = 0; // boost::hash_combine(seed, bg::get<0>(p)); // boost::hash_combine(seed, bg::get<1>(p)); // return seed; // } //}; // //struct PointEqual_t { // bool operator()(const Point_t& a, const Point_t& b) const { // return bg::equals(a, b); // } //}; class Bridge : public Fill { //public: // Bridge(Polygon _polygon, const double o) : offset(o), polygon(std::move(_polygon)) {}; // ~Bridge() = default; public: //Slic3r::Fill* clone() const override { return new Bridge(*this); }; Fill* clone() const override { return new Bridge(*this); }; //Bridge() {}; //Bridge(Polygon_t _polygon, const double o) : offset(o), polygon(std::move(_polygon)) {}; ~Bridge() override = default; Polylines fill_surface(const Surface* surface, const FillParams& params) override; protected: /*void _fill_surface_single( const FillParams& params, unsigned int thickness_layers, const std::pair& direction, ExPolygon expolygon, Polylines& polylines_out) override;*/ //Polylines fill_surface(const Surface* surface, const FillParams& params) override; coord_t _min_spacing; coord_t _line_spacing; // distance threshold for allowing the horizontal infill lines to be connected into a continuous path coord_t _diagonal_distance; // only for line infill coord_t _line_oscillation; private: //计算多边形的外边界和内边界 void computePolygonBoundaries(const Polygon_t& polygon); // 判断两个环是否相交(不包括包含关系) bool ringsIntersect(const Ring& ring1, const Ring& ring2); //获取环偏移后的环(可能为空) std::vector offsetRing(const Ring& ring, double distance); // 查找环非邻边的相交点 std::vector findNonAdjacentIntersections(const Ring& ring); // 将环拆分成多个环 std::vector split(const Ring& ring, const std::vector& intersections); // 合并两个环 std::vector merge(const RingNode& ring1, const RingNode& ring2); //生成环集 void generateRings(); //形成节点 RingNode formatNode(size_t id, size_t index, const Ring& ring, int orientation); void addNode(RingNode& node); void removeNode(IdIndex id); //查找节点 RingNode& findNode(IdIndex ii); //形成树 void formatTree(); // 深度优先搜索遍历树 void dfs(RingNode& node, std::vector& visited,size_t& edge); //找到多边形环第 N 条边的中心点 Point_t findCenterPointOnEdge(Ring& ring, size_t N); // 在环上按顺时针方向查找距离给定点d的另一个点 Point_t find_point_at_distance_clockwise(Ring& ring, const Point_t& start_point, double d); size_t findLongestEdgeIndex(const Ring& ring); //在第N条边上进行内外环桥接,并插入桥接点 //o_ii 外环IdIndex i_ii 内环IdIndex ring_size内环大小 N边索引 void handleBridge(IdIndex o_ii, IdIndex i_ii, const size_t ring_size, const size_t N); //递归遍历环 void traverseRing( RingNode& node, IdIndex parent, Point_t& start, Point_t& end, bool isOutermostLayer //是否最外层 ); //输出所有环 void printRings(); //sf::VertexArray convertToSFML(const Polygon& poly, const sf::Color& color); public: //输出树结构 void printTree(); //std::vector outputPaths(); //画路径 SFML顶点数组集 //std::vector outputPaths(); //std::vector convert2vertex(); //std::vector verteies; //std::vector convertBridge(); private: size_t maxRid = 1; //最大环类型ID值 double offset; //偏移距离 Polygon_t polygon; //2D多边形 double area_threshold = 4; //面积阈值 PolygonBoundaries boundaries; //外/内边界 std::map> ringNodes; //存储不同环类型的节点集合 size_t 环类型id std::vector nodeHandles; //当前需进行自交或互交处理的节点集合 std::map> splitMap; //分裂映射集 std::vector mergeMap; //合并映射集 std::map> offsetMap; //偏移后产生的分裂映射集 std::vector bridges; //桥接映射 std::vector path; // 路径 bool isFront{ false }; size_t sel_edge_index{ 1 }; //选择桥接边的索引 }; }; // namespace Slic3r //#endif //DBRIDGE_HPP #endif // slic3r_Bridge_hpp_