mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-24 15:13:58 -06:00
EdgeGrid refactoring to support both open and closed contours.
Squashed commit of the following: commit 4e13a8fe19abcc9aae39a9bc4c7953a743196504 Merge: 6ae7664096f89da1f3
Author: Vojtech Bubnik <bubnikv@gmail.com> Date: Fri Feb 5 11:19:35 2021 +0100 Merge remote-tracking branch 'remotes/origin/master' into vb_edgegrid_open_lines commit 6ae76640942269993c942861f0444088843e3fa1 Author: Vojtech Bubnik <bubnikv@gmail.com> Date: Fri Feb 5 11:14:48 2021 +0100 EdgeGrid enhancement to accept both the open and closed lines. commit 36a5efcd558bd5fd5f46b5f561387a2c73221553 Author: Vojtech Bubnik <bubnikv@gmail.com> Date: Fri Feb 5 10:52:14 2021 +0100 EdgeGrid improvements: Documentation, one bug fix after recent refactoring. commit6f89da1f39
Author: tamasmeszaros <meszaros.q@gmail.com> Date: Thu Feb 4 20:31:50 2021 +0100 Disable libicu for boost-regex Should have been disabled from the beginning commit ffc77b1a72a0be9b5622fd33defeebb24bf07b34 Author: Vojtech Bubnik <bubnikv@gmail.com> Date: Thu Feb 4 18:40:33 2021 +0100 EdgeGrid: Annotated those methods that do not work with open contours. commit 8039a645b4bf0c46c99b90a9c34e7189d7442f86 Author: Vojtech Bubnik <bubnikv@gmail.com> Date: Thu Feb 4 18:28:21 2021 +0100 Refactoring of EdgeGrid structure to support both closed and open lines.
This commit is contained in:
parent
6f89da1f39
commit
5f86d11c74
6 changed files with 272 additions and 187 deletions
|
@ -34,76 +34,82 @@ EdgeGrid::Grid::~Grid()
|
|||
|
||||
void EdgeGrid::Grid::create(const Polygons &polygons, coord_t resolution)
|
||||
{
|
||||
// Count the contours.
|
||||
size_t ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j].points.empty())
|
||||
++ ncontours;
|
||||
|
||||
// Collect the contours.
|
||||
m_contours.assign(ncontours, nullptr);
|
||||
ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j].points.empty())
|
||||
m_contours[ncontours ++] = &polygons[j].points;
|
||||
m_contours.reserve(std::count_if(polygons.begin(), polygons.end(), [](const Polygon &p) { return ! p.empty(); }));
|
||||
for (const Polygon &polygon : polygons)
|
||||
if (! polygon.empty())
|
||||
m_contours.emplace_back(polygon.points, false);
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
||||
void EdgeGrid::Grid::create(const std::vector<const Polygon*> &polygons, coord_t resolution)
|
||||
{
|
||||
// Count the contours.
|
||||
size_t ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j]->points.empty())
|
||||
++ ncontours;
|
||||
|
||||
// Collect the contours.
|
||||
m_contours.assign(ncontours, nullptr);
|
||||
ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j]->points.empty())
|
||||
m_contours[ncontours ++] = &polygons[j]->points;
|
||||
m_contours.reserve(std::count_if(polygons.begin(), polygons.end(), [](const Polygon *p) { return ! p->empty(); }));
|
||||
for (const Polygon *polygon : polygons)
|
||||
if (! polygon->empty())
|
||||
m_contours.emplace_back(polygon->points, false);
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
||||
void EdgeGrid::Grid::create(const std::vector<Points> &polygons, coord_t resolution)
|
||||
void EdgeGrid::Grid::create(const std::vector<Points> &polygons, coord_t resolution, bool open_polylines)
|
||||
{
|
||||
// Count the contours.
|
||||
size_t ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j].empty())
|
||||
++ ncontours;
|
||||
|
||||
// Collect the contours.
|
||||
m_contours.assign(ncontours, nullptr);
|
||||
ncontours = 0;
|
||||
for (size_t j = 0; j < polygons.size(); ++ j)
|
||||
if (! polygons[j].empty())
|
||||
m_contours[ncontours ++] = &polygons[j];
|
||||
m_contours.reserve(std::count_if(polygons.begin(), polygons.end(), [](const Points &p) { return p.size() > 1; }));
|
||||
for (const Points &points : polygons)
|
||||
if (points.size() > 1) {
|
||||
const Point *begin = points.data();
|
||||
const Point *end = points.data() + points.size();
|
||||
bool open = open_polylines;
|
||||
if (open_polylines) {
|
||||
if (*begin == end[-1]) {
|
||||
open = false;
|
||||
-- end;
|
||||
}
|
||||
} else
|
||||
assert(*begin != end[-1]);
|
||||
m_contours.emplace_back(begin, end, open);
|
||||
}
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
||||
void EdgeGrid::Grid::create(const Polygons &polygons, const Polylines &polylines, coord_t resolution)
|
||||
{
|
||||
// Collect the contours.
|
||||
m_contours.reserve(
|
||||
std::count_if(polygons.begin(), polygons.end(), [](const Polygon &p) { return p.size() > 1; }) +
|
||||
std::count_if(polylines.begin(), polylines.end(), [](const Polyline &p) { return p.size() > 1; }));
|
||||
|
||||
for (const Polyline &polyline : polylines)
|
||||
if (polyline.size() > 1) {
|
||||
const Point *begin = polyline.points.data();
|
||||
const Point *end = polyline.points.data() + polyline.size();
|
||||
bool open = true;
|
||||
if (*begin == end[-1]) {
|
||||
open = false;
|
||||
-- end;
|
||||
}
|
||||
m_contours.emplace_back(begin, end, open);
|
||||
}
|
||||
|
||||
for (const Polygon &polygon : polygons)
|
||||
if (polygon.size() > 1)
|
||||
m_contours.emplace_back(polygon.points, false);
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
||||
void EdgeGrid::Grid::create(const ExPolygon &expoly, coord_t resolution)
|
||||
{
|
||||
// Count the contours.
|
||||
size_t ncontours = 0;
|
||||
if (! expoly.contour.points.empty())
|
||||
++ ncontours;
|
||||
for (size_t j = 0; j < expoly.holes.size(); ++ j)
|
||||
if (! expoly.holes[j].points.empty())
|
||||
++ ncontours;
|
||||
|
||||
// Collect the contours.
|
||||
m_contours.assign(ncontours, nullptr);
|
||||
ncontours = 0;
|
||||
if (! expoly.contour.points.empty())
|
||||
m_contours[ncontours++] = &expoly.contour.points;
|
||||
for (size_t j = 0; j < expoly.holes.size(); ++ j)
|
||||
if (! expoly.holes[j].points.empty())
|
||||
m_contours[ncontours++] = &expoly.holes[j].points;
|
||||
m_contours.reserve((expoly.contour.empty() ? 0 : 1) + std::count_if(expoly.holes.begin(), expoly.holes.end(), [](const Polygon &p) { return ! p.empty(); }));
|
||||
if (! expoly.contour.empty())
|
||||
m_contours.emplace_back(expoly.contour.points, false);
|
||||
for (const Polygon &hole : expoly.holes)
|
||||
if (! hole.empty())
|
||||
m_contours.emplace_back(hole.points, false);
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
}
|
||||
|
@ -112,25 +118,20 @@ void EdgeGrid::Grid::create(const ExPolygons &expolygons, coord_t resolution)
|
|||
{
|
||||
// Count the contours.
|
||||
size_t ncontours = 0;
|
||||
for (size_t i = 0; i < expolygons.size(); ++ i) {
|
||||
const ExPolygon &expoly = expolygons[i];
|
||||
if (! expoly.contour.points.empty())
|
||||
for (const ExPolygon &expoly : expolygons) {
|
||||
if (! expoly.contour.empty())
|
||||
++ ncontours;
|
||||
for (size_t j = 0; j < expoly.holes.size(); ++ j)
|
||||
if (! expoly.holes[j].points.empty())
|
||||
++ ncontours;
|
||||
ncontours += std::count_if(expoly.holes.begin(), expoly.holes.end(), [](const Polygon &p) { return ! p.empty(); });
|
||||
}
|
||||
|
||||
// Collect the contours.
|
||||
m_contours.assign(ncontours, nullptr);
|
||||
ncontours = 0;
|
||||
for (size_t i = 0; i < expolygons.size(); ++ i) {
|
||||
const ExPolygon &expoly = expolygons[i];
|
||||
if (! expoly.contour.points.empty())
|
||||
m_contours[ncontours++] = &expoly.contour.points;
|
||||
for (size_t j = 0; j < expoly.holes.size(); ++ j)
|
||||
if (! expoly.holes[j].points.empty())
|
||||
m_contours[ncontours++] = &expoly.holes[j].points;
|
||||
m_contours.reserve(ncontours);
|
||||
for (const ExPolygon &expoly : expolygons) {
|
||||
if (! expoly.contour.empty())
|
||||
m_contours.emplace_back(expoly.contour.points, false);
|
||||
for (const Polygon &hole : expoly.holes)
|
||||
if (! hole.empty())
|
||||
m_contours.emplace_back(hole.points, false);
|
||||
}
|
||||
|
||||
create_from_m_contours(resolution);
|
||||
|
@ -146,11 +147,13 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
|
|||
{
|
||||
assert(resolution > 0);
|
||||
// 1) Measure the bounding box.
|
||||
for (size_t i = 0; i < m_contours.size(); ++ i) {
|
||||
const Slic3r::Points &pts = *m_contours[i];
|
||||
for (size_t j = 0; j < pts.size(); ++ j)
|
||||
m_bbox.merge(pts[j]);
|
||||
for (const Contour &contour : m_contours) {
|
||||
assert(contour.num_segments() > 0);
|
||||
assert(*contour.begin() != contour.end()[-1]);
|
||||
for (const Slic3r::Point &pt : contour)
|
||||
m_bbox.merge(pt);
|
||||
}
|
||||
|
||||
coord_t eps = 16;
|
||||
m_bbox.min(0) -= eps;
|
||||
m_bbox.min(1) -= eps;
|
||||
|
@ -165,11 +168,11 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
|
|||
|
||||
// 3) First round of contour rasterization, count the edges per grid cell.
|
||||
for (size_t i = 0; i < m_contours.size(); ++ i) {
|
||||
const Slic3r::Points &pts = *m_contours[i];
|
||||
for (size_t j = 0; j < pts.size(); ++ j) {
|
||||
const Contour &contour = m_contours[i];
|
||||
for (size_t j = 0; j < contour.num_segments(); ++ j) {
|
||||
// End points of the line segment.
|
||||
Slic3r::Point p1(pts[j]);
|
||||
Slic3r::Point p2 = pts[(j + 1 == pts.size()) ? 0 : j + 1];
|
||||
Slic3r::Point p1(contour.segment_start(j));
|
||||
Slic3r::Point p2(contour.segment_end(j));
|
||||
p1(0) -= m_bbox.min(0);
|
||||
p1(1) -= m_bbox.min(1);
|
||||
p2(0) -= m_bbox.min(0);
|
||||
|
@ -328,9 +331,9 @@ void EdgeGrid::Grid::create_from_m_contours(coord_t resolution)
|
|||
|
||||
assert(visitor.i == 0);
|
||||
for (; visitor.i < m_contours.size(); ++ visitor.i) {
|
||||
const Slic3r::Points &pts = *m_contours[visitor.i];
|
||||
for (visitor.j = 0; visitor.j < pts.size(); ++ visitor.j)
|
||||
this->visit_cells_intersecting_line(pts[visitor.j], pts[(visitor.j + 1 == pts.size()) ? 0 : visitor.j + 1], visitor);
|
||||
const Contour &contour = m_contours[visitor.i];
|
||||
for (visitor.j = 0; visitor.j < contour.num_segments(); ++ visitor.j)
|
||||
this->visit_cells_intersecting_line(contour.segment_start(visitor.j), contour.segment_end(visitor.j), visitor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -696,11 +699,12 @@ void EdgeGrid::Grid::calculate_sdf()
|
|||
const Cell &cell = m_cells[r * m_cols + c];
|
||||
// For each segment in the cell:
|
||||
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
||||
const Slic3r::Points &pts = *m_contours[m_cell_data[i].first];
|
||||
const Contour &contour = m_contours[m_cell_data[i].first];
|
||||
assert(contour.closed());
|
||||
size_t ipt = m_cell_data[i].second;
|
||||
// End points of the line segment.
|
||||
const Slic3r::Point &p1 = pts[ipt];
|
||||
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
||||
const Slic3r::Point &p1 = contour.segment_start(ipt);
|
||||
const Slic3r::Point &p2 = contour.segment_end(ipt);
|
||||
// Segment vector
|
||||
const Slic3r::Point v_seg = p2 - p1;
|
||||
// l2 of v_seg
|
||||
|
@ -724,7 +728,7 @@ void EdgeGrid::Grid::calculate_sdf()
|
|||
double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
|
||||
if (dabs < d_min) {
|
||||
// Previous point.
|
||||
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
||||
const Slic3r::Point &p0 = contour.segment_prev(ipt);
|
||||
Slic3r::Point v_seg_prev = p1 - p0;
|
||||
int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
|
||||
if (t2_pt > 0) {
|
||||
|
@ -1044,7 +1048,7 @@ float EdgeGrid::Grid::signed_distance_bilinear(const Point &pt) const
|
|||
return f;
|
||||
}
|
||||
|
||||
EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt, coord_t search_radius) const
|
||||
EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point_signed_distance(const Point &pt, coord_t search_radius) const
|
||||
{
|
||||
BoundingBox bbox;
|
||||
bbox.min = bbox.max = Point(pt(0) - m_bbox.min(0), pt(1) - m_bbox.min(1));
|
||||
|
@ -1083,12 +1087,13 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt
|
|||
for (int c = bbox.min(0); c <= bbox.max(0); ++ c) {
|
||||
const Cell &cell = m_cells[r * m_cols + c];
|
||||
for (size_t i = cell.begin; i < cell.end; ++ i) {
|
||||
const size_t contour_idx = m_cell_data[i].first;
|
||||
const Slic3r::Points &pts = *m_contours[contour_idx];
|
||||
const size_t contour_idx = m_cell_data[i].first;
|
||||
const Contour &contour = m_contours[contour_idx];
|
||||
assert(contour.closed());
|
||||
size_t ipt = m_cell_data[i].second;
|
||||
// End points of the line segment.
|
||||
const Slic3r::Point &p1 = pts[ipt];
|
||||
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
||||
const Slic3r::Point &p1 = contour.segment_start(ipt);
|
||||
const Slic3r::Point &p2 = contour.segment_end(ipt);
|
||||
const Slic3r::Point v_seg = p2 - p1;
|
||||
const Slic3r::Point v_pt = pt - p1;
|
||||
// dot(p2-p1, pt-p1)
|
||||
|
@ -1100,7 +1105,7 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt
|
|||
double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
|
||||
if (dabs < d_min) {
|
||||
// Previous point.
|
||||
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
||||
const Slic3r::Point &p0 = contour.segment_prev(ipt);
|
||||
Slic3r::Point v_seg_prev = p1 - p0;
|
||||
int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
|
||||
if (t2_pt > 0) {
|
||||
|
@ -1156,9 +1161,9 @@ EdgeGrid::Grid::ClosestPointResult EdgeGrid::Grid::closest_point(const Point &pt
|
|||
assert(result.t >= 0. && result.t <= 1.);
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
const Slic3r::Points &pts = *m_contours[result.contour_idx];
|
||||
const Slic3r::Point &p1 = pts[result.start_point_idx];
|
||||
const Slic3r::Point &p2 = pts[(result.start_point_idx + 1 == pts.size()) ? 0 : result.start_point_idx + 1];
|
||||
const Contour &contour = m_contours[result.contour_idx];
|
||||
const Slic3r::Point &p1 = contour.segment_start(result.start_point_idx);
|
||||
const Slic3r::Point &p2 = contour.segment_end(result.start_point_idx);
|
||||
Vec2d vfoot;
|
||||
if (result.t == 0)
|
||||
vfoot = p1.cast<double>() - pt.cast<double>();
|
||||
|
@ -1212,11 +1217,12 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
|
|||
for (int c = bbox.min(0); c <= bbox.max(0); ++ c) {
|
||||
const Cell &cell = m_cells[r * m_cols + c];
|
||||
for (size_t i = cell.begin; i < cell.end; ++ i) {
|
||||
const Slic3r::Points &pts = *m_contours[m_cell_data[i].first];
|
||||
const Contour &contour = m_contours[m_cell_data[i].first];
|
||||
assert(contour.closed());
|
||||
size_t ipt = m_cell_data[i].second;
|
||||
// End points of the line segment.
|
||||
const Slic3r::Point &p1 = pts[ipt];
|
||||
const Slic3r::Point &p2 = pts[(ipt + 1 == pts.size()) ? 0 : ipt + 1];
|
||||
const Slic3r::Point &p1 = contour.segment_start(ipt);
|
||||
const Slic3r::Point &p2 = contour.segment_end(ipt);
|
||||
Slic3r::Point v_seg = p2 - p1;
|
||||
Slic3r::Point v_pt = pt - p1;
|
||||
// dot(p2-p1, pt-p1)
|
||||
|
@ -1228,7 +1234,7 @@ bool EdgeGrid::Grid::signed_distance_edges(const Point &pt, coord_t search_radiu
|
|||
double dabs = sqrt(int64_t(v_pt(0)) * int64_t(v_pt(0)) + int64_t(v_pt(1)) * int64_t(v_pt(1)));
|
||||
if (dabs < d_min) {
|
||||
// Previous point.
|
||||
const Slic3r::Point &p0 = pts[(ipt == 0) ? (pts.size() - 1) : ipt - 1];
|
||||
const Slic3r::Point &p0 = contour.segment_prev(ipt);
|
||||
Slic3r::Point v_seg_prev = p1 - p0;
|
||||
int64_t t2_pt = int64_t(v_seg_prev(0)) * int64_t(v_pt(0)) + int64_t(v_seg_prev(1)) * int64_t(v_pt(1));
|
||||
if (t2_pt > 0) {
|
||||
|
@ -1418,26 +1424,26 @@ std::vector<std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge>>
|
|||
const Cell &cell = m_cells[r * m_cols + c];
|
||||
// For each pair of segments in the cell:
|
||||
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
||||
const Slic3r::Points &ipts = *m_contours[m_cell_data[i].first];
|
||||
const Contour &icontour = m_contours[m_cell_data[i].first];
|
||||
size_t ipt = m_cell_data[i].second;
|
||||
// End points of the line segment and their vector.
|
||||
const Slic3r::Point &ip1 = ipts[ipt];
|
||||
const Slic3r::Point &ip2 = ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1];
|
||||
const Slic3r::Point &ip1 = icontour.segment_start(ipt);
|
||||
const Slic3r::Point &ip2 = icontour.segment_end(ipt);
|
||||
for (size_t j = i + 1; j != cell.end; ++ j) {
|
||||
const Slic3r::Points &jpts = *m_contours[m_cell_data[j].first];
|
||||
size_t jpt = m_cell_data[j].second;
|
||||
const Contour &jcontour = m_contours[m_cell_data[j].first];
|
||||
size_t jpt = m_cell_data[j].second;
|
||||
// End points of the line segment and their vector.
|
||||
const Slic3r::Point &jp1 = jpts[jpt];
|
||||
const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1];
|
||||
if (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2))
|
||||
const Slic3r::Point &jp1 = jcontour.segment_start(jpt);
|
||||
const Slic3r::Point &jp2 = jcontour.segment_end(jpt);
|
||||
if (&icontour == &jcontour && (&ip1 == &jp2 || &jp1 == &ip2))
|
||||
// Segments of the same contour share a common vertex.
|
||||
continue;
|
||||
if (Geometry::segments_intersect(ip1, ip2, jp1, jp2)) {
|
||||
// The two segments intersect. Add them to the output.
|
||||
int jfirst = (&jpts < &ipts) || (&jpts == &ipts && jpt < ipt);
|
||||
int jfirst = (&jcontour < &icontour) || (&jcontour == &icontour && jpt < ipt);
|
||||
out.emplace_back(jfirst ?
|
||||
std::make_pair(std::make_pair(&ipts, ipt), std::make_pair(&jpts, jpt)) :
|
||||
std::make_pair(std::make_pair(&ipts, ipt), std::make_pair(&jpts, jpt)));
|
||||
std::make_pair(std::make_pair(&icontour, ipt), std::make_pair(&jcontour, jpt)) :
|
||||
std::make_pair(std::make_pair(&icontour, ipt), std::make_pair(&jcontour, jpt)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1455,18 +1461,18 @@ bool EdgeGrid::Grid::has_intersecting_edges() const
|
|||
const Cell &cell = m_cells[r * m_cols + c];
|
||||
// For each pair of segments in the cell:
|
||||
for (size_t i = cell.begin; i != cell.end; ++ i) {
|
||||
const Slic3r::Points &ipts = *m_contours[m_cell_data[i].first];
|
||||
const Contour &icontour = m_contours[m_cell_data[i].first];
|
||||
size_t ipt = m_cell_data[i].second;
|
||||
// End points of the line segment and their vector.
|
||||
const Slic3r::Point &ip1 = ipts[ipt];
|
||||
const Slic3r::Point &ip2 = ipts[(ipt + 1 == ipts.size()) ? 0 : ipt + 1];
|
||||
const Slic3r::Point &ip1 = icontour.segment_start(ipt);
|
||||
const Slic3r::Point &ip2 = icontour.segment_end(ipt);
|
||||
for (size_t j = i + 1; j != cell.end; ++ j) {
|
||||
const Slic3r::Points &jpts = *m_contours[m_cell_data[j].first];
|
||||
const Contour &jcontour = m_contours[m_cell_data[j].first];
|
||||
size_t jpt = m_cell_data[j].second;
|
||||
// End points of the line segment and their vector.
|
||||
const Slic3r::Point &jp1 = jpts[jpt];
|
||||
const Slic3r::Point &jp2 = jpts[(jpt + 1 == jpts.size()) ? 0 : jpt + 1];
|
||||
if (! (&ipts == &jpts && (&ip1 == &jp2 || &jp1 == &ip2)) &&
|
||||
const Slic3r::Point &jp1 = jcontour.segment_start(jpt);
|
||||
const Slic3r::Point &jp2 = jcontour.segment_end(jpt);
|
||||
if (! (&icontour == &jcontour && (&ip1 == &jp2 || &jp1 == &ip2)) &&
|
||||
Geometry::segments_intersect(ip1, ip2, jp1, jp2))
|
||||
return true;
|
||||
}
|
||||
|
@ -1601,22 +1607,27 @@ void export_intersections_to_svg(const std::string &filename, const Polygons &po
|
|||
SVG svg(filename.c_str(), bbox);
|
||||
svg.draw(union_ex(polygons), "gray", 0.25f);
|
||||
svg.draw_outline(polygons, "black");
|
||||
std::set<const Points*> intersecting_contours;
|
||||
std::set<const EdgeGrid::Contour*> intersecting_contours;
|
||||
for (const std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge> &ie : intersections) {
|
||||
intersecting_contours.insert(ie.first.first);
|
||||
intersecting_contours.insert(ie.second.first);
|
||||
}
|
||||
// Highlight the contours with intersections.
|
||||
coord_t line_width = coord_t(scale_(0.01));
|
||||
for (const Points *ic : intersecting_contours) {
|
||||
svg.draw_outline(Polygon(*ic), "green");
|
||||
svg.draw_outline(Polygon(*ic), "black", line_width);
|
||||
for (const EdgeGrid::Contour *ic : intersecting_contours) {
|
||||
if (ic->open())
|
||||
svg.draw(Polyline(Points(ic->begin(), ic->end())), "green");
|
||||
else {
|
||||
Polygon polygon(Points(ic->begin(), ic->end()));
|
||||
svg.draw_outline(polygon, "green");
|
||||
svg.draw_outline(polygon, "black", line_width);
|
||||
}
|
||||
}
|
||||
// Paint the intersections.
|
||||
for (const std::pair<EdgeGrid::Grid::ContourEdge, EdgeGrid::Grid::ContourEdge> &intersecting_edges : intersections) {
|
||||
auto edge = [](const EdgeGrid::Grid::ContourEdge &e) {
|
||||
return Line(e.first->at(e.second),
|
||||
e.first->at((e.second + 1 == e.first->size()) ? 0 : e.second + 1));
|
||||
return Line(e.first->segment_start(e.second),
|
||||
e.first->segment_end(e.second));
|
||||
};
|
||||
svg.draw(edge(intersecting_edges.first), "red", line_width);
|
||||
svg.draw(edge(intersecting_edges.second), "red", line_width);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue