mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-05-20 17:48:06 +08:00
Merge branch 'master' of https://github.com/prusa3d/PrusaSlicer into et_colorprint_no_m600
This commit is contained in:
commit
c1d8fa377e
@ -127,6 +127,8 @@ add_library(libslic3r STATIC
|
|||||||
Point.hpp
|
Point.hpp
|
||||||
Polygon.cpp
|
Polygon.cpp
|
||||||
Polygon.hpp
|
Polygon.hpp
|
||||||
|
PolygonTrimmer.cpp
|
||||||
|
PolygonTrimmer.hpp
|
||||||
Polyline.cpp
|
Polyline.cpp
|
||||||
Polyline.hpp
|
Polyline.hpp
|
||||||
PolylineCollection.cpp
|
PolylineCollection.cpp
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "libslic3r.h"
|
#include "libslic3r.h"
|
||||||
#include "ClipperUtils.hpp"
|
#include "ClipperUtils.hpp"
|
||||||
#include "EdgeGrid.hpp"
|
#include "EdgeGrid.hpp"
|
||||||
|
#include "Geometry.hpp"
|
||||||
#include "SVG.hpp"
|
#include "SVG.hpp"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -275,134 +276,24 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
|
|||||||
// 6) Finally fill in m_cell_data by rasterizing the lines once again.
|
// 6) Finally fill in m_cell_data by rasterizing the lines once again.
|
||||||
for (size_t i = 0; i < m_cells.size(); ++i)
|
for (size_t i = 0; i < m_cells.size(); ++i)
|
||||||
m_cells[i].end = m_cells[i].begin;
|
m_cells[i].end = m_cells[i].begin;
|
||||||
for (size_t i = 0; i < m_contours.size(); ++i) {
|
|
||||||
const Slic3r::Points &pts = *m_contours[i];
|
struct Visitor {
|
||||||
for (size_t j = 0; j < pts.size(); ++j) {
|
Visitor(std::vector<std::pair<size_t, size_t>> &cell_data, std::vector<Cell> &cells, size_t cols) :
|
||||||
// End points of the line segment.
|
cell_data(cell_data), cells(cells), cols(cols), i(0), j(0) {}
|
||||||
Slic3r::Point p1(pts[j]);
|
|
||||||
Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1];
|
void operator()(coord_t iy, coord_t ix) { cell_data[cells[iy*cols + ix].end++] = std::pair<size_t, size_t>(i, j); }
|
||||||
p1(0) -= m_bbox.min(0);
|
|
||||||
p1(1) -= m_bbox.min(1);
|
std::vector<std::pair<size_t, size_t>> &cell_data;
|
||||||
p2(0) -= m_bbox.min(0);
|
std::vector<Cell> &cells;
|
||||||
p2(1) -= m_bbox.min(1);
|
size_t cols;
|
||||||
// Get the cells of the end points.
|
size_t i;
|
||||||
coord_t ix = p1(0) / m_resolution;
|
size_t j;
|
||||||
coord_t iy = p1(1) / m_resolution;
|
} visitor(m_cell_data, m_cells, m_cols);
|
||||||
coord_t ixb = p2(0) / m_resolution;
|
|
||||||
coord_t iyb = p2(1) / m_resolution;
|
for (; visitor.i < m_contours.size(); ++ visitor.i) {
|
||||||
assert(ix >= 0 && size_t(ix) < m_cols);
|
const Slic3r::Points &pts = *m_contours[visitor.i];
|
||||||
assert(iy >= 0 && size_t(iy) < m_rows);
|
for (; visitor.j < pts.size(); ++ visitor.j)
|
||||||
assert(ixb >= 0 && size_t(ixb) < m_cols);
|
this->visit_cells_intersecting_line(pts[visitor.j], pts[(visitor.j + 1 == pts.size()) ? 0 : visitor.j + 1], visitor);
|
||||||
assert(iyb >= 0 && size_t(iyb) < m_rows);
|
|
||||||
// Account for the end points.
|
|
||||||
m_cell_data[m_cells[iy*m_cols + ix].end++] = std::pair<size_t, size_t>(i, j);
|
|
||||||
if (ix == ixb && iy == iyb)
|
|
||||||
// Both ends fall into the same cell.
|
|
||||||
continue;
|
|
||||||
// Raster the centeral part of the line.
|
|
||||||
coord_t dx = std::abs(p2(0) - p1(0));
|
|
||||||
coord_t dy = std::abs(p2(1) - p1(1));
|
|
||||||
if (p1(0) < p2(0)) {
|
|
||||||
int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
|
|
||||||
if (p1(1) < p2(1)) {
|
|
||||||
// x positive, y positive
|
|
||||||
int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
|
|
||||||
do {
|
|
||||||
assert(ix <= ixb && iy <= iyb);
|
|
||||||
if (ex < ey) {
|
|
||||||
ey -= ex;
|
|
||||||
ex = int64_t(dy) * m_resolution;
|
|
||||||
ix += 1;
|
|
||||||
}
|
|
||||||
else if (ex == ey) {
|
|
||||||
ex = int64_t(dy) * m_resolution;
|
|
||||||
ey = int64_t(dx) * m_resolution;
|
|
||||||
ix += 1;
|
|
||||||
iy += 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(ex > ey);
|
|
||||||
ex -= ey;
|
|
||||||
ey = int64_t(dx) * m_resolution;
|
|
||||||
iy += 1;
|
|
||||||
}
|
|
||||||
m_cell_data[m_cells[iy*m_cols + ix].end++] = std::pair<size_t, size_t>(i, j);
|
|
||||||
} while (ix != ixb || iy != iyb);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// x positive, y non positive
|
|
||||||
int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
|
|
||||||
do {
|
|
||||||
assert(ix <= ixb && iy >= iyb);
|
|
||||||
if (ex <= ey) {
|
|
||||||
ey -= ex;
|
|
||||||
ex = int64_t(dy) * m_resolution;
|
|
||||||
ix += 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ex -= ey;
|
|
||||||
ey = int64_t(dx) * m_resolution;
|
|
||||||
iy -= 1;
|
|
||||||
}
|
|
||||||
m_cell_data[m_cells[iy*m_cols + ix].end++] = std::pair<size_t, size_t>(i, j);
|
|
||||||
} while (ix != ixb || iy != iyb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
|
|
||||||
if (p1(1) < p2(1)) {
|
|
||||||
// x non positive, y positive
|
|
||||||
int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
|
|
||||||
do {
|
|
||||||
assert(ix >= ixb && iy <= iyb);
|
|
||||||
if (ex < ey) {
|
|
||||||
ey -= ex;
|
|
||||||
ex = int64_t(dy) * m_resolution;
|
|
||||||
ix -= 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(ex >= ey);
|
|
||||||
ex -= ey;
|
|
||||||
ey = int64_t(dx) * m_resolution;
|
|
||||||
iy += 1;
|
|
||||||
}
|
|
||||||
m_cell_data[m_cells[iy*m_cols + ix].end++] = std::pair<size_t, size_t>(i, j);
|
|
||||||
} while (ix != ixb || iy != iyb);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// x non positive, y non positive
|
|
||||||
int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
|
|
||||||
do {
|
|
||||||
assert(ix >= ixb && iy >= iyb);
|
|
||||||
if (ex < ey) {
|
|
||||||
ey -= ex;
|
|
||||||
ex = int64_t(dy) * m_resolution;
|
|
||||||
ix -= 1;
|
|
||||||
}
|
|
||||||
else if (ex == ey) {
|
|
||||||
// The lower edge of a grid cell belongs to the cell.
|
|
||||||
// Handle the case where the ray may cross the lower left corner of a cell in a general case,
|
|
||||||
// or a left or lower edge in a degenerate case (horizontal or vertical line).
|
|
||||||
if (dx > 0) {
|
|
||||||
ex = int64_t(dy) * m_resolution;
|
|
||||||
ix -= 1;
|
|
||||||
}
|
|
||||||
if (dy > 0) {
|
|
||||||
ey = int64_t(dx) * m_resolution;
|
|
||||||
iy -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(ex > ey);
|
|
||||||
ex -= ey;
|
|
||||||
ey = int64_t(dx) * m_resolution;
|
|
||||||
iy -= 1;
|
|
||||||
}
|
|
||||||
m_cell_data[m_cells[iy*m_cols + ix].end++] = std::pair<size_t, size_t>(i, j);
|
|
||||||
} while (ix != ixb || iy != iyb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,28 +1251,6 @@ Polygons EdgeGrid::Grid::contours_simplified(coord_t offset, bool fill_holes) co
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int segments_could_intersect(
|
|
||||||
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
|
|
||||||
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
|
|
||||||
{
|
|
||||||
Vec2i64 iv = (ip2 - ip1).cast<int64_t>();
|
|
||||||
Vec2i64 vij1 = (jp1 - ip1).cast<int64_t>();
|
|
||||||
Vec2i64 vij2 = (jp2 - ip1).cast<int64_t>();
|
|
||||||
int64_t tij1 = cross2(iv, vij1);
|
|
||||||
int64_t tij2 = cross2(iv, vij2);
|
|
||||||
int sij1 = (tij1 > 0) ? 1 : ((tij1 < 0) ? -1 : 0); // signum
|
|
||||||
int sij2 = (tij2 > 0) ? 1 : ((tij2 < 0) ? -1 : 0);
|
|
||||||
return sij1 * sij2;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool segments_intersect(
|
|
||||||
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
|
|
||||||
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
|
|
||||||
{
|
|
||||||
return segments_could_intersect(ip1, ip2, jp1, jp2) <= 0 &&
|
|
||||||
segments_could_intersect(jp1, jp2, ip1, ip2) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> EdgeGrid::Grid::intersecting_edges() const
|
std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>> EdgeGrid::Grid::intersecting_edges() const
|
||||||
{
|
{
|
||||||
std::vector<std::pair<ContourEdge, ContourEdge>> out;
|
std::vector<std::pair<ContourEdge, ContourEdge>> out;
|
||||||
@ -1405,7 +1274,7 @@ std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>>
|
|||||||
if (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2))
|
if (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2))
|
||||||
// Segments of the same contour share a common vertex.
|
// Segments of the same contour share a common vertex.
|
||||||
continue;
|
continue;
|
||||||
if (segments_intersect(ip1, ip2, jp1, jp2)) {
|
if (Geometry::segments_intersect(ip1, ip2, jp1, jp2)) {
|
||||||
// The two segments intersect. Add them to the output.
|
// The two segments intersect. Add them to the output.
|
||||||
int jfirst = (&jpts < &ipts) || (&jpts == &ipts && jpt < ipt);
|
int jfirst = (&jpts < &ipts) || (&jpts == &ipts && jpt < ipt);
|
||||||
out.emplace_back(jfirst ?
|
out.emplace_back(jfirst ?
|
||||||
@ -1440,7 +1309,7 @@ bool EdgeGrid::Grid::has_intersecting_edges() const
|
|||||||
const Slic3r::Point &jp1 = jpts[jpt];
|
const Slic3r::Point &jp1 = jpts[jpt];
|
||||||
const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1];
|
const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1];
|
||||||
if (! (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2)) &&
|
if (! (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2)) &&
|
||||||
segments_intersect(ip1, ip2, jp1, jp2))
|
Geometry::segments_intersect(ip1, ip2, jp1, jp2))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,145 @@ public:
|
|||||||
std::vector<std::pair<ContourEdge, ContourEdge>> intersecting_edges() const;
|
std::vector<std::pair<ContourEdge, ContourEdge>> intersecting_edges() const;
|
||||||
bool has_intersecting_edges() const;
|
bool has_intersecting_edges() const;
|
||||||
|
|
||||||
|
template<typename FUNCTION> void visit_cells_intersecting_line(Slic3r::Point p1, Slic3r::Point p2, FUNCTION func) const
|
||||||
|
{
|
||||||
|
// End points of the line segment.
|
||||||
|
p1(0) -= m_bbox.min(0);
|
||||||
|
p1(1) -= m_bbox.min(1);
|
||||||
|
p2(0) -= m_bbox.min(0);
|
||||||
|
p2(1) -= m_bbox.min(1);
|
||||||
|
// Get the cells of the end points.
|
||||||
|
coord_t ix = p1(0) / m_resolution;
|
||||||
|
coord_t iy = p1(1) / m_resolution;
|
||||||
|
coord_t ixb = p2(0) / m_resolution;
|
||||||
|
coord_t iyb = p2(1) / m_resolution;
|
||||||
|
assert(ix >= 0 && size_t(ix) < m_cols);
|
||||||
|
assert(iy >= 0 && size_t(iy) < m_rows);
|
||||||
|
assert(ixb >= 0 && size_t(ixb) < m_cols);
|
||||||
|
assert(iyb >= 0 && size_t(iyb) < m_rows);
|
||||||
|
// Account for the end points.
|
||||||
|
func(iy, ix);
|
||||||
|
if (ix == ixb && iy == iyb)
|
||||||
|
// Both ends fall into the same cell.
|
||||||
|
return;
|
||||||
|
// Raster the centeral part of the line.
|
||||||
|
coord_t dx = std::abs(p2(0) - p1(0));
|
||||||
|
coord_t dy = std::abs(p2(1) - p1(1));
|
||||||
|
if (p1(0) < p2(0)) {
|
||||||
|
int64_t ex = int64_t((ix + 1)*m_resolution - p1(0)) * int64_t(dy);
|
||||||
|
if (p1(1) < p2(1)) {
|
||||||
|
// x positive, y positive
|
||||||
|
int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
|
||||||
|
do {
|
||||||
|
assert(ix <= ixb && iy <= iyb);
|
||||||
|
if (ex < ey) {
|
||||||
|
ey -= ex;
|
||||||
|
ex = int64_t(dy) * m_resolution;
|
||||||
|
ix += 1;
|
||||||
|
}
|
||||||
|
else if (ex == ey) {
|
||||||
|
ex = int64_t(dy) * m_resolution;
|
||||||
|
ey = int64_t(dx) * m_resolution;
|
||||||
|
ix += 1;
|
||||||
|
iy += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(ex > ey);
|
||||||
|
ex -= ey;
|
||||||
|
ey = int64_t(dx) * m_resolution;
|
||||||
|
iy += 1;
|
||||||
|
}
|
||||||
|
func(iy, ix);
|
||||||
|
} while (ix != ixb || iy != iyb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// x positive, y non positive
|
||||||
|
int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
|
||||||
|
do {
|
||||||
|
assert(ix <= ixb && iy >= iyb);
|
||||||
|
if (ex <= ey) {
|
||||||
|
ey -= ex;
|
||||||
|
ex = int64_t(dy) * m_resolution;
|
||||||
|
ix += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ex -= ey;
|
||||||
|
ey = int64_t(dx) * m_resolution;
|
||||||
|
iy -= 1;
|
||||||
|
}
|
||||||
|
func(iy, ix);
|
||||||
|
} while (ix != ixb || iy != iyb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int64_t ex = int64_t(p1(0) - ix*m_resolution) * int64_t(dy);
|
||||||
|
if (p1(1) < p2(1)) {
|
||||||
|
// x non positive, y positive
|
||||||
|
int64_t ey = int64_t((iy + 1)*m_resolution - p1(1)) * int64_t(dx);
|
||||||
|
do {
|
||||||
|
assert(ix >= ixb && iy <= iyb);
|
||||||
|
if (ex < ey) {
|
||||||
|
ey -= ex;
|
||||||
|
ex = int64_t(dy) * m_resolution;
|
||||||
|
ix -= 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(ex >= ey);
|
||||||
|
ex -= ey;
|
||||||
|
ey = int64_t(dx) * m_resolution;
|
||||||
|
iy += 1;
|
||||||
|
}
|
||||||
|
func(iy, ix);
|
||||||
|
} while (ix != ixb || iy != iyb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// x non positive, y non positive
|
||||||
|
int64_t ey = int64_t(p1(1) - iy*m_resolution) * int64_t(dx);
|
||||||
|
do {
|
||||||
|
assert(ix >= ixb && iy >= iyb);
|
||||||
|
if (ex < ey) {
|
||||||
|
ey -= ex;
|
||||||
|
ex = int64_t(dy) * m_resolution;
|
||||||
|
ix -= 1;
|
||||||
|
}
|
||||||
|
else if (ex == ey) {
|
||||||
|
// The lower edge of a grid cell belongs to the cell.
|
||||||
|
// Handle the case where the ray may cross the lower left corner of a cell in a general case,
|
||||||
|
// or a left or lower edge in a degenerate case (horizontal or vertical line).
|
||||||
|
if (dx > 0) {
|
||||||
|
ex = int64_t(dy) * m_resolution;
|
||||||
|
ix -= 1;
|
||||||
|
}
|
||||||
|
if (dy > 0) {
|
||||||
|
ey = int64_t(dx) * m_resolution;
|
||||||
|
iy -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(ex > ey);
|
||||||
|
ex -= ey;
|
||||||
|
ey = int64_t(dx) * m_resolution;
|
||||||
|
iy -= 1;
|
||||||
|
}
|
||||||
|
func(iy, ix);
|
||||||
|
} while (ix != ixb || iy != iyb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::vector<std::pair<size_t, size_t>>::const_iterator, std::vector<std::pair<size_t, size_t>>::const_iterator> cell_data_range(coord_t row, coord_t col) const
|
||||||
|
{
|
||||||
|
const EdgeGrid::Grid::Cell &cell = m_cells[row * m_cols + col];
|
||||||
|
return std::make_pair(m_cell_data.begin() + cell.begin, m_cell_data.begin() + cell.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<const Slic3r::Point&, const Slic3r::Point&> segment(const std::pair<size_t, size_t> &contour_and_segment_idx) const
|
||||||
|
{
|
||||||
|
const Slic3r::Points &ipts = *m_contours[contour_and_segment_idx.first];
|
||||||
|
size_t ipt = contour_and_segment_idx.second;
|
||||||
|
return std::pair<const Slic3r::Point&, const Slic3r::Point&>(ipts[ipt], ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Cell {
|
struct Cell {
|
||||||
Cell() : begin(0), end(0) {}
|
Cell() : begin(0), end(0) {}
|
||||||
|
@ -111,6 +111,29 @@ inline bool segment_segment_intersection(const Vec2d &p1, const Vec2d &v1, const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int segments_could_intersect(
|
||||||
|
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
|
||||||
|
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
|
||||||
|
{
|
||||||
|
Vec2i64 iv = (ip2 - ip1).cast<int64_t>();
|
||||||
|
Vec2i64 vij1 = (jp1 - ip1).cast<int64_t>();
|
||||||
|
Vec2i64 vij2 = (jp2 - ip1).cast<int64_t>();
|
||||||
|
int64_t tij1 = cross2(iv, vij1);
|
||||||
|
int64_t tij2 = cross2(iv, vij2);
|
||||||
|
int sij1 = (tij1 > 0) ? 1 : ((tij1 < 0) ? -1 : 0); // signum
|
||||||
|
int sij2 = (tij2 > 0) ? 1 : ((tij2 < 0) ? -1 : 0);
|
||||||
|
return sij1 * sij2;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool segments_intersect(
|
||||||
|
const Slic3r::Point &ip1, const Slic3r::Point &ip2,
|
||||||
|
const Slic3r::Point &jp1, const Slic3r::Point &jp2)
|
||||||
|
{
|
||||||
|
return segments_could_intersect(ip1, ip2, jp1, jp2) <= 0 &&
|
||||||
|
segments_could_intersect(jp1, jp2, ip1, ip2) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
Pointf3s convex_hull(Pointf3s points);
|
Pointf3s convex_hull(Pointf3s points);
|
||||||
Polygon convex_hull(Points points);
|
Polygon convex_hull(Points points);
|
||||||
Polygon convex_hull(const Polygons &polygons);
|
Polygon convex_hull(const Polygons &polygons);
|
||||||
|
56
src/libslic3r/PolygonTrimmer.cpp
Normal file
56
src/libslic3r/PolygonTrimmer.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "PolygonTrimmer.hpp"
|
||||||
|
#include "EdgeGrid.hpp"
|
||||||
|
#include "Geometry.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
TrimmedLoop trim_loop(const Polygon &loop, const EdgeGrid::Grid &grid)
|
||||||
|
{
|
||||||
|
assert(! loop.empty());
|
||||||
|
assert(loop.size() >= 2);
|
||||||
|
|
||||||
|
TrimmedLoop out;
|
||||||
|
|
||||||
|
if (loop.size() >= 2) {
|
||||||
|
size_t cnt = loop.points.size();
|
||||||
|
|
||||||
|
struct Visitor {
|
||||||
|
Visitor(const EdgeGrid::Grid &grid, const Slic3r::Point *pt_prev, const Slic3r::Point *pt_this) : grid(grid), pt_prev(pt_prev), pt_this(pt_this) {}
|
||||||
|
|
||||||
|
void operator()(coord_t iy, coord_t ix) {
|
||||||
|
// Called with a row and colum of the grid cell, which is intersected by a line.
|
||||||
|
auto cell_data_range = grid.cell_data_range(iy, ix);
|
||||||
|
for (auto it_contour_and_segment = cell_data_range.first; it_contour_and_segment != cell_data_range.second; ++ it_contour_and_segment) {
|
||||||
|
// End points of the line segment and their vector.
|
||||||
|
auto segment = grid.segment(*it_contour_and_segment);
|
||||||
|
if (Geometry::segments_intersect(segment.first, segment.second, *pt_prev, *pt_this)) {
|
||||||
|
// The two segments intersect. Add them to the output.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const EdgeGrid::Grid &grid;
|
||||||
|
const Slic3r::Point *pt_this;
|
||||||
|
const Slic3r::Point *pt_prev;
|
||||||
|
} visitor(grid, &loop.points.back(), nullptr);
|
||||||
|
|
||||||
|
for (const Point &pt_this : loop.points) {
|
||||||
|
visitor.pt_this = &pt_this;
|
||||||
|
grid.visit_cells_intersecting_line(*visitor.pt_prev, pt_this, visitor);
|
||||||
|
visitor.pt_prev = &pt_this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TrimmedLoop> trim_loops(const Polygons &loops, const EdgeGrid::Grid &grid)
|
||||||
|
{
|
||||||
|
std::vector<TrimmedLoop> out;
|
||||||
|
out.reserve(loops.size());
|
||||||
|
for (const Polygon &loop : loops)
|
||||||
|
out.emplace_back(trim_loop(loop, grid));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/libslic3r/PolygonTrimmer.hpp
Normal file
31
src/libslic3r/PolygonTrimmer.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef slic3r_PolygonTrimmer_hpp_
|
||||||
|
#define slic3r_PolygonTrimmer_hpp_
|
||||||
|
|
||||||
|
#include "libslic3r.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "Line.hpp"
|
||||||
|
#include "MultiPoint.hpp"
|
||||||
|
#include "Polyline.hpp"
|
||||||
|
|
||||||
|
namespace Slic3r {
|
||||||
|
|
||||||
|
namespace EdgeGrid {
|
||||||
|
class Grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TrimmedLoop
|
||||||
|
{
|
||||||
|
std::vector<Point> points;
|
||||||
|
// Number of points per segment. Empty if the loop is
|
||||||
|
std::vector<unsigned int> segments;
|
||||||
|
|
||||||
|
bool is_trimmed() const { return ! segments.empty(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
TrimmedLoop trim_loop(const Polygon &loop, const EdgeGrid::Grid &grid);
|
||||||
|
std::vector<TrimmedLoop> trim_loops(const Polygons &loops, const EdgeGrid::Grid &grid);
|
||||||
|
|
||||||
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
#endif /* slic3r_PolygonTrimmer_hpp_ */
|
Loading…
x
Reference in New Issue
Block a user