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_
|