Skip to content

Commit 2ca61b6

Browse files
committed
Improved mergeFirstSegments handling
1 parent 25f7091 commit 2ca61b6

File tree

1 file changed

+41
-10
lines changed

1 file changed

+41
-10
lines changed

Lib/booleanOperations/flatten.py

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -692,23 +692,50 @@ def reCurveSubSegments(self, inputContours):
692692
fp = segmentedFlatPoints[0][0]
693693
lp = segmentedFlatPoints[-1][-1]
694694
mergeFirstSegments = False
695+
duplicatePoint = 0
695696
if fp in flatInputPoints and lp in flatInputPoints:
697+
# fp and lp are "known" points with associated input
698+
# segments. If they're on the same segment, merge
699+
# them.
700+
# Otherwise, if the opposite segment is curved we
701+
# need to duplicate the point so that we have
702+
# the full curve when processing that segment.
703+
# However, there is an exception case: If the
704+
# inputSegment type is "curved" but it was encoded
705+
# for pyClipper as a line anyway, do nothing.
696706
firstInputSegment = flatInputPointsSegmentDict[fp]
697707
lastInputSegment = flatInputPointsSegmentDict[lp]
698708
reversedFirstInputSegment = reversedFlatInputPointsSegmentDict[fp]
699709
reversedLastInputSegment = reversedFlatInputPointsSegmentDict[lp]
700-
if (firstInputSegment.segmentType == reversedFirstInputSegment.segmentType == "curve") or (lastInputSegment.segmentType == reversedLastInputSegment.segmentType == "curve"):
710+
# Note: len(segmentedFlatPoints[0]) == 0 in this code,
711+
# so firstCurved is at least very unlikely. I don't
712+
# think I've hit the firstCurved conditions below in
713+
# my generated test data.
714+
firstCurved = firstInputSegment.segmentType == reversedFirstInputSegment.segmentType == "curve"
715+
lastCurved = lastInputSegment.segmentType == reversedLastInputSegment.segmentType == "curve"
716+
if firstCurved or lastCurved:
701717
if firstInputSegment == lastInputSegment or reversedFirstInputSegment == reversedLastInputSegment:
702718
mergeFirstSegments = True
703-
# elif len(firstInputSegment.points) > 1 and len(lastInputSegment.points) > 1:
704-
elif fp == lastInputSegment.scaledPreviousOnCurve:
705-
mergeFirstSegments = True
706-
elif lp == firstInputSegment.scaledPreviousOnCurve:
707-
mergeFirstSegments = True
708-
elif fp == reversedLastInputSegment.scaledPreviousOnCurve:
709-
mergeFirstSegments = True
710-
elif lp == reversedFirstInputSegment.scaledPreviousOnCurve:
711-
mergeFirstSegments = True
719+
elif fp == lastInputSegment.scaledPreviousOnCurve and lastCurved:
720+
if lp == lastInputSegment.flat[-1]:
721+
pass
722+
else:
723+
duplicatePoint = 1
724+
elif lp == firstInputSegment.scaledPreviousOnCurve and firstCurved:
725+
if fp == firstInputSegment.flat[-1]:
726+
pass
727+
else:
728+
duplicatePoint = -1
729+
elif fp == reversedLastInputSegment.scaledPreviousOnCurve and lastCurved:
730+
if lp == reversedLastInputSegment.flat[-1]:
731+
pass
732+
else:
733+
duplicatePoint = 1
734+
elif lp == reversedFirstInputSegment.scaledPreviousOnCurve and firstCurved:
735+
if fp == reversedFirstInputSegment.flat[-1]:
736+
pass
737+
else:
738+
duplicatePoint = -1
712739
elif not hasOncurvePoints and _distance(fp, lp):
713740
# Merge last segment with first segment if the distance between the last point and the first
714741
# point is less than the step distance between the last two points. _approximateSegmentLength
@@ -726,6 +753,10 @@ def reCurveSubSegments(self, inputContours):
726753
segmentedFlatPoints[0] = segmentedFlatPoints[-1] + segmentedFlatPoints[0]
727754
segmentedFlatPoints.pop(-1)
728755
mergeFirstSegments = False
756+
elif duplicatePoint == 1:
757+
segmentedFlatPoints[-1].append(segmentedFlatPoints[0][0])
758+
elif duplicatePoint == -1:
759+
segmentedFlatPoints[0].insert(0, segmentedFlatPoints[-1][-1])
729760
convertedSegments = []
730761
previousIntersectionPoint = None
731762
if segmentedFlatPoints[-1][-1] in intersectionPoints:

0 commit comments

Comments
 (0)