Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Lib/booleanOperations/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
from __future__ import print_function, division, absolute_import
from .booleanOperationManager import BooleanOperationManager

__version__ = "0.2"
__version__ = "0.3"

# export BooleanOperationManager static methods
union = BooleanOperationManager.union
difference = BooleanOperationManager.difference
intersection = BooleanOperationManager.intersection
xor = BooleanOperationManager.xor
getIntersections = BooleanOperationManager.getIntersections
94 changes: 50 additions & 44 deletions Lib/booleanOperations/booleanOperationManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,58 +13,64 @@
"""


class BooleanOperationManager(object):
def _performOperation(operation, subjectContours, clipContours, outPen):
# prep the contours
subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]
clipInputContours = [InputContour(contour) for contour in clipContours if contour and len(contour) > 1]
inputContours = subjectInputContours + clipInputContours

def _performOperation(self, operation, subjectContours, clipContours, outPen):
# prep the contours
subjectInputContours = [InputContour(contour) for contour in subjectContours if contour and len(contour) > 1]
clipInputContours = [InputContour(contour) for contour in clipContours if contour and len(contour) > 1]
inputContours = subjectInputContours + clipInputContours

resultContours = pyClipper.clipExecute([subjectInputContour.originalFlat for subjectInputContour in subjectInputContours],
[clipInputContour.originalFlat for clipInputContour in clipInputContours],
operation, subjectFillType="noneZero", clipFillType="noneZero")
# convert to output contours
outputContours = [OutputContour(contour) for contour in resultContours]
# re-curve entire contour
for inputContour in inputContours:
for outputContour in outputContours:
if outputContour.final:
continue
if outputContour.reCurveFromEntireInputContour(inputContour):
# the input is expired if a match was made,
# so stop passing it to the outputs
break
# re-curve segments
for inputContour in inputContours:
# skip contours that were comppletely used in the previous step
if inputContour.used:
continue
# XXX this could be expensive if an input becomes completely used
# it doesn't stop from being passed to the output
for outputContour in outputContours:
outputContour.reCurveFromInputContourSegments(inputContour)
# curve fit
resultContours = pyClipper.clipExecute([subjectInputContour.originalFlat for subjectInputContour in subjectInputContours],
[clipInputContour.originalFlat for clipInputContour in clipInputContours],
operation, subjectFillType="noneZero", clipFillType="noneZero")
# convert to output contours
outputContours = [OutputContour(contour) for contour in resultContours]
# re-curve entire contour
for inputContour in inputContours:
for outputContour in outputContours:
outputContour.reCurveSubSegments(inputContours)
# output the results
if outputContour.final:
continue
if outputContour.reCurveFromEntireInputContour(inputContour):
# the input is expired if a match was made,
# so stop passing it to the outputs
break
# re-curve segments
for inputContour in inputContours:
# skip contours that were comppletely used in the previous step
if inputContour.used:
continue
# XXX this could be expensive if an input becomes completely used
# it doesn't stop from being passed to the output
for outputContour in outputContours:
outputContour.drawPoints(outPen)
return outputContours
outputContour.reCurveFromInputContourSegments(inputContour)
# curve fit
for outputContour in outputContours:
outputContour.reCurveSubSegments(inputContours)
# output the results
for outputContour in outputContours:
outputContour.drawPoints(outPen)
return outputContours


class BooleanOperationManager(object):

def union(self, contours, outPen):
return self._performOperation("union", contours, [], outPen)
@staticmethod
def union(contours, outPen):
return _performOperation("union", contours, [], outPen)

def difference(self, subjectContours, clipContours, outPen):
return self._performOperation("difference", subjectContours, clipContours, outPen)
@staticmethod
def difference(subjectContours, clipContours, outPen):
return _performOperation("difference", subjectContours, clipContours, outPen)

def intersection(self, subjectContours, clipContours, outPen):
return self._performOperation("intersection", subjectContours, clipContours, outPen)
@staticmethod
def intersection(subjectContours, clipContours, outPen):
return _performOperation("intersection", subjectContours, clipContours, outPen)

def xor(self, subjectContours, clipContours, outPen):
return self._performOperation("xor", subjectContours, clipContours, outPen)
@staticmethod
def xor(subjectContours, clipContours, outPen):
return _performOperation("xor", subjectContours, clipContours, outPen)

def getIntersections(self, contours):
@staticmethod
def getIntersections(contours):
from flatten import _scalePoints, inverseClipperScale
# prep the contours
inputContours = [InputContour(contour) for contour in contours if contour and len(contour) > 1]
Expand Down