def get_k(csp, c1, d):
                    c2 = [c1[0] - d, c1[1]]
                    alpha2_ = []

                    for n in range(self.num):
                        alpha1 = math.pi * 2 * (
                            n) / self.num * self.second_teeth
                        d_alpha1 = math.pi * 2 / self.num * self.second_teeth
                        csp_ = [[[p[:] for p in point] for point in subpath]
                                for subpath in csp]
                        transform = get_transform(c1, c2, alpha1, 0)
                        simpletransform.applyTransformToPath(transform, csp_)
                        # r2 = distance to second gear's center
                        [r2, i, j,
                         t] = csp_to_point_distance(csp_,
                                                    c2,
                                                    dist_bounds=[0, 1e100],
                                                    tolerance=.001)
                        r2 = math.sqrt(r2)

                        p = csp_at_t(csp_[i][j - 1], csp_[i][j], t)
                        r1 = math.sqrt((p[0] - c1[0])**2 + (p[1] - c1[1])**2)
                        # d_alpha2 = rotation speed factor
                        if r2 == 0: return 1e100, []
                        alpha2_.append(d_alpha1 * r1 / r2)
                    return math.pi * 2 * self.first_teeth / sum(
                        alpha2_), alpha2_
Example #2
0
    def effect(self):
        self.dxf_insert_code('999',
                             '"DXF R12 Output" (www.mydxf.blogspot.com)')
        self.dxf_add(r12_header)

        scale = 25.4 / 90.0
        h = self.unittouu(self.getDocumentHeight())

        path = '//svg:path'
        for node in self.document.getroot().xpath(path, namespaces=inkex.NSS):

            layer = node.getparent().get(inkex.addNS('label', 'inkscape'))
            if layer == None:
                layer = 'Layer 1'

            d = node.get('d')
            p = cubicsuperpath.parsePath(d)

            t = node.get('transform')
            if t != None:
                m = simpletransform.parseTransform(t)
                simpletransform.applyTransformToPath(m, p)

            m = [[scale, 0, 0], [0, -scale, h * scale]]
            simpletransform.applyTransformToPath(m, p)

            if re.search('drill$', layer, re.I) == None:
                #if layer == 'Brackets Drill':
                self.dxf_path_to_lines(layer, p)
            else:
                self.dxf_path_to_point(layer, p)

        self.dxf_add(r12_footer)
Example #3
0
   def plotPath(self, node, matTransform):
      """ Plot the path while applying the transformation defined by the matrix matTransform. """

      filledPath = (simplestyle.parseStyle(node.get("style")).get("fill", "none") != "none")

      # Plan: Turn this path into a cubicsuperpath (list of beziers)...
      d = node.get("d")
      if len(simplepath.parsePath(d)) == 0:
         return
      p = cubicsuperpath.parsePath(d)

      # ... and apply the transformation to each point.
      simpletransform.applyTransformToPath(matTransform, p)

      # p is now a list of lists of cubic beziers [cp1, cp2, endp]
      # where the start-point is the last point of the previous segment.
      # For some reason the inkscape extensions uses csp[1] as the coordinates of each point,
      # but that makes it seem like they are using control point 2 as line points.
      # Maybe that is a side-effect of the CSP subdivion process? TODO
      realPoints = []
      for sp in p:
         cspsubdiv.subdiv(sp, self.smoothness)
         for csp in sp:
            realPoints.append( (csp[1][0], csp[1][1]) )

      self.rawObjects.append( (filledPath, realPoints) )
Example #4
0
def point_generator(path, mat, flatness):

        rirCount = 0

        if len(simplepath.parsePath(path)) == 0:
                return
       
        simple_path = simplepath.parsePath(path)
        startX,startY = float(simple_path[0][1][0]), float(simple_path[0][1][1])
        command = simple_path[0][0][0]
        
        yield startX, startY, command

        p = cubicsuperpath.parsePath(path)
                
        if mat:
            simpletransform.applyTransformToPath(mat, p)

        commandPile = []

        for sp in p:
                cspsubdiv.subdiv( sp, flatness)
                for csp in sp:
                    ctrl_pt1 = csp[0]
                    ctrl_pt2 = csp[1]
                    end_pt = csp[2]
                    command = csp[-1]
                    commandPile.append(command)
                    
                    yield end_pt[0], end_pt[1], command
                    rirCount += 1
Example #5
0
def apply_transforms(path, node):
    transform = get_node_transform(node)

    # apply the combined transform to this node's path
    simpletransform.applyTransformToPath(transform, path)

    return path
Example #6
0
def path_to_segments(node, smoothness=0.1):
    '''
        Generator to convert a path node to an interator on
        segmented paths (bezier curves broken to approximated
        straights lines).
    '''
    mat = simpletransform.composeParents(node,
                                         [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
    d = node.get('d')

    if len(simplepath.parsePath(d)) == 0:
        return

    p = cubicsuperpath.parsePath(d)
    simpletransform.applyTransformToPath(mat, p)

    # p is now a list of lists of cubic beziers [ctrl p1, ctrl p2, endpoint]
    # where the start-point is the last point in the previous segment

    for sp in p:
        path = []
        subdivideCubicPath(sp, smoothness)
        for csp in sp:
            path.append([csp[1][0], csp[1][1]])
        yield path
    def effect(self):
        paths = []
        for id, node in self.selected.iteritems():
            if node.tag == '{http://www.w3.org/2000/svg}path':
                paths.append(node)
                if len(paths) == 2:
                    break
        else:
            sys.stderr.write('Need 2 paths selected\n')
            return

        pts = [cubicsuperpath.parsePath(paths[i].get('d')) for i in (0, 1)]

        for i in (0, 1):
            if 'transform' in paths[i].keys():
                trans = paths[i].get('transform')
                trans = simpletransform.parseTransform(trans)
                simpletransform.applyTransformToPath(trans, pts[i])

        verts = []
        for i in range(0, min(map(len, pts))):
            comp = []
            for j in range(0, min(len(pts[0][i]), len(pts[1][i]))):
                comp.append([pts[0][i][j][1][-2:], pts[1][i][j][1][-2:]])
            verts.append(comp)

        if self.options.mode.lower() == 'lines':
            line = []
            for comp in verts:
                for n, v in enumerate(comp):
                    line += [('M', v[0])]
                    line += [('L', v[1])]
            ele = inkex.etree.Element('{http://www.w3.org/2000/svg}path')
            paths[0].xpath('..')[0].append(ele)
            ele.set('d', simplepath.formatPath(line))
            ele.set(
                'style',
                'fill:none;stroke:#000000;stroke-opacity:1;stroke-width:1;')
        elif self.options.mode.lower() == 'polygons':
            g = inkex.etree.Element('{http://www.w3.org/2000/svg}g')
            g.set(
                'style',
                'fill:#000000;stroke:#000000;fill-opacity:0.3;stroke-width:2;stroke-opacity:0.6;'
            )
            paths[0].xpath('..')[0].append(g)
            for comp in verts:
                for n, v in enumerate(comp):
                    nn = n + 1
                    if nn == len(comp): nn = 0
                    line = []
                    line += [('M', comp[n][0])]
                    line += [('L', comp[n][1])]
                    line += [('L', comp[nn][1])]
                    line += [('L', comp[nn][0])]
                    line += [('L', comp[n][0])]
                    ele = inkex.etree.Element(
                        '{http://www.w3.org/2000/svg}path')
                    g.append(ele)
                    ele.set('d', simplepath.formatPath(line))
Example #8
0
    def effect(self):
        if len(self.options.ids) < 2:
            inkex.errormsg(_("This extension requires two selected paths. \nThe second path must be exactly four nodes long."))
            exit()

        #obj is selected second
        scale = self.unittouu('1px')    # convert to document units
        obj = self.selected[self.options.ids[0]]
        trafo = self.selected[self.options.ids[1]]
        if obj.get(inkex.addNS('type','sodipodi')):
            inkex.errormsg(_("The first selected object is of type '%s'.\nTry using the procedure Path->Object to Path." % obj.get(inkex.addNS('type','sodipodi'))))
            exit()
        if obj.tag == inkex.addNS('path','svg') or obj.tag == inkex.addNS('g','svg'):
            if trafo.tag == inkex.addNS('path','svg'):
                #distil trafo into four node points
                mat = simpletransform.composeParents(trafo, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
                trafo = cubicsuperpath.parsePath(trafo.get('d'))
                if len(trafo[0]) < 4:
                    inkex.errormsg(_("This extension requires that the second selected path be four nodes long."))
                    exit()
                simpletransform.applyTransformToPath(mat, trafo)
                trafo = [[Point(csp[1][0],csp[1][1]) for csp in subs] for subs in trafo][0][:4]

                #vectors pointing away from the trafo origin
                self.t1 = Segment(trafo[0],trafo[1])
                self.t2 = Segment(trafo[1],trafo[2])
                self.t3 = Segment(trafo[3],trafo[2])
                self.t4 = Segment(trafo[0],trafo[3])

                #query inkscape about the bounding box of obj
                self.q = {'x':0,'y':0,'width':0,'height':0}
                file = self.args[-1]
                id = self.options.ids[0]
                for query in self.q.keys():
                    if bsubprocess:
                        p = Popen('inkscape --query-%s --query-id=%s "%s"' % (query,id,file), shell=True, stdout=PIPE, stderr=PIPE)
                        rc = p.wait()
                        self.q[query] = scale*float(p.stdout.read())
                        err = p.stderr.read()
                    else:
                        f,err = os.popen3('inkscape --query-%s --query-id=%s "%s"' % (query,id,file))[1:]
                        self.q[query] = scale*float(f.read())
                        f.close()
                        err.close()

                if obj.tag == inkex.addNS("path",'svg'):
                    self.process_path(obj)
                if obj.tag == inkex.addNS("g",'svg'):
                    self.process_group(obj)
            else:
                if trafo.tag == inkex.addNS('g','svg'):
                    inkex.errormsg(_("The second selected object is a group, not a path.\nTry using the procedure Object->Ungroup."))
                else:
                    inkex.errormsg(_("The second selected object is not a path.\nTry using the procedure Path->Object to Path."))
                exit()
        else:
            inkex.errormsg(_("The first selected object is not a path.\nTry using the procedure Path->Object to Path."))
            exit()
Example #9
0
 def process_shape(self, node, mat):
     rgb = (0, 0, 0)  # stroke color
     fillcolor = None  # fill color
     stroke = 1  # pen width in printer pixels
     # Very NB : If the pen width is greater than 1 then the output will Not be a vector output !
     style = node.get('style')
     if style:
         style = simplestyle.parseStyle(style)
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none' and style[
                     'stroke'][0:3] != 'url':
                 rgb = simplestyle.parseColor(style['stroke'])
         if style.has_key('stroke-width'):
             stroke = self.unittouu(
                 style['stroke-width']) / self.unittouu('1px')
             stroke = int(stroke * self.scale)
         if style.has_key('fill'):
             if style['fill'] and style['fill'] != 'none' and style['fill'][
                     0:3] != 'url':
                 fill = simplestyle.parseColor(style['fill'])
                 fillcolor = fill[0] + 256 * fill[1] + 256 * 256 * fill[2]
     color = rgb[0] + 256 * rgb[1] + 256 * 256 * rgb[2]
     if node.tag == inkex.addNS('path', 'svg'):
         d = node.get('d')
         if not d:
             return
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('rect', 'svg'):
         x = float(node.get('x'))
         y = float(node.get('y'))
         width = float(node.get('width'))
         height = float(node.get('height'))
         p = [[[x, y], [x, y], [x, y]]]
         p.append([[x + width, y], [x + width, y], [x + width, y]])
         p.append([[x + width, y + height], [x + width, y + height],
                   [x + width, y + height]])
         p.append([[x, y + height], [x, y + height], [x, y + height]])
         p.append([[x, y], [x, y], [x, y]])
         p = [p]
     else:
         return
     trans = node.get('transform')
     if trans:
         mat = simpletransform.composeTransform(
             mat, simpletransform.parseTransform(trans))
     simpletransform.applyTransformToPath(mat, p)
     hPen = mygdi.CreatePen(0, stroke, color)
     mygdi.SelectObject(self.hDC, hPen)
     self.emit_path(p)
     if fillcolor is not None:
         brush = LOGBRUSH(0, fillcolor, 0)
         hBrush = mygdi.CreateBrushIndirect(addressof(brush))
         mygdi.SelectObject(self.hDC, hBrush)
         mygdi.BeginPath(self.hDC)
         self.emit_path(p)
         mygdi.EndPath(self.hDC)
         mygdi.FillPath(self.hDC)
     return
Example #10
0
    def recursiveFuseTransform(self, node, transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = composeTransform(transf, parseTransform(node.get("transform", None)))

        if 'transform' in node.attrib:
            del node.attrib['transform']

        if 'style' in node.attrib:
            style = node.attrib.get('style')
            style = simplestyle.parseStyle(style)
            update = False

            if 'stroke-width' in style:
                try:
                    stroke_width = self.unittouu(style.get('stroke-width').strip())
                    # pixelsnap ext assumes scaling is similar in x and y
                    # and uses the x scale...
                    # let's try to be a bit smarter
                    stroke_width *= math.sqrt(transf[0][0]**2 + transf[1][1]**2)
                    style['stroke-width'] = str(stroke_width)
                    update = True
                except AttributeError:
                    pass

            if update:
                style = simplestyle.formatStyle(style)
                node.attrib['style'] = style

        node = ApplyTransform.objectToPath(node)

        if 'd' in node.attrib:
            d = node.get('d')
            p = cubicsuperpath.parsePath(d)
            applyTransformToPath(transf, p)
            node.set('d', cubicsuperpath.formatPath(p))

        elif node.tag in [inkex.addNS('polygon', 'svg'),
                          inkex.addNS('polyline', 'svg')]:
            points = node.get('points')
            points = points.strip().split(' ')
            for k,p in enumerate(points):
                if ',' in p:
                    p = p.split(',')
                    p = [float(p[0]),float(p[1])]
                    applyTransformToPoint(transf, p)
                    p = [str(p[0]),str(p[1])]
                    p = ','.join(p)
                    points[k] = p
            points = ' '.join(points)
            node.set('points', points)

        elif node.tag in [inkex.addNS('rect', 'svg'),
                          inkex.addNS('text', 'svg'),
                          inkex.addNS('image', 'svg'),
                          inkex.addNS('use', 'svg')]:
            node.set('transform', formatTransform(transf))

        for child in node.getchildren():
            self.recursiveFuseTransform(child, transf)
Example #11
0
    def effect(self):

        # if self.options.mformat == '"presets"':
        #     self.setPreset()

        # njj: hack some options
        # get number of digits
        # prec = int(self.options.precision)
        prec = 2
        self.options.fontsize = 20
        self.options.unit = 'mm'
        self.options.scale = 1
        self.options.angle = 0
        self.options.offset = -6

        scale = self.unittouu('1px')  # convert to document units
        # self.options.offset *= scale
        factor = 1.0
        doc = self.document.getroot()
        if doc.get('viewBox'):
            (viewx, viewy, vieww,
             viewh) = re.sub(' +|, +|,', ' ',
                             doc.get('viewBox')).strip().split(' ', 4)
            factor = self.unittouu(doc.get('width')) / float(vieww)
            if self.unittouu(doc.get('height')) / float(viewh) < factor:
                factor = self.unittouu(doc.get('height')) / float(viewh)
            factor /= self.unittouu('1px')
            self.options.fontsize /= factor
        factor *= scale / self.unittouu('1' + self.options.unit)

        # Gather paths
        debug(dir(self))
        paths = self.document.findall('.//{0}'.format(nspath))
        # Act on paths
        for node in paths:
            mat = simpletransform.composeParents(
                node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
            p = cubicsuperpath.parsePath(node.get('d'))
            simpletransform.applyTransformToPath(mat, p)
            stotal = abs(measure.csparea(p) * factor * self.options.scale)
            self.group = inkex.etree.SubElement(node.getparent(),
                                                inkex.addNS('text', 'svg'))

            # Format the area as string
            resultstr = locale.format(
                "%(len)25." + str(prec) + "f", {
                    'len': round(stotal * factor * self.options.scale, prec)
                }).strip()
            # Fixed text, in the center of each path
            bbox = simpletransform.computeBBox([node])
            tx = bbox[0] + (bbox[1] - bbox[0]) / 2.0
            ty = bbox[2] + (bbox[3] - bbox[2]) / 2.0
            anchor = 'middle'
            self.addTextWithTspan(
                self.group, tx, ty, resultstr + ' ' + self.options.unit + '^2',
                id, anchor, -int(self.options.angle),
                -self.options.offset + self.options.fontsize / 2)
    def effect(self):
        """ This method is called first, and sets up the self.commands list for later output. """
        svg = self.document.getroot()
        # find document width and height, used to scale down
        self.doc_width = inkex.unittouu(svg.get('width'))
        self.doc_height = inkex.unittouu(svg.get('height'))

        # add header
        self.commands.append("^DF;")
        self.commands.append("! 1;")
        self.commands.append("H;")
        self.commands.append("@ %d %d;" % (self.options.z_down, self.options.z_up))
        self.commands.append("V {0};F {0};\n".format(self.options.feed_rate_moving))
        self.commands.append("Z 0 0 %d;" % self.options.z_up)

        # mostly borrowed from hgpl_output.py
        lastX = 0
        lastY = 0

        # find paths in layers
        i = 0
        layerPath = '//svg:g[@inkscape:groupmode="layer"]'
        for layer in svg.xpath(layerPath, namespaces=inkex.NSS):
            i += 1

            nodePath = ('//svg:g[@inkscape:groupmode="layer"][%d]/descendant::svg:path') % i
            for node in svg.xpath(nodePath, namespaces=inkex.NSS):
                # these next lines added from this patch to fix the transformation issues - http://launchpadlibrarian.net/36269154/hpgl_output.py.patch
                # possibly also want to try this code: https://bugs.launchpad.net/inkscape/+bug/600472/+attachment/1475310/+files/hpgl_output.py
                transforms = node.xpath("./ancestor-or-self::svg:*[@transform]",namespaces=inkex.NSS)
                matrix = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
                for parenttransform in transforms:
                    newmatrix = simpletransform.parseTransform(parenttransform.get("transform"))
                    matrix = simpletransform.composeTransform(matrix, newmatrix)

                d = node.get('d')
                if len(simplepath.parsePath(d)):
                    p = cubicsuperpath.parsePath(d)
                    simpletransform.applyTransformToPath(matrix, p) # this line is also from the transform-fixing patch mentioned above
                    cspsubdiv.cspsubdiv(p, self.options.flat)
                    for sp in p:
                        first = True
                        for csp in sp:
                            if first:
                                x, y = self.conv_coords(csp[1][0], self.doc_height - csp[1][1])
                                self.commands.append("Z %d %d %d;" % (x, y, self.options.z_up))
                                self.commands.append("V {0};F {0};".format(self.options.feed_rate_cutting))
                            first = False
                            x, y = self.conv_coords(csp[1][0], self.doc_height - csp[1][1])
                            self.commands.append("Z %d %d %d;" % (x, y, self.options.z_down))
                            lastX = x
                            lastY = y
                        self.commands.append("V {0};F {0};".format(self.options.feed_rate_moving))
                        self.commands.append("Z %d %d %d;" % (lastX, lastY, self.options.z_up))

        self.commands.append("Z 0 0 %d;" % self.options.z_up)
        self.commands.append("H;")
Example #13
0
 def process_shape(self, node, mat):
     rgb = (0, 0, 0)
     style = node.get('style')
     if style:
         style = simplestyle.parseStyle(style)
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none' and style[
                     'stroke'][0:3] != 'url':
                 rgb = simplestyle.parseColor(style['stroke'])
     hsl = coloreffect.ColorEffect.rgb_to_hsl(coloreffect.ColorEffect(),
                                              rgb[0] / 255.0,
                                              rgb[1] / 255.0,
                                              rgb[2] / 255.0)
     self.closed = 0  # only for LWPOLYLINE
     self.color = 7  # default is black
     if hsl[2]:
         self.color = 1 + (int(6 * hsl[0] + 0.5) % 6)  # use 6 hues
     if node.tag == inkex.addNS('path', 'svg'):
         d = node.get('d')
         if not d:
             return
         if (d[-1] == 'z' or d[-1] == 'Z'):
             self.closed = 1
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('rect', 'svg'):
         self.closed = 1
         x = float(node.get('x'))
         y = float(node.get('y'))
         width = float(node.get('width'))
         height = float(node.get('height'))
         p = [[[x, y], [x, y], [x, y]]]
         p.append([[x + width, y], [x + width, y], [x + width, y]])
         p.append([[x + width, y + height], [x + width, y + height],
                   [x + width, y + height]])
         p.append([[x, y + height], [x, y + height], [x, y + height]])
         p.append([[x, y], [x, y], [x, y]])
         p = [p]
     else:
         return
     trans = node.get('transform')
     if trans:
         mat = simpletransform.composeTransform(
             mat, simpletransform.parseTransform(trans))
     simpletransform.applyTransformToPath(mat, p)
     for sub in p:
         for i in range(len(sub) - 1):
             s = sub[i]
             e = sub[i + 1]
             if s[1] == s[2] and e[0] == e[1]:
                 if (self.options.POLY == 'true'):
                     self.LWPOLY_line([s[1], e[1]])
                 else:
                     self.dxf_line([s[1], e[1]])
             elif (self.options.ROBO == 'true'):
                 self.ROBO_spline([s[1], s[2], e[0], e[1]])
             else:
                 self.dxf_spline([s[1], s[2], e[0], e[1]])
Example #14
0
    def load(self, node, mat):
        self.id = node.get('id')
        d = node.get('d')
        if len(simplepath.parsePath(d)) == 0:
            return
        p = cubicsuperpath.parsePath(d)
        applyTransformToPath(mat, p)

        # p is now a list of lists of cubic beziers [ctrl p1, ctrl p2, endpoint]
        # where the start-point is the last point in the previous segment
        self.points = []
        self.paths = []
        for sp in p:
            path = []
            subdivide_cubic_path(sp, 0.2)  # TODO: smoothness preference
            for csp in sp:
                point = [csp[1][0], csp[1][1]]
                if point not in self.points:
                    self.points.append(point)
                path.append(self.points.index(point))
            self.paths.append(path)

        # get color
        style = node.get('style')
        try:
            hexcolor = re.search('fill:#([0-9a-fA-f]{6})', style).group(1)
            rgb = [
                int(hexcolor[0:2], 16),
                int(hexcolor[2:4], 16),
                int(hexcolor[4:6], 16)
            ]
        except (TypeError, AttributeError):
            rgb = None

        # get optional opacity
        try:
            opacity = float(re.search('(?:^|;)opacity:([0-9]*\.?[0-9]+)', style).group(1))
        except (TypeError, AttributeError):
            opacity = 1.0

        # get optional fill-opacity (of course there is more than one way to set opacity of paths...)
        try:
            fill_opacity = float(re.search('(?:^|;)fill-opacity:([0-9]*\.?[0-9]+)', style).group(1))
        except (TypeError, AttributeError):
            fill_opacity = 1.0

        if rgb:
            self.color = [
                rgb[0] / 255.0,
                rgb[1] / 255.0,
                rgb[2] / 255.0,
                opacity * fill_opacity
            ]
        else:
            self.color = None
    def effect(self):
        paths = []
        for id, node in self.selected.iteritems():
            if node.tag == '{http://www.w3.org/2000/svg}path':
                paths.append(node)
                if len(paths) == 2:
                    break
        else:
            sys.stderr.write('Need 2 paths selected\n')
            return


        pts = [cubicsuperpath.parsePath(paths[i].get('d'))
               for i in (0,1)]

        for i in (0,1):
            if 'transform' in paths[i].keys():
                trans = paths[i].get('transform')
                trans = simpletransform.parseTransform(trans)
                simpletransform.applyTransformToPath(trans, pts[i])

        verts = []
        for i in range(0, min(map(len, pts))):
            comp = []
            for j in range(0, min(len(pts[0][i]), len(pts[1][i]))):
                comp.append([pts[0][i][j][1][-2:], pts[1][i][j][1][-2:]])
            verts.append(comp)

        if self.options.mode.lower() == 'lines':
            line = []
            for comp in verts:
                for n,v in enumerate(comp):
                  line += [('M', v[0])]
                  line += [('L', v[1])]
            ele = inkex.etree.Element('{http://www.w3.org/2000/svg}path')
            paths[0].xpath('..')[0].append(ele)
            ele.set('d', simplepath.formatPath(line))
            ele.set('style', 'fill:none;stroke:#000000;stroke-opacity:1;stroke-width:1;')
        elif self.options.mode.lower() == 'polygons':
            g = inkex.etree.Element('{http://www.w3.org/2000/svg}g')
            g.set('style', 'fill:#000000;stroke:#000000;fill-opacity:0.3;stroke-width:2;stroke-opacity:0.6;')   
            paths[0].xpath('..')[0].append(g)
            for comp in verts:
                for n,v in enumerate(comp):
                    nn = n+1
                    if nn == len(comp): nn = 0
                    line = []
                    line += [('M', comp[n][0])]
                    line += [('L', comp[n][1])]
                    line += [('L', comp[nn][1])]
                    line += [('L', comp[nn][0])]
                    line += [('L', comp[n][0])]
                    ele = inkex.etree.Element('{http://www.w3.org/2000/svg}path')
                    g.append(ele)
                    ele.set('d', simplepath.formatPath(line))
Example #16
0
	def effect(self):
		for id, node in self.selected.iteritems():
			if node.tag == '{http://www.w3.org/2000/svg}path':
				path=node
				break
		else:
			sys.stderr.write('Need one path selected\n')
			return

		pts = cubicsuperpath.parsePath(path.get('d'))

		if 'transform' in path.keys():
			trans = path.get('transform')
			trans = simpletransform.parseTransform(trans)
			simpletransform.applyTransformToPath(trans, pts[i])

		gtext = inkex.etree.SubElement(path.xpath('..')[0], inkex.addNS('g','svg'), {} )
		gdots = inkex.etree.SubElement(path.xpath('..')[0], inkex.addNS('g','svg'), {} )

		size = 10
		if 'style' in path.attrib:
			style=path.get('style')
			if style!='':
				styles=style.split(';')
            			for i in range(len(styles)):
					if styles[i].startswith('stroke-width'):
						if ( styles[i].endswith('px') or styles[i].endswith('cm') ) :
							size=float(styles[i][len('stroke-width:'):-2])*2
						else:
							size=float(styles[i][len('stroke-width:'):])*2
#		if len(pts[0])>2:
#			size = math.sqrt(math.pow(pts[0][0][0][0]-pts[0][1][0][0],2)+math.pow(pts[0][0][0][1]-pts[0][1][0][1],2))/10

		it = 0
		for sub in pts:
			for p in sub:
				if it == 0:
					style = { 'stroke': 'none', 'fill': 'black' }
					x0 = p[0][0]
					y0 = p[0][1]
					circ_attribs = {'id':'pt0','style':simplestyle.formatStyle(style),'cx':str(x0), 'cy':str(y0),'r':str(size)}
					circle = inkex.etree.SubElement(gdots, inkex.addNS('circle','svg'), circ_attribs )
				else:
					clone_attribs = { 'x':'0', 'y':'0', 'transform':'translate(%f,%f)' % (p[0][0]-x0,p[0][1]-y0) }
					clone = inkex.etree.SubElement(gdots, inkex.addNS('use','svg'), clone_attribs )
					xlink = inkex.addNS('href','xlink')
					clone.set(xlink, '#pt0')

				text_style = { 'font-size':'%dpx' % (size*2.4), 'fill':'black', 'font-family':'DejaVu Sans', 'text-anchor':'middle' }
				text_attribs = { 'x':str(p[0][0]), 'y':str(p[0][1]-size*1.8), 'style':simplestyle.formatStyle(text_style) }
				text = inkex.etree.SubElement(gtext, inkex.addNS('text','svg'), text_attribs)
				tspan = inkex.etree.SubElement(text , 'tspan', {inkex.addNS('role','sodipodi'): 'line'})
            			tspan.text = '%d' % ( it+1 )

				it+=1
Example #17
0
    def effect(self):
        paths = []
        for id, node in self.selected.iteritems():
            if node.tag == "{http://www.w3.org/2000/svg}path":
                paths.append(node)
                if len(paths) == 2:
                    break
        else:
            sys.stderr.write("Need 2 paths selected\n")
            return

        pts = [cubicsuperpath.parsePath(paths[i].get("d")) for i in (0, 1)]

        for i in (0, 1):
            if "transform" in paths[i].keys():
                trans = paths[i].get("transform")
                trans = simpletransform.parseTransform(trans)
                simpletransform.applyTransformToPath(trans, pts[i])

        verts = []
        for i in range(0, min(map(len, pts))):
            comp = []
            for j in range(0, min(len(pts[0][i]), len(pts[1][i]))):
                comp.append([pts[0][i][j][1][-2:], pts[1][i][j][1][-2:]])
            verts.append(comp)

        if self.options.mode.lower() == "lines":
            line = []
            for comp in verts:
                for n, v in enumerate(comp):
                    line += [("M", v[0])]
                    line += [("L", v[1])]
            ele = inkex.etree.Element("{http://www.w3.org/2000/svg}path")
            paths[0].xpath("..")[0].append(ele)
            ele.set("d", simplepath.formatPath(line))
            ele.set("style", "fill:none;stroke:#000000;stroke-opacity:1;stroke-width:1;")
        elif self.options.mode.lower() == "polygons":
            g = inkex.etree.Element("{http://www.w3.org/2000/svg}g")
            g.set("style", "fill:#000000;stroke:#000000;fill-opacity:0.3;stroke-width:2;stroke-opacity:0.6;")
            paths[0].xpath("..")[0].append(g)
            for comp in verts:
                for n, v in enumerate(comp):
                    nn = n + 1
                    if nn == len(comp):
                        nn = 0
                    line = []
                    line += [("M", comp[n][0])]
                    line += [("L", comp[n][1])]
                    line += [("L", comp[nn][1])]
                    line += [("L", comp[nn][0])]
                    line += [("L", comp[n][0])]
                    ele = inkex.etree.Element("{http://www.w3.org/2000/svg}path")
                    g.append(ele)
                    ele.set("d", simplepath.formatPath(line))
Example #18
0
    def recursiveFuseTransform(self,
                               node,
                               transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = composeTransform(transf,
                                  parseTransform(node.get("transform", None)))

        if 'transform' in node.attrib:
            del node.attrib['transform']

        node = self.objectToPath(node)

        if 'd' in node.attrib:
            d = node.get('d')
            p = cubicsuperpath.parsePath(d)
            applyTransformToPath(transf, p)
            node.set('d', cubicsuperpath.formatPath(p))

            self.scaleStrokeWidth(node, transf)

        elif node.tag in [
                inkex.addNS('polygon', 'svg'),
                inkex.addNS('polyline', 'svg')
        ]:
            points = node.get('points')
            points = points.strip().split(' ')
            for k, p in enumerate(points):
                if ',' in p:
                    p = p.split(',')
                    p = [float(p[0]), float(p[1])]
                    applyTransformToPoint(transf, p)
                    p = [str(p[0]), str(p[1])]
                    p = ','.join(p)
                    points[k] = p
            points = ' '.join(points)
            node.set('points', points)

            self.scaleStrokeWidth(node, transf)

        elif node.tag in [
                inkex.addNS('rect', 'svg'),
                inkex.addNS('text', 'svg'),
                inkex.addNS('image', 'svg'),
                inkex.addNS('use', 'svg'),
                inkex.addNS('circle', 'svg')
        ]:
            node.set('transform', formatTransform(transf))

        else:
            # e.g. <g style="...">
            self.scaleStrokeWidth(node, transf)

        for child in node.getchildren():
            self.recursiveFuseTransform(child, transf)
Example #19
0
 def process_shape(self, node, mat):
     rgb = (0,0,0)                   # stroke color
     fillcolor = None                # fill color
     stroke = 1                      # pen width in printer pixels
     # Very NB : If the pen width is greater than 1 then the output will Not be a vector output !
     style = node.get('style')
     if style:
         style = simplestyle.parseStyle(style)
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none' and style['stroke'][0:3] != 'url':
                 rgb = simplestyle.parseColor(style['stroke'])
         if style.has_key('stroke-width'):
             stroke = self.unittouu(style['stroke-width'])
             stroke = int(stroke*self.scale)
         if style.has_key('fill'):
             if style['fill'] and style['fill'] != 'none' and style['fill'][0:3] != 'url':
                 fill = simplestyle.parseColor(style['fill'])
                 fillcolor = fill[0] + 256*fill[1] + 256*256*fill[2]
     color = rgb[0] + 256*rgb[1] + 256*256*rgb[2]
     if node.tag == inkex.addNS('path','svg'):
         d = node.get('d')
         if not d:
             return
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('rect','svg'):
         x = float(node.get('x'))
         y = float(node.get('y'))
         width = float(node.get('width'))
         height = float(node.get('height'))
         p = [[[x, y],[x, y],[x, y]]]
         p.append([[x + width, y],[x + width, y],[x + width, y]])
         p.append([[x + width, y + height],[x + width, y + height],[x + width, y + height]])
         p.append([[x, y + height],[x, y + height],[x, y + height]])
         p.append([[x, y],[x, y],[x, y]])
         p = [p]
     else:
         return
     trans = node.get('transform')
     if trans:
         mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
     simpletransform.applyTransformToPath(mat, p)
     hPen = mygdi.CreatePen(0, stroke, color)
     mygdi.SelectObject(self.hDC, hPen)
     self.emit_path(p)
     if fillcolor is not None:
         brush = LOGBRUSH(0, fillcolor, 0)
         hBrush = mygdi.CreateBrushIndirect(addressof(brush))
         mygdi.SelectObject(self.hDC, hBrush)
         mygdi.BeginPath(self.hDC)
         self.emit_path(p)
         mygdi.EndPath(self.hDC)
         mygdi.FillPath(self.hDC)
     return
 def process_shape(self, node, mat):
     rgb = (0,0,0)
     style = node.get('style')
     if style:
         style = simplestyle.parseStyle(style)
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none' and style['stroke'][0:3] != 'url':
                 rgb = simplestyle.parseColor(style['stroke'])
     hsl = coloreffect.ColorEffect.rgb_to_hsl(coloreffect.ColorEffect(),rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0)
     self.closed = 0                                 # only for LWPOLYLINE
     self.color = 7                                  # default is black
     if hsl[2]:
         #self.color = 1 + (int(6*hsl[0] + 0.5) % 6)  # use 6 hues
         self.color = 1 + (int(10*hsl[0] + 0.5) % 10)  # use 6 hues
     if node.tag == inkex.addNS('path','svg'):
         d = node.get('d')
         if not d:
             return
         if (d[-1] == 'z' or d[-1] == 'Z'):
             self.closed = 1
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('rect','svg'):
         self.closed = 1
         x = float(node.get('x'))
         y = float(node.get('y'))
         width = float(node.get('width'))
         height = float(node.get('height'))
         p = [[[x, y],[x, y],[x, y]]]
         p.append([[x + width, y],[x + width, y],[x + width, y]])
         p.append([[x + width, y + height],[x + width, y + height],[x + width, y + height]])
         p.append([[x, y + height],[x, y + height],[x, y + height]])
         p.append([[x, y],[x, y],[x, y]])
         p = [p]
     else:
         return
     trans = node.get('transform')
     if trans:
         mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
     simpletransform.applyTransformToPath(mat, p)
     for sub in p:
         for i in range(len(sub)-1):
             s = sub[i]
             e = sub[i+1]
             if s[1] == s[2] and e[0] == e[1]:
                 if (self.options.POLY == 'true'):
                     self.LWPOLY_line([s[1],e[1]])
                 else:
                     self.dxf_line([s[1],e[1]])
             elif (self.options.ROBO == 'true'):
                 self.ROBO_spline([s[1],s[2],e[0],e[1]])
             else:
                 self.dxf_spline([s[1],s[2],e[0],e[1]])
 def process_shape(self, node, mat):
     readStrokeWidth = not self.options.ignoreStrokeWidth
     color = None  # stroke color
     fillcolor = None  # fill color
     stroke = 1  # pen width in printer pixels
     # Very NB : If the pen width is greater than 1 then the output will Not be a vector output !
     node_style = node.get('style')
     if node_style:
         style = self.groupstyle.copy()
         style.update(simplestyle.parseStyle(node_style))
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none' and style[
                     'stroke'][0:3] != 'url':
                 rgb = simplestyle.parseColor(style['stroke'])
                 color = rgb[0] + 256 * rgb[1] + 256 * 256 * rgb[2]
         if readStrokeWidth and style.has_key('stroke-width'):
             stroke = self.unittouu(
                 style['stroke-width']) / self.unittouu('1px')
             stroke = int(stroke * self.scale)
         if style.has_key('fill'):
             if style['fill'] and style['fill'] != 'none' and style['fill'][
                     0:3] != 'url':
                 fill = simplestyle.parseColor(style['fill'])
                 fillcolor = fill[0] + 256 * fill[1] + 256 * 256 * fill[2]
     if node.tag == inkex.addNS('path', 'svg'):
         d = node.get('d')
         if not d:
             self.not_converted.append(node.get('id'))
             return
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('rect', 'svg'):
         x = float(node.get('x'))
         y = float(node.get('y'))
         width = float(node.get('width'))
         height = float(node.get('height'))
         p = self.printer.rectangle_path(x, y, width, height)
     elif node.tag == inkex.addNS('defs', 'svg') or node.tag == inkex.addNS(
             'metadata', 'svg'):
         # ignore svg:defs and svg:metadata
         return
     elif node.tag.startswith('{' + inkex.NSS['svg']) == False:
         # ignore non-SVG elements
         return
     else:
         self.not_converted.append(node.get('id'))
         return
     trans = node.get('transform')
     if trans:
         mat = simpletransform.composeTransform(
             mat, simpletransform.parseTransform(trans))
     simpletransform.applyTransformToPath(mat, p)
     self.printer.draw_path(p, color, stroke, fillcolor)
Example #22
0
 def process_path(self,path):
     mat = simpletransform.composeParents(path, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
     d = path.get('d')
     p = cubicsuperpath.parsePath(d)
     simpletransform.applyTransformToPath(mat, p)
     for subs in p:
         for csp in subs:
             csp[0] = self.trafopoint(csp[0])
             csp[1] = self.trafopoint(csp[1])
             csp[2] = self.trafopoint(csp[2])
     mat = simpletransform.invertTransform(mat)
     simpletransform.applyTransformToPath(mat, p)
     path.set('d',cubicsuperpath.formatPath(p))
 def appendPolygonsFromPath(self, d, layer, style):
     fill = True
     if style.has_key('fill'):
         fill = style['fill']
     if not fill or fill == 'none':
         return
     # ix.debug('appendPolygonsFromPath')
     path = cubicsuperpath.parsePath(d)
     cspsubdiv.cspsubdiv(path, self.options.flatness)
     path = listit(path)
     simpletransform.applyTransformToPath(self.currentTransform(), path)
     polygons = constructBridgedPolygonsFromPath(path)
     for polygon in polygons:
         self.appendPolygon(polygon, layer)
    def processPaths(self, transformMatrix):
        path = '//svg:path'
        pm = pathmodifier.PathModifier()

        for node in self.document.getroot().xpath(path, namespaces=inkex.NSS):
            pm.objectToPath(node, True)
            d = node.get('d')
            p = cubicsuperpath.parsePath(d)
            t = node.get('transform')
            if t is not None:
                transformMatrix = composeTransform(transformMatrix, parseTransform(t))

            applyTransformToPath(transformMatrix, p)
            yield [p, node]
Example #25
0
def apply_transforms(path, node):
    # start with the identity transform
    transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]

    # combine this node's transform with all parent groups' transforms
    transform = simpletransform.composeParents(node, transform)

    # add in the transform implied by the viewBox
    viewbox_transform = get_viewbox_transform(node.getroottree().getroot())
    transform = simpletransform.composeTransform(viewbox_transform, transform)

    # apply the combined transform to this node's path
    simpletransform.applyTransformToPath(transform, path)

    return path
Example #26
0
 def processPath(self, node, mat, pen):
     # process path
     path = node.get('d')
     if path:
         # parse and transform path
         path = cubicsuperpath.parsePath(path)
         simpletransform.applyTransformToPath(mat, path)
         cspsubdiv.cspsubdiv(path, self.flat)
         # path to HPGL commands
         oldPosX = 0.0
         oldPosY = 0.0
         for singlePath in path:
             cmd = 'PU'
             for singlePathPoint in singlePath:
                 posX, posY = singlePathPoint[1]
                 # check if point is repeating, if so, ignore
                 if int(round(posX)) != int(round(oldPosX)) or int(
                         round(posY)) != int(round(oldPosY)):
                     self.processOffset(cmd, posX, posY, pen)
                     cmd = 'PD'
                     oldPosX = posX
                     oldPosY = posY
             # perform overcut
             if self.overcut > 0.0 and not self.dryRun:
                 # check if last and first points are the same, otherwise the path is not closed and no overcut can be performed
                 if int(round(oldPosX)) == int(round(
                         singlePath[0][1][0])) and int(
                             round(oldPosY)) == int(
                                 round(singlePath[0][1][1])):
                     overcutLength = 0
                     for singlePathPoint in singlePath:
                         posX, posY = singlePathPoint[1]
                         # check if point is repeating, if so, ignore
                         if int(round(posX)) != int(round(oldPosX)) or int(
                                 round(posY)) != int(round(oldPosY)):
                             overcutLength += self.getLength(
                                 oldPosX, oldPosY, posX, posY)
                             if overcutLength >= self.overcut:
                                 newLength = self.changeLength(
                                     oldPosX, oldPosY, posX, posY,
                                     -(overcutLength - self.overcut))
                                 self.processOffset(cmd, newLength[0],
                                                    newLength[1], pen)
                                 break
                             else:
                                 self.processOffset(cmd, posX, posY, pen)
                             oldPosX = posX
                             oldPosY = posY
Example #27
0
 def process_path(self, node, mat):
     d = node.get('d')
     if d:
         p = cubicsuperpath.parsePath(d)
         trans = node.get('transform')
         if trans:
             mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
         simpletransform.applyTransformToPath(mat, p)
         cspsubdiv.cspsubdiv(p, self.options.flat)
         for sp in p:
             first = True
             for csp in sp:
                 cmd = 'PD'
                 if first:
                     cmd = 'PU'
                 first = False
                 self.hpgl.append('%s%d,%d;' % (cmd,csp[1][0],csp[1][1]))
Example #28
0
    def effect(self):
        """
        Effect behaviour.
        """
        # Get script's "--what" option value.
        fontsize = str(self.options.fontsize) + 'px'
        color = self.options.color
        font = self.options.font
        fontweight = self.options.fontweight
        replaced = self.options.replaced
        replacewith = self.options.replacewith
        angle = -int(self.options.angle)
        capitals = self.options.capitals

        if len(self.selected) == 0:
            inkex.errormsg(_("Please select some paths first."))
            exit()

        for id, node in self.selected.iteritems():
            mat = simpletransform.composeParents(
                node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
            p = cubicsuperpath.parsePath(node.get('d'))
            simpletransform.applyTransformToPath(mat, p)
            self.group = inkex.etree.SubElement(node.getparent(),
                                                inkex.addNS('text', 'svg'))
            tx, ty = cspcofm(p)
            new = inkex.etree.SubElement(
                self.group, inkex.addNS('tspan', 'svg'),
                {inkex.addNS('role', 'sodipodi'): 'line'})
            s = {
                'text-align': 'center',
                'vertical-align': 'bottom',
                'text-anchor': 'middle',
                'font-size': fontsize,
                'font-weight': fontweight,
                'font-style': 'normal',
                'font-family': font,
                'fill': color
            }
            new.set('style', simplestyle.formatStyle(s))
            if capitals:
                id = id.upper()
            new.text = id.replace(replaced, replacewith)
            self.group.set('x', str(tx))
            self.group.set('y', str(ty))
            self.group.set('transform', 'rotate(%s, %s, %s)' % (angle, tx, ty))
Example #29
0
    def parse_path(self):
        # A CSP is a  "cubic superpath".
        #
        # A "path" is a sequence of strung-together bezier curves.
        #
        # A "superpath" is a collection of paths that are all in one object.
        #
        # The "cubic" bit in "cubic superpath" is because the bezier curves
        # inkscape uses involve cubic polynomials.
        #
        # Each path is a collection of tuples, each of the form:
        #
        # (control_before, point, control_after)
        #
        # A bezier curve segment is defined by an endpoint, a control point,
        # a second control point, and a final endpoint.  A path is a bunch of
        # bezier curves strung together.  One could represent a path as a set
        # of four-tuples, but there would be redundancy because the ending
        # point of one bezier is the starting point of the next.  Instead, a
        # path is a set of 3-tuples as shown above, and one must construct
        # each bezier curve by taking the appropriate endpoints and control
        # points.  Bleh. It should be noted that a straight segment is
        # represented by having the control point on each end equal to that
        # end's point.
        #
        # In a path, each element in the 3-tuple is itself a tuple of (x, y).
        # Tuples all the way down.  Hasn't anyone heard of using classes?

        path = self.path

        # start with the identity transform
        transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]

        # combine this node's transform with all parent groups' transforms
        transform = simpletransform.composeParents(self.node, transform)

        # add in the transform implied by the viewBox
        viewbox_transform = get_viewbox_transform(
            self.node.getroottree().getroot())
        transform = simpletransform.composeTransform(viewbox_transform,
                                                     transform)

        # apply the combined transform to this node's path
        simpletransform.applyTransformToPath(transform, path)

        return path
Example #30
0
File: tcnc.py Project: fabien/tcnc
    def process_shapes(self, shapelist, transform):
        """Convert the SVG shape elements to Lines and CubicBeziers,
        and apply object/layer transforms.
        Returns a list of tuples ((path-id, path), ...).
        """
        cutpath_list = []
        for node, layer_transform in shapelist:
            # Convert the shape element to a simplepath
            path = supereffect.convert_element_to_path(node)
            
            # Convert the simplepath to a 'cubicsuperpath' which is
            # just a list of cubic bezier curves.
            # This seems to be how most Inkscape plugins do things...
            # TODO: This is really an unnecessary step since
            # we could deal with SVG shapes directly...
            csp = cubicsuperpath.CubicSuperPath(path)
            
            # Apply the SVG element transform and it's layer transform to the
            # path segments so that we are working in absolute coordinates.
            # Transform SVG coordinates into cartesian (ie G code) coordinates
            # (flip the Y axis from upper left to lower left).
#            node_transform = simpletransform.parseTransform(node.get('transform'))
#            node_transform = simpletransform.composeTransform(node_transform, transform)
#            node_transform = simpletransform.composeTransform(node_transform, layer_transform)
            node_transform = simpletransform.composeTransform(transform, layer_transform)
            simpletransform.applyTransformToPath(node_transform, csp)
                        
            # Convert cubic path segments to curves and lines
            # TODO: get bounding boxes and calculate offset if doc origin not used.
            cutpath = paths.Path(name=node.get('id'))
            for subcsp in csp:
                for i in range(1,len(subcsp)):
                    p1 = geom.P(subcsp[i-1][1])
                    c1 = geom.P(subcsp[i-1][2])
                    p2 = geom.P(subcsp[i][0])
                    c2 = geom.P(subcsp[i][1])
                    if p1 == c1 and p2 == c2:
                        segment = geom.Line(p1, p2)
                    else:
                        segment = geom.CubicBezier(p1, c1, p2, c2)
                    cutpath.append(segment)

            cutpath_list.append(cutpath)
        
        return cutpath_list
Example #31
0
 def effect(self):
     # get number of digits
     prec = int(self.options.precision)
     scale = self.unittouu('1px')    # convert to document units
     self.options.offset *= scale
     factor = 1.0
     doc = self.document.getroot()
     if doc.get('viewBox'):
         [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
         factor = self.unittouu(doc.get('width'))/float(vieww)
         if self.unittouu(doc.get('height'))/float(viewh) < factor:
             factor = self.unittouu(doc.get('height'))/float(viewh)
         factor /= self.unittouu('1px')
         self.options.fontsize /= factor
     # loop over all selected paths
     for id, node in self.selected.iteritems():
         if node.tag == inkex.addNS('path','svg'):
             mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
             p = cubicsuperpath.parsePath(node.get('d'))
             simpletransform.applyTransformToPath(mat, p)
             factor *= scale/self.unittouu('1'+self.options.unit)
             if self.options.type == "length":
                 slengths, stotal = csplength(p)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             elif self.options.type == "area":
                 stotal = csparea(p)*factor*self.options.scale
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             else:
                 xc, yc = cspcofm(p)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('path','svg'))
                 self.group.set('id', 'MassCenter_' + node.get('id'))
                 self.addCross(self.group, xc, yc, scale)
                 continue
             # Format the length as string
             lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip()
             if self.options.format == 'textonpath':
                 if self.options.type == "length":
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit, id, 'start', '50%', self.options.offset)
                 else:
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit+'^2', id, 'start', '0%', self.options.offset)
             else:
                 if self.options.type == "length":
                     self.addTextWithTspan(self.group, p[0][0][1][0], p[0][0][1][1], lenstr+' '+self.options.unit, id, 'start', -int(self.options.angle), self.options.offset + self.options.fontsize/2)
                 else:
                     self.addTextWithTspan(self.group, p[0][0][1][0], p[0][0][1][1], lenstr+' '+self.options.unit+'^2', id, 'start', -int(self.options.angle), -self.options.offset + self.options.fontsize/2)
Example #32
0
 def process_path(self, node, mat):
     d = node.get('d')
     if d:
         p = cubicsuperpath.parsePath(d)
         trans = node.get('transform')
         if trans:
             mat = simpletransform.composeTransform(
                 mat, simpletransform.parseTransform(trans))
         simpletransform.applyTransformToPath(mat, p)
         cspsubdiv.cspsubdiv(p, self.options.flat)
         for sp in p:
             first = True
             for csp in sp:
                 cmd = 'PD'
                 if first:
                     cmd = 'PU'
                 first = False
                 self.hpgl.append('%s%d,%d;' % (cmd, csp[1][0], csp[1][1]))
    def recursiveFuseTransform(node, transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = composeTransform(transf, parseTransform(node.get("transform", None)))

        if 'transform' in node.attrib:
            del node.attrib['transform']

        node = ApplyTransform.objectToPath(node)

        if 'd' in node.attrib:
            d = node.get('d')
            p = cubicsuperpath.parsePath(d)
            applyTransformToPath(transf, p)
            node.set('d', cubicsuperpath.formatPath(p))

        elif node.tag == inkex.addNS('rect', 'svg'):
            node.set('transform', formatTransform(transf))

        for child in node.getchildren():
            ApplyTransform.recursiveFuseTransform(child, transf)
    def recursiveFuseTransform(node, transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = composeTransform(transf, parseTransform(node.get("transform", None)))

        if "transform" in node.attrib:
            del node.attrib["transform"]

        node = ApplyTransform.objectToPath(node)

        if "d" in node.attrib:
            d = node.get("d")
            p = cubicsuperpath.parsePath(d)
            applyTransformToPath(transf, p)
            node.set("d", cubicsuperpath.formatPath(p))

        elif node.tag == inkex.addNS("rect", "svg"):
            node.set("transform", formatTransform(transf))

        for child in node.getchildren():
            ApplyTransform.recursiveFuseTransform(child, transf)
Example #35
0
   def plotPath(self, node, matTransform):
      """ Plot the path while applying the transformation defined by the matrix matTransform. """

      filledPath = (simplestyle.parseStyle(node.get("style")).get("fill", "none") != "none")

      # Plan: Turn this path into a cubicsuperpath (list of beziers)...
      d = node.get("d")
      if len(simplepath.parsePath(d)) == 0:
         return
      p = cubicsuperpath.parsePath(d)

      # ... and apply the transformation to each point.
      simpletransform.applyTransformToPath(matTransform, p)

      # p is now a list of lists of cubic beziers [cp1, cp2, endp]
      # where the start-point is the last point of the previous segment.
      # For some reason the inkscape extensions uses csp[1] as the coordinates of each point,
      # but that makes it seem like they are using control point 2 as line points.
      # Maybe that is a side-effect of the CSP subdivion process? TODO
      realPoints = []
      for sp in p:
         cspsubdiv.subdiv(sp, self.smoothness)
      
      for i in range(1, len(p)):
         pStart = [p[i][0][1][0], p[i][0][1][1]]
         pClose = []
         pDist = -1
         for k in range(len(p)):
            if (k == i):
               continue
            for j in range(len(p[k])):
               csp = p[k][j];
               tDist = self.getDist(pStart, [csp[1][0], csp[1][1]])
               if (pDist < 0) or (tDist < pDist):
                  pDist = tDist
                  pClose = [k, j]
         if pClose:
            #print "close " + repr(i) + " " + repr(pClose) + " " + repr(p[pClose[0]][pClose[1]])
            p[pClose[0]][pClose[1]].append(i)
      
      self.genPoints(p, p[0], realPoints)
      self.rawObjects.append( (filledPath, realPoints) )
				def get_k (csp, c1,d):
					c2 = [c1[0]-d, c1[1]]
					alpha2_ = []
				
					for n in range(self.num):
						alpha1 = math.pi*2*(n)/self.num * self.second_teeth
						d_alpha1 = math.pi*2/self.num * self.second_teeth
						csp_ = [[[p[:] for p in point] for point in subpath] for subpath in csp ]
						transform = get_transform(c1,c2,alpha1,0)
						simpletransform.applyTransformToPath(transform, csp_)
						# r2 = distance to second gear's center
						[r2, i,j,t] = csp_to_point_distance(csp_, c2, dist_bounds = [0,1e100], tolerance=.001)
						r2 = math.sqrt(r2)

						p = csp_at_t(csp_[i][j-1],csp_[i][j],t)
						r1 = math.sqrt((p[0]-c1[0])**2 +(p[1]-c1[1])**2)
						# d_alpha2 = rotation speed factor
						if r2 == 0 : return 1e100, []
						alpha2_.append(d_alpha1 * r1/r2)
					return math.pi*2 * self.first_teeth / sum(alpha2_), alpha2_
Example #37
0
def point_generator(path, mat, flatness):

        if len(simplepath.parsePath(path)) == 0:
                return
       
        simple_path = simplepath.parsePath(path)
        startX,startY = float(simple_path[0][1][0]), float(simple_path[0][1][1])
        yield startX, startY

        p = cubicsuperpath.parsePath(path)
        
        if mat:
            simpletransform.applyTransformToPath(mat, p)

        for sp in p:
                cspsubdiv.subdiv( sp, flatness)
                for csp in sp:
                    ctrl_pt1 = csp[0]
                    ctrl_pt2 = csp[1]
                    end_pt = csp[2]
                    yield end_pt[0], end_pt[1],    
Example #38
0
def point_generator(path, mat, flatness):

        if len(simplepath.parsePath(path)) == 0:
                return
       
        simple_path = simplepath.parsePath(path)
        startX,startY = float(simple_path[0][1][0]), float(simple_path[0][1][1])
        yield startX, startY

        p = cubicsuperpath.parsePath(path)
        
        if mat:
            simpletransform.applyTransformToPath(mat, p)

        for sp in p:
                cspsubdiv.subdiv( sp, flatness)
                for csp in sp:
                    ctrl_pt1 = csp[0]
                    ctrl_pt2 = csp[1]
                    end_pt = csp[2]
                    yield end_pt[0], end_pt[1],    
Example #39
0
 def processPath(self, node, mat):
     # process path
     paths = node.get('d')
     if paths:
         # parse and transform path
         paths = cubicsuperpath.parsePath(paths)
         simpletransform.applyTransformToPath(mat, paths)
         cspsubdiv.cspsubdiv(paths, self.options.flat)
         # path to HPGL commands
         oldPosX = 0.0
         oldPosY = 0.0
         # TODO: Plot smallest parts first to avid plotter dragging parts of foil around (on text)
         for singlePath in paths:
             cmd = 'PU'
             for singlePathPoint in singlePath:
                 posX, posY = singlePathPoint[1]
                 # check if point is repeating, if so, ignore
                 if int(round(posX)) != int(round(oldPosX)) or int(round(posY)) != int(round(oldPosY)):
                     self.processOffset(cmd, posX, posY)
                     cmd = 'PD'
                     oldPosX = posX
                     oldPosY = posY
             # perform overcut
             if self.options.useOvercut and not self.dryRun:
                 # check if last and first points are the same, otherwise the path is not closed and no overcut can be performed
                 if int(round(oldPosX)) == int(round(singlePath[0][1][0])) and int(round(oldPosY)) == int(round(singlePath[0][1][1])):
                     overcutLength = 0
                     for singlePathPoint in singlePath:
                         posX, posY = singlePathPoint[1]
                         # check if point is repeating, if so, ignore
                         if int(round(posX)) != int(round(oldPosX)) or int(round(posY)) != int(round(oldPosY)):
                             overcutLength += self.getLength(oldPosX, oldPosY, posX, posY)
                             if overcutLength >= self.options.overcut:
                                 newLength = self.changeLength(oldPosX, oldPosY, posX, posY, - (overcutLength - self.options.overcut))
                                 self.processOffset(cmd, newLength[0], newLength[1])
                                 break
                             else:
                                 self.processOffset(cmd, posX, posY)
                             oldPosX = posX
                             oldPosY = posY
Example #40
0
 def processPath(self, node, mat, pen):
     # process path
     path = node.get('d')
     if path:
         # parse and transform path
         path = cubicsuperpath.parsePath(path)
         simpletransform.applyTransformToPath(mat, path)
         cspsubdiv.cspsubdiv(path, self.flat)
         # path to HPGL commands
         oldPosX = 0.0
         oldPosY = 0.0
         for singlePath in path:
             cmd = 'PU'
             for singlePathPoint in singlePath:
                 posX, posY = singlePathPoint[1]
                 # check if point is repeating, if so, ignore
                 if int(round(posX)) != int(round(oldPosX)) or int(round(posY)) != int(round(oldPosY)):
                     self.processOffset(cmd, posX, posY, pen)
                     cmd = 'PD'
                     oldPosX = posX
                     oldPosY = posY
             # perform overcut
             if self.overcut > 0.0 and not self.dryRun:
                 # check if last and first points are the same, otherwise the path is not closed and no overcut can be performed
                 if int(round(oldPosX)) == int(round(singlePath[0][1][0])) and int(round(oldPosY)) == int(round(singlePath[0][1][1])):
                     overcutLength = 0
                     for singlePathPoint in singlePath:
                         posX, posY = singlePathPoint[1]
                         # check if point is repeating, if so, ignore
                         if int(round(posX)) != int(round(oldPosX)) or int(round(posY)) != int(round(oldPosY)):
                             overcutLength += self.getLength(oldPosX, oldPosY, posX, posY)
                             if overcutLength >= self.overcut:
                                 newLength = self.changeLength(oldPosX, oldPosY, posX, posY, - (overcutLength - self.overcut))
                                 self.processOffset(cmd, newLength[0], newLength[1], pen)
                                 break
                             else:
                                 self.processOffset(cmd, posX, posY, pen)
                             oldPosX = posX
                             oldPosY = posY
Example #41
0
	def parsePath(self, node, transforms, names):
		name = ""
		for n in names:
			name = n + "_" + name
		name = name + node.get("id")

		m2 = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
		for t in transforms:
			m = simpletransform.parseTransform(t)
			m2 = simpletransform.composeTransform(m2, m)

		m = simpletransform.parseTransform(node.get("transform"))
		m2 = simpletransform.composeTransform(m2, m)


		color = self.get_color(node)

		path = simplepath.formatPath(simplepath.parsePath(node.get('d')))
		subpaths = path.split('M')

		for i in range(1, len(subpaths)):
			subpaths[i] = 'M ' + rstrip(subpaths[i])
			closed = subpaths[i][-1] in ['Z', 'z']

			csp = cubicsuperpath.parsePath(subpaths[i])

			simpletransform.applyTransformToPath(m2, csp)

			if closed:
				self.closed2curves(csp)
			else:
				self.opened2curves(csp)

			vertices = self.cast2spine(csp, closed)

			if len(vertices) >= 9 and closed or len(vertices) >= 6 and not closed:
				self.path2json(name + "_" + str(i), closed, color, vertices)
			else:
				inkex.debug("skipping " + name + "_" + str(i) + ": vertex count < 6 (" + str(len(vertices)) + ")")
Example #42
0
 def process_path(self, node, mat):
     rgb = (0, 0, 0)
     style = node.get('style')
     if style:
         style = simplestyle.parseStyle(style)
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none':
                 rgb = simplestyle.parseColor(style['stroke'])
     hsl = coloreffect.ColorEffect.rgb_to_hsl(coloreffect.ColorEffect(),
                                              rgb[0] / 255.0,
                                              rgb[1] / 255.0,
                                              rgb[2] / 255.0)
     self.color = 7  # default is black
     if hsl[2]:
         self.color = 1 + (int(6 * hsl[0] + 0.5) % 6)  # use 6 hues
     d = node.get('d')
     if d:
         p = cubicsuperpath.parsePath(d)
         trans = node.get('transform')
         if trans:
             mat = simpletransform.composeTransform(
                 mat, simpletransform.parseTransform(trans))
         simpletransform.applyTransformToPath(mat, p)
         for sub in p:
             for i in range(len(sub) - 1):
                 s = sub[i]
                 e = sub[i + 1]
                 if s[1] == s[2] and e[0] == e[1]:
                     if (self.options.POLY == 'true'):
                         self.LWPOLY_line([s[1], e[1]])
                     else:
                         self.dxf_line([s[1], e[1]])
                 elif (self.options.ROBO == 'true'):
                     self.ROBO_spline([s[1], s[2], e[0], e[1]])
                 else:
                     self.dxf_spline([s[1], s[2], e[0], e[1]])
Example #43
0
 def effect(self):
     # get number of digits
     prec = int(self.options.precision)
     factor = 1.0
     doc = self.document.getroot()
     if doc.get('viewBox'):
         [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
         factor = float(doc.get('width'))/float(vieww)
         if float(doc.get('height'))/float(viewh) < factor:
             factor = float(doc.get('height'))/float(viewh)
         self.options.fontsize /= factor
     # loop over all selected paths
     for id, node in self.selected.iteritems():
         if node.tag == inkex.addNS('path','svg'):
             self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             a =[]
             mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
             p = cubicsuperpath.parsePath(node.get('d'))
             simpletransform.applyTransformToPath(mat, p)
             factor = factor/inkex.unittouu('1'+self.options.unit)
             if self.options.type == "length":
                 slengths, stotal = csplength(p)
             else:
                 stotal = csparea(p)*factor*self.options.scale
             # Format the length as string
             lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip()
             if self.options.format == 'textonpath':
                 if self.options.type == "length":
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit, id, 'start', '50%', self.options.offset)
                 else:
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit+'^2', id, 'start', '0%', self.options.offset)
             else:
                 if self.options.type == "length":
                     self.addTextWithTspan(self.group, p[0][0][1][0], p[0][0][1][1], lenstr+' '+self.options.unit, id, 'start', -int(self.options.angle), self.options.offset + self.options.fontsize/2)
                 else:
                     self.addTextWithTspan(self.group, p[0][0][1][0], p[0][0][1][1], lenstr+' '+self.options.unit+'^2', id, 'start', -int(self.options.angle), -self.options.offset + self.options.fontsize/2)
        def compile_paths(node, trans):
            # Apply the object transform, along with the parent transformation
            mat = node.get('transform', None)
            if mat:
                mat = simpletransform.parseTransform(mat)
                trans = simpletransform.composeTransform(trans, mat)

            if node.tag == SVG_PATH_TAG:
                # This is a path object
                if (not node.get("d")): return []
                csp = cubicsuperpath.parsePath(node.get("d"))
                if (trans):
                    simpletransform.applyTransformToPath(trans, csp)
                return csp

            elif node.tag == SVG_GROUP_TAG:
                # This node is a group of other nodes
                path = []
                for child in node.iterchildren():
                    path += compile_paths(child, trans)
                return path
            logger.write("skipping " + str(node.tag))
            self.skipped += 1
            return []
def path_to_segments(node, smoothness=0.1):
    '''
        Generator to convert a path node to an interator on
        segmented paths (bezier curves broken to approximated
        straights lines).
    '''
    mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
    d = node.get('d')

    if len(simplepath.parsePath(d)) == 0:
        return

    p = cubicsuperpath.parsePath(d)
    simpletransform.applyTransformToPath(mat, p)

    # p is now a list of lists of cubic beziers [ctrl p1, ctrl p2, endpoint]
    # where the start-point is the last point in the previous segment

    for sp in p:
        path = []
        subdivideCubicPath(sp, smoothness)
        for csp in sp:
            path.append([csp[1][0], csp[1][1]])
        yield path
Example #46
0
        def compile_paths(node, trans):
            # Apply the object transform, along with the parent transformation
            mat = node.get('transform', None)
            if mat:
                mat = simpletransform.parseTransform(mat)
                trans = simpletransform.composeTransform(trans, mat)

            if node.tag == SVG_PATH_TAG:
                # This is a path object
                if (not node.get("d")): return []
                csp = cubicsuperpath.parsePath(node.get("d"))
                if (trans):
                    simpletransform.applyTransformToPath(trans, csp)
                return csp

            elif node.tag == SVG_GROUP_TAG:
                # This node is a group of other nodes
                path = []
                for child in node.iterchildren():
                    path += compile_paths(child, trans)
                return path
            logger.write("skipping " + str(node.tag))
            self.skipped += 1
            return []
Example #47
0
    def effect(self):
        # Get number of digits
        scale = self.unittouu('1px')    # Convert to document units
        factor = 1.0
        doc = self.document.getroot()
        if doc.get('viewBox'):
            [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
            factor = self.unittouu(doc.get('width'))/float(vieww)
            if self.unittouu(doc.get('height'))/float(viewh) < factor:
                factor = self.unittouu(doc.get('height'))/float(viewh)
            factor /= self.unittouu('1px')
        # Loop over all selected paths
        obj_lengths = []  
        obj_ids = []
        obj_nodes = []
        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path','svg'):
                mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
                p = cubicsuperpath.parsePath(node.get('d'))
                node.set('d', cubicsuperpath.formatPath(p))
                simpletransform.applyTransformToPath(mat, p)
                factor *= scale/self.unittouu('1'+self.options.unit)
                if self.options.type == "length":
                    slengths, stotal = csplength(p)
                    
                    # Save the path length and segment lengths in the document 
                    node.set('pathlength', str(stotal))
                    tmp = ''
                    for slen in slengths[0][::-1]:
                        tmp += str(slen) + ' '
                    tmp = tmp[:-1] # Remove the space at the end
                    node.set('segmentlengths', tmp)
                    
                    obj_lengths += [stotal]
                    obj_ids += [id]
                    obj_nodes += [node] 
                # Format the length as string
        
        id_min = 0
        id_max = 1
        # Set bigger and smaller object
        if obj_lengths[id_min] > obj_lengths[id_max]:
            id_min = 1
            id_max = 0
        
        # Get paths and collect pathlength and segmentlengths
        obj_lengths = []  
        obj_ids = []
        obj_nodes = []
        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path','svg'):
                mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
                p = cubicsuperpath.parsePath(node.get('d'))
                simpletransform.applyTransformToPath(mat, p)
                node.set('d', cubicsuperpath.formatPath(p))
                factor *= scale/self.unittouu('1'+self.options.unit)
                if self.options.type == "length":
                    slengths, stotal = csplength(p)
                    
                    # Save the path length and segment lengths in the document 
                    node.set('pathlength', str(stotal))
                    tmp = ''
                    for slen in slengths[0][::-1]:
                        tmp += str(slen) + ' '
                    tmp = tmp[:-1] # Remove the space at the end
                    node.set('segmentlengths', tmp)
                    
                    obj_lengths += [stotal]
                    obj_ids += [id]
                    obj_nodes += [node] 
                # Format the length as string
        
        points = []

		# Apply the leaves method to both paths 
        addLeaves(obj_nodes[id_min], self.options.pointsL, self.options.offsetL, self.options.slideL, doc)
        addLeaves(obj_nodes[id_max], self.options.pointsL, self.options.offsetL, self.options.slideL, doc)    
Example #48
0
    def process_shape(self, node, mat, group_stroke = None):
        #################################
        ### Determine the shape type  ###
        #################################
        try:
            i = node.tag.find('}')
            if i >= 0:
                tag_type = node.tag[i+1:]
        except:
            tag_type=""
        
        ##############################################
        ### Set a unique identifier for each shape ###
        ##############################################
        self.id_cnt=self.id_cnt+1
        path_id = "ID%d"%(self.id_cnt)
        sw_flag = False
        changed = False
        #######################################
        ### Handle references to CSS data   ###
        #######################################
        class_val = node.get('class')
        if class_val:
            css_data = ""
            for cv in class_val.split(' '):
                if css_data!="":
                    css_data = self.CSS_values.get_css_value(tag_type,cv)+";"+css_data
                else:
                    css_data = self.CSS_values.get_css_value(tag_type,cv)
                
            # Remove the reference to the CSS data 
            del node.attrib['class']

            # Check if a style entry already exists. If it does
            # append the the existing style data to the CSS data
            # otherwise create a new style entry.
            if node.get('style'):
                if css_data!="":
                    css_data = css_data + ";" + node.get('style')
                    node.set('style', css_data)
            else:
                node.set('style', css_data)

        style   = node.get('style')
        self.Cut_Type[path_id]="raster" # Set default type to raster

        text_message_warning = "SVG File with Color Coded Text Outlines Found: (i.e. Blue: engrave/ Red: cut)"
        line1 = "SVG File with color coded text outlines found (i.e. Blue: engrave/ Red: cut)."
        line2 = "Automatic conversion to paths failed: Try upgrading to Inkscape .90 or later"
        line3 = "To convert manually in Inkscape: select the text then select \"Path\"-\"Object to Path\" in the menu bar."
        text_message_fatal  = "%s\n\n%s\n\n%s" %(line1,line2,line3)
        
        ##############################################
        ### Handle 'style' data outside of style   ###
        ##############################################
        stroke_outside = node.get('stroke')
        if not stroke_outside:
            stroke_outside = group_stroke
        if stroke_outside:
            stroke_width_outside = node.get('stroke-width')
            
            col = stroke_outside
            col= col.strip()
            if simplestyle.isColor(col):
                c=simplestyle.parseColor(col)
                (new_val,changed,k40_action)=self.colmod(c[0],c[1],c[2],path_id)
            else:
                new_val = col
            if changed:
                node.set('stroke',new_val)
                node.set('stroke-width',"0.0")
                node.set('k40_action', k40_action)
                sw_flag = True

            if sw_flag == True:
                if node.tag == inkex.addNS('text','svg') or node.tag == inkex.addNS('flowRoot','svg'):
                    if (self.txt2paths==False):
                        raise SVG_TEXT_EXCEPTION(text_message_warning)
                    else:
                        raise Exception(text_message_fatal)

        ###################################################
        ### Handle 'k40_action' data outside of style   ###
        ###################################################
        if node.get('k40_action'):
            k40_action = node.get('k40_action')
            changed=True
            self.Cut_Type[path_id]=k40_action

        ##############################################
        ### Handle 'style' data                    ###
        ##############################################
        if style:
            declarations = style.split(';')
            i_sw = -1
            
            sw_prop = 'stroke-width'
            for i,decl in enumerate(declarations):
                parts = decl.split(':', 2)
                if len(parts) == 2:
                    (prop, col) = parts
                    prop = prop.strip().lower()
                    
                    if prop == 'k40_action':
                        changed = True
                        self.Cut_Type[path_id]=col
                        
                    #if prop in color_props:
                    if prop == sw_prop:
                        i_sw = i
                    if prop == 'stroke':
                        col= col.strip()
                        if simplestyle.isColor(col):
                            c=simplestyle.parseColor(col)
                            (new_val,changed,k40_action)=self.colmod(c[0],c[1],c[2],path_id)
                        else:
                            new_val = col
                        if changed:
                            declarations[i] = prop + ':' + new_val
                            declarations.append('k40_action' + ':' + k40_action)
                            sw_flag = True
            if sw_flag == True:
                if node.tag == inkex.addNS('text','svg') or node.tag == inkex.addNS('flowRoot','svg'):
                    if (self.txt2paths==False):
                        raise SVG_TEXT_EXCEPTION(text_message_warning)
                    else:
                        raise Exception(text_message_fatal)

                if i_sw != -1:
                    declarations[i_sw] = sw_prop + ':' + "0.0"
                else:
                    declarations.append(sw_prop + ':' + "0.0")
            node.set('style', ';'.join(declarations))
        ##############################################

        #####################################################
        ### If vector data was found save the path data   ###
        #####################################################
        if changed:
            if node.tag == inkex.addNS('path','svg'):
                d = node.get('d')
                if not d:
                    return
                p = cubicsuperpath.parsePath(d)
            elif node.tag == inkex.addNS('rect','svg'):
                x = float(node.get('x'))
                y = float(node.get('y'))
                width = float(node.get('width'))
                height = float(node.get('height'))
                rx = 0.0
                ry = 0.0
                if node.get('rx'):
                    rx=float(node.get('rx'))
                if node.get('ry'):
                    ry=float(node.get('ry'))
                    
                if max(rx,ry) > 0.0:
                    if rx==0.0 or ry==0.0:
                        rx = max(rx,ry)
                        ry = rx
                    Rxmax = abs(width)/2.0
                    Rymax = abs(height)/2.0
                    rx = min(rx,Rxmax)
                    ry = min(ry,Rymax)
                    L1 = "M %f,%f %f,%f "      %(x+rx       , y          , x+width-rx , y          )
                    C1 = "A %f,%f 0 0 1 %f,%f" %(rx         , ry         , x+width    , y+ry       )
                    L2 = "M %f,%f %f,%f "      %(x+width    , y+ry       , x+width    , y+height-ry)
                    C2 = "A %f,%f 0 0 1 %f,%f" %(rx         , ry         , x+width-rx , y+height   )
                    L3 = "M %f,%f %f,%f "      %(x+width-rx , y+height   , x+rx       , y+height   )
                    C3 = "A %f,%f 0 0 1 %f,%f" %(rx         , ry         , x          , y+height-ry)
                    L4 = "M %f,%f %f,%f "      %(x          , y+height-ry, x          , y+ry       )
                    C4 = "A %f,%f 0 0 1 %f,%f" %(rx         , ry         , x+rx       , y          )
                    d =  L1 + C1 + L2 + C2 + L3 + C3 + L4 + C4    
                else:
                    d = "M %f,%f %f,%f %f,%f %f,%f Z" %(x,y, x+width,y,  x+width,y+height, x,y+height) 
                p = cubicsuperpath.parsePath(d)
                
            elif node.tag == inkex.addNS('circle','svg'):
                cx = float(node.get('cx') )
                cy = float(node.get('cy'))
                r  = float(node.get('r'))
                d  = "M %f,%f A   %f,%f 0 0 1 %f,%f   %f,%f 0 0 1 %f,%f   %f,%f 0 0 1 %f,%f   %f,%f 0 0 1 %f,%f Z" %(cx+r,cy, r,r,cx,cy+r,  r,r,cx-r,cy,  r,r,cx,cy-r, r,r,cx+r,cy)
                p = cubicsuperpath.parsePath(d)
            
            elif node.tag == inkex.addNS('ellipse','svg'):
                cx = float(node.get('cx')) 
                cy = float(node.get('cy'))
                if node.get('r'):
                    r = float(node.get('r'))
                    rx = r
                    ry = r
                if node.get('rx'):
                    rx = float(node.get('rx'))
                if node.get('ry'):
                    ry = float(node.get('ry'))
                    
                d  = "M %f,%f A   %f,%f 0 0 1 %f,%f   %f,%f 0 0 1 %f,%f   %f,%f 0 0 1 %f,%f   %f,%f 0 0 1 %f,%f Z" %(cx+rx,cy, rx,ry,cx,cy+ry,  rx,ry,cx-rx,cy,  rx,ry,cx,cy-ry, rx,ry,cx+rx,cy)
                p = cubicsuperpath.parsePath(d)
                
            elif (node.tag == inkex.addNS('polygon','svg')) or (node.tag == inkex.addNS('polyline','svg')):
                points = node.get('points')
                if not points:
                    return
               
                points = points.replace(',', ' ')
                while points.find('  ') > -1:
                    points = points.replace('  ', ' ')
                    
                points = points.strip().split(" ")
                d = "M "
                for i in range(0,len(points),2):
                    x = float(points[i])
                    y = float(points[i+1])
                    d = d + "%f,%f " %(x,y)

                #Close the loop if it is a ploygon
                if node.tag == inkex.addNS('polygon','svg'):
                    d = d + "Z"
                p = cubicsuperpath.parsePath(d)

            elif node.tag == inkex.addNS('line','svg'):
                x1 = float(node.get('x1')) 
                y1 = float(node.get('y1'))
                x2 = float(node.get('x2'))
                y2 = float(node.get('y2'))
                d = "M "
                d = "M %f,%f %f,%f" %(x1,y1,x2,y2)
                p = cubicsuperpath.parsePath(d)          
            else:
                #print("something was ignored")
                #print(node.tag)
                return
            
            trans = node.get('transform')
            if trans:
                mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
            simpletransform.applyTransformToPath(mat, p)
            
            ##########################################
            ## Break Curves down into small lines  ###
            ##########################################
            f = self.flatness
            is_flat = 0
            while is_flat < 1:
                try:
                    cspsubdiv.cspsubdiv(p, f)
                    is_flat = 1
                except IndexError:
                    break
                except:
                    f += 0.1
                    if f>2 :
                      break
                      #something has gone very wrong.
            ##########################################
            rgb=(0,0,0)
            for sub in p:
                for i in range(len(sub)-1):
                    x1 = sub[i][1][0]
                    y1 = sub[i][1][1]
                    x2 = sub[i+1][1][0]
                    y2 = sub[i+1][1][1]
                    self.lines.append([x1,y1,x2,y2,rgb,path_id])
Example #49
0
	def addPathVertices( self, path, node=None, transform=None ):

		'''
		Decompose the path data from an SVG element into individual
		subpaths, each starting with an absolute move-to (x, y)
		coordinate followed by one or more absolute line-to (x, y)
		coordinates.  Each subpath is stored as a list of (x, y)
		coordinates, with the first entry understood to be a
		move-to coordinate and the rest line-to coordinates.  A list
		is then made of all the subpath lists and then stored in the
		self.paths dictionary using the path's lxml.etree node pointer
		as the dictionary key.
		'''

		if ( not path ) or ( len( path ) == 0 ):
			return

		# parsePath() may raise an exception.  This is okay
		sp = simplepath.parsePath( path )
		if ( not sp ) or ( len( sp ) == 0 ):
			return

		# Get a cubic super duper path
		p = cubicsuperpath.CubicSuperPath( sp )
		if ( not p ) or ( len( p ) == 0 ):
			return

		# Apply any transformation
		if transform != None:
			simpletransform.applyTransformToPath( transform, p )

		# Now traverse the simplified path
		subpaths = []
		subpath_vertices = []
		for sp in p:
			# We've started a new subpath
			# See if there is a prior subpath and whether we should keep it
			if len( subpath_vertices ):
				if distanceSquared( subpath_vertices[0], subpath_vertices[-1] ) < 1:
					# Keep the prior subpath: it appears to be a closed path
					subpaths.append( subpath_vertices )
			subpath_vertices = []
			subdivideCubicPath( sp, float( self.options.tolerance / 100 ) )
			for csp in sp:
				# Add this vertex to the list of vetices
				subpath_vertices.append( csp[1] )

		# Handle final subpath
		if len( subpath_vertices ):
			if distanceSquared( subpath_vertices[0], subpath_vertices[-1] ) < 1:
				# Path appears to be closed so let's keep it
				subpaths.append( subpath_vertices )

		# Empty path?
		if len( subpaths ) == 0:
			return

		# And add this path to our dictionary of paths
		self.paths[node] = subpaths

		# And save the transform for this element in a dictionary keyed
		# by the element's lxml node pointer
		self.transforms[node] = transform
Example #50
0
    def effect(self):
        exponent = self.options.exponent
        if exponent>= 0:
            exponent = 1.0 + exponent
        else:
            exponent = 1.0/(1.0 - exponent)
        steps = [1.0/(self.options.steps + 1.0)]
        for i in range(self.options.steps - 1):
            steps.append(steps[0] + steps[-1])
        steps = [step**exponent for step in steps]
            
        paths = {}            
        styles = {}
        for id in self.options.ids:
            node = self.selected[id]
            if node.tag ==inkex.addNS('path','svg'):
                paths[id] = cubicsuperpath.parsePath(node.get('d'))
                styles[id] = simplestyle.parseStyle(node.get('style'))
                trans = node.get('transform')
                if trans:
                    simpletransform.applyTransformToPath(simpletransform.parseTransform(trans), paths[id])
            else:
                self.options.ids.remove(id)

        for i in range(1,len(self.options.ids)):
            start = copy.deepcopy(paths[self.options.ids[i-1]])
            end = copy.deepcopy(paths[self.options.ids[i]])
            sst = copy.deepcopy(styles[self.options.ids[i-1]])
            est = copy.deepcopy(styles[self.options.ids[i]])
            basestyle = copy.deepcopy(sst)
            if basestyle.has_key('stroke-width'):
                basestyle['stroke-width'] = self.tweenstyleunit('stroke-width',sst,est,0)

            #prepare for experimental style tweening
            if self.options.style:
                dostroke = True
                dofill = True
                styledefaults = {'opacity':'1.0', 'stroke-opacity':'1.0', 'fill-opacity':'1.0',
                        'stroke-width':'1.0', 'stroke':'none', 'fill':'none'}
                for key in styledefaults.keys():
                    sst.setdefault(key,styledefaults[key])
                    est.setdefault(key,styledefaults[key])
                isnotplain = lambda x: not (x=='none' or x[:1]=='#')
                if isnotplain(sst['stroke']) or isnotplain(est['stroke']) or (sst['stroke']=='none' and est['stroke']=='none'):
                    dostroke = False
                if isnotplain(sst['fill']) or isnotplain(est['fill']) or (sst['fill']=='none' and est['fill']=='none'):
                    dofill = False
                if dostroke:
                    if sst['stroke']=='none':
                        sst['stroke-width'] = '0.0'
                        sst['stroke-opacity'] = '0.0'
                        sst['stroke'] = est['stroke'] 
                    elif est['stroke']=='none':
                        est['stroke-width'] = '0.0'
                        est['stroke-opacity'] = '0.0'
                        est['stroke'] = sst['stroke'] 
                if dofill:
                    if sst['fill']=='none':
                        sst['fill-opacity'] = '0.0'
                        sst['fill'] = est['fill'] 
                    elif est['fill']=='none':
                        est['fill-opacity'] = '0.0'
                        est['fill'] = sst['fill'] 

                    

            if self.options.method == 2:
                #subdivide both paths into segments of relatively equal lengths
                slengths, stotal = csplength(start)
                elengths, etotal = csplength(end)
                lengths = {}
                t = 0
                for sp in slengths:
                    for l in sp:
                        t += l / stotal
                        lengths.setdefault(t,0)
                        lengths[t] += 1
                t = 0
                for sp in elengths:
                    for l in sp:
                        t += l / etotal
                        lengths.setdefault(t,0)
                        lengths[t] += -1
                sadd = [k for (k,v) in lengths.iteritems() if v < 0]
                sadd.sort()
                eadd = [k for (k,v) in lengths.iteritems() if v > 0]
                eadd.sort()

                t = 0
                s = [[]]
                for sp in slengths:
                    if not start[0]:
                        s.append(start.pop(0))
                    s[-1].append(start[0].pop(0))
                    for l in sp:
                        pt = t
                        t += l / stotal
                        if sadd and t > sadd[0]:
                            while sadd and sadd[0] < t:
                                nt = (sadd[0] - pt) / (t - pt)
                                bezes = cspbezsplitatlength(s[-1][-1][:],start[0][0][:], nt)
                                s[-1][-1:] = bezes[:2]
                                start[0][0] = bezes[2]
                                pt = sadd.pop(0)
                        s[-1].append(start[0].pop(0))
                t = 0
                e = [[]]
                for sp in elengths:
                    if not end[0]:
                        e.append(end.pop(0))
                    e[-1].append(end[0].pop(0))
                    for l in sp:
                        pt = t
                        t += l / etotal
                        if eadd and t > eadd[0]:
                            while eadd and eadd[0] < t:
                                nt = (eadd[0] - pt) / (t - pt)
                                bezes = cspbezsplitatlength(e[-1][-1][:],end[0][0][:], nt)
                                e[-1][-1:] = bezes[:2]
                                end[0][0] = bezes[2]
                                pt = eadd.pop(0)
                        e[-1].append(end[0].pop(0))
                start = s[:]
                end = e[:]
            else:
                #which path has fewer segments?
                lengthdiff = numsegs(start) - numsegs(end)
                #swap shortest first
                if lengthdiff > 0:
                    start, end = end, start
                #subdivide the shorter path
                for x in range(abs(lengthdiff)):
                    maxlen = 0
                    subpath = 0
                    segment = 0
                    for y in range(len(start)):
                        for z in range(1, len(start[y])):
                            leng = bezlenapprx(start[y][z-1], start[y][z])
                            if leng > maxlen:
                                maxlen = leng
                                subpath = y
                                segment = z
                    sp1, sp2 = start[subpath][segment - 1:segment + 1]
                    start[subpath][segment - 1:segment + 1] = cspbezsplit(sp1, sp2)
                #if swapped, swap them back
                if lengthdiff > 0:
                    start, end = end, start
            
            #break paths so that corresponding subpaths have an equal number of segments
            s = [[]]
            e = [[]]
            while start and end:
                if start[0] and end[0]:
                    s[-1].append(start[0].pop(0))
                    e[-1].append(end[0].pop(0))
                elif end[0]:
                    s.append(start.pop(0))
                    e[-1].append(end[0][0])
                    e.append([end[0].pop(0)])
                elif start[0]:
                    e.append(end.pop(0))
                    s[-1].append(start[0][0])
                    s.append([start[0].pop(0)])
                else:
                    s.append(start.pop(0))
                    e.append(end.pop(0))
    
            if self.options.dup:
                steps = [0] + steps + [1]    
            #create an interpolated path for each interval
            group = inkex.etree.SubElement(self.current_layer,inkex.addNS('g','svg'))    
            for time in steps:
                interp = []
                #process subpaths
                for ssp,esp in zip(s, e):
                    if not (ssp or esp):
                        break
                    interp.append([])
                    #process superpoints
                    for sp,ep in zip(ssp, esp):
                        if not (sp or ep):
                            break
                        interp[-1].append([])
                        #process points
                        for p1,p2 in zip(sp, ep):
                            if not (sp or ep):
                                break
                            interp[-1][-1].append(interppoints(p1, p2, time))

                #remove final subpath if empty.
                if not interp[-1]:
                    del interp[-1]

                #basic style tweening
                if self.options.style:
                    basestyle['opacity'] = tweenstylefloat('opacity',sst,est,time)
                    if dostroke:
                        basestyle['stroke-opacity'] = tweenstylefloat('stroke-opacity',sst,est,time)
                        basestyle['stroke-width'] = self.tweenstyleunit('stroke-width',sst,est,time)
                        basestyle['stroke'] = tweenstylecolor('stroke',sst,est,time)
                    if dofill:
                        basestyle['fill-opacity'] = tweenstylefloat('fill-opacity',sst,est,time)
                        basestyle['fill'] = tweenstylecolor('fill',sst,est,time)
                attribs = {'style':simplestyle.formatStyle(basestyle),'d':cubicsuperpath.formatPath(interp)}
                new = inkex.etree.SubElement(group,inkex.addNS('path','svg'), attribs)
Example #51
0
    def getPathVertices(self, path, node=None, transform=None):

        '''
        Decompose the path data from an SVG element into individual
        subpaths, each subpath consisting of absolute move to and line
        to coordinates.  Place these coordinates into a list of polygon
        vertices.
        '''

        if (not path) or (len(path) == 0):
            # Nothing to do
            return None

        # parsePath() may raise an exception.  This is okay
        sp = simplepath.parsePath(path)
        if (not sp) or (len(sp) == 0):
            # Path must have been devoid of any real content
            return None

        # Get a cubic super path
        p = cubicsuperpath.CubicSuperPath(sp)
        if (not p) or (len(p) == 0):
            # Probably never happens, but...
            return None

        if transform:
            simpletransform.applyTransformToPath(transform, p)

        # Now traverse the cubic super path
        subpath_list = []
        subpath_vertices = []

        for sp in p:

            # We've started a new subpath
            # See if there is a prior subpath and whether we should keep it
            if len(subpath_vertices):
                subpath_list.append(
                    [subpath_vertices, [sp_xmin, sp_xmax, sp_ymin, sp_ymax]])

            subpath_vertices = []
            subdivideCubicPath(sp, float(self.options.smoothness))

            # Note the first point of the subpath
            first_point = sp[0][1]
            subpath_vertices.append(first_point)
            sp_xmin = first_point[0]
            sp_xmax = first_point[0]
            sp_ymin = first_point[1]
            sp_ymax = first_point[1]

            # See if the first and last points are identical
            # OpenSCAD doesn't mind if we duplicate the first and last
            # vertex, but our polygon in polygon algorithm may
            n = len(sp)
            last_point = sp[n - 1][1]
            if first_point[0] == last_point[0] and \
                    first_point[1] == last_point[1]:
                n = n - 1

            # Traverse each point of the subpath
            for csp in sp[1:n]:

                # Append the vertex to our list of vertices
                pt = csp[1]
                subpath_vertices.append(pt)

                # Track the bounding box of this subpath
                if pt[0] < sp_xmin:
                    sp_xmin = pt[0]
                elif pt[0] > sp_xmax:
                    sp_xmax = pt[0]
                if pt[1] < sp_ymin:
                    sp_ymin = pt[1]
                elif pt[1] > sp_ymax:
                    sp_ymax = pt[1]

            # Track the bounding box of the overall drawing
            # This is used for centering the polygons in OpenSCAD around the
            # (x,y) origin
            if sp_xmin < self.xmin:
                self.xmin = sp_xmin
            if sp_xmax > self.xmax:
                self.xmax = sp_xmax
            if sp_ymin < self.ymin:
                self.ymin = sp_ymin
            if sp_ymax > self.ymax:
                self.ymax = sp_ymax

        # Handle the final subpath
        if len(subpath_vertices):
            subpath_list.append(
                [subpath_vertices, [sp_xmin, sp_xmax, sp_ymin, sp_ymax]])

        if len(subpath_list) > 0:
            self.paths[node] = subpath_list
Example #52
0
 def effect(self):
     if self.options.mformat == '"presets"':
         self.setPreset()
     # get number of digits
     prec = int(self.options.precision)
     scale = self.unittouu('1px')    # convert to document units
     self.options.offset *= scale
     factor = 1.0
     doc = self.document.getroot()
     if doc.get('viewBox'):
         [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
         factor = self.unittouu(doc.get('width'))/float(vieww)
         if self.unittouu(doc.get('height'))/float(viewh) < factor:
             factor = self.unittouu(doc.get('height'))/float(viewh)
         factor /= self.unittouu('1px')
         self.options.fontsize /= factor
     factor *= scale/self.unittouu('1'+self.options.unit)
     # loop over all selected paths
     for id, node in self.selected.iteritems():
         if node.tag == inkex.addNS('path','svg'):
             mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
             p = cubicsuperpath.parsePath(node.get('d'))
             simpletransform.applyTransformToPath(mat, p)
             if self.options.mtype == "length":
                 slengths, stotal = csplength(p)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             elif self.options.mtype == "area":
                 stotal = abs(csparea(p)*factor*self.options.scale)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             else:
                 xc, yc = cspcofm(p)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('path','svg'))
                 self.group.set('id', 'MassCenter_' + node.get('id'))
                 self.addCross(self.group, xc, yc, scale)
                 continue
             # Format the length as string
             lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip()
             if self.options.mformat == '"textonpath"':
                 startOffset = self.options.startOffset
                 if startOffset == "custom":
                     startOffset = str(self.options.startOffsetCustom) + '%'
                 if self.options.mtype == "length":
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit, id, self.options.anchor, startOffset, self.options.offset)
                 else:
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit+'^2', id, self.options.anchor, startOffset, self.options.offset)
             elif self.options.mformat == '"fixedtext"':
                 if self.options.position == "mass":
                     tx, ty = cspcofm(p)
                     anchor = 'middle'
                 elif self.options.position == "center":
                     bbox = simpletransform.computeBBox([node])
                     tx = bbox[0] + (bbox[1] - bbox[0])/2.0
                     ty = bbox[2] + (bbox[3] - bbox[2])/2.0
                     anchor = 'middle'
                 else:  # default
                     tx = p[0][0][1][0]
                     ty = p[0][0][1][1]
                     anchor = 'start'
                 if self.options.mtype == "length":
                     self.addTextWithTspan(self.group, tx, ty, lenstr+' '+self.options.unit, id, anchor, -int(self.options.angle), self.options.offset + self.options.fontsize/2)
                 else:
                     self.addTextWithTspan(self.group, tx, ty, lenstr+' '+self.options.unit+'^2', id, anchor, -int(self.options.angle), -self.options.offset + self.options.fontsize/2)
             else:
                 # center of mass, no text
                 pass
Example #53
0
 def process_shape(self, node, mat):
     rgb = (0,0,0)
     style = node.get('style')
     if style:
         style = simplestyle.parseStyle(style)
         if style.has_key('stroke'):
             if style['stroke'] and style['stroke'] != 'none' and style['stroke'][0:3] != 'url':
                 rgb = simplestyle.parseColor(style['stroke'])
     hsl = coloreffect.ColorEffect.rgb_to_hsl(coloreffect.ColorEffect(),rgb[0]/255.0,rgb[1]/255.0,rgb[2]/255.0)
     self.color = 7                                  # default is black
     if hsl[2]:
         self.color = 1 + (int(6*hsl[0] + 0.5) % 6)  # use 6 hues
     if node.tag == inkex.addNS('path','svg'):
         d = node.get('d')
         if not d:
             return
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('rect','svg'):
         x = float(node.get('x', 0))
         y = float(node.get('y', 0))
         width = float(node.get('width'))
         height = float(node.get('height'))
         d = "m %s,%s %s,%s %s,%s %s,%s z" % (x, y, width, 0, 0, height, -width, 0)
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('line','svg'):
         x1 = float(node.get('x1', 0))
         x2 = float(node.get('x2', 0))
         y1 = float(node.get('y1', 0))
         y2 = float(node.get('y2', 0))
         d = "M %s,%s L %s,%s" % (x1, y1, x2, y2)
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('circle','svg'):
         cx = float(node.get('cx', 0))
         cy = float(node.get('cy', 0))
         r = float(node.get('r'))
         d = "m %s,%s a %s,%s 0 0 1 %s,%s %s,%s 0 0 1 %s,%s z" % (cx + r, cy, r, r, -2*r, 0, r, r, 2*r, 0)
         p = cubicsuperpath.parsePath(d)
     elif node.tag == inkex.addNS('ellipse','svg'):
         cx = float(node.get('cx', 0))
         cy = float(node.get('cy', 0))
         rx = float(node.get('rx'))
         ry = float(node.get('ry'))
         d = "m %s,%s a %s,%s 0 0 1 %s,%s %s,%s 0 0 1 %s,%s z" % (cx + rx, cy, rx, ry, -2*rx, 0, rx, ry, 2*rx, 0)
         p = cubicsuperpath.parsePath(d)
     else:
         return
     trans = node.get('transform')
     if trans:
         mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
     simpletransform.applyTransformToPath(mat, p)
     for sub in p:
         for i in range(len(sub)-1):
             s = sub[i]
             e = sub[i+1]
             if s[1] == s[2] and e[0] == e[1]:
                 if (self.options.POLY == 'true'):
                     self.LWPOLY_line([s[1],e[1]])
                 else:
                     self.dxf_line([s[1],e[1]])
             elif (self.options.ROBO == 'true'):
                 self.ROBO_spline([s[1],s[2],e[0],e[1]])
             else:
                 self.dxf_spline([s[1],s[2],e[0],e[1]])
Example #54
0
 def effect(self):
     if self.options.mformat == '"presets"':
         self.setPreset()
     # get number of digits
     prec = int(self.options.precision)
     scale = self.unittouu('1px')  # convert to document units
     self.options.offset *= scale
     factor = 1.0
     doc = self.document.getroot()
     if doc.get('viewBox'):
         [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
         factor = self.unittouu(doc.get('width')) / float(vieww)
         if self.unittouu(doc.get('height')) / float(viewh) < factor:
             factor = self.unittouu(doc.get('height')) / float(viewh)
         factor /= self.unittouu('1px')
         self.options.fontsize /= factor
     factor *= scale / self.unittouu('1' + self.options.unit)
     # loop over all selected paths
     for id, node in self.selected.iteritems():
         if node.tag == inkex.addNS('path', 'svg'):
             mat = simpletransform.composeParents(
                 node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
             p = cubicsuperpath.parsePath(node.get('d'))
             simpletransform.applyTransformToPath(mat, p)
             if self.options.mtype == "length":
                 slengths, stotal = csplength(p)
                 self.group = inkex.etree.SubElement(
                     node.getparent(), inkex.addNS('text', 'svg'))
             elif self.options.mtype == "area":
                 stotal = abs(csparea(p) * factor * self.options.scale)
                 self.group = inkex.etree.SubElement(
                     node.getparent(), inkex.addNS('text', 'svg'))
             else:
                 xc, yc = cspcofm(p)
                 self.group = inkex.etree.SubElement(
                     node.getparent(), inkex.addNS('path', 'svg'))
                 self.group.set('id', 'MassCenter_' + node.get('id'))
                 self.addCross(self.group, xc, yc, scale)
                 continue
             # Format the length as string
             lenstr = locale.format("%(len)25." + str(prec) + "f", {
                 'len':
                 round(stotal * factor * self.options.scale, prec)
             }).strip()
             if self.options.mformat == '"textonpath"':
                 startOffset = self.options.startOffset
                 if startOffset == "custom":
                     startOffset = str(self.options.startOffsetCustom) + '%'
                 if self.options.mtype == "length":
                     self.addTextOnPath(self.group, 0, 0,
                                        lenstr + ' ' + self.options.unit,
                                        id, self.options.anchor,
                                        startOffset, self.options.offset)
                 else:
                     self.addTextOnPath(
                         self.group, 0, 0,
                         lenstr + ' ' + self.options.unit + '^2', id,
                         self.options.anchor, startOffset,
                         self.options.offset)
             elif self.options.mformat == '"fixedtext"':
                 if self.options.position == "mass":
                     tx, ty = cspcofm(p)
                     anchor = 'middle'
                 elif self.options.position == "center":
                     bbox = simpletransform.computeBBox([node])
                     tx = bbox[0] + (bbox[1] - bbox[0]) / 2.0
                     ty = bbox[2] + (bbox[3] - bbox[2]) / 2.0
                     anchor = 'middle'
                 else:  # default
                     tx = p[0][0][1][0]
                     ty = p[0][0][1][1]
                     anchor = 'start'
                 if self.options.mtype == "length":
                     self.addTextWithTspan(
                         self.group, tx, ty,
                         lenstr + ' ' + self.options.unit, id, anchor,
                         -int(self.options.angle),
                         self.options.offset + self.options.fontsize / 2)
                 else:
                     self.addTextWithTspan(
                         self.group, tx, ty,
                         lenstr + ' ' + self.options.unit + '^2', id,
                         anchor, -int(self.options.angle),
                         -self.options.offset + self.options.fontsize / 2)
             else:
                 # center of mass, no text
                 pass
Example #55
0
    def effect(self):
        object2path.ObjectToPath.effect(self)
        self.dxf += self.dxf_add_codes([('999', 'Inkscape export via OpenSCAD DXF Export')])
        self.dxf += dxf_templates.r14_header
        
        scale = 25.4/90.0
        h = self.unittouu(self.document.getroot().xpath('@height',namespaces=inkex.NSS)[0])

        path = '//svg:path'
        pm = pathmodifier.PathModifier()
        layers = []
        dxf_body = ''
        for node in self.document.getroot().xpath(path,namespaces=inkex.NSS):
            pm.objectToPath(node, True)
            layer = node.getparent().get(inkex.addNS('label', 'inkscape'))
            if layer == None:
                layer = 'Layer 1'
            layer = layer.replace(' ', '_')

            if layer not in layers:
                layers.append(layer)
                self.layer_dims[layer] = {
                    'minX':None,
                    'minY':None,
                    'maxX':None,
                    'maxY':None
                }

            d = node.get('d')
            color = (0,0,0)
            style = node.get('style')
            if style:
                style = simplestyle.parseStyle(style)
                if style.has_key('stroke'):
                    if style['stroke'] and style['stroke'] != 'none':
                        color = simplestyle.parseColor(style['stroke'])

            p = cubicsuperpath.parsePath(d)
            
            t = node.get('transform')
            if t != None:
                m = simpletransform.parseTransform(t)
                simpletransform.applyTransformToPath(m,p)
            
            m = [[scale,0,0],[0,-scale,h*scale]]
            simpletransform.applyTransformToPath(m,p)

            dxf_body += self.dxf_path_to_lines(layer, p, color)

        self.dxf += self.dxf_add_codes([
            ('0', 'TABLE'),
            ('2', 'LAYER'),
            ('5', '2'),
            ('330', '0'),
            ('100', 'AcDbSymbolTable'),
            # group code 70 tells a reader how many table records to expect (e.g. pre-allocate memory for).
            # It must be greater or equal to the actual number of records
            ('70', str(len(layers)))
        ])

        # Add dimensions for total width and height
        dxf_dims = self.dxf_add_dimension('total_width', 
            [self.global_dims['minX'], self.global_dims['maxX']])
        dxf_dims += self.dxf_add_dimension('total_height', 
            None, [self.global_dims['minY'], self.global_dims['maxY']])
        for layer in layers:
            self.dxf += self.dxf_add_codes([
                ('0', 'LAYER'),
                ('5', '10'),
                ('330', '2'),
                ('100', 'AcDbSymbolTableRecord'),
                ('100', 'AcDbLayerTableRecord'),
                ('2', layer),
                ('70', '0'),
                ('62', '7'),
                ('6', 'CONTINUOUS')
            ])
            # Add dimensions for layer width and height
            dxf_dims += self.dxf_add_dimension(layer + '_width', 
                [self.layer_dims[layer]['minX'], self.layer_dims[layer]['maxX']], None, layer)
            dxf_dims += self.dxf_add_dimension(layer + '_height', 
                None, [self.layer_dims[layer]['minY'], self.layer_dims[layer]['maxY']], layer)

        self.dxf += self.dxf_add_codes([
            ('0', 'ENDTAB'),
            ('0', 'ENDSEC')
        ])

        self.dxf += dxf_templates.r14_style
        self.dxf += dxf_dims
        self.dxf += dxf_body

        self.dxf += dxf_templates.r14_footer
Example #56
0
	def compute_bbox(self, node, transform=True, use_cache=False):
		'''
		Compute the bounding box of a element in its parent coordinate system,
		or in its own coordinate system if "transform" is False.

		Uses a cache to not compute the bounding box multiple times for
		elements like referenced symbols.

		Returns [xmin, xmax, ymin, ymax]

		Enhanced version of simpletransform.computeBBox()

		Warning: Evaluates "transform" attribute for symbol tags, which is
		wrong according to SVG spec, but matches Inkscape's behaviour.
		'''
		import cubicsuperpath
		from simpletransform import boxunion, parseTransform, applyTransformToPath, formatTransform
		try:
			from simpletransform import refinedBBox
		except:
			from simpletransform import roughBBox as refinedBBox

		d = None
		recurse = False
		node_bbox = None

		if transform:
			transform = node.get('transform', '')
		else:
			transform = ''

		if use_cache and node in self.bbox_cache:
			node_bbox = self.bbox_cache[node]
		elif node.tag in [ svg_use, 'use' ]:
			x, y = float(node.get('x', 0)), float(node.get('y', 0))
			refid = node.get(xlink_href)
			refnode = self.getElementById(refid[1:])

			if refnode is None:
				return None

			if 'width' in node.attrib and 'height' in node.attrib and 'viewBox' in refnode.attrib:
				mat = parseViewBox(refnode.get('viewBox'), node.get('width'), node.get('height'))
				transform += ' ' + formatTransform(mat)

			refbbox = self.compute_bbox(refnode, True, True)
			if refbbox is not None:
				node_bbox = [refbbox[0] + x, refbbox[1] + x, refbbox[2] + y, refbbox[3] + y]

		elif node.get('d'):
			d = node.get('d')
		elif node.get('points'):
			d = 'M' + node.get('points')
		elif node.tag in [ svg_rect, 'rect', svg_image, 'image' ]:
			d = 'M' + node.get('x', '0') + ',' + node.get('y', '0') + \
				'h' + node.get('width') + 'v' + node.get('height') + \
				'h-' + node.get('width')
		elif node.tag in [ svg_line, 'line' ]:
			d = 'M' + node.get('x1') + ',' + node.get('y1') + \
				' ' + node.get('x2') + ',' + node.get('y2')
		elif node.tag in [ svg_circle, 'circle', svg_ellipse, 'ellipse' ]:
			rx = node.get('r')
			if rx is not None:
				ry = rx
			else:
				rx = node.get('rx')
				ry = node.get('ry')
			rx, ry = float(rx), float(ry)
			cx = float(node.get('cx', '0'))
			cy = float(node.get('cy', '0'))
			node_bbox = [cx - rx, cx + rx, cy - ry, cy + ry]
			'''
			a = 0.555
			d = 'M %f %f C' % (cx-rx, cy) + ' '.join('%f' % c for c in [
				cx-rx,   cy-ry*a, cx-rx*a, cy-ry,   cx,    cy-ry,
				cx+rx*a, cy-ry,   cx+rx,   cy-ry*a, cx+rx, cy,
				cx+rx,   cy+ry*a, cx+rx*a, cy+ry,   cx,    cy+ry,
				cx-rx*a, cy+ry,   cx-rx,   cy+ry*a, cx-rx, cy,
				])
			'''
		elif node.tag in [ svg_text, 'text', svg_tspan, 'tspan' ]:
			# very rough estimate of text bounding box
			x = node.get('x', '0').split()
			y = node.get('y', '0').split()
			if len(x) == 1 and len(y) > 1:
				x = x * len(y)
			elif len(y) == 1 and len(x) > 1:
				y = y * len(x)
			d = 'M' + ' '.join('%f' % self.unittouu(c) for xy in zip(x, y) for c in xy)
			recurse = True
		elif node.tag in [ svg_g, 'g', svg_symbol, 'symbol', svg_svg, 'svg' ]:
			recurse = True

		if d is not None:
			p = cubicsuperpath.parsePath(d)
			node_bbox = refinedBBox(p)

		if recurse:
			for child in node:
				child_bbox = self.compute_bbox(child, True, use_cache)
				node_bbox = boxunion(child_bbox, node_bbox)

		self.bbox_cache[node] = node_bbox

		if transform.strip() != '' and node_bbox != None:
			mat = parseTransform(transform)
			p = [[[	[node_bbox[0], node_bbox[2]],
					[node_bbox[0], node_bbox[3]],
					[node_bbox[1], node_bbox[2]],
					[node_bbox[1], node_bbox[3]]]]]
			applyTransformToPath(mat, p)
			x, y = zip(*p[0][0])
			node_bbox = [min(x), max(x), min(y), max(y)]

		return node_bbox