257 lines
7.8 KiB
C++
257 lines
7.8 KiB
C++
//
|
||
// 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 <utility>
|
||
//#include <vector>
|
||
//#include <unordered_set>
|
||
#include <boost/geometry.hpp>
|
||
//#include <boost/multiprecision/decimal/decimal.hpp>
|
||
//#include <boost/geometry/geometries/point_xy.hpp>
|
||
//#include <boost/geometry/geometries/segment.hpp>
|
||
//#include <boost/geometry/geometries/polygon.hpp>
|
||
//#include <boost/geometry/geometries/ring.hpp>
|
||
//#include <boost/geometry/geometries/linestring.hpp>
|
||
//#include <boost/functional/hash/hash.hpp>
|
||
#include "FillBase.hpp"
|
||
|
||
namespace bg = boost::geometry;
|
||
|
||
//#include <SFML/Graphics.hpp>
|
||
namespace Slic3r{
|
||
|
||
class Surface;
|
||
|
||
//namespace bg = boost::geometry;
|
||
|
||
// 定义点类型
|
||
typedef bg::model::d2::point_xy<double> Point_t;
|
||
|
||
//定义线段
|
||
typedef bg::model::segment<Point_t> Segment;
|
||
|
||
// 定义多边形类型
|
||
typedef bg::model::polygon<Point_t> Polygon_t;
|
||
|
||
// 多边形集合
|
||
typedef bg::model::multi_polygon<Polygon_t> MultiPolygon;
|
||
|
||
// 定义环类型
|
||
typedef bg::model::ring<Point_t> Ring;
|
||
|
||
// 定义折线类型(用于表示直线)
|
||
//typedef bg::model::linestring<Point> Linestring;
|
||
|
||
// 定义多边形的外边界和内边界
|
||
struct PolygonBoundaries {
|
||
Ring outerBoundary; // 外边界
|
||
std::vector<Ring> 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<RingNode> 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<IdIndex> nodes; //产生的环集
|
||
// 构造函数
|
||
MergeMap(const IdIndex& i1, const IdIndex& i2, const std::vector<IdIndex>& 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<float, Point>& 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<Ring> offsetRing(const Ring& ring, double distance);
|
||
|
||
// 查找环非邻边的相交点
|
||
std::vector<Point_t> findNonAdjacentIntersections(const Ring& ring);
|
||
// 将环拆分成多个环
|
||
std::vector<Ring> split(const Ring& ring, const std::vector<Point_t>& intersections);
|
||
// 合并两个环
|
||
std::vector<Ring> 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<IdIndex>& 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<Point_t> outputPaths();
|
||
//画路径 SFML顶点数组集
|
||
//std::vector<sf::Vertex> outputPaths();
|
||
|
||
//std::vector<sf::VertexArray> convert2vertex();
|
||
//std::vector<sf::VertexArray> verteies;
|
||
//std::vector<sf::VertexArray> convertBridge();
|
||
|
||
private:
|
||
|
||
size_t maxRid = 1; //最大环类型ID值
|
||
double offset; //偏移距离
|
||
Polygon_t polygon; //2D多边形
|
||
double area_threshold = 4; //面积阈值
|
||
|
||
|
||
PolygonBoundaries boundaries; //外/内边界
|
||
std::map<size_t, std::vector<RingNode>> ringNodes; //存储不同环类型的节点集合 size_t 环类型id
|
||
std::vector<RingNode> nodeHandles; //当前需进行自交或互交处理的节点集合
|
||
std::map<IdIndex, std::vector<IdIndex>> splitMap; //分裂映射集
|
||
std::vector<MergeMap> mergeMap; //合并映射集
|
||
std::map<IdIndex, std::vector<IdIndex>> offsetMap; //偏移后产生的分裂映射集
|
||
|
||
std::vector<BridgeMap> bridges; //桥接映射
|
||
|
||
std::vector<Point_t> path; // 路径
|
||
|
||
bool isFront{ false };
|
||
size_t sel_edge_index{ 1 }; //选择桥接边的索引
|
||
|
||
|
||
};
|
||
}; // namespace Slic3r
|
||
//#endif //DBRIDGE_HPP
|
||
#endif // slic3r_Bridge_hpp_
|