BambuStudio/libslic3r/Fill/Bridge.hpp

257 lines
7.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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