fix several bugs in contour scanner and trimmer extension
This commit is contained in:
parent
b347187ff9
commit
7f5069387d
@ -22,7 +22,7 @@ Extension for InkScape 1.0+
|
|||||||
- 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()
|
||||||
- maybe option: break apart while keeping relative/absolute commands (more complex and not sure if we have a great advantage having this)
|
- maybe option: break apart while keeping relative/absolute commands (more complex and not sure if we have a great advantage having this)
|
||||||
|
- if calculation of trim lines fails (bentley ottmann) we could try to sort out the lines where slope is nearly identical and then we try again
|
||||||
|
|
||||||
- important to notice
|
- important to notice
|
||||||
- this algorithm might be really slow. Reduce flattening quality to speed up
|
- this algorithm might be really slow. Reduce flattening quality to speed up
|
||||||
@ -51,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: 11.06.2021
|
Last patch: 22.06.2021
|
||||||
License: GNU GPL v3
|
License: GNU GPL v3
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -73,8 +73,9 @@ if speedups.available:
|
|||||||
speedups.enable()
|
speedups.enable()
|
||||||
|
|
||||||
|
|
||||||
idPrefix = "subsplit"
|
idPrefixSubSplit = "subsplit"
|
||||||
intersectedVerb = "-intersected-"
|
idPrefixTrimming = "shapely"
|
||||||
|
intersectedVerb = "intersected"
|
||||||
|
|
||||||
class ContourScannerAndTrimmer(inkex.EffectExtension):
|
class ContourScannerAndTrimmer(inkex.EffectExtension):
|
||||||
|
|
||||||
@ -252,10 +253,10 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
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(ls, globalIntersectionPoints, self.options.snap_tolerance)
|
linesWithSnappedIntersectionPoints = snap(ls, globalIntersectionPoints, self.options.snap_tolerance)
|
||||||
trimGroupId = 'shapely-' + subSplitLineArray[subSplitIndex].attrib['id'].split("_")[0] #split at "_" (_ from subSplitId)
|
trimGroupParentId = subSplitLineArray[subSplitIndex].attrib['originalPathId']
|
||||||
trimGroupParentId = subSplitLineArray[subSplitIndex].attrib['id'].split(idPrefix+"-")[1].split("_")[0]
|
trimGroupId = '{}-{}-{}'.format(idPrefixTrimming, idPrefixSubSplit, trimGroupParentId)
|
||||||
trimGroupParent = self.svg.getElementById(trimGroupParentId)
|
trimGroupParent = self.svg.getElementById(trimGroupParentId)
|
||||||
trimGroupParentTransform = trimGroupParent.composed_transform()
|
#trimGroupParentTransform = trimGroupParent.composed_transform()
|
||||||
trimGroup = self.find_group(trimGroupId)
|
trimGroup = self.find_group(trimGroupId)
|
||||||
if trimGroup is None:
|
if trimGroup is None:
|
||||||
trimGroup = trimGroupParent.getparent().add(inkex.Group(id=trimGroupId))
|
trimGroup = trimGroupParent.getparent().add(inkex.Group(id=trimGroupId))
|
||||||
@ -273,19 +274,19 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
trimLineId = "{}-{}".format(trimGroupId, subSplitIndex)
|
trimLineId = "{}-{}".format(trimGroupId, subSplitIndex)
|
||||||
splitAt.append(trimGroupId)
|
splitAt.append(trimGroupId)
|
||||||
if splitAt.count(trimGroupId) > 1: #we detected a lines with intersection on
|
if splitAt.count(trimGroupId) > 1: #we detected a lines with intersection on
|
||||||
trimLineId = trimLineId + self.svg.get_unique_id(intersectedVerb)
|
trimLineId = "{}-{}".format(trimLineId, self.svg.get_unique_id(intersectedVerb + "-"))
|
||||||
'''
|
'''
|
||||||
so the previous lines was an intersection lines too. so we change the id to include the intersected verb
|
so the previous lines was an intersection lines too. so we change the id to include the intersected verb
|
||||||
(left side and right side of cut) - note: updating element
|
(left side and right side of cut) - note: updating element
|
||||||
id sometimes seems not to work if the id was used before in Inkscape
|
id sometimes seems not to work if the id was used before in Inkscape
|
||||||
'''
|
'''
|
||||||
prevLine.attrib['id'] = trimGroupId + "-" + str(subSplitIndex) + self.svg.get_unique_id(intersectedVerb)
|
prevLine.attrib['id'] = "{}-{}".format(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)
|
||||||
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:
|
||||||
trimLine.path = trimLine.path.transform(-trimGroupParentTransform)
|
# trimLine.path = trimLine.path.transform(-trimGroupParentTransform)
|
||||||
if self.options.apply_style_to_trimmed is False:
|
if self.options.apply_style_to_trimmed is False:
|
||||||
trimLine.style = trimLineStyle
|
trimLine.style = trimLineStyle
|
||||||
else:
|
else:
|
||||||
@ -301,15 +302,16 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
allTrimGroups = allTrimGroups[::-1]
|
allTrimGroups = allTrimGroups[::-1]
|
||||||
for trimGroup in allTrimGroups:
|
for trimGroup in allTrimGroups:
|
||||||
for element in trimGroup:
|
for element in trimGroup:
|
||||||
if element.path not in totalTrimPaths:
|
path = element.path.transform(element.composed_transform())
|
||||||
totalTrimPaths.append(element.path)
|
if path not in totalTrimPaths:
|
||||||
|
totalTrimPaths.append(path)
|
||||||
else:
|
else:
|
||||||
if self.options.show_debug is True:
|
if self.options.show_debug is True:
|
||||||
self.msg("Deleting {}".format(element.get('id')))
|
self.msg("Deleting path {}".format(element.get('id')))
|
||||||
element.delete()
|
element.delete()
|
||||||
if len(trimGroup) == 0:
|
if len(trimGroup) == 0:
|
||||||
if self.options.show_debug is True:
|
if self.options.show_debug is True:
|
||||||
self.msg("Deleting {}".format(trimGroup.get('id')))
|
self.msg("Deleting group {}".format(trimGroup.get('id')))
|
||||||
trimGroup.delete()
|
trimGroup.delete()
|
||||||
|
|
||||||
|
|
||||||
@ -564,7 +566,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:
|
||||||
subSplitLineGroup = pathElement.getparent().add(inkex.Group(id="{}-{}".format(idPrefix, originalPathId)))
|
subSplitLineGroup = pathElement.getparent().add(inkex.Group(id="{}-{}".format(idPrefixSubSplit, originalPathId)))
|
||||||
|
|
||||||
#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
|
||||||
@ -601,7 +603,7 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
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.line_from_segments(segs, i, so.decimals)
|
x1, y1, x2, y2 = self.line_from_segments(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(idPrefixSubSplit, originalPathId, i)
|
||||||
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]]]
|
||||||
@ -721,8 +723,18 @@ class ContourScannerAndTrimmer(inkex.EffectExtension):
|
|||||||
allSubSplitLineStrings = []
|
allSubSplitLineStrings = []
|
||||||
for subSplitLine in subSplitLineArray:
|
for subSplitLine in subSplitLineArray:
|
||||||
csp = subSplitLine.path.to_arrays()
|
csp = subSplitLine.path.to_arrays()
|
||||||
allSubSplitLineStrings.append([(csp[0][1][0], csp[0][1][1]), (csp[1][1][0], csp[1][1][1])])
|
lineString = [(csp[0][1][0], csp[0][1][1]), (csp[1][1][0], csp[1][1][1])]
|
||||||
|
if so.remove_duplicates is True:
|
||||||
|
if lineString not in allSubSplitLineStrings:
|
||||||
|
allSubSplitLineStrings.append(lineString)
|
||||||
|
else:
|
||||||
|
if so.show_debug is True:
|
||||||
|
self.msg("line {} already in sub split line collection. Dropping ...".format(lineString))
|
||||||
|
else: #if false we append all segments without filtering duplicate ones
|
||||||
|
allSubSplitLineStrings.append(lineString)
|
||||||
|
|
||||||
|
# Very small step sizes over near-vertical lines can cause errors. We hide exceptions with try-catch, thus we disabled the debugging in poly_point_isect:
|
||||||
|
# by setting USE_DEBUG = False (True was default setting)
|
||||||
globalIntersectionPoints = MultiPoint(isect_segments(allSubSplitLineStrings, validate=True))
|
globalIntersectionPoints = MultiPoint(isect_segments(allSubSplitLineStrings, validate=True))
|
||||||
|
|
||||||
if so.show_debug is True:
|
if so.show_debug is True:
|
||||||
|
@ -26,7 +26,7 @@ __all__ = (
|
|||||||
# their end points form the intersection point.
|
# their end points form the intersection point.
|
||||||
USE_IGNORE_SEGMENT_ENDINGS = True
|
USE_IGNORE_SEGMENT_ENDINGS = True
|
||||||
|
|
||||||
USE_DEBUG = True
|
USE_DEBUG = False
|
||||||
|
|
||||||
USE_VERBOSE = False
|
USE_VERBOSE = False
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user