From 060195bd17fcc8d72f7f4aa09b04b3f3f939d801 Mon Sep 17 00:00:00 2001 From: Fedr Date: Thu, 3 Nov 2022 16:11:46 +0300 Subject: [PATCH] PolylineDecimator: prohibit collapse if it introduces a sharp turn in the line (#665) --- source/MRMesh/MRPolylineDecimate.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/source/MRMesh/MRPolylineDecimate.cpp b/source/MRMesh/MRPolylineDecimate.cpp index ba8c22c50e7d..87e9ba82cd7d 100644 --- a/source/MRMesh/MRPolylineDecimate.cpp +++ b/source/MRMesh/MRPolylineDecimate.cpp @@ -248,11 +248,29 @@ VertId PolylineDecimator::collapse_( EdgeId edgeToCollapse, const V & collaps vo = topology.org( edgeToCollapse ); } - const auto e1 = topology.next( edgeToCollapse ).sym(); - const auto e2 = topology.next( e1 ).sym(); - const auto e3 = topology.next( e2 ).sym(); - if ( e1 != edgeToCollapse.sym() && e2 != e1.sym() && e3 != e2.sym() && e3 == edgeToCollapse ) - return {}; // keep at least a triangle from every closed contour + const auto ep = topology.next( edgeToCollapse ).sym(); + if ( ep != edgeToCollapse.sym() ) + { + const auto epp = topology.next( ep ).sym(); + const auto eppp = topology.next( epp ).sym(); + if ( epp != ep.sym() && eppp != epp.sym() && eppp == edgeToCollapse ) + return {}; // keep at least a triangle from every closed contour + + const auto en = topology.next( edgeToCollapse.sym() ); + if ( en != edgeToCollapse.sym() ) + { + const auto po = polyline_.orgPnt( ep ); + const auto nd = polyline_.destPnt( en ); + if ( dot( po - collapsePos, nd - collapsePos ) > 0 ) + { + // after the collapse the line will make a sharp turn in remaining vertex + const auto o = polyline_.orgPnt( edgeToCollapse ); + const auto d = polyline_.destPnt( edgeToCollapse ); + if ( dot( po - o, d - o ) <= 0 && dot( o - d, nd - d ) <= 0 ) + return {}; // there are no sharp turns before the collapse, so prohibit it + } + } + } if ( settings_.preCollapse && !settings_.preCollapse( edgeToCollapse, collapsePos ) ) return {}; // user prohibits the collapse