SPE-2298: Add detection of Voronoi diagram with parabolic edge without a focus point.
Cherry-picked from prusa3d/PrusaSlicer@c44ffed475 Co-authored-by: Lukáš Hejl <hejl.lukas@gmail.com>
This commit is contained in:
parent
44e53c90f0
commit
4b739539a4
2 changed files with 19 additions and 7 deletions
|
@ -35,6 +35,8 @@ VoronoiDiagram::construct_voronoi(const SegmentIterator segment_begin, const Seg
|
||||||
BOOST_LOG_TRIVIAL(warning) << "Detected Voronoi edge intersecting input segment, input polygons will be rotated back and forth.";
|
BOOST_LOG_TRIVIAL(warning) << "Detected Voronoi edge intersecting input segment, input polygons will be rotated back and forth.";
|
||||||
} else if (m_issue_type == IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX) {
|
} else if (m_issue_type == IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX) {
|
||||||
BOOST_LOG_TRIVIAL(warning) << "Detected finite Voronoi vertex with non finite vertex, input polygons will be rotated back and forth.";
|
BOOST_LOG_TRIVIAL(warning) << "Detected finite Voronoi vertex with non finite vertex, input polygons will be rotated back and forth.";
|
||||||
|
} else if (m_issue_type == IssueType::PARABOLIC_VORONOI_EDGE_WITHOUT_FOCUS_POINT) {
|
||||||
|
BOOST_LOG_TRIVIAL(warning) << "Detected parabolic Voronoi edges without focus point, input polygons will be rotated back and forth.";
|
||||||
} else {
|
} else {
|
||||||
BOOST_LOG_TRIVIAL(error) << "Detected unknown Voronoi diagram issue, input polygons will be rotated back and forth.";
|
BOOST_LOG_TRIVIAL(error) << "Detected unknown Voronoi diagram issue, input polygons will be rotated back and forth.";
|
||||||
}
|
}
|
||||||
|
@ -48,6 +50,8 @@ VoronoiDiagram::construct_voronoi(const SegmentIterator segment_begin, const Seg
|
||||||
BOOST_LOG_TRIVIAL(error) << "Detected Voronoi edge intersecting input segment even after the rotation of input.";
|
BOOST_LOG_TRIVIAL(error) << "Detected Voronoi edge intersecting input segment even after the rotation of input.";
|
||||||
} else if (m_issue_type == IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX) {
|
} else if (m_issue_type == IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX) {
|
||||||
BOOST_LOG_TRIVIAL(error) << "Detected finite Voronoi vertex with non finite vertex even after the rotation of input.";
|
BOOST_LOG_TRIVIAL(error) << "Detected finite Voronoi vertex with non finite vertex even after the rotation of input.";
|
||||||
|
} else if (m_issue_type == IssueType::PARABOLIC_VORONOI_EDGE_WITHOUT_FOCUS_POINT) {
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "Detected parabolic Voronoi edges without focus point even after the rotation of input.";
|
||||||
} else {
|
} else {
|
||||||
BOOST_LOG_TRIVIAL(error) << "Detected unknown Voronoi diagram issue even after the rotation of input.";
|
BOOST_LOG_TRIVIAL(error) << "Detected unknown Voronoi diagram issue even after the rotation of input.";
|
||||||
}
|
}
|
||||||
|
@ -159,8 +163,8 @@ typename boost::polygon::enable_if<
|
||||||
VoronoiDiagram::IssueType>::type
|
VoronoiDiagram::IssueType>::type
|
||||||
VoronoiDiagram::detect_known_issues(const VoronoiDiagram &voronoi_diagram, SegmentIterator segment_begin, SegmentIterator segment_end)
|
VoronoiDiagram::detect_known_issues(const VoronoiDiagram &voronoi_diagram, SegmentIterator segment_begin, SegmentIterator segment_end)
|
||||||
{
|
{
|
||||||
if (has_finite_edge_with_non_finite_vertex(voronoi_diagram)) {
|
if (const IssueType edge_issue_type = detect_known_voronoi_edge_issues(voronoi_diagram); edge_issue_type != IssueType::NO_ISSUE_DETECTED) {
|
||||||
return IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX;
|
return edge_issue_type;
|
||||||
} else if (const IssueType cell_issue_type = detect_known_voronoi_cell_issues(voronoi_diagram, segment_begin, segment_end); cell_issue_type != IssueType::NO_ISSUE_DETECTED) {
|
} else if (const IssueType cell_issue_type = detect_known_voronoi_cell_issues(voronoi_diagram, segment_begin, segment_end); cell_issue_type != IssueType::NO_ISSUE_DETECTED) {
|
||||||
return cell_issue_type;
|
return cell_issue_type;
|
||||||
}
|
}
|
||||||
|
@ -220,16 +224,20 @@ VoronoiDiagram::detect_known_voronoi_cell_issues(const VoronoiDiagram &voronoi_d
|
||||||
return IssueType::NO_ISSUE_DETECTED;
|
return IssueType::NO_ISSUE_DETECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoronoiDiagram::has_finite_edge_with_non_finite_vertex(const VoronoiDiagram &voronoi_diagram)
|
VoronoiDiagram::IssueType VoronoiDiagram::detect_known_voronoi_edge_issues(const VoronoiDiagram &voronoi_diagram)
|
||||||
{
|
{
|
||||||
for (const voronoi_diagram_type::edge_type &edge : voronoi_diagram.edges()) {
|
for (const voronoi_diagram_type::edge_type &edge : voronoi_diagram.edges()) {
|
||||||
if (edge.is_finite()) {
|
if (edge.is_finite()) {
|
||||||
assert(edge.vertex0() != nullptr && edge.vertex1() != nullptr);
|
assert(edge.vertex0() != nullptr && edge.vertex1() != nullptr);
|
||||||
if (edge.vertex0() == nullptr || edge.vertex1() == nullptr || !VoronoiUtils::is_finite(*edge.vertex0()) || !VoronoiUtils::is_finite(*edge.vertex1()))
|
if (edge.vertex0() == nullptr || edge.vertex1() == nullptr || !VoronoiUtils::is_finite(*edge.vertex0()) || !VoronoiUtils::is_finite(*edge.vertex1()))
|
||||||
return true;
|
return IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX;
|
||||||
|
|
||||||
|
if (edge.is_curved() && !edge.cell()->contains_point() && !edge.twin()->cell()->contains_point())
|
||||||
|
return IssueType::PARABOLIC_VORONOI_EDGE_WITHOUT_FOCUS_POINT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
return IssueType::NO_ISSUE_DETECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename SegmentIterator>
|
template<typename SegmentIterator>
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
MISSING_VORONOI_VERTEX,
|
MISSING_VORONOI_VERTEX,
|
||||||
NON_PLANAR_VORONOI_DIAGRAM,
|
NON_PLANAR_VORONOI_DIAGRAM,
|
||||||
VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT,
|
VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT,
|
||||||
|
PARABOLIC_VORONOI_EDGE_WITHOUT_FOCUS_POINT,
|
||||||
UNKNOWN // Repairs are disabled in the constructor.
|
UNKNOWN // Repairs are disabled in the constructor.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,7 +159,10 @@ private:
|
||||||
IssueType>::type
|
IssueType>::type
|
||||||
detect_known_voronoi_cell_issues(const VoronoiDiagram &voronoi_diagram, SegmentIterator segment_begin, SegmentIterator segment_end);
|
detect_known_voronoi_cell_issues(const VoronoiDiagram &voronoi_diagram, SegmentIterator segment_begin, SegmentIterator segment_end);
|
||||||
|
|
||||||
static bool has_finite_edge_with_non_finite_vertex(const VoronoiDiagram &voronoi_diagram);
|
// Detect issues related to Voronoi edges, or that can be detected by iterating over Voronoi edges.
|
||||||
|
// The first type of issue that can be detected is a finite Voronoi edge with a non-finite vertex.
|
||||||
|
// The second type of issue that can be detected is a parabolic Voronoi edge without a focus point (produced by two segments).
|
||||||
|
static IssueType detect_known_voronoi_edge_issues(const VoronoiDiagram &voronoi_diagram);
|
||||||
|
|
||||||
voronoi_diagram_type m_voronoi_diagram;
|
voronoi_diagram_type m_voronoi_diagram;
|
||||||
vertex_container_type m_vertices;
|
vertex_container_type m_vertices;
|
||||||
|
|
Loading…
Reference in a new issue