|
13 | 13 | """ |
14 | 14 |
|
15 | 15 |
|
16 | | -class BooleanOperationManager(object): |
| 16 | +def _performOperation(operation, subjectContours, clipContours, outPen): |
| 17 | + # prep the contours |
| 18 | + subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1] |
| 19 | + clipInputContours = [InputContour(contour) for contour in clipContours if contour and len(contour) > 1] |
| 20 | + inputContours = subjectInputContours + clipInputContours |
17 | 21 |
|
18 | | - def _performOperation(self, operation, subjectContours, clipContours, outPen): |
19 | | - # prep the contours |
20 | | - subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1] |
21 | | - clipInputContours = [InputContour(contour) for contour in clipContours if contour and len(contour) > 1] |
22 | | - inputContours = subjectInputContours + clipInputContours |
23 | | - |
24 | | - resultContours = pyClipper.clipExecute([subjectInputContour.originalFlat for subjectInputContour in subjectInputContours], |
25 | | - [clipInputContour.originalFlat for clipInputContour in clipInputContours], |
26 | | - operation, subjectFillType="noneZero", clipFillType="noneZero") |
27 | | - # convert to output contours |
28 | | - outputContours = [OutputContour(contour) for contour in resultContours] |
29 | | - # re-curve entire contour |
30 | | - for inputContour in inputContours: |
31 | | - for outputContour in outputContours: |
32 | | - if outputContour.final: |
33 | | - continue |
34 | | - if outputContour.reCurveFromEntireInputContour(inputContour): |
35 | | - # the input is expired if a match was made, |
36 | | - # so stop passing it to the outputs |
37 | | - break |
38 | | - # re-curve segments |
39 | | - for inputContour in inputContours: |
40 | | - # skip contours that were comppletely used in the previous step |
41 | | - if inputContour.used: |
42 | | - continue |
43 | | - # XXX this could be expensive if an input becomes completely used |
44 | | - # it doesn't stop from being passed to the output |
45 | | - for outputContour in outputContours: |
46 | | - outputContour.reCurveFromInputContourSegments(inputContour) |
47 | | - # curve fit |
| 22 | + resultContours = pyClipper.clipExecute([subjectInputContour.originalFlat for subjectInputContour in subjectInputContours], |
| 23 | + [clipInputContour.originalFlat for clipInputContour in clipInputContours], |
| 24 | + operation, subjectFillType="noneZero", clipFillType="noneZero") |
| 25 | + # convert to output contours |
| 26 | + outputContours = [OutputContour(contour) for contour in resultContours] |
| 27 | + # re-curve entire contour |
| 28 | + for inputContour in inputContours: |
48 | 29 | for outputContour in outputContours: |
49 | | - outputContour.reCurveSubSegments(inputContours) |
50 | | - # output the results |
| 30 | + if outputContour.final: |
| 31 | + continue |
| 32 | + if outputContour.reCurveFromEntireInputContour(inputContour): |
| 33 | + # the input is expired if a match was made, |
| 34 | + # so stop passing it to the outputs |
| 35 | + break |
| 36 | + # re-curve segments |
| 37 | + for inputContour in inputContours: |
| 38 | + # skip contours that were comppletely used in the previous step |
| 39 | + if inputContour.used: |
| 40 | + continue |
| 41 | + # XXX this could be expensive if an input becomes completely used |
| 42 | + # it doesn't stop from being passed to the output |
51 | 43 | for outputContour in outputContours: |
52 | | - outputContour.drawPoints(outPen) |
53 | | - return outputContours |
| 44 | + outputContour.reCurveFromInputContourSegments(inputContour) |
| 45 | + # curve fit |
| 46 | + for outputContour in outputContours: |
| 47 | + outputContour.reCurveSubSegments(inputContours) |
| 48 | + # output the results |
| 49 | + for outputContour in outputContours: |
| 50 | + outputContour.drawPoints(outPen) |
| 51 | + return outputContours |
| 52 | + |
| 53 | + |
| 54 | +class BooleanOperationManager(object): |
54 | 55 |
|
55 | | - def union(self, contours, outPen): |
56 | | - return self._performOperation("union", contours, [], outPen) |
| 56 | + @staticmethod |
| 57 | + def union(contours, outPen): |
| 58 | + return _performOperation("union", contours, [], outPen) |
57 | 59 |
|
58 | | - def difference(self, subjectContours, clipContours, outPen): |
59 | | - return self._performOperation("difference", subjectContours, clipContours, outPen) |
| 60 | + @staticmethod |
| 61 | + def difference(subjectContours, clipContours, outPen): |
| 62 | + return _performOperation("difference", subjectContours, clipContours, outPen) |
60 | 63 |
|
61 | | - def intersection(self, subjectContours, clipContours, outPen): |
62 | | - return self._performOperation("intersection", subjectContours, clipContours, outPen) |
| 64 | + @staticmethod |
| 65 | + def intersection(subjectContours, clipContours, outPen): |
| 66 | + return _performOperation("intersection", subjectContours, clipContours, outPen) |
63 | 67 |
|
64 | | - def xor(self, subjectContours, clipContours, outPen): |
65 | | - return self._performOperation("xor", subjectContours, clipContours, outPen) |
| 68 | + @staticmethod |
| 69 | + def xor(subjectContours, clipContours, outPen): |
| 70 | + return _performOperation("xor", subjectContours, clipContours, outPen) |
66 | 71 |
|
67 | | - def getIntersections(self, contours): |
| 72 | + @staticmethod |
| 73 | + def getIntersections(contours): |
68 | 74 | from flatten import _scalePoints, inverseClipperScale |
69 | 75 | # prep the contours |
70 | 76 | inputContours = [InputContour(contour) for contour in contours if contour and len(contour) > 1] |
|
0 commit comments