refactored contour scanner
This commit is contained in:
parent
908a389eea
commit
f1c189919b
@ -37,7 +37,7 @@
|
|||||||
<param name="highlight_closed" type="bool" gui-text="closed paths">false</param>
|
<param name="highlight_closed" type="bool" gui-text="closed paths">false</param>
|
||||||
<param name="highlight_self_intersecting" type="bool" gui-text="self-intersecting paths" gui-description="Requires to draw sub split lines. Will override highlighting colors for open and closed paths (if those options are enabled)">false</param>
|
<param name="highlight_self_intersecting" type="bool" gui-text="self-intersecting paths" gui-description="Requires to draw sub split lines. Will override highlighting colors for open and closed paths (if those options are enabled)">false</param>
|
||||||
<param name="visualize_self_intersections" type="bool" gui-text="self-intersecting path points">false</param>
|
<param name="visualize_self_intersections" type="bool" gui-text="self-intersecting path points">false</param>
|
||||||
<param name="visualize_global_intersections" type="bool" gui-text="global intersection points" gui-description="Will also contain self-intersecting points!">false</param>
|
<param name="visualize_global_intersections" type="bool" gui-text="global intersection points" gui-description="Will also contain self-intersecting points! Global intersections will only show if 'Draw trimmed lines' is enabled!">false</param>
|
||||||
</vbox>
|
</vbox>
|
||||||
<separator/>
|
<separator/>
|
||||||
<vbox>
|
<vbox>
|
||||||
|
@ -18,7 +18,6 @@ Extension for InkScape 1.0+
|
|||||||
- duplicates in original selection
|
- duplicates in original selection
|
||||||
- duplicates in split bezier
|
- duplicates in split bezier
|
||||||
- ...
|
- ...
|
||||||
- refactor subSplitData stuff by some clean mapping/structure instead having a lot of useless arays
|
|
||||||
- maybe option: convert abs path to rel path
|
- maybe option: convert abs path to rel path
|
||||||
- maybe option: convert rel path to abs path
|
- maybe option: convert rel path to abs path
|
||||||
replacedelement.path = replacedelement.path.to_absolute().to_superpath().to_path()
|
replacedelement.path = replacedelement.path.to_absolute().to_superpath().to_path()
|
||||||
@ -52,7 +51,7 @@ Extension for InkScape 1.0+
|
|||||||
Author: Mario Voigt / FabLab Chemnitz
|
Author: Mario Voigt / FabLab Chemnitz
|
||||||
Mail: mario.voigt@stadtfabrikanten.org
|
Mail: mario.voigt@stadtfabrikanten.org
|
||||||
Date: 09.08.2020 (extension originally called "Contour Scanner")
|
Date: 09.08.2020 (extension originally called "Contour Scanner")
|
||||||
Last patch: 05.06.2021
|
Last patch: 11.06.2021
|
||||||
License: GNU GPL v3
|
License: GNU GPL v3
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -143,7 +142,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
|
|
||||||
if len(pathElements) == 0:
|
if len(pathElements) == 0:
|
||||||
self.msg('Selection appears to be empty or does not contain any valid svg:path nodes. Try to cast your objects to paths using CTRL + SHIFT + C or strokes to paths using CTRL + ALT + C')
|
self.msg('Selection appears to be empty or does not contain any valid svg:path nodes. Try to cast your objects to paths using CTRL + SHIFT + C or strokes to paths using CTRL + ALT + C')
|
||||||
return
|
exit(1)
|
||||||
|
|
||||||
if self.options.break_apart is True:
|
if self.options.break_apart is True:
|
||||||
breakApartElements = None
|
breakApartElements = None
|
||||||
@ -238,21 +237,24 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
globalIntersectionGroup.add(globalIntersectionPointCircle)
|
globalIntersectionGroup.add(globalIntersectionPointCircle)
|
||||||
|
|
||||||
|
|
||||||
def buildTrimLineGroups(self, allSubSplitData, subSplitIndex, globalIntersectionPoints,
|
def buildTrimLineGroups(self, subSplitLineArray, subSplitIndex, globalIntersectionPoints,
|
||||||
snap_tolerance, apply_style_to_trimmed):
|
snap_tolerance, apply_style_to_trimmed):
|
||||||
''' make a group containing trimmed lines'''
|
''' make a group containing trimmed lines'''
|
||||||
|
|
||||||
#Check if we should skip or process the path anyway
|
#Check if we should skip or process the path anyway
|
||||||
isClosed = allSubSplitData[5][subSplitIndex]
|
isClosed = subSplitLineArray[subSplitIndex].attrib['originalPathIsClosed']
|
||||||
if self.options.trimming_path_types == 'open_paths' and isClosed is True: return #skip this call
|
if self.options.trimming_path_types == 'open_paths' and isClosed == 'True': return #skip this call
|
||||||
elif self.options.trimming_path_types == 'closed_paths' and isClosed is False: return #skip this call
|
elif self.options.trimming_path_types == 'closed_paths' and isClosed == 'False': return #skip this call
|
||||||
elif self.options.trimming_path_types == 'both': pass
|
elif self.options.trimming_path_types == 'both': pass
|
||||||
|
|
||||||
|
csp = subSplitLineArray[subSplitIndex].path.to_arrays()
|
||||||
|
ls = LineString([(csp[0][1][0], csp[0][1][1]), (csp[1][1][0], csp[1][1][1])])
|
||||||
|
|
||||||
trimLineStyle = {'stroke': str(self.options.color_trimmed), 'fill': 'none', 'stroke-width': self.options.strokewidth}
|
trimLineStyle = {'stroke': str(self.options.color_trimmed), 'fill': 'none', 'stroke-width': self.options.strokewidth}
|
||||||
|
|
||||||
linesWithSnappedIntersectionPoints = snap(LineString(allSubSplitData[0][subSplitIndex]), globalIntersectionPoints, snap_tolerance)
|
linesWithSnappedIntersectionPoints = snap(ls, globalIntersectionPoints, snap_tolerance)
|
||||||
trimGroupId = 'shapely-' + allSubSplitData[1][subSplitIndex].split("_")[0] #spit at "_" (_ from subSplitId)
|
trimGroupId = 'shapely-' + subSplitLineArray[subSplitIndex].attrib['id'].split("_")[0] #split at "_" (_ from subSplitId)
|
||||||
trimGroupParentId = allSubSplitData[1][subSplitIndex].split(idPrefix+"-")[1].split("_")[0]
|
trimGroupParentId = subSplitLineArray[subSplitIndex].attrib['id'].split(idPrefix+"-")[1].split("_")[0]
|
||||||
trimGroupParent = self.svg.getElementById(trimGroupParentId)
|
trimGroupParent = self.svg.getElementById(trimGroupParentId)
|
||||||
trimGroupParentTransform = trimGroupParent.composed_transform()
|
trimGroupParentTransform = trimGroupParent.composed_transform()
|
||||||
trimGroup = self.findGroup(trimGroupId)
|
trimGroup = self.findGroup(trimGroupId)
|
||||||
@ -260,8 +262,8 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
trimGroup = trimGroupParent.getparent().add(inkex.Group(id=trimGroupId))
|
trimGroup = trimGroupParent.getparent().add(inkex.Group(id=trimGroupId))
|
||||||
|
|
||||||
#apply isBezier and original path id information to group (required for bezier splitting the original path at the end)
|
#apply isBezier and original path id information to group (required for bezier splitting the original path at the end)
|
||||||
trimGroup.attrib['isBezier'] = str(allSubSplitData[3][subSplitIndex])
|
trimGroup.attrib['originalPathIsBezier'] = subSplitLineArray[subSplitIndex].attrib['originalPathIsBezier']
|
||||||
trimGroup.attrib['originalId'] = allSubSplitData[4][subSplitIndex]
|
trimGroup.attrib['originalPathId'] = subSplitLineArray[subSplitIndex].attrib['originalPathId']
|
||||||
|
|
||||||
#split all lines against all other lines using the intersection points
|
#split all lines against all other lines using the intersection points
|
||||||
trimLines = split(linesWithSnappedIntersectionPoints, globalIntersectionPoints)
|
trimLines = split(linesWithSnappedIntersectionPoints, globalIntersectionPoints)
|
||||||
@ -281,9 +283,6 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
prevLine.attrib['id'] = trimGroupId + "-" + str(subSplitIndex) + self.svg.get_unique_id(intersectedVerb)
|
prevLine.attrib['id'] = trimGroupId + "-" + str(subSplitIndex) + self.svg.get_unique_id(intersectedVerb)
|
||||||
prevLine.attrib['intersected'] = 'True' #some dirty flag we need
|
prevLine.attrib['intersected'] = 'True' #some dirty flag we need
|
||||||
prevLine = trimLine = inkex.PathElement(id=trimLineId)
|
prevLine = trimLine = inkex.PathElement(id=trimLineId)
|
||||||
#if so.show_debug is True:
|
|
||||||
# self.msg(prevLine.attrib['id'])
|
|
||||||
# self.msg(trimLineId)
|
|
||||||
x, y = trimLines[j].coords.xy
|
x, y = trimLines[j].coords.xy
|
||||||
trimLine.path = [['M', [x[0],y[0]]], ['L', [x[1],y[1]]]]
|
trimLine.path = [['M', [x[0],y[0]]], ['L', [x[1],y[1]]]]
|
||||||
if trimGroupParentTransform is not None:
|
if trimGroupParentTransform is not None:
|
||||||
@ -291,7 +290,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
if apply_style_to_trimmed is False:
|
if apply_style_to_trimmed is False:
|
||||||
trimLine.style = trimLineStyle
|
trimLine.style = trimLineStyle
|
||||||
else:
|
else:
|
||||||
trimLine.style = allSubSplitData[2][subSplitIndex]
|
trimLine.style = subSplitLineArray[subSplitIndex].attrib['originalPathStyle']
|
||||||
trimGroup.add(trimLine)
|
trimGroup.add(trimLine)
|
||||||
return trimGroup
|
return trimGroup
|
||||||
|
|
||||||
@ -395,9 +394,9 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
self.msg("t parameter = {}".format(globalTParameter))
|
self.msg("t parameter = {}".format(globalTParameter))
|
||||||
chainLength = 0
|
chainLength = 0
|
||||||
if self.options.show_debug is True:
|
if self.options.show_debug is True:
|
||||||
self.msg("Trimming the original bezier path {} at global t parameters: {}".format(trimGroup.attrib['originalId'], globalTParameters))
|
self.msg("Trimming the original bezier path {} at global t parameters: {}".format(trimGroup.attrib['originalPathId'], globalTParameters))
|
||||||
for globalTParameter in globalTParameters:
|
for globalTParameter in globalTParameters:
|
||||||
csp = CubicSuperPath(self.svg.getElementById(trimGroup.attrib['originalId']))
|
csp = CubicSuperPath(self.svg.getElementById(trimGroup.attrib['originalPathId']))
|
||||||
'''
|
'''
|
||||||
Sadly, those calculated global t parameters are useless for splitting because we cannot split the complete curve at a t parameter
|
Sadly, those calculated global t parameters are useless for splitting because we cannot split the complete curve at a t parameter
|
||||||
Instead we only can split a bezier by getting to commands which build up a bezier path segment.
|
Instead we only can split a bezier by getting to commands which build up a bezier path segment.
|
||||||
@ -500,20 +499,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
#get all paths which are within selection or in document and generate sub split lines
|
#get all paths which are within selection or in document and generate sub split lines
|
||||||
pathElements = self.getPathElements()
|
pathElements = self.getPathElements()
|
||||||
|
|
||||||
allSubSplitLines = []
|
subSplitLineArray = []
|
||||||
allSubSplitIds = []
|
|
||||||
allSubSplitStyles = []
|
|
||||||
allSubSplitIsBezier = []
|
|
||||||
allSubSplitOriginalPathIds = []
|
|
||||||
allSubSplitIsClosed = []
|
|
||||||
|
|
||||||
allSubSplitData = [] #an array of sub split lines and it's belonging sub path id
|
|
||||||
allSubSplitData.append(allSubSplitLines) #column 0
|
|
||||||
allSubSplitData.append(allSubSplitIds) #column 1
|
|
||||||
allSubSplitData.append(allSubSplitStyles) #column 2
|
|
||||||
allSubSplitData.append(allSubSplitIsBezier) #column 3
|
|
||||||
allSubSplitData.append(allSubSplitOriginalPathIds) #column 4
|
|
||||||
allSubSplitData.append(allSubSplitIsClosed) #column 5
|
|
||||||
|
|
||||||
for pathElement in pathElements:
|
for pathElement in pathElements:
|
||||||
originalPathId = pathElement.attrib["id"]
|
originalPathId = pathElement.attrib["id"]
|
||||||
@ -579,7 +565,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
continue #skip this loop iteration
|
continue #skip this loop iteration
|
||||||
|
|
||||||
if so.draw_subsplit is True:
|
if so.draw_subsplit is True:
|
||||||
subSplitTrimLineGroup = pathElement.getparent().add(inkex.Group(id="{}-{}".format(idPrefix, pathElement.attrib["id"])))
|
subSplitLineGroup = pathElement.getparent().add(inkex.Group(id="{}-{}".format(idPrefix, pathElement.attrib["id"])))
|
||||||
|
|
||||||
#get all sub paths for the path of the element
|
#get all sub paths for the path of the element
|
||||||
subPaths, prev = [], 0
|
subPaths, prev = [], 0
|
||||||
@ -613,103 +599,78 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
|
|
||||||
#build polylines from segment data
|
#build polylines from segment data
|
||||||
subSplitLines = []
|
subSplitLines = []
|
||||||
subSplitIds = []
|
|
||||||
subSplitStyles = []
|
|
||||||
subSplitIsBezier = []
|
|
||||||
subSplitOriginalPathIds = []
|
|
||||||
subSplitIsClosed = []
|
|
||||||
for i in range(len(segs) - 1): #we could do the same routine to build up polylines using "for x, y in node.path.end_points". See "number nodes" extension
|
for i in range(len(segs) - 1): #we could do the same routine to build up polylines using "for x, y in node.path.end_points". See "number nodes" extension
|
||||||
x1, y1, x2, y2 = self.lineFromSegments(segs, i, so.decimals)
|
x1, y1, x2, y2 = self.lineFromSegments(segs, i, so.decimals)
|
||||||
#self.msg("(y1 = {},y2 = {},x1 = {},x2 = {})".format(x1, y1, x2, y2))
|
#self.msg("(y1 = {},y2 = {},x1 = {},x2 = {})".format(x1, y1, x2, y2))
|
||||||
subSplitId = "{}-{}_{}".format(idPrefix, originalPathId, i)
|
subSplitId = "{}-{}_{}".format(idPrefix, originalPathId, i)
|
||||||
if so.draw_subsplit is True:
|
|
||||||
line = inkex.PathElement(id=subSplitId)
|
line = inkex.PathElement(id=subSplitId)
|
||||||
#apply line path with composed negative transform from parent element
|
#apply line path with composed negative transform from parent element
|
||||||
line.path = [['M', [x1, y1]], ['L', [x2, y2]]]
|
line.path = [['M', [x1, y1]], ['L', [x2, y2]]]
|
||||||
if pathElement.getparent() != self.svg.root:
|
if pathElement.getparent() != self.svg.root and pathElement.getparent() != None:
|
||||||
line.path = line.path.transform(-pathElement.getparent().composed_transform())
|
line.path = line.path.transform(-pathElement.getparent().composed_transform())
|
||||||
line.style = basicSubSplitLineStyle
|
line.style = basicSubSplitLineStyle
|
||||||
line.attrib['isRelative'] = str(isRelative)
|
line.attrib['originalPathId'] = originalPathId
|
||||||
line.attrib['isAbsolute'] = str(isAbsolute)
|
line.attrib['originalPathIsRelative'] = str(isRelative)
|
||||||
line.attrib['isMixed'] = str(isMixed)
|
line.attrib['originalPathIsAbsolute'] = str(isAbsolute)
|
||||||
line.attrib['isBezier'] = str(isBezier)
|
line.attrib['originalPathIsMixed'] = str(isMixed)
|
||||||
line.attrib['isClosed'] = str(isClosed)
|
line.attrib['originalPathIsBezier'] = str(isBezier)
|
||||||
subSplitTrimLineGroup.add(line)
|
line.attrib['originalPathIsClosed'] = str(isClosed)
|
||||||
|
line.attrib['originalPathStyle'] = str(pathElement.style)
|
||||||
|
subSplitLineArray.append(line)
|
||||||
|
|
||||||
subSplitLines.append([(x1, y1), (x2, y2)])
|
if so.apply_style_to_subsplits is True:
|
||||||
subSplitIds.append(subSplitId)
|
if line.attrib['originalPathIsRelative'] == 'True':
|
||||||
subSplitStyles.append(pathElement.style)
|
|
||||||
subSplitIsBezier.append(isBezier) #some dirty flag we need
|
|
||||||
subSplitOriginalPathIds.append(originalPathId) #some dirty flag we need
|
|
||||||
subSplitIsClosed.append(isClosed) #some dirty flag we need
|
|
||||||
|
|
||||||
if so.draw_subsplit is True and so.apply_style_to_subsplits is True:
|
|
||||||
for subSplitLine in subSplitTrimLineGroup:
|
|
||||||
if subSplitLine.attrib['isRelative'] == 'True':
|
|
||||||
if so.highlight_relative is True:
|
if so.highlight_relative is True:
|
||||||
subSplitLine.style = relativePathStyle
|
line.style = relativePathStyle
|
||||||
|
|
||||||
if subSplitLine.attrib['isAbsolute'] == 'True':
|
if line.attrib['originalPathIsAbsolute'] == 'True':
|
||||||
if so.highlight_absolute is True:
|
if so.highlight_absolute is True:
|
||||||
subSplitLine.style = absolutePathStyle
|
line.style = absolutePathStyle
|
||||||
|
|
||||||
if subSplitLine.attrib['isMixed'] == 'True':
|
if line.attrib['originalPathIsMixed'] == 'True':
|
||||||
if so.highlight_mixed is True:
|
if so.highlight_mixed is True:
|
||||||
subSplitLine.style = mixedPathStyle
|
line.style = mixedPathStyle
|
||||||
|
|
||||||
if subSplitLine.attrib['isBezier'] == 'True':
|
if line.attrib['originalPathIsBezier'] == 'True':
|
||||||
if so.highlight_beziers is True:
|
if so.highlight_beziers is True:
|
||||||
subSplitLine.style = bezierPathStyle
|
line.style = bezierPathStyle
|
||||||
else:
|
else:
|
||||||
if so.highlight_polylines is True:
|
if so.highlight_polylines is True:
|
||||||
subSplitLine.style = polylinePathStyle
|
line.style = polylinePathStyle
|
||||||
|
|
||||||
if subSplitLine.attrib['isClosed'] == 'True':
|
if line.attrib['originalPathIsClosed'] == 'True':
|
||||||
#if subPathIsClosed is True:
|
|
||||||
if so.highlight_closed is True:
|
if so.highlight_closed is True:
|
||||||
subSplitLine.style = closedPathStyle
|
line.style = closedPathStyle
|
||||||
else:
|
else:
|
||||||
if so.highlight_opened is True:
|
if so.highlight_opened is True:
|
||||||
subSplitLine.style = openPathStyle
|
line.style = openPathStyle
|
||||||
|
|
||||||
|
if so.draw_subsplit is True:
|
||||||
|
subSplitLineGroup.add(line)
|
||||||
|
subSplitLines.append([(x1, y1), (x2, y2)])
|
||||||
|
|
||||||
#check for self intersections using Bentley-Ottmann algorithm.
|
#check for self intersections using Bentley-Ottmann algorithm.
|
||||||
|
isSelfIntersecting = False
|
||||||
selfIntersectionPoints = isect_segments(subSplitLines, validate=True)
|
selfIntersectionPoints = isect_segments(subSplitLines, validate=True)
|
||||||
if len(selfIntersectionPoints) > 0:
|
if len(selfIntersectionPoints) > 0:
|
||||||
|
isSelfIntersecting = True
|
||||||
if so.show_debug is True:
|
if so.show_debug is True:
|
||||||
self.msg("{} in {} intersects itself with {} intersections!".format(subSplitId, originalPathId, len(selfIntersectionPoints)))
|
self.msg("{} in {} intersects itself with {} intersections!".format(subSplitId, originalPathId, len(selfIntersectionPoints)))
|
||||||
if so.draw_subsplit is True:
|
if so.draw_subsplit is True:
|
||||||
if so.highlight_self_intersecting is True:
|
if so.highlight_self_intersecting is True:
|
||||||
for subSplitLine in subSplitTrimLineGroup:
|
for subSplitLine in subSplitLineGroup:
|
||||||
subSplitLine.style = selfIntersectingPathStyle #adjusts line color
|
subSplitLine.style = selfIntersectingPathStyle #adjusts line color
|
||||||
#delete cosmetic sub split lines if desired
|
#delete cosmetic sub split lines if desired
|
||||||
if so.remove_self_intersecting:
|
if so.remove_self_intersecting:
|
||||||
subSplitTrimLineGroup.delete()
|
subSplitLineGroup.delete()
|
||||||
if so.visualize_self_intersections is True: #draw points (circles)
|
if so.visualize_self_intersections is True: #draw points (circles)
|
||||||
self.visualize_self_intersections(pathElement, selfIntersectionPoints)
|
self.visualize_self_intersections(pathElement, selfIntersectionPoints)
|
||||||
|
|
||||||
#and also delete non-cosmetics
|
#delete self-intersecting sub split lines and orginal paths
|
||||||
if so.remove_self_intersecting:
|
if so.remove_self_intersecting:
|
||||||
#if we also want to avoid processing them for trimming
|
subSplitLineArray = subSplitLineArray[:len(subSplitLineArray) - len(segs) - 1] #remove all last added lines
|
||||||
subSplitLines = None
|
|
||||||
subSplitIds = None
|
|
||||||
subSplitStyles = None
|
|
||||||
subSplitIsBezier = None
|
|
||||||
subSplitOriginalPathIds = None
|
|
||||||
pathElement.delete() #and finally delete the orginal path
|
pathElement.delete() #and finally delete the orginal path
|
||||||
|
continue
|
||||||
#extend the complete collection
|
|
||||||
if subSplitLines != None and \
|
|
||||||
subSplitIds != None and \
|
|
||||||
subSplitStyles != None and \
|
|
||||||
subSplitIsBezier != None and \
|
|
||||||
allSubSplitOriginalPathIds != None and \
|
|
||||||
allSubSplitIsClosed != None:
|
|
||||||
allSubSplitStyles.extend(subSplitStyles)
|
|
||||||
allSubSplitLines.extend(subSplitLines)
|
|
||||||
allSubSplitIds.extend(subSplitIds)
|
|
||||||
allSubSplitIsBezier.extend(subSplitIsBezier)
|
|
||||||
allSubSplitOriginalPathIds.extend(subSplitOriginalPathIds)
|
|
||||||
allSubSplitIsClosed.extend(subSplitIsClosed)
|
|
||||||
|
|
||||||
#adjust the style of original paths if desired. Has influence to the finally trimmed lines style results too!
|
#adjust the style of original paths if desired. Has influence to the finally trimmed lines style results too!
|
||||||
if so.removefillsetstroke is True:
|
if so.removefillsetstroke is True:
|
||||||
@ -742,19 +703,29 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
if so.highlight_opened is True:
|
if so.highlight_opened is True:
|
||||||
pathElement.style = openPathStyle
|
pathElement.style = openPathStyle
|
||||||
|
|
||||||
|
if isSelfIntersecting is True:
|
||||||
|
if so.highlight_self_intersecting is True:
|
||||||
|
pathElement.style = selfIntersectingPathStyle
|
||||||
|
|
||||||
if so.draw_subsplit is True:
|
if so.draw_subsplit is True:
|
||||||
if subSplitTrimLineGroup is not None: #might get deleted before so we need to check this first
|
if subSplitLineGroup is not None: #might get deleted before so we need to check this first
|
||||||
subSplitTrimLineGroup = reversed(subSplitTrimLineGroup) #reverse the order to match the original path segment placing
|
subSplitLineGroup = reversed(subSplitLineGroup) #reverse the order to match the original path segment placing
|
||||||
|
|
||||||
if so.show_debug is True:
|
if so.show_debug is True:
|
||||||
self.msg("sub split line count: {}".format(len(allSubSplitLines)))
|
self.msg("sub split line count: {}".format(len(subSplitLineArray)))
|
||||||
|
|
||||||
'''
|
'''
|
||||||
now we intersect the sub split lines to find the global intersection points using Bentley-Ottmann algorithm (contains self-intersections too!)
|
now we intersect the sub split lines to find the global intersection points using Bentley-Ottmann algorithm (contains self-intersections too!)
|
||||||
'''
|
'''
|
||||||
if so.draw_trimmed is True:
|
if so.draw_trimmed is True:
|
||||||
try:
|
try:
|
||||||
globalIntersectionPoints = MultiPoint(isect_segments(allSubSplitData[0], validate=True))
|
allSubSplitLineStrings = []
|
||||||
|
for subSplitLine in subSplitLineArray:
|
||||||
|
csp = subSplitLine.path.to_arrays()
|
||||||
|
allSubSplitLineStrings.append([(csp[0][1][0], csp[0][1][1]), (csp[1][1][0], csp[1][1][1])])
|
||||||
|
|
||||||
|
globalIntersectionPoints = MultiPoint(isect_segments(allSubSplitLineStrings, validate=True))
|
||||||
|
|
||||||
if so.show_debug is True:
|
if so.show_debug is True:
|
||||||
self.msg("global intersection points count: {}".format(len(globalIntersectionPoints)))
|
self.msg("global intersection points count: {}".format(len(globalIntersectionPoints)))
|
||||||
if len(globalIntersectionPoints) > 0:
|
if len(globalIntersectionPoints) > 0:
|
||||||
@ -765,10 +736,9 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
now we trim the sub split lines at all calculated intersection points.
|
now we trim the sub split lines at all calculated intersection points.
|
||||||
We do this path by path to keep the logic between original paths, sub split lines and the final output
|
We do this path by path to keep the logic between original paths, sub split lines and the final output
|
||||||
'''
|
'''
|
||||||
|
|
||||||
allTrimGroups = [] #container to collect all trim groups for later on processing
|
allTrimGroups = [] #container to collect all trim groups for later on processing
|
||||||
for subSplitIndex in range(len(allSubSplitData[0])):
|
for subSplitIndex in range(len(subSplitLineArray)):
|
||||||
trimGroup = self.buildTrimLineGroups(allSubSplitData, subSplitIndex,
|
trimGroup = self.buildTrimLineGroups(subSplitLineArray, subSplitIndex,
|
||||||
globalIntersectionPoints, so.snap_tolerance, so.apply_style_to_trimmed)
|
globalIntersectionPoints, so.snap_tolerance, so.apply_style_to_trimmed)
|
||||||
if trimGroup is not None:
|
if trimGroup is not None:
|
||||||
if trimGroup not in allTrimGroups:
|
if trimGroup not in allTrimGroups:
|
||||||
|
Reference in New Issue
Block a user