From cc30a8f9a406e148dd1d0183a38bcd436d4d45e4 Mon Sep 17 00:00:00 2001 From: Mario Voigt Date: Sat, 23 Oct 2021 22:42:22 +0200 Subject: [PATCH] updated laser check --- .../laser_check/laser_check.inx | 63 +- .../fablabchemnitz/laser_check/laser_check.py | 605 ++++++++++-------- 2 files changed, 395 insertions(+), 273 deletions(-) diff --git a/extensions/fablabchemnitz/laser_check/laser_check.inx b/extensions/fablabchemnitz/laser_check/laser_check.inx index f5ffadff..f8a1158d 100644 --- a/extensions/fablabchemnitz/laser_check/laser_check.inx +++ b/extensions/fablabchemnitz/laser_check/laser_check.inx @@ -2,8 +2,67 @@ Laser Check fablabchemnitz.de.laser_check - - + + + + + + + + + + false + 5.000 + false + false + false + false + false + false + false + + + + false + false + false + false + false + false + false + 1.000 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../000_about_fablabchemnitz.svg + + + all diff --git a/extensions/fablabchemnitz/laser_check/laser_check.py b/extensions/fablabchemnitz/laser_check/laser_check.py index a30b34df..53a48b29 100644 --- a/extensions/fablabchemnitz/laser_check/laser_check.py +++ b/extensions/fablabchemnitz/laser_check/laser_check.py @@ -12,11 +12,32 @@ class LaserCheck(inkex.EffectExtension): check for old styles which should be upgraded ''' - #def add_arguments(self, pars): - # pars.add_argument('-d', '--depth', type = int, default = 1, help = 'Convert nested group up to DEPTH layers deep') - + def add_arguments(self, pars): + pars.add_argument('--tab') + pars.add_argument('--checks', default="check_all") + pars.add_argument('--bbox', type=inkex.Boolean, default=False) + pars.add_argument('--bbox_offset', type=float, default=5.000) + pars.add_argument('--groups_and_layers', type=inkex.Boolean, default=False) + pars.add_argument('--clones', type=inkex.Boolean, default=False) + pars.add_argument('--clippaths', type=inkex.Boolean, default=False) + pars.add_argument('--images', type=inkex.Boolean, default=False) + pars.add_argument('--texts', type=inkex.Boolean, default=False) + pars.add_argument('--lowlevelstrokes', type=inkex.Boolean, default=False) + pars.add_argument('--stroke_colors', type=inkex.Boolean, default=False) + pars.add_argument('--stroke_widths', type=inkex.Boolean, default=False) + pars.add_argument('--stroke_opacities', type=inkex.Boolean, default=False) + pars.add_argument('--cosmestic_dashes', type=inkex.Boolean, default=False) + pars.add_argument('--invisible_shapes', type=inkex.Boolean, default=False) + pars.add_argument('--pointy_paths', type=inkex.Boolean, default=False) + pars.add_argument('--transformations', type=inkex.Boolean, default=False) + pars.add_argument('--short_paths', type=inkex.Boolean, default=False) + pars.add_argument('--short_paths_min', type=float, default=1.000) + pars.add_argument('--non_path_shapes', type=inkex.Boolean, default=False) + def effect(self): + so = self.options + def parseChildren(element): if element not in selected: selected.append(element) @@ -36,84 +57,12 @@ class LaserCheck(inkex.EffectExtension): selected.append(element) else: for element in self.svg.selected.values(): - parseChildren(element) - - + parseChildren(element) namedView = self.document.getroot().find(inkex.addNS('namedview', 'sodipodi')) doc_units = namedView.get(inkex.addNS('document-units', 'inkscape')) - pagecolor = namedView.get('pagecolor') + pagecolor = namedView.get('pagecolor') + inkex.utils.debug("---------- Default checks") inkex.utils.debug("Document units: {}".format(doc_units)) - - inkex.utils.debug("---------- Groups and layers") - groups = [] - layers = [] - for element in selected: - if element.tag == inkex.addNS('g','svg'): - if element.get('inkscape:groupmode') == 'layer': - layers.append(element) - else: - groups.append(element) - inkex.utils.debug("{} groups in total".format(len(groups))) - inkex.utils.debug("{} layers in total".format(len(layers))) - - #check for empty groups - for group in groups: - if len(group) == 0: - inkex.utils.debug("group id={} is empty".format(group.get('id'))) - - #check for empty layers - for layer in layers: - if len(layer) == 0: - inkex.utils.debug("layer id={} is empty".format(layer.get('id'))) - - inkex.utils.debug("---------- Clones (svg:use) - maybe unlink") - uses = [] - for element in selected: - if element.tag == inkex.addNS('use','svg'): - uses.append(element) - inkex.utils.debug("{} svg:use clones in total".format(len(uses))) - for use in uses: - inkex.utils.debug("clone id={}".format(use.get('id'))) - - inkex.utils.debug("---------- Clippings (svg:clipPath) - please replace with real cut paths") - clipPaths = [] - for element in selected: - if element.tag == inkex.addNS('clipPath','svg'): - clipPaths.append(element) - inkex.utils.debug("{} svg:clipPath in total".format(len(clipPaths))) - for clipPath in clipPaths: - inkex.utils.debug("clipPath id={}".format(clipPath.get('id'))) - - - inkex.utils.debug("---------- Images (svg:image) - maybe trace to svg") - images = [] - for element in selected: - if element.tag == inkex.addNS('image','svg'): - images.append(element) - inkex.utils.debug("{} svg:image in total".format(len(images))) - for image in images: - inkex.utils.debug("image id={}".format(image.get('id'))) - - inkex.utils.debug("---------- Low level strokes (svg:line/polyline/polygon) - maybe convert to path") - lowlevels = [] - for element in selected: - if element.tag in (inkex.addNS('line','svg'), inkex.addNS('polyline','svg'), inkex.addNS('polygon','svg')): - lowlevels.append(element) - inkex.utils.debug("{} low level strokes in total".format(len(lowlevels))) - for lowlevel in lowlevels: - inkex.utils.debug("stroke id={}".format(lowlevel.get('id'))) - - inkex.utils.debug("---------- Texts (should be converted to paths)") - texts = [] - for element in selected: - if element.tag == inkex.addNS('text','svg'): - texts.append(element) - inkex.utils.debug("{} svg:text in total".format(len(texts))) - for text in texts: - inkex.utils.debug("text id={}".format(text.get('id'))) - - - inkex.utils.debug("---------- Shapes / Non-shapes") nonShapes = [] shapes = [] for element in selected: @@ -125,202 +74,316 @@ class LaserCheck(inkex.EffectExtension): inkex.utils.debug("{} non-shape elements in total".format(len(nonShapes))) for nonShape in nonShapes: inkex.utils.debug("non-shape id={}".format(nonShape.get('id'))) + + if so.checks == "check_all" or so.groups_and_layers is True: + inkex.utils.debug("\n---------- Groups and layers") + groups = [] + layers = [] + for element in selected: + if element.tag == inkex.addNS('g','svg'): + if element.get('inkscape:groupmode') == 'layer': + layers.append(element) + else: + groups.append(element) + inkex.utils.debug("{} groups in total".format(len(groups))) + inkex.utils.debug("{} layers in total".format(len(layers))) + + #check for empty groups + for group in groups: + if len(group) == 0: + inkex.utils.debug("id={} is empty group".format(group.get('id'))) + + #check for empty layers + for layer in layers: + if len(layer) == 0: + inkex.utils.debug("id={} is empty layer".format(layer.get('id'))) - inkex.utils.debug("---------- Stroke colors") - strokeColors = [] - for element in shapes: - style = element.get('style') - if style is not None: - stroke = re.search('(;|^)stroke:(.*?)(;|$)', style) - if stroke is not None: - strokeColor = stroke[0].split("stroke:")[1].split(";")[0] - if strokeColor not in strokeColors: - strokeColors.append(strokeColor) - inkex.utils.debug("{} different stroke colors in total".format(len(strokeColors))) - for strokeColor in strokeColors: - inkex.utils.debug("stroke color {}".format(strokeColor)) - - inkex.utils.debug("---------- Borders around all elements - minimum offset 5mm from each side") - bbox = inkex.BoundingBox() - for element in self.document.getroot().iter(tag=etree.Element): - if element != self.document.getroot() and isinstance(element, inkex.ShapeElement) and element.tag != inkex.addNS('use','svg') and element.get('inkscape:groupmode') != 'layer': #bbox fails for svg:use elements and layers - transform = inkex.Transform() - parent = element.getparent() - if parent is not None and isinstance(parent, inkex.ShapeElement): - transform = parent.composed_transform() - try: - bbox += element.bounding_box(transform) - except Exception: - transform = element.composed_transform() - x1, y1 = transform.apply_to_point([0, 0]) - x2, y2 = transform.apply_to_point([1, 1]) - bbox += inkex.BoundingBox((x1, x2), (y1, y2)) - - if abs(bbox.width) == math.inf or abs(bbox.height) == math.inf: - inkex.utils.debug("bounding box could not be calculated") - else: - inkex.utils.debug("bounding box is {}".format(bbox)) - page_width = self.svg.unittouu(self.document.getroot().attrib['width']) - width_height = self.svg.unittouu(self.document.getroot().attrib['height']) - fmm = self.svg.unittouu("5mm") - if bbox.left > fmm: - self.msg("left ok") - else: - self.msg("left fail") - - if bbox.top > fmm: - self.msg("top ok") - else: - self.msg("top fail") - - if bbox.right + fmm <= page_width: - self.msg("right ok") - else: - self.msg("right fail") - - if bbox.bottom + fmm <= width_height: - self.msg("bottom ok") - else: - self.msg("bottom fail") - - inkex.utils.debug("---------- Stroke widths") - strokeWidths = [] - for element in shapes: - style = element.get('style') - if style is not None: - stroke_width = re.search('stroke-width:(.*?)(;|$)', style) - if stroke_width is not None: - strokeWidth = self.svg.unittouu(stroke_width[0].split("stroke-width:")[1].split(";")[0]) - if strokeWidth not in strokeWidths: - strokeWidths.append(strokeWidth) - inkex.utils.debug("{} different stroke widths in total".format(len(strokeWidths))) - for strokeWidth in strokeWidths: - inkex.utils.debug("stroke width {}".format(strokeWidth)) - - inkex.utils.debug("---------- Cosmetic dashes - should be converted to paths") - strokeDasharrays = [] - for element in shapes: - style = element.get('style') - if style is not None: - stroke_dasharray = re.search('stroke-dasharray:(.*?)(;|$)', style) - if stroke_dasharray is not None: - strokeDasharray = stroke_dasharray[0].split("stroke-dasharray:")[1].split(";")[0] - if strokeDasharray not in strokeDasharrays: - strokeDasharrays.append(strokeDasharray) - inkex.utils.debug("{} different stroke dash arrays in total".format(len(strokeDasharrays))) - for strokeDasharray in strokeDasharrays: - inkex.utils.debug("stroke dash array {}".format(strokeDasharray)) - - inkex.utils.debug("---------- Invisible shapes") - invisibles = [] - for element in shapes: - if element.tag not in (inkex.addNS('tspan','svg')): - style = element.get('style') - if style is not None: - stroke = re.search('stroke:(.*?)(;|$)', style) #filter white on white (we guess the background color of the document is white too but we do not check) - if stroke is None: - strokeVis = 0 - elif stroke[0].split("stroke:")[1].split(";")[0] == 'none': - strokeVis = 0 - elif stroke[0].split("stroke:")[1].split(";")[0] in ('#ffffff', 'white', 'rgb(255,255,255)'): - strokeVis = 0 - else: - strokeVis = 1 - - stroke_width = re.search('stroke-width:(.*?)(;|$)', style) - if stroke_width is None: - widthVis = 0 - elif self.svg.unittouu(stroke_width[0].split("stroke-width:")[1].split(";")[0]) < 0.005: #really thin (0,005pc = 0,080px) - widthVis = 0 - else: - widthVis = 1 - - stroke_opacity = re.search('stroke-opacity:(.*?)(;|$)', style) - if stroke_opacity is None: - strokeOpacityVis = 0 - elif float(stroke_opacity[0].split("stroke-opacity:")[1].split(";")[0]) < 0.05: #nearly invisible (<5% opacity) - strokeOpacityVis = 0 - else: - strokeOpacityVis = 1 - - if pagecolor == '#ffffff': - invisColors = [pagecolor, 'white', 'rgb(255,255,255)'] - else: - invisColors = [pagecolor] #we could add some parser to convert pagecolor to rgb/hsl/cmyk - fill = re.search('fill:(.*?)(;|$)', style) - if fill is None: - fillVis = 0 - elif fill[0].split("fill:")[1].split(";")[0] == 'none': - fillVis = 0 - elif fill[0].split("fill:")[1].split(";")[0] in invisColors: - fillVis = 0 - else: - fillVis = 1 - - fill_opacity = re.search('fill-opacity:(.*?)(;|$)', style) - if fill_opacity is None: - fillOpacityVis = 0 - elif float(fill_opacity[0].split("fill-opacity:")[1].split(";")[0]) < 0.05: #nearly invisible (<5% opacity) - fillOpacityVis = 0 - else: - fillOpacityVis = 1 - - #self.msg("strokeVis={}, widthVis={}, strokeOpacityVis={}, fillVis={}, fillOpacityVis={}".format(strokeVis, widthVis, strokeOpacityVis, fillVis, fillOpacityVis)) - if (strokeVis == 0 or widthVis == 0 or strokeOpacityVis == 0) and (fillVis == 0 or fillOpacityVis == 0): - if element not in invisibles: - invisibles.append(element) - inkex.utils.debug("{} invisible shapes in total".format(len(invisibles))) - for invisible in invisibles: - inkex.utils.debug("shape id={}".format(invisible.get('id'))) - - inkex.utils.debug("---------- Objects with stroke transparencies (< 1.0) - should be set to 1.0") - transparencies = [] - for element in shapes: - style = element.get('style') - if style is not None: - stroke_opacity = re.search('stroke-opacity:(.*?)(;|$)', style) - if stroke_opacity is not None: - if float(stroke_opacity[0].split("stroke-opacity:")[1].split(";")[0]) < 1.0: - if element not in transparencies: - transparencies.append(element) - inkex.utils.debug("{} stroke transparencies shapes in total".format(len(transparencies))) - for transparency in transparencies: - inkex.utils.debug("shape id={}".format(transparency.get('id'))) - - inkex.utils.debug("---------- Pointy paths - should be deleted") - pointyPaths = [] - for element in shapes: - if isinstance(element, inkex.PathElement): - p = element.path - commandsCoords = p.to_arrays() - if len(commandsCoords) == 1 or \ - (len(commandsCoords) == 2 and commandsCoords[0][1] == commandsCoords[1][1]) or \ - (len(commandsCoords) == 2 and commandsCoords[-1][0] == 'Z') or \ - (len(commandsCoords) == 3 and commandsCoords[0][1] == commandsCoords[1][1] and commandsCoords[2][1] == 'Z'): - pointyPaths.append(element) - inkex.utils.debug("{} pointy paths in total".format(len(pointyPaths))) - for pointyPath in pointyPaths: - inkex.utils.debug("path id={}".format(pointyPath.get('id'))) + + if so.checks == "check_all" or so.clones is True: + inkex.utils.debug("\n---------- Clones (svg:use) - maybe unlink") + uses = [] + for element in selected: + if element.tag == inkex.addNS('use','svg'): + uses.append(element) + inkex.utils.debug("{} svg:use clones in total".format(len(uses))) + for use in uses: + inkex.utils.debug("id={}".format(use.get('id'))) - inkex.utils.debug("---------- Transformations - should be applied to absolute") - transformations = [] - for element in shapes: - if element.get('transform') is not None: - transformations.append(element) - inkex.utils.debug("{} transformation in total".format(len(transformations))) - for transformation in transformations: - inkex.utils.debug("transformation in id={}".format(transformation.get('id'))) + + if so.checks == "check_all" or so.clippaths is True: + inkex.utils.debug("\n---------- Clippings (svg:clipPath) - please replace with real cut paths") + clipPaths = [] + for element in selected: + if element.tag == inkex.addNS('clipPath','svg'): + clipPaths.append(element) + inkex.utils.debug("{} svg:clipPath in total".format(len(clipPaths))) + for clipPath in clipPaths: + inkex.utils.debug("id={}".format(clipPath.get('id'))) + + + if so.checks == "check_all" or so.images is True: + inkex.utils.debug("\n---------- Images (svg:image) - maybe trace to svg") + images = [] + for element in selected: + if element.tag == inkex.addNS('image','svg'): + images.append(element) + inkex.utils.debug("{} svg:image in total".format(len(images))) + for image in images: + inkex.utils.debug("image id={}".format(image.get('id'))) + + + if so.checks == "check_all" or so.lowlevelstrokes is True: + inkex.utils.debug("\n---------- Low level strokes (svg:line/polyline/polygon) - maybe convert to path") + lowlevels = [] + for element in selected: + if element.tag in (inkex.addNS('line','svg'), inkex.addNS('polyline','svg'), inkex.addNS('polygon','svg')): + lowlevels.append(element) + inkex.utils.debug("{} low level strokes in total".format(len(lowlevels))) + for lowlevel in lowlevels: + inkex.utils.debug("id={}".format(lowlevel.get('id'))) + + + if so.checks == "check_all" or so.texts is True: + inkex.utils.debug("\n---------- Texts (should be converted to paths)") + texts = [] + for element in selected: + if element.tag == inkex.addNS('text','svg'): + texts.append(element) + inkex.utils.debug("{} svg:text in total".format(len(texts))) + for text in texts: + inkex.utils.debug("id={}".format(text.get('id'))) + + + if so.checks == "check_all" or so.stroke_colors is True: + inkex.utils.debug("\n---------- Stroke colors") + strokeColors = [] + for element in shapes: + style = element.get('style') + if style is not None: + stroke = re.search('(;|^)stroke:(.*?)(;|$)', style) + if stroke is not None: + strokeColor = stroke[0].split("stroke:")[1].split(";")[0] + if strokeColor not in strokeColors: + strokeColors.append(strokeColor) + inkex.utils.debug("{} different stroke colors in total".format(len(strokeColors))) + for strokeColor in strokeColors: + inkex.utils.debug("stroke color {}".format(strokeColor)) + + + if so.checks == "check_all" or so.bbox is True: + inkex.utils.debug("\n---------- Borders around all elements - minimum offset {} mm from each side".format(so.bbox_offset)) + bbox = inkex.BoundingBox() + for element in self.document.getroot().iter(tag=etree.Element): + if element != self.document.getroot() and isinstance(element, inkex.ShapeElement) and element.tag != inkex.addNS('use','svg') and element.get('inkscape:groupmode') != 'layer': #bbox fails for svg:use elements and layers + transform = inkex.Transform() + parent = element.getparent() + if parent is not None and isinstance(parent, inkex.ShapeElement): + transform = parent.composed_transform() + try: + bbox += element.bounding_box(transform) + except Exception: + transform = element.composed_transform() + x1, y1 = transform.apply_to_point([0, 0]) + x2, y2 = transform.apply_to_point([1, 1]) + bbox += inkex.BoundingBox((x1, x2), (y1, y2)) + + if abs(bbox.width) == math.inf or abs(bbox.height) == math.inf: + inkex.utils.debug("bounding box could not be calculated") + #else: + # inkex.utils.debug("bounding box is {}".format(bbox)) + page_width = self.svg.unittouu(self.document.getroot().attrib['width']) + width_height = self.svg.unittouu(self.document.getroot().attrib['height']) + fmm = self.svg.unittouu(str(so.bbox_offset) + "mm") + if bbox.left > fmm: + inkex.utils.debug("left border... ok") + else: + inkex.utils.debug("left border... fail") + + if bbox.top > fmm: + inkex.utils.debug("top border... ok") + else: + inkex.utils.debug("top border... fail") + + if bbox.right + fmm <= page_width: + inkex.utils.debug("right border... ok") + else: + inkex.utils.debug("right border... fail") + + if bbox.bottom + fmm <= width_height: + inkex.utils.debug("bottom border... ok") + else: + inkex.utils.debug("bottom border... fail") + + + if so.checks == "check_all" or so.stroke_widths is True: + inkex.utils.debug("\n---------- Stroke widths") + strokeWidths = [] + for element in shapes: + style = element.get('style') + if style is not None: + stroke_width = re.search('stroke-width:(.*?)(;|$)', style) + if stroke_width is not None: + strokeWidth = self.svg.unittouu(stroke_width[0].split("stroke-width:")[1].split(";")[0]) + if strokeWidth not in strokeWidths: + strokeWidths.append(strokeWidth) + inkex.utils.debug("{} different stroke widths in total".format(len(strokeWidths))) + for strokeWidth in strokeWidths: + inkex.utils.debug("stroke width {}".format(strokeWidth)) + + + if so.checks == "check_all" or so.cosmestic_dashes is True: + inkex.utils.debug("\n---------- Cosmetic dashes - should be converted to paths") + strokeDasharrays = [] + for element in shapes: + style = element.get('style') + if style is not None: + stroke_dasharray = re.search('stroke-dasharray:(.*?)(;|$)', style) + if stroke_dasharray is not None: + strokeDasharray = stroke_dasharray[0].split("stroke-dasharray:")[1].split(";")[0] + if strokeDasharray not in strokeDasharrays: + strokeDasharrays.append(strokeDasharray) + inkex.utils.debug("{} different stroke dash arrays in total".format(len(strokeDasharrays))) + for strokeDasharray in strokeDasharrays: + inkex.utils.debug("stroke dash array {}".format(strokeDasharray)) + + + if so.checks == "check_all" or so.invisible_shapes is True: + inkex.utils.debug("\n---------- Invisible shapes") + invisibles = [] + for element in shapes: + if element.tag not in (inkex.addNS('tspan','svg')): + style = element.get('style') + if style is not None: + stroke = re.search('stroke:(.*?)(;|$)', style) #filter white on white (we guess the background color of the document is white too but we do not check) + if stroke is None: + strokeVis = 0 + elif stroke[0].split("stroke:")[1].split(";")[0] == 'none': + strokeVis = 0 + elif stroke[0].split("stroke:")[1].split(";")[0] in ('#ffffff', 'white', 'rgb(255,255,255)'): + strokeVis = 0 + else: + strokeVis = 1 + + stroke_width = re.search('stroke-width:(.*?)(;|$)', style) + if stroke_width is None: + widthVis = 0 + elif self.svg.unittouu(stroke_width[0].split("stroke-width:")[1].split(";")[0]) < 0.005: #really thin (0,005pc = 0,080px) + widthVis = 0 + else: + widthVis = 1 + + stroke_opacity = re.search('stroke-opacity:(.*?)(;|$)', style) + if stroke_opacity is None: + strokeOpacityVis = 0 + elif float(stroke_opacity[0].split("stroke-opacity:")[1].split(";")[0]) < 0.05: #nearly invisible (<5% opacity) + strokeOpacityVis = 0 + else: + strokeOpacityVis = 1 + + if pagecolor == '#ffffff': + invisColors = [pagecolor, 'white', 'rgb(255,255,255)'] + else: + invisColors = [pagecolor] #we could add some parser to convert pagecolor to rgb/hsl/cmyk + fill = re.search('fill:(.*?)(;|$)', style) + if fill is None: + fillVis = 0 + elif fill[0].split("fill:")[1].split(";")[0] == 'none': + fillVis = 0 + elif fill[0].split("fill:")[1].split(";")[0] in invisColors: + fillVis = 0 + else: + fillVis = 1 + + fill_opacity = re.search('fill-opacity:(.*?)(;|$)', style) + if fill_opacity is None: + fillOpacityVis = 0 + elif float(fill_opacity[0].split("fill-opacity:")[1].split(";")[0]) < 0.05: #nearly invisible (<5% opacity) + fillOpacityVis = 0 + else: + fillOpacityVis = 1 + + #inkex.utils.debug("strokeVis={}, widthVis={}, strokeOpacityVis={}, fillVis={}, fillOpacityVis={}".format(strokeVis, widthVis, strokeOpacityVis, fillVis, fillOpacityVis)) + if (strokeVis == 0 or widthVis == 0 or strokeOpacityVis == 0) and (fillVis == 0 or fillOpacityVis == 0): + if element not in invisibles: + invisibles.append(element) + inkex.utils.debug("{} invisible shapes in total".format(len(invisibles))) + for invisible in invisibles: + inkex.utils.debug("id={}".format(invisible.get('id'))) + + + if so.checks == "check_all" or so.stroke_opacities is True: + inkex.utils.debug("\n---------- Objects with stroke transparencies < 1.0 - should be set to 1.0") + transparencies = [] + for element in shapes: + style = element.get('style') + if style is not None: + stroke_opacity = re.search('stroke-opacity:(.*?)(;|$)', style) + if stroke_opacity is not None: + if float(stroke_opacity[0].split("stroke-opacity:")[1].split(";")[0]) < 1.0: + if element not in transparencies: + transparencies.append(element) + inkex.utils.debug("{} objects with stroke transparencies < 1.0 in total".format(len(transparencies))) + for transparency in transparencies: + inkex.utils.debug("id={}".format(transparency.get('id'))) + - inkex.utils.debug("---------- Short paths (< 1mm)") - shortPaths = [] - for element in shapes: - if isinstance(element, inkex.PathElement): - slengths, stotal = csplength(element.path.transform(element.composed_transform()).to_superpath()) - if stotal < self.svg.unittouu("1mm"): - shortPaths.append(element) - inkex.utils.debug("{} short paths in total".format(len(shortPaths))) - for shortPath in shortPaths: - inkex.utils.debug("short path id={}".format(shortPath.get('id'))) + if so.checks == "check_all" or so.pointy_paths is True: + inkex.utils.debug("\n---------- Pointy paths - should be deleted") + pointyPaths = [] + for element in shapes: + if isinstance(element, inkex.PathElement): + p = element.path + commandsCoords = p.to_arrays() + if len(commandsCoords) == 1 or \ + (len(commandsCoords) == 2 and commandsCoords[0][1] == commandsCoords[1][1]) or \ + (len(commandsCoords) == 2 and commandsCoords[-1][0] == 'Z') or \ + (len(commandsCoords) == 3 and commandsCoords[0][1] == commandsCoords[1][1] and commandsCoords[2][1] == 'Z'): + pointyPaths.append(element) + inkex.utils.debug("{} pointy paths in total".format(len(pointyPaths))) + for pointyPath in pointyPaths: + inkex.utils.debug("id={}".format(pointyPath.get('id'))) + + + if so.checks == "check_all" or so.transformations is True: + inkex.utils.debug("\n---------- Transformations - should be applied to absolute") + transformations = [] + for element in shapes: + if element.get('transform') is not None: + transformations.append(element) + inkex.utils.debug("{} transformation in total".format(len(transformations))) + for transformation in transformations: + inkex.utils.debug("transformation in id={}".format(transformation.get('id'))) + + + if so.checks == "check_all" or so.short_paths is True: + inkex.utils.debug("\n---------- Short paths (< {} mm)".format(so.short_paths_min)) + shortPaths = [] + totalLength = 0 + totalDropLength = 0 + for element in shapes: + if isinstance(element, inkex.PathElement): + slengths, stotal = csplength(element.path.transform(element.composed_transform()).to_superpath()) + totalLength += stotal + if stotal < self.svg.unittouu(str(so.short_paths_min) + "mm"): + shortPaths.append(element) + totalDropLength += stotal + inkex.utils.debug("{} short paths in total".format(len(shortPaths))) + if totalLength > 0: + inkex.utils.debug("{:0.2f}% of total ({:0.2f} mm /{:0.2f} mm)".format(totalDropLength / totalLength, totalDropLength, totalLength)) + for shortPath in shortPaths: + inkex.utils.debug("id={}".format(shortPath.get('id'))) + + + if so.checks == "check_all" or so.non_path_shapes is True: + inkex.utils.debug("\n---------- Non-path shapes - should be converted to paths") + nonPathShapes = [] + for element in shapes: + if not isinstance(element, inkex.PathElement) and not isinstance(element, inkex.Group): + nonPathShapes.append(element) + inkex.utils.debug("{} non-path shapes in total".format(len(nonPathShapes))) + for nonPathShape in nonPathShapes: + inkex.utils.debug("id={}".format(nonPathShape.get('id'))) + if __name__ == '__main__': LaserCheck().run() \ No newline at end of file