@@ -799,20 +799,37 @@ SSurface *SCurve::GetSurfaceB(SShell *a, SShell *b) const {
799799// stuff in the Booleans. So remove them.
800800// -----------------------------------------------------------------------------
801801void SCurve::RemoveShortSegments (SSurface *srfA, SSurface *srfB) {
802- // Three, not two; curves are pwl'd to at least two edges (three points)
803- // even if not necessary, to avoid square holes.
804- if (pts.n <= 3 ) return ;
802+ if (pts.n <= 2 ) return ;
805803 pts.ClearTags ();
806804
807805 Vector prev = pts[0 ].p ;
806+ double tprev = 0 ;
807+ double t = 0 ;
808+ double tnext = 0 ;
809+
808810 int i, a;
809811 for (i = 1 ; i < pts.n - 1 ; i++) {
810812 SCurvePt *sct = &(pts[i]),
811813 *scn = &(pts[i+1 ]);
814+
812815 if (sct->vertex ) {
813816 prev = sct->p ;
814817 continue ;
815818 }
819+
820+ // if the curve is exact and points are >0.1 appart wrt t, point is there
821+ // deliberately regardless of chord tolerance (ex: small circles)
822+ tprev = t = tnext = 0 ;
823+ if (isExact) {
824+ exact.ClosestPointTo (prev, &tprev, /* mustconverge=*/ true );
825+ exact.ClosestPointTo (sct->p , &t, /* mustconverge=*/ true );
826+ exact.ClosestPointTo (scn->p , &tnext, /* mustconverge=*/ true );
827+ }
828+ if ( (t - tprev > 0.1 ) && (tnext - t > 0.1 ) ) {
829+ prev = sct->p ;
830+ continue ;
831+ }
832+
816833 bool mustKeep = false ;
817834
818835 // We must check against both surfaces; the piecewise linear edge
@@ -826,7 +843,7 @@ void SCurve::RemoveShortSegments(SSurface *srfA, SSurface *srfB) {
826843 srf->ClosestPointTo (prev, &(puv.x ), &(puv.y ));
827844 srf->ClosestPointTo (scn->p , &(nuv.x ), &(nuv.y ));
828845
829- if (srf->ChordToleranceForEdge (nuv, puv) > SS.ChordTolMm ()) {
846+ if (srf->ChordToleranceForEdge (nuv, puv) > SS.ChordTolMm () ) {
830847 mustKeep = true ;
831848 }
832849 }
0 commit comments