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.";
|
||||
} 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.";
|
||||
} 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 {
|
||||
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.";
|
||||
} 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.";
|
||||
} 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 {
|
||||
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::detect_known_issues(const VoronoiDiagram &voronoi_diagram, SegmentIterator segment_begin, SegmentIterator segment_end)
|
||||
{
|
||||
if (has_finite_edge_with_non_finite_vertex(voronoi_diagram)) {
|
||||
return IssueType::FINITE_EDGE_WITH_NON_FINITE_VERTEX;
|
||||
if (const IssueType edge_issue_type = detect_known_voronoi_edge_issues(voronoi_diagram); edge_issue_type != IssueType::NO_ISSUE_DETECTED) {
|
||||
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) {
|
||||
return cell_issue_type;
|
||||
}
|
||||
|
@ -220,16 +224,20 @@ VoronoiDiagram::detect_known_voronoi_cell_issues(const VoronoiDiagram &voronoi_d
|
|||
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()) {
|
||||
if (edge.is_finite()) {
|
||||
assert(edge.vertex0() != nullptr && edge.vertex1() != nullptr);
|
||||
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>
|
||||
|
|
|
@ -44,7 +44,8 @@ public:
|
|||
MISSING_VORONOI_VERTEX,
|
||||
NON_PLANAR_VORONOI_DIAGRAM,
|
||||
VORONOI_EDGE_INTERSECTING_INPUT_SEGMENT,
|
||||
UNKNOWN // Repairs are disabled in the constructor.
|
||||
PARABOLIC_VORONOI_EDGE_WITHOUT_FOCUS_POINT,
|
||||
UNKNOWN // Repairs are disabled in the constructor.
|
||||
};
|
||||
|
||||
enum class State {
|
||||
|
@ -158,7 +159,10 @@ private:
|
|||
IssueType>::type
|
||||
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;
|
||||
vertex_container_type m_vertices;
|
||||
|
|
Loading…
Reference in a new issue