Ejemplo n.º 1
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()
Ejemplo n.º 2
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))
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
	def effect(self):
		zoom = self.unittouu( str(self.options.zoom) + 'px')

		if self.options.randomize:
			imagelist = generate_random_string(self.options.text, zoom)
		else:
			tokens = tokenize(self.options.text)
			imagelist = randomize_input_string(tokens, zoom)

		image = layoutstring( imagelist, zoom )

		if image:
			s = { 'stroke': 'none', 'fill': '#000000' }

			new = inkex.etree.Element(inkex.addNS('path','svg'))
			new.set('style', simplestyle.formatStyle(s))

			new.set('d', simplepath.formatPath(image))
			self.current_layer.append(new)

			# compensate preserved transforms of parent layer
			if self.current_layer.getparent() is not None:
				mat = simpletransform.composeParents(self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
				simpletransform.applyTransformToNode(simpletransform.invertTransform(mat), new)
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
Ejemplo n.º 6
0
    def effect(self):
        if not self.options.ids:
            inkex.errormsg(_("Please select an object"))
            exit()
        scale = self.unittouu('1px')            # convert to document units
        self.options.size *= scale
        self.options.border *= scale
        q = {'x':0,'y':0,'width':0,'height':0}  # query the bounding box of ids[0]
        for query in q.keys():
            p = Popen('inkscape --query-%s --query-id=%s "%s"' % (query, self.options.ids[0], self.args[-1]), shell=True, stdout=PIPE, stderr=PIPE)
            rc = p.wait()
            q[query] = scale*float(p.stdout.read())
        mat = simpletransform.composeParents(self.selected[self.options.ids[0]], [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
        defs = self.xpathSingle('/svg:svg//svg:defs')
        pattern = inkex.etree.SubElement(defs ,inkex.addNS('pattern','svg'))
        pattern.set('id', 'Voronoi' + str(random.randint(1, 9999)))
        pattern.set('width', str(q['width']))
        pattern.set('height', str(q['height']))
        pattern.set('patternTransform', 'translate(%s,%s)' % (q['x'] - mat[0][2], q['y'] - mat[1][2]))
        pattern.set('patternUnits', 'userSpaceOnUse')

        # generate random pattern of points
        c = voronoi.Context()
        pts = []
        b = float(self.options.border)          # width of border
        for i in range(int(q['width']*q['height']/self.options.size/self.options.size)):
            x = random.random()*q['width']
            y = random.random()*q['height']
            if b > 0:                           # duplicate border area
                pts.append(voronoi.Site(x, y))
                if x < b:
                    pts.append(voronoi.Site(x + q['width'], y))
                    if y < b:
                        pts.append(voronoi.Site(x + q['width'], y + q['height']))
                    if y > q['height'] - b:
                        pts.append(voronoi.Site(x + q['width'], y - q['height']))
                if x > q['width'] - b:
                    pts.append(voronoi.Site(x - q['width'], y))
                    if y < b:
                        pts.append(voronoi.Site(x - q['width'], y + q['height']))
                    if y > q['height'] - b:
                        pts.append(voronoi.Site(x - q['width'], y - q['height']))
                if y < b:
                    pts.append(voronoi.Site(x, y + q['height']))
                if y > q['height'] - b:
                    pts.append(voronoi.Site(x, y - q['height']))
            elif x > -b and y > -b and x < q['width'] + b and y < q['height'] + b:
                pts.append(voronoi.Site(x, y))  # leave border area blank
            # dot = inkex.etree.SubElement(pattern, inkex.addNS('rect','svg'))
            # dot.set('x', str(x-1))
            # dot.set('y', str(y-1))
            # dot.set('width', '2')
            # dot.set('height', '2')
        if len(pts) < 3:
            inkex.errormsg("Please choose a larger object, or smaller cell size")
            exit()

        # plot Voronoi diagram
        sl = voronoi.SiteList(pts)
        voronoi.voronoi(sl, c)
        path = ""
        for edge in c.edges:
            if edge[1] >= 0 and edge[2] >= 0:       # two vertices
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], c.vertices[edge[2]][0], c.vertices[edge[2]][1], q['width'], q['height'])
            elif edge[1] >= 0:                      # only one vertex
                if c.lines[edge[0]][1] == 0:        # vertical line
                    xtemp = c.lines[edge[0]][2]/c.lines[edge[0]][0]
                    if c.vertices[edge[1]][1] > q['height']/2:
                        ytemp = q['height']
                    else:
                        ytemp = 0
                else:
                    xtemp = q['width']
                    ytemp = (c.lines[edge[0]][2] - q['width']*c.lines[edge[0]][0])/c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], xtemp, ytemp, q['width'], q['height'])
            elif edge[2] >= 0:                      # only one vertex
                if c.lines[edge[0]][1] == 0:        # vertical line
                    xtemp = c.lines[edge[0]][2]/c.lines[edge[0]][0]
                    if c.vertices[edge[2]][1] > q['height']/2:
                        ytemp = q['height']
                    else:
                        ytemp = 0
                else:
                    xtemp = 0
                    ytemp = c.lines[edge[0]][2]/c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(xtemp, ytemp, c.vertices[edge[2]][0], c.vertices[edge[2]][1], q['width'], q['height'])
            if x1 or x2 or y1 or y2:
                path += 'M %.3f,%.3f %.3f,%.3f ' % (x1, y1, x2, y2)

        patternstyle = {'stroke': '#000000', 'stroke-width': str(scale)}
        attribs = {'d': path, 'style': simplestyle.formatStyle(patternstyle)}
        inkex.etree.SubElement(pattern, inkex.addNS('path', 'svg'), attribs)

        # link selected object to pattern
        obj = self.selected[self.options.ids[0]]
        style = {}
        if obj.attrib.has_key('style'):
            style = simplestyle.parseStyle(obj.attrib['style'])
        style['fill'] = 'url(#%s)' % pattern.get('id')
        obj.attrib['style'] = simplestyle.formatStyle(style)
        if obj.tag == inkex.addNS('g', 'svg'):
            for node in obj:
                style = {}
                if node.attrib.has_key('style'):
                    style = simplestyle.parseStyle(node.attrib['style'])
                style['fill'] = 'url(#%s)' % pattern.get('id')
                node.attrib['style'] = simplestyle.formatStyle(style)
Ejemplo n.º 7
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)    
Ejemplo n.º 8
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
Ejemplo n.º 9
0
    def effect(self):

        docW = self.unittouu(self.document.getroot().get('width'))
        docH = self.unittouu(self.document.getroot().get('height'))

        boxW = self.unittouu( str(self.options.width)  + self.options.unit )
        boxH = self.unittouu( str(self.options.height) + self.options.unit )
        boxD = self.unittouu( str(self.options.depth)  + self.options.unit )
        tabProp = self.options.tabProportion
        tabH = boxD * tabProp

        box_id = self.uniqueId('box')
        self.box = g = inkex.etree.SubElement(self.current_layer, 'g', {'id':box_id})

        line_style = simplestyle.formatStyle({ 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) })

        #self.createGuide( 0, docH, 0 );

        # Inner Close Tab
        line_path = [
                      [ 'M', [ boxW-(tabH*0.7),  0 ] ],
                      [ 'C', [ boxW-(tabH*0.25), 0, boxW, tabH*0.3, boxW, tabH*0.9 ] ],
                      [ 'L', [ boxW, tabH     ] ],
                      [ 'L', [ 0,    tabH     ] ],
                      [ 'L', [ 0,    tabH*0.9 ] ],
                      [ 'C', [ 0,    tabH*0.3, tabH*0.25, 0, tabH*0.7, 0 ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-inner-close-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        lower_pos = boxD+tabH
        left_pos = 0

        #self.createGuide( 0, docH-tabH, 0 );

        # Upper Close Tab
        line_path = [
                      [ 'M', [ left_pos,        tabH      ] ],
                      [ 'L', [ left_pos + boxW, tabH      ] ],
                      [ 'L', [ left_pos + boxW, lower_pos ] ],
                      [ 'L', [ left_pos + 0,    lower_pos ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-upper-close-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Upper Right Tab
        sideTabH = lower_pos - (boxW/2)
        if sideTabH < tabH: sideTabH = tabH
        line_path = [
                      [ 'M', [ left_pos,        sideTabH  ] ],
                      [ 'L', [ left_pos + (boxD*0.8), sideTabH  ] ],
                      [ 'L', [ left_pos + boxD, ((lower_pos*3)-sideTabH)/3 ] ],
                      [ 'L', [ left_pos + boxD, lower_pos ] ],
                      [ 'L', [ left_pos + 0,    lower_pos ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-upper-right-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW + boxD

        # Upper Left Tab
        line_path = [
                      [ 'M', [ left_pos + boxD,       sideTabH  ] ],
                      [ 'L', [ left_pos + (boxD*0.2), sideTabH  ] ],
                      [ 'L', [ left_pos, ((lower_pos*3)-sideTabH)/3 ] ],
                      [ 'L', [ left_pos,              lower_pos ] ],
                      [ 'L', [ left_pos + boxD,       lower_pos ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-upper-left-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos = 0

        #self.createGuide( 0, docH-tabH-boxD, 0 );

        # Right Tab
        line_path = [
                      [ 'M', [ left_pos,            lower_pos                   ] ],
                      [ 'L', [ left_pos - (boxD/2), lower_pos + (boxD/4)        ] ],
                      [ 'L', [ left_pos - (boxD/2), lower_pos + boxH - (boxD/4) ] ],
                      [ 'L', [ left_pos,            lower_pos + boxH            ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-left-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        # Front
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-front', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Right
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-right', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxD

        # Back
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-back', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Left
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-left', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        lower_pos += boxH
        left_pos = 0
        bTab = lower_pos + boxD
        if bTab > boxW / 2.5: bTab = boxW / 2.5

        # Bottom Front Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos            ] ],
                      [ 'L', [ left_pos,        lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos            ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-front-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Bottom Right Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos,        lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-right-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxD

        # Bottom Back Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos            ] ],
                      [ 'L', [ left_pos,        lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos            ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-back-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Bottom Left Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos,        lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-left-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxD
        lower_pos += bTab

        g.set( 'transform', 'translate(%f,%f)' % ( (docW-left_pos)/2, (docH-lower_pos)/2 ) )

        # compensate preserved transforms of parent layer
        if self.current_layer.getparent() is not None:
            mat = simpletransform.composeParents(self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
            simpletransform.applyTransformToNode(simpletransform.invertTransform(mat), g)
Ejemplo n.º 10
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] 
        
        id_min = 0
        id_max = 1
        minOrigin = []
        maxOrigin = []
        # Set bigger and smaller object
        if obj_lengths[id_min] > obj_lengths[id_max]:
            id_min = 1
            id_max = 0
            
        minOrigin = originParse(obj_nodes[id_min])
        maxOrigin = originParse(obj_nodes[id_max])
        
        #Scaling Radio Button Options
        if self.options.radioScale == "B2S":
            ratio = obj_lengths[id_min] / obj_lengths[id_max]
            obj_ori = []
            ori_trans = []      
            obj_nodes[id_max].set('transform', 'scale(' + str(ratio) + ' ' + str(ratio) +')')      
            fuseTransform(obj_nodes[id_max])

            obj_ori = originParse(obj_nodes[id_max])
            ori_trans = [(maxOrigin[0] - obj_ori[0]), (maxOrigin[1] - obj_ori[1])]
            obj_nodes[id_max].set('transform', 'translate(' + str(ori_trans[0]) + ' ' + str(ori_trans[1]) +')')
            fuseTransform(obj_nodes[id_max])
            
        elif self.options.radioScale == "S2B":
            ratio = obj_lengths[id_max] / obj_lengths[id_min]
            obj_ori = []
            ori_trans = []
            obj_nodes[id_min].set('transform', 'scale(' + str(ratio) + ' ' + str(ratio) +')')
            fuseTransform(obj_nodes[id_min])
            
            obj_ori = originParse(obj_nodes[id_min])
            ori_trans = [(minOrigin[0] - obj_ori[0]), (minOrigin[1] - obj_ori[1])]
            obj_nodes[id_min].set('transform', 'translate(' + str(ori_trans[0]) + ' ' + str(ori_trans[1]) +')')
            fuseTransform(obj_nodes[id_min])
        
        # 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 = []
        # Run Functions based on active Tab
        if self.options.tab == "\"stitch\"":
            addStitching(obj_nodes[id_min], self.options.points, self.options.offset, self.options.paraStitch, doc)
            addStitching(obj_nodes[id_max], self.options.points, self.options.offset, self.options.paraStitch, doc)
        elif self.options.tab == "\"tooth\"":
            addNotches(obj_nodes[id_min], self.options.points, self.options.offset, False, self.options.paraTooth,doc)
            addNotches(obj_nodes[id_max], self.options.points, self.options.offset, True, self.options.paraTooth,doc)
        elif self.options.tab == "\"leaf\"": 
            addLeaves(obj_nodes[id_min], self.options.points, self.options.offset, self.options.paraLeaf, doc)
            addLeaves(obj_nodes[id_max], self.options.points, self.options.offset, self.options.paraLeaf, doc)
Ejemplo n.º 11
0
def generatePoints(obj, offset, n):
# Create n equidistant points around the path
    pointList = []  
    targetDist = offset * read_stored_info("pathlength", obj)/ n 
    segmentLengths = [0.0] + read_stored_info("segmentlengths", obj)[::-1]
    
    mat = simpletransform.composeParents(obj, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
    p = cubicsuperpath.parsePath(obj.get('d'))
    simpletransform.applyTransformToPath(mat, p)
    
    segments = p[0]
    new_path = segments
    
    i = 0
    count = 0
    total = 0
    
    while i < len(segments): 
    # Cycle through path and add a node where targetDist = 0
        if segmentLengths[i] == targetDist:
            pointList += [segments[i][1]]
            targetDist = read_stored_info("pathlength", obj)/ n

        elif targetDist > segmentLengths[i] or segmentLengths[i] == 0:
            targetDist -= segmentLengths[i]

        else:
            t = targetDist / float(segmentLengths[i]) 
            
            t1 = segments[i-1][1]
            t2 = segments[i][1]
            
            pathList = addnodes.cspbezsplitatlength(segments[i-1], segments[i], t,tolerance=0.00001)
            pointList += [pathList[1][1]]
            prev = segments[:i - 1]
            next = segments[i + 1:]
            segments = prev + pathList + next
            
            len1 = targetDist
            len2 = segmentLengths[i] - targetDist
            
            if abs((len1 + len2) - segmentLengths[i]) >= 0.0001:
                raise Exception("There is an issue with the bezier split function. (" + str(len1 + len2) + " vs. " + str(segmentLengths[i]) + ")")
                
            
            prev = segmentLengths[:i]
            next = segmentLengths[i+1:]

            segmentLengths = prev + [len1, len2] + next
        
            targetDist = read_stored_info("pathlength", obj)/n           
            
            count += 1
        if(len(pointList) == n):
            break;
        i += 1
    
    pointList += [segments[0][1]]
    
    if abs(sum(segmentLengths) - read_stored_info("pathlength", obj)) >= 0.001:
        raise Exception("Internal Error: The total length of the new path does not equal the original path.")
    obj.set('d', cubicsuperpath.formatPath([segments[:-1]])+'Z')
    obj.set('segmentlengths', str(segmentLengths))
      
    return pointList 
Ejemplo n.º 12
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
     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.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,
                     )
Ejemplo n.º 13
0
    def effect(self):
        if len(self.options.ids) < 2:
            inkex.errormsg(_("This extension requires two selected paths."))
            exit()            
            
        #obj is selected second
        obj = self.selected[self.options.ids[0]]
        envelope = 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 envelope.tag == inkex.addNS('path','svg'):
                mat = simpletransform.composeParents(envelope, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
                path = cubicsuperpath.parsePath(envelope.get('d'))
                if len(path) < 1 or len(path[0]) < 4:
                    inkex.errormsg(_("This extension requires that the second selected path be four nodes long."))
                    exit()
                simpletransform.applyTransformToPath(mat, path)
                dp = zeros((4,2), dtype=float64)
                for i in range(4):
                    dp[i][0] = path[0][i][1][0]
                    dp[i][1] = path[0][i][1][1]

                #query inkscape about the bounding box of obj
                q = {'x':0,'y':0,'width':0,'height':0}
                file = self.args[-1]
                id = self.options.ids[0]
                for query in 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()
                        q[query] = float(p.stdout.read())
                        err = p.stderr.read()
                    else:
                        f,err = os.popen3('inkscape --query-%s --query-id=%s "%s"' % (query,id,file))[1:]
                        q[query] = float(f.read())
                        f.close()
                        err.close()
                sp = array([[q['x'], q['y']+q['height']],[q['x'], q['y']],[q['x']+q['width'], q['y']],[q['x']+q['width'], q['y']+q['height']]], dtype=float64)
            else:
                if envelope.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()

        solmatrix = zeros((8,8), dtype=float64)
        free_term = zeros((8), dtype=float64)
        for i in (0,1,2,3):
            solmatrix[i][0] = sp[i][0]
            solmatrix[i][1] = sp[i][1]
            solmatrix[i][2] = 1
            solmatrix[i][6] = -dp[i][0]*sp[i][0]
            solmatrix[i][7] = -dp[i][0]*sp[i][1]
            solmatrix[i+4][3] = sp[i][0]
            solmatrix[i+4][4] = sp[i][1]
            solmatrix[i+4][5] = 1
            solmatrix[i+4][6] = -dp[i][1]*sp[i][0]
            solmatrix[i+4][7] = -dp[i][1]*sp[i][1]
            free_term[i] = dp[i][0]
            free_term[i+4] = dp[i][1]

        res = solve(solmatrix, free_term)
        projmatrix = array([[res[0],res[1],res[2]],[res[3],res[4],res[5]],[res[6],res[7],1.0]],dtype=float64)
        if obj.tag == inkex.addNS("path",'svg'):
            self.process_path(obj,projmatrix)
        if obj.tag == inkex.addNS("g",'svg'):
            self.process_group(obj,projmatrix)