BambuStudio/libslic3r/Fill/Bridge.hpp

257 lines
7.8 KiB
C++
Raw Normal View History

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