def _render(self, parent):
     qrcode = self._generate()
     if not qrcode:
         return
     
     # Parse SVG and draw elements to the workspace
     output = StringIO()
     qrcode.save(output)
     output.seek(0)
     tree = ElementTree()
     tree.parse(output)
     root = tree.getroot()
 
     vbox = map(int, root.get("viewBox").split())
     vbox = vbox[0]-self.options.padding*self.options.size/10, \
            vbox[1]-self.options.padding*self.options.size/10, \
            vbox[2]+2*self.options.padding*self.options.size/10, \
            vbox[3]+2*self.options.padding*self.options.size/10
     vbox = map(str, vbox)
 
     rect = inkex.etree.SubElement(
             parent,
             inkex.addNS('rect', 'svg'),
             {"x": vbox[0],
              "y": vbox[1],
              "width": vbox[2],
              "height": vbox[3],
              "style": "fill:#fff;"})
     for m in root.getchildren():
         attribs = {}
         for k in m.keys():
             attribs[k] = str(m.get(k))
         inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'), attribs)
def computeBBox(aList,mat=[[1,0,0],[0,1,0]]):
    bbox=None
    for node in aList:
        m = parseTransform(node.get('transform'))
        m = composeTransform(mat,m)
        #TODO: text not supported!
        if node.get("d"):
            d = node.get('d')
            p = cubicsuperpath.parsePath(d)
            applyTransformToPath(m,p)
            bbox=boxunion(roughBBox(p),bbox)

        elif node.tag == inkex.addNS('rect','svg') or node.tag=='rect':
            w = float(node.get('width'))/2.
            h = float(node.get('height'))/2.
            x = float(node.get('x'))
            y = float(node.get('y'))
            C = [x + w , y + h ]
            applyTransformToPoint(mat,C)
            xmin = C[0] - abs(m[0][0]) * w - abs(m[0][1]) * h
            xmax = C[0] + abs(m[0][0]) * w + abs(m[0][1]) * h
            ymin = C[1] - abs(m[1][0]) * w - abs(m[1][1]) * h
            ymax = C[1] + abs(m[1][0]) * w + abs(m[1][1]) * h
            bbox = xmin,xmax,ymin,ymax
            
        elif node.tag == inkex.addNS('use','svg') or node.tag=='use':
            refid=node.get(inkex.addNS('href','xlink'))
            path = '//*[@id="%s"]' % refid[1:]
            refnode = node.xpath(path)
            bbox=boxunion(computeBBox(refnode,m),bbox)
            
        bbox=boxunion(computeBBox(node,m),bbox)
    return bbox
Example #3
0
def draw_SVG_circle(r, cx, cy, width, fill, name, parent):
    style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': fill }
    circ_attribs = {'style':simplestyle.formatStyle(style),
                    'cx':str(cx), 'cy':str(cy), 
                    'r':str(r),
                    inkex.addNS('label','inkscape'):name}
    circle = inkex.etree.SubElement(parent, inkex.addNS('circle','svg'), circ_attribs )
    def drawCircles(self, circles, trans_point = (0.0, 0.0)):
        parent = self.current_layer
        i = 0
        for layer in circles:
            for c in layer:
                x = trans_point[0] + c.x
                y = trans_point[1] + c.y

                if not self.options.tinned:
                    material = 'CU'
                    color = '#aa4400'
                else:
                    material = 'CU-T'
                    color = '#808080'

                style = {'stroke': 'none', 'fill': color}

                attribs = {'cx': str(x), 
                           'cy': str(y), 
                           'r': str(c.r),
                           inkex.addNS('label', 'inkscape'):"is%d" %i,
                           'material':material,
                           'style': simplestyle.formatStyle(style)}

                inkex.etree.SubElement(parent, inkex.addNS('circle', 'svg'),
                        attribs)
                i += 1
Example #5
0
    def effect(self):
        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path','svg'):
                p = simplepath.parsePath(node.get('d'))
                a =[]
                pen = None
                subPathStart = None
                for cmd,params in p:
                    if cmd == 'C':
                        a.extend([['M', params[:2]], ['L', pen],
                            ['M', params[2:4]], ['L', params[-2:]]])
                    if cmd == 'Q':
                        a.extend([['M', params[:2]], ['L', pen],
                            ['M', params[:2]], ['L', params[-2:]]])
                    
                    if cmd == 'M':
                        subPathStart = params

                    if cmd == 'Z':
                        pen = subPathStart
                    else:
                        pen = params[-2:]
                    
                if len(a) > 0:
                    s = {'stroke-linejoin': 'miter', 'stroke-width': '1.0px', 
                        'stroke-opacity': '1.0', 'fill-opacity': '1.0', 
                        'stroke': '#000000', 'stroke-linecap': 'butt', 
                        'fill': 'none'}
                    attribs = {'style':simplestyle.formatStyle(s),'d':simplepath.formatPath(a)}
                    inkex.etree.SubElement(node.getparent(), inkex.addNS('path','svg'), attribs)
def draw_SVG_circle(parent, r, cx, cy, name, style):
    " add an SVG circle entity to parent "
    circ_attribs = {'style': simplestyle.formatStyle(style),
                    'cx': str(cx), 'cy': str(cy), 
                    'r': str(r),
                    inkex.addNS('label','inkscape'):name}
    circle = inkex.etree.SubElement(parent, inkex.addNS('circle','svg'), circ_attribs )
Example #7
0
	def joinFillsWithNode ( self, node, stroke_width, path ):

		'''
		Generate a SVG <path> element containing the path data "path".
		Then put this new <path> element into a <group> with the supplied
		node.  This means making a new <group> element and moving node
		under it with the new <path> as a sibling element.
		'''

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

		# Make a new SVG <group> element whose parent is the parent of node
		parent = node.getparent()
		#was: if not parent:
		if parent is None:
			parent = self.document.getroot()
		g = inkex.etree.SubElement( parent, inkex.addNS( 'g', 'svg' ) )

		# Move node to be a child of this new <g> element
		g.append( node )

		# Now make a <path> element which contains the hatches & is a child
		# of the new <g> element
		style = { 'stroke': '#000000', 'fill': 'none', 'stroke-width': '%f' % stroke_width}
		line_attribs = { 'style':simplestyle.formatStyle( style ), 'd': path }
		tran = node.get( 'transform' )
		if ( tran != None ) and ( tran != '' ):
			line_attribs['transform'] = tran
		inkex.etree.SubElement( g, inkex.addNS( 'path', 'svg' ), line_attribs )
Example #8
0
    def make_double_line(self, length):
        opt = self.options
        
        w1 = float(opt.stroke_width_1)
        w2 = float(opt.stroke_width_2)
        offset = 0.5*(w1 + w2)

        line = inkex.etree.Element('g')

        style_line1 = {
                'fill': 'none',
                'stroke': simplestyle.svgcolors[opt.stroke_color_1],
                'stroke-width': opt.stroke_width_1+'px',}
        path_atts_1 = {
            inkex.addNS('connector-curvature', 'inkscape'): "0",
            'd': "M 0.0,0.0 %f,0.0" % (length,),
            'style': simplestyle.formatStyle(style_line1), }
        inkex.etree.SubElement(line, 'path', path_atts_1)

        style_line2 = {
                'fill': 'none',
                'stroke': simplestyle.svgcolors[opt.stroke_color_2],
                'stroke-width': opt.stroke_width_2+'px',}
        path_atts_2 = {
            inkex.addNS('connector-curvature', 'inkscape'): "0",
            'd': "M 0.0,%f %f,%f.0" % (offset, length, offset),
            'style': simplestyle.formatStyle(style_line2),}
        inkex.etree.SubElement(line, 'path', path_atts_2)
            
        return line
Example #9
0
 def process_clone(self, node):
     trans = node.get('transform')
     x = node.get('x')
     y = node.get('y')
     mat = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
     if trans:
         mat = simpletransform.composeTransform(mat, simpletransform.parseTransform(trans))
     if x:
         mat = simpletransform.composeTransform(mat, [[1.0, 0.0, float(x)], [0.0, 1.0, 0.0]])
     if y:
         mat = simpletransform.composeTransform(mat, [[1.0, 0.0, 0.0], [0.0, 1.0, float(y)]])
     # push transform
     if trans or x or y:
         self.groupmat.append(simpletransform.composeTransform(self.groupmat[-1], mat))
     # get referenced node
     refid = node.get(inkex.addNS('href','xlink'))
     refnode = self.getElementById(refid[1:])
     if refnode is not None:
         if refnode.tag == inkex.addNS('g','svg'):
             self.process_group(refnode)
         elif refnode.tag == inkex.addNS('use', 'svg'):
             self.process_clone(refnode)
         else:
             self.process_shape(refnode, self.groupmat[-1])
     # pop transform
     if trans or x or y:
         self.groupmat.pop()
Example #10
0
def export_MTEXT():
    # mandatory group codes : (1 or 3, 10, 20) (text, x, y)
    if (vals[groups['1']] or vals[groups['3']]) and vals[groups['10']] and vals[groups['20']]:
        x = vals[groups['10']][0]
        y = vals[groups['20']][0]
        # optional group codes : (21, 40, 50) (direction, text height mm, text angle)
        size = 12                       # default fontsize in px
        if vals[groups['40']] and vals[groups['40']][0]:
            size = scale*vals[groups['40']][0]
        attribs = {'x': '%f' % x, 'y': '%f' % y, 'style': 'font-size: %.1fpx; fill: %s; font-family: %s' % (size, color, options.font)}
        angle = 0                       # default angle in degrees
        if vals[groups['50']]:
            angle = vals[groups['50']][0]
            attribs.update({'transform': 'rotate (%f %f %f)' % (-angle, x, y)})
        elif vals[groups['21']]:
            if vals[groups['21']][0] == 1.0:
                attribs.update({'transform': 'rotate (%f %f %f)' % (-90, x, y)})
            elif vals[groups['21']][0] == -1.0:
                attribs.update({'transform': 'rotate (%f %f %f)' % (90, x, y)})
        attribs.update({inkex.addNS('linespacing','sodipodi'): '125%'})
        node = inkex.etree.SubElement(layer, 'text', attribs)
        text = ''
        if vals[groups['3']]:
            for i in range (0, len(vals[groups['3']])):
                text += vals[groups['3']][i]
        if vals[groups['1']]:
            text += vals[groups['1']][0]
        found = text.find('\P')         # new line
        while found > -1:
            tspan = inkex.etree.SubElement(node , 'tspan', {inkex.addNS('role','sodipodi'): 'line'})
            tspan.text = text[:found]
            text = text[(found+2):]
            found = text.find('\P')
        tspan = inkex.etree.SubElement(node , 'tspan', {inkex.addNS('role','sodipodi'): 'line'})
        tspan.text = text
Example #11
0
    def effect(self):
        #References:   Minimum Requirements for Creating a DXF File of a 3D Model By Paul Bourke
        #              NURB Curves: A Guide for the Uninitiated By Philip J. Schneider
        #              The NURBS Book By Les Piegl and Wayne Tiller (Springer, 1995)
        # self.dxf_add("999\nDXF created by Inkscape\n")  # Some programs do not take comments in DXF files (KLayout 0.21.12 for example)
        self.dxf_add(dxf_templates.r14_header)
        for node in self.document.getroot().xpath('//svg:g', namespaces=inkex.NSS):
            if node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer':
                layer = node.get(inkex.addNS('label', 'inkscape'))
                layer = layer.replace(' ', '_')
                if layer and not layer in self.layers:
                    self.layers.append(layer)
        self.dxf_add("  2\nLAYER\n  5\n2\n100\nAcDbSymbolTable\n 70\n%s\n" % len(self.layers))
        for i in range(len(self.layers)):
            self.dxf_add("  0\nLAYER\n  5\n%x\n100\nAcDbSymbolTableRecord\n100\nAcDbLayerTableRecord\n  2\n%s\n 70\n0\n  6\nCONTINUOUS\n" % (i + 80, self.layers[i]))
        self.dxf_add(dxf_templates.r14_style)

        scale = eval(self.options.units)
        if not scale:
            scale = 25.4/90     # if no scale is specified, assume inch as baseunit
        h = inkex.unittouu(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0])
        self.groupmat = [[[scale, 0.0, 0.0], [0.0, -scale, h*scale]]]
        doc = self.document.getroot()
        self.process_group(doc)
        if self.options.ROBO == 'true':
            self.ROBO_output()
        if self.options.POLY == 'true':
            self.LWPOLY_output()
        self.dxf_add(dxf_templates.r14_footer)
Example #12
0
    def effect(self):

        # Dimensions in mm
        width = 259.0  # Before adding spine width or bleed
        height = 183.0  # Before adding bleed

        bleed = self.options.dvd_cover_bleed
        spine = float(self.options.dvd_cover_spine)

        width += spine
        width += 2.0 * bleed
        height += 2.0 * bleed

        self.root = self.document.getroot()
        self.root.set("id", "SVGRoot")
        self.root.set("width", str(width) + "mm")
        self.root.set("height", str(height) + "mm")
        self.root.set("viewBox", "0 0 " + str(width) + " " + str(height))

        namedview = self.root.find(inkex.addNS("namedview", "sodipodi"))
        if namedview is None:
            namedview = inkex.etree.SubElement(self.root, inkex.addNS("namedview", "sodipodi"))

        namedview.set(inkex.addNS("document-units", "inkscape"), "mm")

        # Until units are supported in 'cx', etc.
        namedview.set(inkex.addNS("cx", "inkscape"), str(self.uutounit(width, "px") / 2.0))
        namedview.set(inkex.addNS("cy", "inkscape"), str(self.uutounit(height, "px") / 2.0))

        self.create_horizontal_guideline("bottom", str(self.uutounit(bleed, "px")))
        self.create_horizontal_guideline("top", str(self.uutounit(height - bleed, "px")))
        self.create_vertical_guideline("left edge", str(self.uutounit(bleed, "px")))
        self.create_vertical_guideline("left spline", str(self.uutounit((width - spine) / 2.0, "px")))
        self.create_vertical_guideline("right spline", str(self.uutounit((width + spine) / 2.0, "px")))
        self.create_vertical_guideline("left edge", str(self.uutounit(width - bleed, "px")))
Example #13
0
File: T.py Project: Alpt/gdadin
def computeBBox(aList,mat=[[1,0,0],[0,1,0]]):
    bbox=None
    for node in aList:
        m = parseTransform(node.get('transform'))
        m = composeTransform(mat,m)
        #TODO: text not supported!

        if node.tag == inkex.addNS('rect','svg'):
                A=[0,0]
                B=[0,0]
                A[0] = float(node.get('x'))
                A[1] = float(node.get('y'))
                B[0] = A[0]+float(node.get('width'))
                B[1] = A[1]+float(node.get('height'))
                applyTransformToPoint(mat, A)
                applyTransformToPoint(mat, B)
                bbox = min(A[0], B[0]), max(A[0], B[0]), min(A[1], B[1]), max(A[1], B[1])
        if node.get("d"):
            d = node.get('d')
            p = cubicsuperpath.parsePath(d)
            applyTransformToPath(m,p)
            bbox=boxunion(roughBBox(p),bbox)

        if  node.tag == inkex.addNS('use','svg') or node.tag=='use':
            refid=node.get(inkex.addNS('href','xlink'))
            path = '//*[@id="%s"]' % refid[1:]
            refnode = node.getroottree().xpath(path, namespaces=inkex.NSS)
            bbox=boxunion(computeBBox(refnode,m),bbox)
            
        bbox=boxunion(computeBBox(node,m),bbox)
    return bbox
Example #14
0
    def split_letters(self, node):
        """Returns a list of letters"""

        letters = []
        
        words = self.split_words(node)
        if not words:
            return letters

        for word in words:
            
            x = float(word.get("x"))
            y = word.get("y")
           
            #gets the font size. If element doesn't have a style attribute, it assumes font-size = 12px
            try:
                import simplestyle
                fontsize = simplestyle.parseStyle(word.get("style"))["font-size"]
            except:
                fontsize = "12px"
            fs = self.unittouu(fontsize)

            #for each letter in element string
            for letter in word[0].text:
                tspan = inkex.etree.Element(inkex.addNS("tspan", "svg"))
                tspan.text = letter

                text = inkex.etree.Element(inkex.addNS("text", "svg"), node.attrib)
                text.set("x", str(x))
                text.set("y", str(y))
                x += fs
                
                text.append(tspan)
                letters.append(text)
        return letters
Example #15
0
    def effect(self):
        """Applies the effect"""

        split_type = self.options.split_type
        preserve = self.options.preserve
       
        #checks if the selected elements are text nodes
        for id, node in self.selected.iteritems():
            if not (node.tag == inkex.addNS("text", "svg") or node.tag == inkex.addNS("flowRoot", "svg")):
                inkex.debug("Please select only text elements.")
                break
            else:
                if split_type == "line":
                    nodes = self.split_lines(node)
                elif split_type == "word":
                    nodes = self.split_words(node)
                elif split_type == "letter":
                    nodes = self.split_letters(node)
                
                for n in nodes:
                    node.getparent().append(n)
                        
                #preserve original element
                if not preserve and nodes:
                    parent = node.getparent()
                    parent.remove(node)
Example #16
0
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.6']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_("The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select \"install/update...\" from the \"JessyInk\" sub-menu of the \"Extensions\" menu to install or update the JessyInk script.\n\n"))

		if len(self.selected) == 0:
			inkex.errormsg(_("No object selected. Please select the object you want to assign an effect to and then press apply.\n"))

		for id, node in list(self.selected.items()):
			if self.options.effectIn in ("appear", "fade", "pop", "matrix"):
				attribs = { inkex.addNS('href','xlink'): '#'+id }
				clone = inkex.etree.SubElement(self.current_layer, inkex.addNS('use','svg'), attribs)
				clone.set("{" + inkex.NSS["jessyink"] + "}effectIn","name:" + self.options.effectIn  + ";length:" + str(int(self.options.effectInDuration * 1000)))
				# Remove possible view argument.
				if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
		
			if self.options.effectOut in ("appear", "fade", "pop", "matrix"):
				attribs = { inkex.addNS('href','xlink'): '#'+id }
				clone = inkex.etree.SubElement(self.current_layer, inkex.addNS('use','svg'), attribs)
				clone.set("{" + inkex.NSS["jessyink"] + "}effectOut","name:" + self.options.effectOut  + ";length:" + str(int(self.options.effectOutDuration * 1000)))
				# Remove possible view argument.
				if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
    def effect(self):
        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path','svg'):
                self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('g','svg'))
                new = inkex.etree.SubElement(self.group,inkex.addNS('path','svg'))
                
                try:
                    t = node.get('transform')
                    self.group.set('transform', t)
                except:
                    pass

                s = simplestyle.parseStyle(node.get('style'))
                s['stroke-linecap']='round'
                s['stroke-width']=self.options.dotsize
                new.set('style', simplestyle.formatStyle(s))

                a =[]
                p = simplepath.parsePath(node.get('d'))
                num = 1
                for cmd,params in p:
                    if cmd != 'Z':
                        a.append(['M',params[-2:]])
                        a.append(['L',params[-2:]])
                        self.addText(self.group,params[-2],params[-1],num)
                        num += 1
                new.set('d', simplepath.formatPath(a))
                node.clear()
Example #18
0
    def effect(self):
        width = self.unittouu(str(self.options.width)+self.options.unit)
        height = self.unittouu(str(self.options.height)+self.options.unit)
        thickness = self.unittouu(str(self.options.thickness)+self.options.unit)

        # Create main element
        t = 'translate(' + str(self.view_center[0]) + ',' + \
            str(self.view_center[1]) + ')'
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'Box' + str(width) + "x"+str(height),
            'transform': t}
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)
        style = {'stroke': '#000000',
                 'fill': 'none',
                 'stroke-width': str(self.unittouu('1px'))}

        # Create path
        points=lc.make_plate((width,height),
                             (self.options.iwidth,self.options.iheight),
                             thickness,self.options.wsplit,self.options.hsplit,
                             self.options.bottom,self.options.bottomshift,
                             self.options.top,self.options.topshift,
                             self.options.left,self.options.leftshift,
                             self.options.right,self.options.rightshift)

        path = lc.points_to_svgd(points)

        
        # Create SVG Path for plate
        box_attribs = {
            'style': formatStyle(style),
            'd': path}
        box = inkex.etree.SubElement(
            g, inkex.addNS('path', 'svg'), box_attribs)    
    def makeMarkerstyle(self, name, rotate):
        " Markers added to defs for reuse "
        defs = self.xpathSingle('/svg:svg//svg:defs')
        if defs == None:
            defs = inkex.etree.SubElement(self.document.getroot(),inkex.addNS('defs','svg'))
        marker = inkex.etree.SubElement(defs ,inkex.addNS('marker','svg'))
        marker.set('id', name)
        marker.set('orient', 'auto')
        marker.set('refX', '0.0')
        marker.set('refY', '0.0')
        marker.set('style', 'overflow:visible')
        marker.set(inkex.addNS('stockid','inkscape'), name)

        arrow = inkex.etree.Element("path")
        # definition of arrows in beautiful DIN-shapes:
        if name.startswith('ArrowDIN-'):
            if rotate:
                arrow.set('d', 'M 8,0 -8,2.11 -8,-2.11 z')
            else:
                arrow.set('d', 'M -8,0 8,-2.11 8,2.11 z')
        if name.startswith('ArrowDINout-'):
            if rotate:
                arrow.set('d', 'M 0,0 16,2.11 16,0.5 26,0.5 26,-0.5 16,-0.5 16,-2.11 z')
            else:
                arrow.set('d', 'M 0,0 -16,2.11 -16,0.5 -26,0.5 -26,-0.5 -16,-0.5 -16,-2.11 z')
        arrow.set('style', 'fill:#000000;stroke:none')
        marker.append(arrow)
Example #20
0
	def parseLayerName(self,node):	
		if ( node.get( inkex.addNS( 'groupmode', 'inkscape' ) ) == 'layer' ): 

			strLayerName = node.get( inkex.addNS( 'label', 'inkscape' ) )
	#		inkex.errormsg('strLayerName: ' + str(strLayerName)) 
	#		inkex.errormsg('id: ' + str(node.get( 'id'))) 
	
			TempNumString = 'x'
			stringPos = 1	
			layerNameInt = -1 
			
			#Check to see if the layer name begins with a number in the range of palette colors
			strLayerName = string.lstrip( strLayerName ) #remove leading whitespace
			MaxLength = len( strLayerName )
			if MaxLength > 0:
				while stringPos <= MaxLength:
					if str.isdigit( strLayerName[:stringPos] ):
						TempNumString = strLayerName[:stringPos] # Store longest numeric string so far
						stringPos = stringPos + 1
					else:
						break
						
			#If it's the first layer found of that color, add its ID to our layer lookup table.
			if ( str.isdigit( TempNumString ) ):
				layerNameInt = int( float( TempNumString ) )
				if (layerNameInt >= 0) and (layerNameInt < len(self.paletteRGB)):
					if (self.layerLabels[layerNameInt] == "layerNotFound"):
						self.layerLabels[layerNameInt] = str(node.get('id'))
	def effect(self):
		node_pos={}
		node_R=[]
		for node in self.selected.values() :
			if node.tag == inkex.addNS('path','svg') and node.get(inkex.addNS("cx","sodipodi")) is not None :#assume circle
				node_pos[node]=simpleprimitive.element_center(node)
				node_R.append(float(node.get(inkex.addNS("rx","sodipodi"))))
		if len(node_pos)>2 :
			size=sum(node_R)/len(node_R)*2.
			cx=sum([pt[0] for pt in node_pos.itervalues()])/len(node_pos)
			cy=sum([pt[1] for pt in node_pos.itervalues()])/len(node_pos)
			node_ref=iter(node_pos).next()
			parent=node_ref.getparent()
			box=simpleprimitive.box(parent,cx,cy,size,size,{"fill":simplestyle.svgcolors["blue"]})
			box.set("id",self.uniqueId("rect"))
			angles=[(angle(node_pos[node_ref],pt,(cx,cy)),node) for node,pt in node_pos.iteritems()]
			angles.sort()
			nb=len(angles)
			for i in xrange(nb) :
				con=simpleprimitive.connect(parent,angles[i][1],angles[(i+1)%nb][1],{"stroke":simplestyle.svgcolors["magenta"]})
				if con is not None :
					con.set("id",self.uniqueId("con"))
			for node in node_pos :
				con=simpleprimitive.connect(parent,box,node,{"stroke":simplestyle.svgcolors["green"]})
				con.set("id",self.uniqueId("con"))
		else :
			raise UserWarning("must select at least 3 elements")
Example #22
0
  def effect(self):

    size   = self.options.desktop_size
    width  = self.options.desktop_width
    height = self.options.desktop_height

    if size != "Custom":
      p = re.compile('([0-9]*)x([0-9]*)')
      m = p.match( size )
      width  = int(m.group(1))
      height = int(m.group(2))


    root = self.document.getroot()
    root.set("id", "SVGRoot")
    root.set("width",  str(width) + 'px')
    root.set("height", str(height) + 'px')
    root.set("viewBox", "0 0 " + str(width) + " " + str(height) )

    namedview = root.find(inkex.addNS('namedview', 'sodipodi'))
    if namedview is None:
        namedview = inkex.etree.SubElement( root, inkex.addNS('namedview', 'sodipodi') );
     
    namedview.set(inkex.addNS('document-units', 'inkscape'), 'px')

    namedview.set(inkex.addNS('cx',        'inkscape'), str(width/2.0) )
    namedview.set(inkex.addNS('cy',        'inkscape'), str(height/2.0) )
Example #23
0
    def innerImage(self, x, y, width, height, padding, path, parent):
        with codecs.open(path, encoding="utf-8") as f:
            doc = etree.parse(f).getroot()

            imgWidth = self.unittouu(doc.get('width'))
            imgHeight = self.unittouu(doc.get('height'))

            sx = (width - padding) / imgWidth
            sy = (height - padding) / imgHeight

            scale = sx
            if sy < sx:
                scale = sy

            x += width / 2 - imgWidth * scale / 2
            y += height / 2 - imgHeight * scale / 2

            attrs = {
                'transform' : 'translate(' + str(x) + ',' + str(y) + ') scale(' + str(scale) + ',' + str(scale) + ')'
            }

            logoLayer = inkex.etree.SubElement(parent, 'g', attrs)
            logoLayer.set(inkex.addNS('label', 'inkscape'), 'Logo Layer')
            logoLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
            logoLayer.append(deepcopy(doc))
Example #24
0
File: sozi.py Project: ingmar-/Sozi
 def upgrade_or_install(self, tag):
     """
     Upgrade or install a script or a style sheet into the document.
         - tag: "script" or "style"
     Depending on the argument, the content of file "sozi.js" or "sozi.css"
     will be copied to the script or style element.
     """
     # Check version and remove older versions
     latest_version_found = False
     for elt in self.document.xpath("//svg:" + tag + "[@id='sozi-" + tag + "']", namespaces=inkex.NSS):
         version = elt.attrib[inkex.addNS("version", "sozi")]
         if version == Sozi.VERSION:
             latest_version_found = True
         elif version < Sozi.VERSION:
             elt.getparent().remove(elt)
         else:
             sys.stderr.write("Document has been created using a higher version of Sozi. Please upgrade the Inkscape plugin.\n")
             exit()
   
     # Create new element if needed
     if not latest_version_found:
         ext = "js" if tag == "script" else "css"
         elt = inkex.etree.Element(inkex.addNS(tag, "svg"))
         elt.text = open(os.path.join(os.path.dirname(__file__), "sozi." + ext)).read()
         elt.set("id","sozi-" + tag)
         elt.set(inkex.addNS("version", "sozi"), Sozi.VERSION)
         self.document.getroot().append(elt)
Example #25
0
File: sozi.py Project: ingmar-/Sozi
    def analyze_document(self):
        """
        Analyze the document and collect information about the presentation.
        Frames with no corresponding SVG element are removed.
        Frames numbers are updated if needed.
        """
        # Get list of valid frame elements and remove orphan frames
        self.frames = []
        for f in self.document.xpath("//sozi:frame", namespaces=inkex.NSS):
            e = self.document.xpath("//svg:*[@id='" + f.attrib[inkex.addNS("refid", "sozi")] + "']", namespaces=inkex.NSS)
            if len(e) == 0:
                self.document.getroot().remove(f)
            else:
                self.frames.append(
                    {
                        "frame_element": f,
                        "svg_element": e[0]
                    }
                )

        # Sort frames by sequence attribute 
        sequence_attr = inkex.addNS("sequence", "sozi")
        self.frames = sorted(self.frames, key=lambda f:
            int(f["frame_element"].attrib[sequence_attr]) if sequence_attr in f["frame_element"].attrib else len(self.frames))

        # Renumber frames
        for i, f in enumerate(self.frames):
            f["frame_element"].set(inkex.addNS("sequence", "sozi"), unicode(i+1))
Example #26
0
def object_bounding_box(obj, box=None):
    """Get the bounding box of an SVG object.

    :param obj: The XML node defining the object.
    :param box: The existing :class:`bounds.BoundingBox` if available.
    :return: A :class:`bounds.BoundingBox` encompassing the object.

    SVG images are constructed of a number of primitive objects (paths,
    rectangles, circles, groups etc.). This function takes an arbitrary object,
    determines what type of object is, and calculates the bounding box
    correspondingly.

    If an existing bounding box is given in the ``box`` parameter, it is
    extended to encompass the object and returned. Otherwise, a new bounding
    box is created and returned.

    Currently, this function can only handle ``path`` and ``rect`` objects.

    """

    if obj.tag == 'path' or obj.tag == inkex.addNS('path', 'svg'):
        objbox = path_bounding_box(obj, box)
    elif obj.tag in ['rect', inkex.addNS('rect', 'svg')]:
        objbox = rect_bounding_box(obj, box)
    else:
        objbox = BoundingBox(0, 0, 0, 0)

    return objbox
    def parseArc(self,node,parent):

        #self.parsing_context = 'arc'

        style = node.get('style')
        style = self.parseStyleAttribute(style)

        arc = {
            'id':node.get('id',''),
            'svg':'arc',
            'label':str(node.get(inkex.addNS('label', 'inkscape'),'')),
            'cx': node.get(inkex.addNS('cx', 'sodipodi'),''),
            'cy':node.get(inkex.addNS('cy', 'sodipodi'),''),
            'rx':node.get(inkex.addNS('rx', 'sodipodi'),''),
            'ry':node.get(inkex.addNS('ry', 'sodipodi'),''),
            'path':simplepath.parsePath(node.get('d')),
            'd':node.get('d',''),
            'box':list(simpletransform.computeBBox([node])),
            'fill':style.get('fill',''),
            'fill-opacity':style.get('fillOpacity',''),
            'stroke':style.get('stroke',''),
            'stroke-width':style.get('strokeWidth',''),
            'stroke-opacity':style.get('strokeOpacity',''),
            'transform':node.get('transform','')
        }


        if(self.reposition):
            arc['path'] = self.movePath(node,0,0,'tl')
        else:
            arc['path'] = arc['d']

        parent.append(arc)
Example #28
0
 def process_group(self, group):
     if group.get(inkex.addNS('groupmode', 'inkscape')) == 'layer':
         style = group.get('style')
         if style:
             style = simplestyle.parseStyle(style)
             if style.has_key('display'):
                 if style['display'] == 'none' and self.options.layer_option and self.options.layer_option=='visible':
                     return
         layer = group.get(inkex.addNS('label', 'inkscape'))
         if self.options.layer_name and self.options.layer_option and self.options.layer_option=='name' and not layer.lower() in self.options.layer_name:
             return
           
         layer = layer.replace(' ', '_')
         if layer in self.layers:
             self.layer = layer
     trans = group.get('transform')
     if trans:
         self.groupmat.append(simpletransform.composeTransform(self.groupmat[-1], simpletransform.parseTransform(trans)))
     for node in group:
         if node.tag == inkex.addNS('g','svg'):
             self.process_group(node)
         elif node.tag == inkex.addNS('use', 'svg'):
             self.process_clone(node)
         else:
             self.process_shape(node, self.groupmat[-1])
     if trans:
         self.groupmat.pop()
Example #29
0
 def getSvg(self):
     actualLayer = 0
     # prepare document
     self.doc = inkex.etree.parse(StringIO('<svg xmlns:sodipodi="' + inkex.NSS['sodipodi'] + '" xmlns:inkscape="' + inkex.NSS['inkscape'] + '" width="%smm" height="%smm" viewBox="0 0 %s %s"></svg>' %
         (self.options.docWidth, self.options.docHeight, self.options.docWidth, self.options.docHeight)))
     inkex.etree.SubElement(self.doc.getroot(), inkex.addNS('namedview', 'sodipodi'), {inkex.addNS('document-units', 'inkscape'): 'mm'})
     if self.options.showMovements:
         self.layers[0] = inkex.etree.SubElement(self.doc.getroot(), 'g', {inkex.addNS('groupmode', 'inkscape'): 'layer', inkex.addNS('label', 'inkscape'): self.textMovements, 'id': self.textMovements})
     # cut stream into commands
     hpglData = self.hpglString.split(';')
     # if number of commands is under needed minimum, no data was found
     if len(hpglData) < 3:
         raise Exception('NO_HPGL_DATA')
     # decode commands into svg data
     for i, command in enumerate(hpglData):
         if command.strip() != '':
             if command[:2] == 'IN' or command[:2] == 'FS' or command[:2] == 'VS':
                 # if Initialize, force or speed command ignore it
                 pass
             elif command[:2] == 'SP':
                 # if Select Pen command
                 actualLayer = int(command[2:])
             elif command[:2] == 'PU':
                 # if Pen Up command
                 self.parametersToPath(command[2:], 0, True)
             elif command[:2] == 'PD':
                 # if Pen Down command
                 self.parametersToPath(command[2:], actualLayer + 1, False)
             else:
                 self.warning = 'UNKNOWN_COMMANDS'
     return (self.doc, self.warning)
Example #30
0
	def updateArmatureData(self,layerSetName,layerGroup):
		stuff = ""
		layerSetId = layerSetName.replace(' ','')

		#has a data node been created
		query='//*[@class="data-node %s"]' % layerSetId
		nodes=self.armatureLayer.xpath(query)

		if not nodes is None and len(nodes)>0:
		#find the node, and update it

			for n in nodes:
				currentData = parseStyle( n.get( inkex.addNS('label', 'inkscape') ) )
				if 'state' in currentData and currentData['state']=='on':
					currentData['on']=layerGroup['on']
				else:
					currentData['off']=layerGroup=['off']

				n.set(inkex.addNS('label', 'inkscape'), formatStyle(currentData) )
		else:
			yNodes=self.armatureLayer.xpath('//*[@y]')
			maxY=0
			for yNode in yNodes:
				className = yNode.get('class')
				if not className is None and 'data-node' in className:
					newY = float(yNode.get('y'))
					if newY>maxY: maxY=newY

			if maxY>self.cursorY: self.cursorY = maxY
			self.cursorY+=35
			self.renderArmatureData(layerSetId,layerGroup)
Example #31
0
    def effect(self):
        ###Hauptprogramm

        # holt die Parameter aus Inkscape
        self.hoehe = self.options.hoehe
        self.durchmesser = self.options.durchmesser
        self.ueberstand = self.options.ueberstand
        self.radius = self.durchmesser / 2
        self.radius_mit_ueberstand = self.radius + self.ueberstand
        self.winkel = self.options.winkel
        self.boden = self.options.boden
        self.material = self.options.material
        self.segmente = int(360 / self.winkel)
        #Ausschnittbreite errechnen
        y = sin(radians(self.winkel)) * self.radius
        beta = 180 - 90 - self.winkel
        b = sin(radians(beta)) * self.radius
        x = self.radius - b
        self.ausschnitt_breite = sqrt((x * x) + (y * y))
        # what page are we on
        page_id = self.options.active_tab  # sometimes wrong the very first time

        #Eigenschaften der SVG auslesen und die Größe der Dose anpassen
        svg = self.document.getroot()
        #viewbox_size = '0 0 ' + str(self.breite) + ' ' + str(self.hoehe)
        #svg.set('viewBox', viewbox_size)
        #svg.set('height', str(self.hoehe))
        #svg.set('width', str(self.breite))

        # Embed the path in a group to make animation easier:
        # Be sure to examine the internal structure by looking in the xml editor inside inkscape

        # Make a nice useful name
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'dosen-gruppe',
            'id': "dose",
        }
        # add the group to the document's current layer
        self.topgroup = inkex.etree.SubElement(self.current_layer, 'g',
                                               g_attribs)
        # Create SVG Path under this top level group
        # Make a nice useful name
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'einschnitt-gruppe',
            'id': "einschnitte",
        }
        # add the group to the document's current layer
        self.undergroup = inkex.etree.SubElement(self.current_layer, 'g',
                                                 g_attribs)
        # Create SVG Path under this top level group

        self.deckel_erstellen()
        self.ausschnitt_erstellen()
        self.seite_erstellen()
        self.einschnitte_erstellen()

        # Make a nice useful name
        text_g_attribs = {
            inkex.addNS('label', 'inkscape'): 'dosen-gruppe',
            'id': "Branding",
        }
        # add the group to the document's current layer
        textgroup = inkex.etree.SubElement(self.current_layer, 'g',
                                           text_g_attribs)

        line_style = {
            'font-size': '10px',
            'font-style': 'normal',
            'font-weight': 'normal',
            'fill': '#ff0000',
            'font-family': 'Consolas',
            'text-anchor': 'start'
        }
        branding_line_attribs = {
            inkex.addNS('label', 'inkscape'): 'branding-text',
            'id': 'front text',
            'style': simplestyle.formatStyle(line_style),
            'x': str(0),
            'y': str(0)
        }

        branding_line = inkex.etree.SubElement(textgroup,
                                               inkex.addNS('text', 'svg'),
                                               branding_line_attribs)
        branding_line.text = 'dosen-generator by mini revollo member of the erfindergarden'

        # Make a nice useful name
        einschnitt_text_g_attribs = {
            inkex.addNS('label', 'inkscape'): 'einschnitt-gruppe',
            'id': "Einschnitte_Text",
        }
        # add the group to the document's current layer
        textgroup = inkex.etree.SubElement(self.current_layer, 'g',
                                           einschnitt_text_g_attribs)

        line_style = {
            'font-size': '5px',
            'font-style': 'normal',
            'font-weight': 'normal',
            'fill': '#00ff00',
            'font-family': 'Consolas',
            'text-anchor': 'start'
        }
        einschnitt_line_attribs = {
            inkex.addNS('label', 'inkscape'): 'Einschnitte_text',
            'id': 'front text',
            'style': simplestyle.formatStyle(line_style),
            'x': str(0),
            'y': str(self.radius_mit_ueberstand + self.hoehe / 2)
        }

        branding_line = inkex.etree.SubElement(textgroup,
                                               inkex.addNS('text', 'svg'),
                                               einschnitt_line_attribs)
        branding_line.text = 'Die Einschnitte nur zu 70 Prozent in das Material lasern'
Example #32
0
    def formatText(self, x, y, text, fontColor, bgColor, parent):
        # Declare the bbcode regex, ...
        bbCodeRegex = re.compile(r'\[(/)?((?(1)(i|b|color)|(i|b|color=[0-9a-fA-F]{3,6})))\]', re.IGNORECASE)

        # ... and check for matches.
        if not bbCodeRegex.findall(text):
            self.positonTspan(x, y, '_', bgColor, parent)
            self.createTspan(text, fontColor, parent)
            return

        # If there are matches fetch all of them.
        matches = bbCodeRegex.finditer(text)

        # Initialize the basic style, ...
        bbStyles = {
            'b' : False,
            'i' : False,
            'color' : fontColor
        }

        # ... and the processing stack.
        stack = Stack()

        # Add a positioning tspan.
        self.positonTspan(x, y, '_', bgColor, parent)

        # Remember the last match position.
        lastMatch = 0

        # Loop over all matches.
        for m in matches:
             # Extract important data from match.
            textChunk = text[lastMatch:m.start()]
            lastMatch = m.start() + len(str(m.group()))
            isClosing = False if m.groups()[0] == None else True
            bbTagName = m.groups()[1].split('=')[0]

            # Setup the basic tspan style.
            style = {
                'font-weight' : 'bold' if bbStyles['b'] else 'normal',
                'font-style' : 'italic' if bbStyles['i'] else 'normal',
                'fill' : '#' + str(bbStyles['color'])
            }

            # Update the current style.
            if isClosing and stack.peek()[0] == bbTagName:
                bbStyles[bbTagName] = stack.pop()[1]
            elif isClosing is False and bbTagName == 'color':
                stack.push((bbTagName, bbStyles[bbTagName]))
                bbStyles[bbTagName] = m.groups()[1].split('=')[1]
            elif isClosing is False:
                stack.push((bbTagName, bbStyles[bbTagName]))
                bbStyles[bbTagName] = False if bbStyles[bbTagName] else True
                
            if len(textChunk) > 0:
                # Prepend spaces.
                if textChunk[0] == ' ':
                    self.createTspan('_', bgColor, parent)

                # Create the new tspan element.
                tspan = inkex.etree.SubElement(parent, inkex.addNS('tspan', 'svg'))
                tspan.set('style', formatStyle(style))
                tspan.text = textChunk

                # Append spaces.
                if textChunk[-1] == ' ' and len(textChunk) > 1:
                    self.createTspan('_', bgColor, parent)

        if len(text) > 0:
            textChunk = text[lastMatch:]
                
            if len(textChunk.strip()) > 0:
                # Setup the basic tspan style.
                style = {
                    'font-weight' : 'bold' if bbStyles['b'] else 'normal',
                    'font-style' : 'italic' if bbStyles['i'] else 'normal',
                    'fill' : '#' + str(bbStyles['color'])
                }

                # Prepend spaces.
                if textChunk[0] == ' ':
                    self.createTspan('_', bgColor, parent)

                # Create the new tspan element.
                tspan = inkex.etree.SubElement(parent, inkex.addNS('tspan', 'svg'))
                tspan.set('style', formatStyle(style))
                tspan.text = textChunk
Example #33
0
    def effect(self):
        # Fetch the svg root element ...
        svg = self.document.getroot()

        # ... as well as the image width and height.
        width  = self.unittouu(svg.get('width'))
        height = self.unittouu(svg.get('height'))

        # Fetch the extention parameters.
        self.sideOneIcon = self.options.sideOneIcon if self.options.sideOneIcon is not None and os.path.isfile(self.options.sideOneIcon) else None
        self.sideTwoIcon = self.options.sideTwoIcon if self.options.sideTwoIcon is not None and os.path.isfile(self.options.sideTwoIcon) else None
        self.sideThreeIcon = self.options.sideThreeIcon if self.options.sideThreeIcon is not None and  os.path.isfile(self.options.sideThreeIcon) else None
        self.sideFourIcon = self.options.sideFourIcon if self.options.sideFourIcon is not None and os.path.isfile(self.options.sideFourIcon) else None
        self.bottomIcon = self.options.bottomIcon if self.options.bottomIcon is not None and os.path.isfile(self.options.bottomIcon) else None
        self.topIcon = self.options.topIcon if self.options.topIcon is not None and os.path.isfile(self.options.topIcon) else None

        # Replace 'none' with '' in strings.
        self.sideOneText = self.sideOneText if self.sideOneText is not None else ''
        self.sideOneHint = self.sideOneHint if self.sideOneHint is not None else ''
        self.sideTwoText = self.sideTwoText if self.sideTwoText is not None else ''
        self.sideTwoHint = self.sideTwoHint if self.sideTwoHint is not None else ''
        self.sideThreeText = self.sideThreeText if self.sideThreeText is not None else ''
        self.sideThreeHint = self.sideThreeHint if self.sideThreeHint is not None else ''
        self.sideFourText = self.sideFourText if self.sideFourText is not None else ''
        self.sideFourHint = self.sideFourHint if self.sideFourHint is not None else ''

        # Create a new layer, ...
        layer = inkex.etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'), 'Basic Shape')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        # ... define and calculate the dimensions (in mm) of the basic shape ...
        cubeWidth = self.unittouu("8.5 cm")
        cubeHeight = self.unittouu("2.5 cm")
        cubeDepth = self.unittouu("5.6 cm")

        wingHeight = self.unittouu("1.0 cm")
        smallWingWidth = cubeDepth - 2 * wingHeight
        largeWingWidth = cubeWidth - 2 * wingHeight

        padding = wingHeight
        borderWidth = 1

        # ... and the headline boxes.
        boxHintFontSize = cubeHeight / 25 * 3
        boxTitleFontSize = cubeHeight / 5
        boxBorderColor = 'ffffff'
        boxBorder = 0

        raspiUsbWidth = self.unittouu("1.5 cm")
        raspiUsbHeight = self.unittouu("1.6 cm")
        raspiEthWidth = self.unittouu("1.6 cm")
        raspiEthHeight = self.unittouu("1.4 cm")
        raspiSoundWidth = raspiSoundHeight = self.unittouu("0.7 cm")
        raspiHdmiWidth = self.unittouu("1.6 cm")
        raspiHdmiHeight = self.unittouu("0.5 cm")
        raspiMusbWidth = self.unittouu("0.9 cm")
        raspiMusbHeight = self.unittouu("0.4 cm")
        raspiSdCardWidth = self.unittouu("1.2 cm")
        raspiSdCardHeight = self.unittouu("0.3 cm")

        raspiUsb1OffsetX = padding + wingHeight + cubeHeight + self.unittouu("0.2 cm")
        raspiUsb1OffsetY = padding + wingHeight + cubeHeight - self.unittouu("0.3 cm")
        raspiUsb2OffsetX = padding + wingHeight + cubeHeight + self.unittouu("2.0 cm")
        raspiUsb2OffsetY = padding + wingHeight + cubeHeight - self.unittouu("0.3 cm")
        raspiEthOffsetX = padding + wingHeight + cubeHeight + self.unittouu("3.8 cm")
        raspiEthOffsetY = padding + wingHeight + cubeHeight - self.unittouu("0.3 cm")
        raspiSoundOffsetX = padding + wingHeight + cubeHeight + cubeDepth + self.unittouu("0.3 cm")
        raspiSoundOffsetY = padding + wingHeight + cubeHeight + self.unittouu("3.5 cm")
        raspiHdmiOffsetX = padding + wingHeight + cubeHeight + cubeDepth + self.unittouu("0.3 cm")
        raspiHdmiOffsetY = padding + wingHeight + cubeHeight + self.unittouu("6.0 cm")
        raspiMusbOffsetX = padding + wingHeight + cubeHeight + cubeDepth + self.unittouu("0.3 cm")
        raspiMusbOffsetY = padding + wingHeight + cubeHeight + self.unittouu("7.9 cm")
        raspiSdCardOffsetX = padding + wingHeight + cubeHeight + self.unittouu("2.2 cm")
        raspiSdCardOffsetY = padding + wingHeight + cubeHeight + cubeWidth
        
        # Draw the basic shape (cutting edges).
        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, layer,
            (padding, padding + cubeHeight + cubeWidth),
            (padding + 2 * wingHeight + cubeHeight, padding + 2 * wingHeight + 2 * cubeHeight + cubeWidth),
            (padding + cubeHeight + cubeDepth, padding + 2 * wingHeight + 2 * cubeHeight + cubeWidth),
            (padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth),
            (padding + 2 * wingHeight + 2 * cubeHeight + cubeDepth, padding + 2 * wingHeight + cubeHeight + cubeWidth),
            (padding + 2 * wingHeight + 2 * cubeHeight + cubeDepth + smallWingWidth, padding + 2 * wingHeight + cubeHeight + cubeWidth),
            (padding + 2 * wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + 2 * wingHeight + cubeHeight + largeWingWidth),
            (padding + 2 * wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + 2 * wingHeight + cubeHeight),
            (padding + 2 * cubeHeight + 2 * cubeDepth, padding + cubeHeight),
            (padding + 2 * wingHeight + 2 * cubeHeight + cubeDepth, padding + cubeHeight),
            (padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + cubeHeight + wingHeight),
            (padding + cubeHeight + cubeDepth, padding),
            (padding + 2 * wingHeight + cubeHeight, padding),
            (padding, padding + 2 * wingHeight + cubeHeight),
            (padding, padding + cubeHeight + cubeWidth),
        )

        # Draw the headline boxes.
        leftLayerAttrs = {
            'transform' : 'rotate(270, ' + str(padding + wingHeight + (cubeHeight / 2)) + ',' + str(padding + wingHeight + cubeHeight + (cubeWidth / 2)) + ')' 
        }

        leftLayer = inkex.etree.SubElement(svg, 'g', leftLayerAttrs)
        leftLayer.set(inkex.addNS('label', 'inkscape'), 'Left Side')
        leftLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        self.drawSide(padding + wingHeight + (cubeHeight / 2) - (cubeWidth / 2), padding + wingHeight + cubeHeight + (cubeWidth / 2) - (cubeHeight / 2), cubeWidth, cubeHeight, boxBorder, boxBorderColor, leftLayer, self.sideOneText, self.titleBgColor, self.textColor, boxTitleFontSize, self.sideOneHint, self.hintBgColor, self.hintColor, boxHintFontSize, self.sideOneIcon)

        topLayer = inkex.etree.SubElement(svg, 'g', {})
        topLayer.set(inkex.addNS('label', 'inkscape'), 'Top Side')
        topLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        self.drawSide(padding + wingHeight + cubeHeight, padding + wingHeight, cubeDepth, cubeHeight, boxBorder, boxBorderColor, topLayer, self.sideTwoText, self.titleBgColor, self.textColor, boxTitleFontSize, self.sideTwoHint, self.hintBgColor, self.hintColor, boxHintFontSize, self.sideTwoIcon)

        rightLayerAttrs = {
            'transform' : 'rotate(90, ' + str(padding + wingHeight + cubeHeight + cubeDepth + (cubeHeight / 2)) + ',' + str(padding + wingHeight + cubeHeight + (cubeWidth / 2)) + ')' 
        }

        rightLayer = inkex.etree.SubElement(svg, 'g', rightLayerAttrs)
        rightLayer.set(inkex.addNS('label', 'inkscape'), 'Right Side')
        rightLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        self.drawSide(padding + wingHeight + cubeHeight + cubeDepth + (cubeHeight / 2) - (cubeWidth / 2), padding + wingHeight + cubeHeight + (cubeWidth / 2) - (cubeHeight / 2), cubeWidth, cubeHeight, boxBorder, boxBorderColor, rightLayer, self.sideThreeText, self.titleBgColor, self.textColor, boxTitleFontSize, self.sideThreeHint, self.hintBgColor, self.hintColor, boxHintFontSize, self.sideThreeIcon)

        bottomLayerAttrs = {
            'transform' : 'rotate(180, ' + str(padding + wingHeight + cubeHeight + (cubeDepth / 2)) + ',' + str(padding + wingHeight + cubeHeight + cubeWidth + (cubeHeight / 2)) + ')' 
        }

        bottomLayer = inkex.etree.SubElement(svg, 'g', bottomLayerAttrs)
        bottomLayer.set(inkex.addNS('label', 'inkscape'), 'Bottom Side')
        bottomLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        self.drawSide(padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight + cubeWidth, cubeDepth, cubeHeight, boxBorder, boxBorderColor, bottomLayer, self.sideFourText, self.titleBgColor, self.textColor, boxTitleFontSize, self.sideFourHint, self.hintBgColor, self.hintColor, boxHintFontSize, self.sideFourIcon)

        # ... and the cutting edges for the slots.
        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, topLayer,
            (raspiUsb1OffsetX, raspiUsb1OffsetY),
            (raspiUsb1OffsetX + raspiUsbWidth, raspiUsb1OffsetY),
            (raspiUsb1OffsetX + raspiUsbWidth, raspiUsb1OffsetY - raspiUsbHeight),
            (raspiUsb1OffsetX, raspiUsb1OffsetY - raspiUsbHeight),
            (raspiUsb1OffsetX, raspiUsb1OffsetY)
        )

        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, topLayer,
            (raspiUsb2OffsetX, raspiUsb2OffsetY),
            (raspiUsb2OffsetX + raspiUsbWidth, raspiUsb2OffsetY),
            (raspiUsb2OffsetX + raspiUsbWidth, raspiUsb2OffsetY - raspiUsbHeight),
            (raspiUsb2OffsetX, raspiUsb2OffsetY - raspiUsbHeight),
            (raspiUsb2OffsetX, raspiUsb2OffsetY)
        )

        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, topLayer,
            (raspiEthOffsetX, raspiEthOffsetY),
            (raspiEthOffsetX + raspiEthWidth, raspiEthOffsetY),
            (raspiEthOffsetX + raspiEthWidth, raspiEthOffsetY - raspiEthHeight),
            (raspiEthOffsetX, raspiEthOffsetY - raspiEthHeight),
            (raspiEthOffsetX, raspiEthOffsetY)
        )

        rightLayer2Attrs = {
            'transform' : 'rotate(0, ' + str(padding + wingHeight + cubeHeight + cubeDepth + (cubeHeight / 2)) + ',' + str(padding + wingHeight + cubeHeight + (cubeWidth / 2)) + ')' 
        }

        rightLayer2 = inkex.etree.SubElement(svg, 'g', rightLayer2Attrs)
        rightLayer2.set(inkex.addNS('label', 'inkscape'), 'Right Side')
        rightLayer2.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        self.drawSide(padding + wingHeight + cubeHeight + cubeDepth + (cubeHeight / 2) - (cubeWidth / 2), padding + wingHeight + cubeHeight + (cubeWidth / 2) - (cubeHeight / 2), cubeWidth, cubeHeight, boxBorder, boxBorderColor, rightLayer, self.sideThreeText, self.titleBgColor, self.textColor, boxTitleFontSize, self.sideThreeHint, self.hintBgColor, self.hintColor, boxHintFontSize, self.sideThreeIcon)

        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, rightLayer2,
            (raspiSoundOffsetX, raspiSoundOffsetY),
            (raspiSoundOffsetX + raspiSoundHeight, raspiSoundOffsetY),
            (raspiSoundOffsetX + raspiSoundHeight, raspiSoundOffsetY - raspiSoundWidth),
            (raspiSoundOffsetX, raspiSoundOffsetY - raspiSoundWidth),
            (raspiSoundOffsetX, raspiSoundOffsetY)
        )

        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, rightLayer2,
            (raspiHdmiOffsetX, raspiHdmiOffsetY),
            (raspiHdmiOffsetX + raspiHdmiHeight, raspiHdmiOffsetY),
            (raspiHdmiOffsetX + raspiHdmiHeight, raspiHdmiOffsetY - raspiHdmiWidth),
            (raspiHdmiOffsetX, raspiHdmiOffsetY - raspiHdmiWidth),
            (raspiHdmiOffsetX, raspiHdmiOffsetY)
        )

        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, rightLayer2,
            (raspiMusbOffsetX, raspiMusbOffsetY),
            (raspiMusbOffsetX + raspiMusbHeight, raspiMusbOffsetY),
            (raspiMusbOffsetX + raspiMusbHeight, raspiMusbOffsetY - raspiMusbWidth),
            (raspiMusbOffsetX, raspiMusbOffsetY - raspiMusbWidth),
            (raspiMusbOffsetX, raspiMusbOffsetY)
        )

        self.drawPolygon(
            borderWidth, self.borderColor, self.mainBgColor, False, layer,
            (raspiSdCardOffsetX, raspiSdCardOffsetY),
            (raspiSdCardOffsetX + raspiSdCardWidth, raspiSdCardOffsetY),
            (raspiSdCardOffsetX + raspiSdCardWidth, raspiSdCardOffsetY - raspiSdCardHeight),
            (raspiSdCardOffsetX, raspiSdCardOffsetY - raspiSdCardHeight),
            (raspiSdCardOffsetX, raspiSdCardOffsetY)
        )

        # Draw the top ...
        self.drawTopBot(padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight, cubeDepth, cubeWidth, boxBorder, boxBorderColor, svg, self.topText, self.topBgColor, self.titleColor, cubeHeight / 5, self.topHint, cubeHeight / 25 * 3, self.topIcon)

        # ... and the bottom layer.
        self.drawTopBot(padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight, cubeDepth, cubeWidth, boxBorder, boxBorderColor, svg, self.bottomText, self.bottomBgColor, self.titleColor, cubeHeight / 5, self.bottomHint, cubeHeight / 25 * 3, self.bottomIcon)

        # Finally create a new layer for the inner folding and cutting edges ...
        innerEdgesLayer = inkex.etree.SubElement(svg, 'g', {})
        innerEdgesLayer.set(inkex.addNS('label', 'inkscape'), 'Inner Edges')
        innerEdgesLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        
        # ... and draw the inner edges, ...
        self.drawPolygon(
            borderWidth, self.borderColor, None, True, innerEdgesLayer,
            (padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight + cubeWidth),
            (padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight + cubeWidth),
            (padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight),
            (padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight),
            (padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight + cubeWidth)
        )

        # ... the wing folding edges, ...
        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth,
            padding + 2 * wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth,
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight + cubeWidth,
            padding + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight + cubeWidth,
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight + cubeWidth,
            padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + cubeHeight + cubeWidth,
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight,
            padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + 2 * wingHeight + cubeHeight,
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight,
            padding + 2 * cubeHeight + 2 * cubeDepth, padding + wingHeight + cubeHeight,
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight,
            padding + 2 * wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight,
            borderWidth, self.borderColor, False, innerEdgesLayer)

        # ... the triangle folding edges, ...
        self.drawLine(
            padding + wingHeight, padding + wingHeight + cubeHeight + cubeWidth, 
            padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight + cubeWidth, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight + cubeWidth, 
            padding + wingHeight + cubeHeight, padding + wingHeight + 2 * cubeHeight + cubeWidth, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth, 
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth + cubeHeight, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight, 
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight, padding + wingHeight + cubeHeight, 
            padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight, padding + wingHeight, 
            padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        # ... the inner triangle folding edges, ...
        self.drawLine(
            padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight + cubeWidth, 
            padding + wingHeight + cubeHeight - cubeHeight / 2, padding + wingHeight + cubeHeight + cubeWidth + cubeHeight / 2, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth, 
            padding + wingHeight + cubeHeight + cubeDepth + cubeHeight / 2, padding + wingHeight + cubeHeight + cubeWidth + cubeHeight / 2, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight, 
            padding + wingHeight + cubeHeight + cubeDepth + cubeHeight / 2, padding + wingHeight + cubeHeight - cubeHeight / 2, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight, padding + wingHeight + cubeHeight, 
            padding + wingHeight + cubeHeight - cubeHeight / 2, padding + wingHeight + cubeHeight - cubeHeight / 2, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        # ... the middle folding edges ...
        self.drawLine(
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight, 
            padding + wingHeight + cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight, 
            padding + wingHeight + 2 * cubeHeight + cubeDepth, padding + wingHeight + cubeHeight + cubeWidth, 
            borderWidth, self.borderColor, True, innerEdgesLayer)

        # ... and the inner cutting edges.
        self.drawLine(
            padding + wingHeight + cubeHeight + wingHeight / 2, padding + wingHeight, 
            padding + wingHeight + cubeHeight + cubeDepth - wingHeight / 2, padding + wingHeight, 
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight, padding + wingHeight + cubeHeight + wingHeight / 2, 
            padding + wingHeight, padding + wingHeight + cubeHeight + cubeWidth - wingHeight / 2, 
            borderWidth, self.borderColor, False, innerEdgesLayer)

        self.drawLine(
            padding + wingHeight + cubeHeight + wingHeight / 2, padding + wingHeight + 2 * cubeHeight + cubeWidth, 
            padding + wingHeight + cubeHeight + cubeDepth - wingHeight / 2, padding + wingHeight + 2 * cubeHeight + cubeWidth, 
            borderWidth, self.borderColor, False, innerEdgesLayer)
Example #34
0
    def effect(self):
        svg_file = self.args[-1]
        ttmp_orig = self.document.getroot()
        docname = ttmp_orig.get(inkex.addNS('docname',u'sodipodi'))
        if docname is None: docname = self.args[-1]
        
        doc_scale = self.getDocumentScale()
        res_scale = eval(self.options.resolution) / 96.0
        scale = doc_scale * res_scale

        pageHeight = self.uutounit(self.unittouu(self.getDocumentHeight()), "px")
        pageWidth = self.uutounit(self.unittouu(self.getDocumentWidth()), "px")
        
        # Create os temp dir (to store exported pngs and Gimp log file)
        self.tmp_dir = tempfile.mkdtemp()

        # Guides
        hGuides = []
        vGuides = []
        if self.options.saveGuides:
            # Grab all guide tags in the namedview tag
            guideXpath = "sodipodi:namedview/sodipodi:guide"
            for guideNode in self.document.xpath(guideXpath, namespaces=inkex.NSS):
                ori = guideNode.get('orientation')
                if  ori == '0,1':
                    # This is a horizontal guide
                    pos = self.uutounit(float(guideNode.get('position').split(',')[1]), "px") * doc_scale
                    # GIMP doesn't like guides that are outside of the image
                    if pos > 0 and pos < pageHeight:
                        # The origin is at the top in GIMP land
                        hGuides.append(str(int(round((pageHeight - pos) * res_scale))))
                elif ori == '1,0':
                    # This is a vertical guide
                    pos = self.uutounit(float(guideNode.get('position').split(',')[0]), "px") * doc_scale
                    # GIMP doesn't like guides that are outside of the image
                    if pos > 0 and pos < pageWidth:
                        vGuides.append(str(int(round(pos * res_scale))))

        hGList = ' '.join(hGuides)
        vGList = ' '.join(vGuides)

        # Grid
        gridSpacingFunc = ''
        gridOriginFunc = '' 
        # GIMP only allows one rectangular grid
        gridXpath = "sodipodi:namedview/inkscape:grid[@type='xygrid' and (not(@units) or @units='px')]"
        if (self.options.saveGrid and self.document.xpath(gridXpath, namespaces=inkex.NSS)):
            gridNode = self.xpathSingle(gridXpath)
            if gridNode != None:
                # These attributes could be nonexistent
                spacingX = gridNode.get('spacingx')
                if spacingX == None:
                    spacingX = 1
                else:
                    spacingX = self.uutounit(float(spacingX),"px") * scale
                spacingY = gridNode.get('spacingy')
                if spacingY == None:
                    spacingY = 1
                else:
                    spacingY = self.uutounit(float(spacingY),"px") * scale
                originX = gridNode.get('originx')
                if originX == None:
                    originX = 0
                else:
                    originX = self.uutounit(float(originX),"px") * scale
                originY = gridNode.get('originy')
                if originY == None:
                    originY = 0
                else:
                    originY = self.uutounit(float(originY),"px") * doc_scale
                    offsetY = pageHeight % (self.uutounit(float(spacingY),"px") * doc_scale)
                    originY = (pageHeight - originY) * res_scale

                gridSpacingFunc = '(gimp-image-grid-set-spacing img %s %s)' % (int(round(float(spacingX))), int(round(float(spacingY))))
                gridOriginFunc = '(gimp-image-grid-set-offset img %s %s)'% (int(round(float(originX))), int(round(float(originY))))

        # Layers
        area = '--export-area-page'
        opacity = '--export-background-opacity='
        resolution = '--export-dpi=' + self.options.resolution

        if self.options.layerBackground:
            opacity += "1"
        else:
            opacity += "0"
        pngs = []
        names = []
        self.valid = 0
        path = "/svg:svg/*[name()='g' or @style][@id]"
        for node in self.document.xpath(path, namespaces=inkex.NSS):
            if len(node) > 0: # Get rid of empty layers
                self.valid = 1
                id = node.get('id')
                if node.get("{" + inkex.NSS["inkscape"] + "}label"):
                    name = node.get("{" + inkex.NSS["inkscape"] + "}label")
                else:
                    name = id
                filename = os.path.join(self.tmp_dir, "%s.png" % id)
                command = "inkscape -i \"%s\" -j %s %s -e \"%s\" %s %s" % (id, area, opacity, filename, svg_file, resolution)

                p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
                return_code = p.wait()
                f = p.stdout
                err = p.stderr
                stdin = p.stdin
                f.read()
                f.close()
                err.close()
                stdin.close()

                if return_code != 0:
                    self.clear_tmp()
                    raise GimpXCFInkscapeNotInstalled

                if os.name == 'nt':
                    filename = filename.replace("\\", "/")
                pngs.append(filename)
                names.append(name)

        if (self.valid == 0):
            self.clear_tmp()
            inkex.errormsg(_('This extension requires at least one non empty layer.'))
        else:
            filelist = '"%s"' % '" "'.join(pngs)
            namelist = '"%s"' % '" "'.join(names)
            xcf = os.path.join(self.tmp_dir, "%s.xcf" % docname)
            if os.name == 'nt':
                xcf = xcf.replace("\\", "/")
            script_fu = """
(tracing 1)
(define
  (png-to-layer img png_filename layer_name)
  (let*
    (
      (png (car (file-png-load RUN-NONINTERACTIVE png_filename png_filename)))
      (png_layer (car (gimp-image-get-active-layer png)))
      (xcf_layer (car (gimp-layer-new-from-drawable png_layer img)))
    )
    (gimp-image-add-layer img xcf_layer -1)
    (gimp-drawable-set-name xcf_layer layer_name)
  )
)
(let*
  (
    (img (car (gimp-image-new 200 200 RGB)))
  )
  (gimp-image-set-resolution img %s %s)
  (gimp-image-undo-disable img)
  (for-each
    (lambda (names)
      (png-to-layer img (car names) (cdr names))
    )
    (map cons '(%s) '(%s))
  )

  (gimp-image-resize-to-layers img)

  (for-each
    (lambda (hGuide)
      (gimp-image-add-hguide img hGuide)
    )
    '(%s)
  )

  (for-each
    (lambda (vGuide)
      (gimp-image-add-vguide img vGuide)
    )
    '(%s)
  )

  %s
  %s

  (gimp-image-undo-enable img)
  (gimp-file-save RUN-NONINTERACTIVE img (car (gimp-image-get-active-layer img)) "%s" "%s"))
(gimp-quit 0)
            """ % (self.options.resolution, self.options.resolution, filelist, namelist, hGList, vGList, gridSpacingFunc, gridOriginFunc, xcf, xcf)

            junk = os.path.join(self.tmp_dir, 'junk_from_gimp.txt')
            command = 'gimp -i --batch-interpreter plug-in-script-fu-eval -b - > %s 2>&1' % junk

            p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
            f = p.stdin
            out = p.stdout
            err = p.stderr
            f.write(script_fu.encode('utf-8'))
            return_code = p.wait()
            
            if p.returncode != 0:
                self.clear_tmp()
                raise GimpXCFGimpNotInstalled

            f.close()
            err.close()
            out.close()
            # Uncomment these lines to see the output from gimp
            #err = open(junk, 'r')
            #inkex.debug(err.read())
            #err.close()

            try:
                x = open(xcf, 'rb')
            except:
                self.clear_tmp()
                raise GimpXCFScriptFuError

            if os.name == 'nt':
                try:
                    import msvcrt
                    msvcrt.setmode(1, os.O_BINARY)
                except:
                    pass
            try:
                sys.stdout.write(x.read())
            finally:
                x.close()
                self.clear_tmp()
    def effect(self):
        """ Calculate Gear factors from inputs.
            - Make list of radii, angles, and centers for each tooth and 
              iterate through them
            - Turn on other visual features e.g. cross, rack, annotations, etc
        """
        path_stroke = '#000000'  # might expose one day
        path_fill = 'none'  # no fill - just a line
        path_stroke_width = 0.6  # might expose one day
        path_stroke_light = path_stroke_width * 0.25  # guides are thinner
        #
        warnings = []  # list of extra messages to be shown in annotations
        # calculate unit factor for units defined in dialog.
        unit_factor = self.calc_unit_factor()
        # User defined options
        teeth = self.options.teeth
        # Angle of tangent to tooth at circular pitch wrt radial line.
        angle = self.options.angle
        # Clearance: Radial distance between top of tooth on one gear to
        # bottom of gap on another.
        clearance = self.options.clearance * unit_factor
        mount_hole = self.options.mount_hole * unit_factor
        # for spokes
        mount_radius = self.options.mount_diameter * 0.5 * unit_factor
        spoke_count = self.options.spoke_count
        spoke_width = self.options.spoke_width * unit_factor
        holes_rounding = self.options.holes_rounding * unit_factor  # unused
        # visible guide lines
        centercross = self.options.centercross  # draw center or not (boolean)
        pitchcircle = self.options.pitchcircle  # draw pitch circle or not (boolean)
        # Accuracy of teeth curves
        accuracy_involute = 20  # Number of points of the involute curve
        accuracy_circular = 9  # Number of points on circular parts
        if self.options.accuracy is not None:
            if self.options.accuracy == 0:
                # automatic
                if teeth < 10: accuracy_involute = 20
                elif teeth < 30: accuracy_involute = 12
                else: accuracy_involute = 6
            else:
                accuracy_involute = self.options.accuracy
            accuracy_circular = max(3,
                                    int(accuracy_involute / 2) -
                                    1)  # never less than three
        # print >>self.tty, "accuracy_circular=%s accuracy_involute=%s" % (accuracy_circular, accuracy_involute)
        # Pitch (circular pitch): Length of the arc from one tooth to the next)
        # Pitch diameter: Diameter of pitch circle.
        pitch = self.calc_circular_pitch()
        # Replace section below with this call to get the combined gear_calculations() above
        (pitch_radius, base_radius, addendum, dedendum, outer_radius,
         root_radius,
         tooth) = gear_calculations(teeth, pitch, angle, clearance,
                                    self.options.internal_ring,
                                    self.options.profile_shift * 0.01)

        # Detect Undercut of teeth
        ##        undercut = int(ceil(undercut_min_teeth( angle )))
        ##        needs_undercut = teeth < undercut #? no longer needed ?
        if have_undercut(teeth, angle, 1.0):
            min_teeth = int(ceil(undercut_min_teeth(angle, 1.0)))
            min_angle = undercut_min_angle(teeth, 1.0) + .1
            max_k = undercut_max_k(teeth, angle)
            msg = "Undercut Warning: This gear (%d teeth) will not work well.\nTry tooth count of %d or more,\nor a pressure angle of %.1f [deg] or more,\nor try a profile shift of %d %%.\nOr other decent combinations." % (
                teeth, min_teeth, min_angle, int(100. * max_k) - 100.)
            # alas annotation cannot handle the degree symbol. Also it ignore newlines.
            # so split and make a list
            warnings.extend(msg.split("\n"))
            if self.options.undercut_alert:
                inkex.debug(msg)
            else:
                print >> self.tty, msg

        # All base calcs done. Start building gear
        points = generate_spur_points(teeth, base_radius, pitch_radius,
                                      outer_radius, root_radius,
                                      accuracy_involute, accuracy_circular)

        ##        half_thick_angle = two_pi / (4.0 * teeth ) #?? = pi / (2.0 * teeth)
        ##        pitch_to_base_angle  = involute_intersect_angle( base_radius, pitch_radius )
        ##        pitch_to_outer_angle = involute_intersect_angle( base_radius, outer_radius ) - pitch_to_base_angle
        ##
        ##        start_involute_radius = max(base_radius, root_radius)
        ##        radii = linspace(start_involute_radius, outer_radius, accuracy_involute)
        ##        angles = [involute_intersect_angle(base_radius, r) for r in radii]
        ##
        ##        centers = [(x * two_pi / float( teeth) ) for x in range( teeth ) ]
        ##        points = []
        ##
        ##        for c in centers:
        ##            # Angles
        ##            pitch1 = c - half_thick_angle
        ##            base1  = pitch1 - pitch_to_base_angle
        ##            offsetangles1 = [ base1 + x for x in angles]
        ##            points1 = [ point_on_circle( radii[i], offsetangles1[i]) for i in range(0,len(radii)) ]
        ##
        ##            pitch2 = c + half_thick_angle
        ##            base2  = pitch2 + pitch_to_base_angle
        ##            offsetangles2 = [ base2 - x for x in angles]
        ##            points2 = [ point_on_circle( radii[i], offsetangles2[i]) for i in range(0,len(radii)) ]
        ##
        ##            points_on_outer_radius = [ point_on_circle(outer_radius, x) for x in linspace(offsetangles1[-1], offsetangles2[-1], accuracy_circular) ]
        ##
        ##            if root_radius > base_radius:
        ##                pitch_to_root_angle = pitch_to_base_angle - involute_intersect_angle(base_radius, root_radius )
        ##                root1 = pitch1 - pitch_to_root_angle
        ##                root2 = pitch2 + pitch_to_root_angle
        ##                points_on_root = [point_on_circle (root_radius, x) for x in linspace(root2, root1+(two_pi/float(teeth)), accuracy_circular) ]
        ##                p_tmp = points1 + points_on_outer_radius[1:-1] + points2[::-1] + points_on_root[1:-1] # [::-1] reverses list; [1:-1] removes first and last element
        ##            else:
        ##                points_on_root = [point_on_circle (root_radius, x) for x in linspace(base2, base1+(two_pi/float(teeth)), accuracy_circular) ]
        ##                p_tmp = points1 + points_on_outer_radius[1:-1] + points2[::-1] + points_on_root # [::-1] reverses list
        ##
        ##            points.extend( p_tmp )

        path = points_to_svgd(points)
        bbox_center = points_to_bbox_center(points)

        # Spokes (add to current path)
        if not self.options.internal_ring:  # only draw internals if spur gear
            spokes_path, msg = generate_spokes_path(root_radius, spoke_width,
                                                    spoke_count, mount_radius,
                                                    mount_hole, unit_factor,
                                                    self.options.units)
            warnings.extend(msg)
            path += spokes_path

            # Draw mount hole
            # A : rx,ry  x-axis-rotation, large-arch-flag, sweepflag  x,y
            r = mount_hole / 2
            path += ("M %f,%f" % (0, r) + "A  %f,%f %s %s %s %f,%f" %
                     (r, r, 0, 0, 0, 0, -r) + "A  %f,%f %s %s %s %f,%f" %
                     (r, r, 0, 0, 0, 0, r))
        else:
            # its a ring gear
            # which only has an outer ring where width = spoke width
            r = outer_radius + spoke_width
            path += ("M %f,%f" % (0, r) + "A  %f,%f %s %s %s %f,%f" %
                     (r, r, 0, 0, 0, 0, -r) + "A  %f,%f %s %s %s %f,%f" %
                     (r, r, 0, 0, 0, 0, r))

        # Embed gear in group to make animation easier:
        #  Translate group, Rotate path.
        t = 'translate(' + str(self.view_center[0]) + ',' + str(
            self.view_center[1]) + ')'
        g_attribs = {
            inkex.addNS('label', 'inkscape'):
            'Gear' + str(teeth),
            inkex.addNS('transform-center-x', 'inkscape'):
            str(-bbox_center[0]),
            inkex.addNS('transform-center-y', 'inkscape'):
            str(-bbox_center[1]),
            'transform':
            t,
            'info':
            'N:' + str(teeth) + '; Pitch:' + str(pitch) +
            '; Pressure Angle: ' + str(angle)
        }
        # add the group to the current layer
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        # Create gear path under top level group
        style = {
            'stroke': path_stroke,
            'fill': path_fill,
            'stroke-width': path_stroke_width
        }
        gear_attribs = {'style': simplestyle.formatStyle(style), 'd': path}
        gear = inkex.etree.SubElement(g, inkex.addNS('path', 'svg'),
                                      gear_attribs)

        # Add center
        if centercross:
            style = {
                'stroke': path_stroke,
                'fill': path_fill,
                'stroke-width': path_stroke_light
            }
            cs = str(pitch / 3)  # centercross length
            d = 'M-' + cs + ',0L' + cs + ',0M0,-' + cs + 'L0,' + cs  # 'M-10,0L10,0M0,-10L0,10'
            center_attribs = {
                inkex.addNS('label', 'inkscape'): 'Center cross',
                'style': simplestyle.formatStyle(style),
                'd': d
            }
            center = inkex.etree.SubElement(g, inkex.addNS('path', 'svg'),
                                            center_attribs)

        # Add pitch circle (for mating)
        if pitchcircle:
            style = {
                'stroke': path_stroke,
                'fill': path_fill,
                'stroke-width': path_stroke_light
            }
            draw_SVG_circle(g, pitch_radius, 0, 0, 'Pitch circle', style)

        # Add Rack (below)
        if self.options.drawrack:
            base_height = self.options.base_height * unit_factor
            tab_width = self.options.base_tab * unit_factor
            tooth_count = self.options.teeth_length
            (points,
             guide_path) = generate_rack_points(tooth_count, pitch, addendum,
                                                angle, base_height, tab_width,
                                                clearance, pitchcircle)
            path = points_to_svgd(points)
            # position below Gear, so that it meshes nicely
            # xoff = 0          ## if teeth % 4 == 2.
            # xoff = -0.5*pitch     ## if teeth % 4 == 0.
            # xoff = -0.75*pitch    ## if teeth % 4 == 3.
            # xoff = -0.25*pitch    ## if teeth % 4 == 1.
            xoff = (-0.5, -0.25, 0, -0.75)[teeth % 4] * pitch
            t = 'translate(' + str(xoff) + ',' + str(pitch_radius) + ')'
            g_attribs = {
                inkex.addNS('label', 'inkscape'):
                'RackGear' + str(tooth_count),
                'transform': t
            }
            rack = inkex.etree.SubElement(g, 'g', g_attribs)

            # Create SVG Path for gear
            style = {
                'stroke': path_stroke,
                'fill': 'none',
                'stroke-width': path_stroke_width
            }
            gear_attribs = {'style': simplestyle.formatStyle(style), 'd': path}
            gear = inkex.etree.SubElement(rack, inkex.addNS('path', 'svg'),
                                          gear_attribs)
            if guide_path is not None:
                style2 = {
                    'stroke': path_stroke,
                    'fill': 'none',
                    'stroke-width': path_stroke_light
                }
                gear_attribs2 = {
                    'style': simplestyle.formatStyle(style2),
                    'd': guide_path
                }
                gear = inkex.etree.SubElement(rack, inkex.addNS('path', 'svg'),
                                              gear_attribs2)

        # Add Annotations (above)
        if self.options.annotation:
            outer_dia = outer_radius * 2
            if self.options.internal_ring:
                outer_dia += 2 * spoke_width
            notes = []
            notes.extend(warnings)
            #notes.append('Document (%s) scale conversion = %2.4f' % (self.document.getroot().find(inkex.addNS('namedview', 'sodipodi')).get(inkex.addNS('document-units', 'inkscape')), unit_factor))
            notes.extend([
                'Teeth: %d   CP: %2.4f(%s) ' %
                (teeth, pitch / unit_factor, self.options.units),
                'DP: %2.3f Module: %2.4f' %
                (pi / pitch * unit_factor, pitch / pi * 25.4),
                'Pressure Angle: %2.2f degrees' % (angle),
                'Pitch diameter: %2.3f %s' %
                (pitch_radius * 2 / unit_factor, self.options.units),
                'Outer diameter: %2.3f %s' %
                (outer_dia / unit_factor, self.options.units),
                'Base diameter:  %2.3f %s' %
                (base_radius * 2 / unit_factor, self.options.units)  #,
                #'Addendum:      %2.4f %s'  % (addendum / unit_factor, self.options.units),
                #'Dedendum:      %2.4f %s'  % (dedendum / unit_factor, self.options.units)
            ])
            # text height relative to gear size.
            # ranges from 10 to 22 over outer radius size 60 to 360
            text_height = max(10, min(10 + (outer_dia - 60) / 24, 22))
            # position above
            y = -outer_radius - (len(notes) + 1) * text_height * 1.2
            for note in notes:
                self.add_text(g, note, [0, y], text_height)
                y += text_height * 1.2
Example #36
0
    def make_paths(self, txt2paths=False ):
        self.txt2paths = txt2paths
        msg               = ""
        
##        self.inkscape_dpi = None
##        try:
##            Inkscape_Version = self.document.getroot().xpath('@inkscape:version', namespaces=inkex.NSS)[0].split(" ")[0]
##        except:
##            Inkscape_Version = None
##
##        if Inkscape_Version <= .91:
##            self.inkscape_dpi = 90.0
##        else:
##            self.inkscape_dpi = 96.0

      
        if (self.txt2paths):
            self.convert_text2paths()
            
        try:
            h_mm = self.unit2mm(self.document.getroot().xpath('@height', namespaces=inkex.NSS)[0])
            w_mm = self.unit2mm(self.document.getroot().xpath('@width', namespaces=inkex.NSS)[0])
        except:
            line1 = "Units not set in SVG File.\n"
            line2 = "Inkscape v0.90 or higher makes SVG files with units data.\n"
            line3 = "1.) In Inkscape (v0.90 or higher) select 'File'-'Document Properties'."
            line4 = "2.) In the 'Custom Size' region on the 'Page' tab set the 'Units' to 'mm' or 'in'."
            raise Exception("%s\n%s\n%s\n%s" %(line1,line2,line3,line4))
        
        try:
            view_box_str = self.document.getroot().xpath('@viewBox', namespaces=inkex.NSS)[0]
            view_box_list = view_box_str.split(' ')
            Wpix = float(view_box_list[2])
            Hpix = float(view_box_list[3])
            scale_h = h_mm/Hpix
            scale_w = w_mm/Wpix
            Dx = float(view_box_list[0]) * scale_w
            Dy = float(view_box_list[1]) * scale_h
        except:
            line1 = "Cannot determine SVG scale (SVG Viewox Missing).\n"
            line2 = "In Inkscape (v0.92) select 'File'-'Document Properties'."
            line3 = "In the 'Scale' region on the 'Page' tab change the 'Scale x:' value"
            line4 = "and press enter. Changing the value will add the Viewbox attribute."
            line5 = "The 'Scale x:' can then be changed back to the original value."
            ##if self.inkscape_dpi==None:
            raise Exception("%s\n%s\n%s\n%s\n%s" %(line1,line2,line3,line4,line5))

##            print "Using guessed dpi value of: ",self.inkscape_dpi
##            scale_h = 25.4/self.inkscape_dpi
##            scale_w = 25.4/self.inkscape_dpi
##            Dx = 0
##            Dy = 0
        
        if abs(1.0-scale_h/scale_w) > .01:
            line1 ="SVG Files with different scales in X and Y are not supported.\n"
            line2 ="In Inkscape (v0.92): 'File'-'Document Properties'"
            line3 ="on the 'Page' tab adjust 'Scale x:' in the 'Scale' section"
            raise Exception("%s\n%s\n%s" %(line1,line2,line3))
        
        for node in self.document.getroot().xpath('//svg:g', namespaces=inkex.NSS):
            if node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer':
                layer = node.get(inkex.addNS('label', 'inkscape'))
                self.layernames.append(layer.lower())
                layer = layer.replace(' ', '_')
                if layer and not layer in self.layers:
                    self.layers.append(layer)

        self.groupmat = [[[scale_w,    0.0,  0.0-Dx],
                          [0.0  , -scale_h, h_mm+Dy]]]

        self.process_group(self.document.getroot())

        
        #################################################
        #msg = msg + "Height(mm)= %f\n" %(h_mm)
        #msg = msg + "Width (mm)= %f\n" %(w_mm)
        #inkex.errormsg(_(msg))
        
##        if not self.raster: 
##            xmin= self.lines[0][0]+0.0
##            xmax= self.lines[0][0]+0.0
##            ymin= self.lines[0][1]+0.0
##            ymax= self.lines[0][1]+0.0
##            for line in self.lines:
##                x1= line[0]
##                y1= line[1]
##                x2= line[2]
##                y2= line[3]
##                xmin = min(min(xmin,x1),x2)
##                ymin = min(min(ymin,y1),y2)
##                xmax = max(max(xmax,x1),x2)
##                ymax = max(max(ymax,y1),y2)
##        else:
        xmin= 0.0
        xmax=  w_mm 
        ymin= -h_mm 
        ymax= 0.0
        self.Make_PNG()
        
        self.Xsize=xmax-xmin
        self.Ysize=ymax-ymin
        Xcorner=xmin
        Ycorner=ymax
        for ii in range(len(self.lines)):
            self.lines[ii][0] = self.lines[ii][0]-Xcorner
            self.lines[ii][1] = self.lines[ii][1]-Ycorner
            self.lines[ii][2] = self.lines[ii][2]-Xcorner
            self.lines[ii][3] = self.lines[ii][3]-Ycorner

        self.cut_lines = []
        self.eng_lines = []
        for line in self.lines:
            ID=line[5]
            if (self.Cut_Type[ID]=="engrave"):
                self.eng_lines.append([line[0],line[1],line[2],line[3]])
            elif (self.Cut_Type[ID]=="cut"):
                self.cut_lines.append([line[0],line[1],line[2],line[3]])
            else:
                pass
Example #37
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)=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")
                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 '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 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)=self.colmod(c[0],c[1],c[2],path_id)
                        else:
                            new_val = col
                        if changed:
                            declarations[i] = prop + ':' + new_val
                            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'))
                rx = float(node.get('rx'))
                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 #38
0
    def effect(self):

        # retrieve label
        label = self.options.label

        # define styles
        style1 = {
            'fill': '#d6e6ec',
            'fill-opacity': '1',
            'stroke': '#000000',
            'stroke-width': '4',
            'stroke-linecap': 'butt',
            'stroke-linejoin': 'miter',
            'stroke-miterlimit': '4',
            'stroke-opacity': '1',
            'stroke-dasharray': 'none'
        }
        style2 = {
            'fill': '#ff4343',
            'fill-opacity': '1',
            'stroke': 'none',
            'display': 'inline'
        }
        style3 = {
            'opacity': '0.3',
            'fill': '#000000',
            'fill-opacity': '1',
            'stroke': 'none'
        }
        style4 = {
            'fill': 'none',
            'stroke': '#000000',
            'stroke-width': '4',
            'stroke-linecap': 'butt',
            'stroke-linejoin': 'miter',
            'stroke-miterlimit': '4',
            'stroke-opacity': '1',
            'stroke-dasharray': 'none',
            'display': 'inline'
        }

        # Get access to main SVG document element and get its dimensions.
        svg = self.document.getroot()
        width = inkex.unittouu(svg.get('width'))
        height = inkex.unittouu(svg.get('height'))

        # Create a new group for the shape
        group = inkex.etree.SubElement(svg, 'g')
        group.set('transform',
                  'matrix(0.2,0,0,0.2,%f,%f)' % (width / 2, height / 2))

        # back 1/5
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style1))
        path.set(
            'd',
            'm 53.626832,237.83881 132.865088,87.10045 -9.70888,14.6732 L 43.825127,252.64 z'
        )
        group.append(path)

        # back 2/5
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style1))
        path.set(
            'd',
            'm 90.193079,213.41382 -21.810543,34.09817 103.387834,67.77647 23.5192,-35.63517 z'
        )
        group.append(path)

        # back 3/5
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style1))
        path.set('d',
                 'm 249.1764,338.56763 0,17.63402 151.03923,0 0,-17.63402 z')
        group.append(path)

        # back 4/5
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style1))
        path.set(inkex.addNS('nodetypes', 'sodipodi'), 'cczccc')
        path.set(
            'd',
            'm 257.61006,356.20165 0,230.00899 c 0,0 27.64765,226.9422 66.70261,226.9422 39.05496,0 68.236,-226.9422 68.236,-226.9422 l 0,-230.00899 z'
        )
        group.append(path)

        # back 5/5
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style1))
        path.set(inkex.addNS('nodetypes', 'sodipodi'), 'czcczcc')
        path.set(
            'd',
            'm 184.71041,327.63169 c 0,0 12.71439,12.24709 23.75073,15.53612 11.03634,3.28903 40.71526,0 40.71526,0 l 0,9.96706 c 0,0 -29.85465,3.5594 -41.79819,0 -11.94354,-3.5594 -27.59766,-18.0526 -27.59766,-18.0526 z'
        )
        group.append(path)

        # content 1/1
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style2))
        path.set(inkex.addNS('nodetypes', 'sodipodi'), 'cczccc')
        path.set(
            'd',
            'm 257.61006,356.20165 0,230.00899 c 0,0 27.64765,226.9422 66.70261,226.9422 39.05496,0 68.236,-226.9422 68.236,-226.9422 l 0,-230.00899 z'
        )
        path.set(inkex.addNS('label', 'inkscape'), label)
        group.append(path)

        # front 1/x
        rect = inkex.etree.Element(inkex.addNS('rect', 'svg'))
        rect.set('style', formatStyle(style3))
        rect.set('width', '72.836182')
        rect.set('height', '7.666966')
        rect.set('x', '267.57712')
        rect.set('y', '397.60327')
        rect.set('ry', '2.8527629')
        group.append(rect)

        # front 2/x
        rect = inkex.etree.Element(inkex.addNS('rect', 'svg'))
        rect.set('style', formatStyle(style3))
        rect.set('width', '72.836182')
        rect.set('height', '7.666966')
        rect.set('x', '267.57712')
        rect.set('y', '510.30768')
        rect.set('ry', '2.8527629')
        group.append(rect)

        # front 3/x
        rect = inkex.etree.Element(inkex.addNS('rect', 'svg'))
        rect.set('style', formatStyle(style3))
        rect.set('width', '72.836182')
        rect.set('height', '7.666966')
        rect.set('x', '267.57712')
        rect.set('y', '623.77875')
        rect.set('ry', '2.8527629')
        group.append(rect)

        # front 4/x
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style4))
        path.set('d',
                 'm 249.1764,338.56763 0,17.63402 151.03923,0 0,-17.63402 z')
        group.append(path)

        # front 5/x
        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
        path.set('style', formatStyle(style4))
        path.set(inkex.addNS('nodetypes', 'sodipodi'), 'cczccc')
        path.set(
            'd',
            'm 257.61006,356.20165 0,230.00899 c 0,0 27.64765,226.9422 66.70261,226.9422 39.05496,0 68.236,-226.9422 68.236,-226.9422 l 0,-230.00899 z'
        )
        group.append(path)
Example #39
0
    def effect(self):
        # loop over all selected paths
        if self.options.selection == "Path_lengthselection":
            for id, node in self.svg.selected.items():
                if node.tag == inkex.addNS('path', 'svg'):
                    l1, l2, l3, l4, l5 = [], [], [], [], []
                    p = paths.CubicSuperPath(inkex.paths.Path(node.get('d')))
                    slengths = csplength(p)
                    b = [slengths, p]

                    # path length select
                    for x in range(0, len(slengths)):
                        if sum(b[0][x]) < self.options.len1:
                            l1.append(b[1][x])
                        if self.options.len2 > sum(
                                b[0][x]) >= self.options.len1:
                            l2.append(b[1][x])
                        if self.options.len3 > sum(
                                b[0][x]) >= self.options.len2:
                            l3.append(b[1][x])
                        if self.options.len4 > sum(
                                b[0][x]) >= self.options.len3:
                            l4.append(b[1][x])
                        if sum(b[0][x]) >= self.options.len4:
                            l5.append(b[1][x])

                # make path
                lensel = [l1, l2, l3, l4, l5]
                strlen = [
                    '#FF0001', '#00FF02', '#AAFF03', '#87CEE4', '#000FF5'
                ]
                for i, x in zip(strlen, lensel):
                    s = {
                        'stroke-linejoin': 'miter',
                        'stroke-width': '0.5px',
                        'stroke-opacity': '1.0',
                        'fill-opacity': '1.0',
                        'stroke': i,
                        'stroke-linecap': 'butt',
                        'fill': 'none'
                    }
                    attribs = {
                        'style':
                        str(inkex.Style(s)),
                        'd':
                        str(
                            paths.Path(
                                paths.CubicSuperPath(x).to_path().to_arrays()))
                    }
                    etree.SubElement(node.getparent(),
                                     inkex.addNS('path', 'svg'), attribs)

        if self.options.selection == "Path_slantselection":
            for id, node in self.svg.selected.items():
                if node.tag == inkex.addNS('path', 'svg'):
                    hor1, ver2, slan3 = [], [], []
                    p = paths.CubicSuperPath(inkex.paths.Path(node.get('d')))

                    # path slant select
                    for i, x in enumerate(p):
                        tn = roughBBox(x)
                        if tn < self.options.hor:
                            hor1.append(p[i])
                        elif tn > self.options.ver:
                            ver2.append(p[i])
                        else:
                            slan3.append(p[i])

                # make path
                slnsel = [hor1, ver2, slan3]
                strsln = ['#FF0001', '#00FF02', '#000FF5']
                for i, x in zip(strsln, slnsel):
                    s = {
                        'stroke-linejoin': 'miter',
                        'stroke-width': '0.5px',
                        'stroke-opacity': '1.0',
                        'fill-opacity': '1.0',
                        'stroke': i,
                        'stroke-linecap': 'butt',
                        'fill': 'none'
                    }
                    attribs = {
                        'style':
                        str(inkex.Style(s)),
                        'd':
                        str(
                            paths.Path(
                                paths.CubicSuperPath(x).to_path().to_arrays()))
                    }
                    etree.SubElement(node.getparent(),
                                     inkex.addNS('path', 'svg'), attribs)
 def newLayer(self, svg, name='no name'):
     layer = inkex.etree.SubElement(svg, 'g')
     layer.set(inkex.addNS('label', 'inkscape'), name)
     layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
     return layer
    def effect(self):
        if (self.options.create_bearing_gear
                and self.options.active_tab == '"help"'):
            self.error("""English spport forum:
http://www.cnc-club.ru/forum/viewforum.php?f=33		
			
Russian support forum:
	http://cnc-club.ru/forum/viewtopic.php?f=15&t=287
			
			
			""")
            return

        time_ = time.time()
        self.distance = self.options.distance * self.options.units
        self.options.linear_distance *= self.options.units
        self.options.gear_r *= self.options.units
        self.options.bearings_d *= self.options.units

        self.first_teeth = self.options.selected_puley_teeth
        self.second_teeth = self.options.generated_puley_teeth
        self.num = self.options.number_of_copies

        def add_circle(c, r, center_mark=False):
            return ("M%s,%s a %s,%s 0 1 1 %s,0 %s,%s 0 1 1 %s,0 z " %
                    (c[0] + r, c[1], r, r, -2 * r, r, r, 2 * r) +
                    #c+r,c   r r        -2*r  r   r       2*r
                    (("M %s,%s l -11,-11 22,22 -11,-11 -11,11, 22,-22" %
                      (c[0], c[1])) if center_mark else ""))

        c = list(self.view_center)
        d = ""
        d1 = ""
        if (self.options.create_bearing_gear
                and self.options.active_tab == '"linear_shaft"'):
            r = (self.options.gear_r * 2 + self.options.bearings_d / 2 + 100)
            for i in range(self.options.number_of_bearings):
                a = i * math.pi * 2 / self.options.number_of_bearings
                d += add_circle([
                    c[0] + math.cos(a) * self.options.gear_r,
                    c[1] + math.sin(a) * self.options.gear_r
                ], self.options.bearings_d / 2)
                d1 += add_circle([
                    c[0] + math.cos(a) * self.options.gear_r,
                    -r + c[1] + math.sin(a) * self.options.gear_r
                ], self.options.bearings_d / 2, True)
            d1 += add_circle([c[0], c[1] - r], self.options.gear_r, True)

            path = inkex.etree.SubElement(
                self.current_layer, inkex.addNS('path', 'svg'), {
                    "d": d,
                    "style": "stroke:#4d4d4d;fill:#ececec"
                })
            path1 = inkex.etree.SubElement(
                self.current_layer, inkex.addNS('path', 'svg'), {
                    "d": d1,
                    "style": "stroke:#4d4d4d;fill:#ececec"
                })

            csp = cubicsuperpath.parsePath(d)
            minx, miny, maxx, maxy = csp_true_bounds(csp)
            c1 = [(maxx[0] + minx[0]) / 2, (maxy[1] + miny[1]) / 2]
            path.set(inkex.addNS('transform-center-x', 'inkscape'),
                     str(-c1[0] + c[0]))
            path.set(inkex.addNS('transform-center-y', 'inkscape'),
                     str(-c1[1] + c[1]))

            self.selected = {"1": path}

        if len(self.selected) != 1:
            self.error('Please select one and only one path!', 'error')
        path = self.selected.values()[0]
        if "d" not in path.keys():
            self.error('Please select a "Path"!', 'error')
        csp = cubicsuperpath.parsePath(path.get("d"))

        center_group = inkex.etree.SubElement(path.getparent(),
                                              inkex.addNS('g', 'svg'))
        group = inkex.etree.SubElement(path.getparent(),
                                       inkex.addNS('g', 'svg'))
        attrib = path.attrib

        if "transform" in path.keys():
            t = path.get('transform')
            t = simpletransform.parseTransform(t)
            simpletransform.applyTransformToPath(t, csp)
            path.set("transform", "")
            path.set('d', cubicsuperpath.formatPath(csp))
            inkex.etree.SubElement(group, inkex.addNS('path', 'svg'),
                                   {"d": cubicsuperpath.formatPath(csp)})
            self.error(path.get("transform"))

        # Will have to find center of bbox
        minx, miny, maxx, maxy = csp_true_bounds(csp)

        c1 = [(maxx[0] + minx[0]) / 2, (maxy[1] + miny[1]) / 2]
        w, h = max(maxx[0] - minx[0], abs(c1[0] - minx[0]),
                   abs(c1[0] - maxx[0])), max(maxy[1] - miny[1],
                                              abs(c1[1] - miny[1]),
                                              abs(c1[1] - maxy[1]))
        if inkex.addNS('transform-center-x', 'inkscape') in path.keys():
            c1[0] += float(
                path.get(inkex.addNS('transform-center-x', 'inkscape')))
        if inkex.addNS('transform-center-y', 'inkscape') in path.keys():
            c1[1] -= float(
                path.get(inkex.addNS('transform-center-y', 'inkscape')))

        c2 = [c1[0] - self.distance, c1[1]]

        def get_transform(c1, c2, a1, a2):
            [c1x, c1y], [c2x, c2y] = c1, c2
            # move c1 to 0
            transform = [[1, 0, -c1x], [0, 1, -c1y]]
            # Rotate to a1 to 0
            transform = simpletransform.composeTransform(
                [[math.cos(a1), -math.sin(a1), 0],
                 [math.sin(a1), math.cos(a1), 0]], transform)
            # Move c2 to 0
            transform = simpletransform.composeTransform(
                [[1, 0, -c2x + c1x], [0, 1, -c2y + c1y]], transform)
            # Rotate to a2 to 0
            transform = simpletransform.composeTransform(
                [[math.cos(a2), -math.sin(a2), 0],
                 [math.sin(a2), math.cos(a2), 0]], transform)
            # move c2 back to c2
            transform = simpletransform.composeTransform(
                [[1, 0, c2x], [0, 1, c2y]], transform)
            return transform

        if not self.options.active_tab == '"linear_shaft"':
            # Radial gear
            if not self.options.variable_speed:
                for i in range(self.num):
                    alpha = math.pi * 2 * (i) / self.num
                    alpha1 = alpha * self.second_teeth
                    alpha2 = alpha * self.first_teeth

                    transform = get_transform(c1, c2, alpha1, alpha2)
                    # add path's clone
                    attrib["transform"] = simpletransform.formatTransform(
                        transform)
                    inkex.etree.SubElement(group, inkex.addNS('path', 'svg'),
                                           attrib)

            else:

                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_

                #get K, firs calculate aproximate turn and then get the K
                if not self.options.optimize_distance:
                    K, alpha2_ = get_k(csp, c1, self.distance)
                else:
                    #set min and max distances
                    dists = [
                        0.,
                        math.sqrt(w**2 + h**2) *
                        (1 + self.second_teeth / self.first_teeth)
                    ]
                    first = True
                    for i in range(optimize_distance_max_iters):
                        d = (
                            dists[0] + dists[1]
                        ) / 2  #	if not first and not dists[0]<self.distance<dists[1] else self.distance
                        first = False
                        K, alpha2_ = get_k(csp, c1, d)
                        if K > 1:
                            dists = [dists[0], d]
                        else:
                            dists = [d, dists[1]]
                        if abs(1. - K) < optimize_distance_tolerance:
                            break
                        #self.error(str((i,K,d)))
                    self.distance = d
                c2 = [c1[0] - self.distance, c1[1]]
                # Now create the paths
                alpha2 = 0
                for i in range(self.num):
                    alpha = math.pi * 2 * (i) / self.num
                    alpha1 = alpha * self.second_teeth
                    alpha2 += alpha2_[i] * K

                    transform = get_transform(c1, c2, alpha1, alpha2)
                    # add path's clone
                    attrib["transform"] = simpletransform.formatTransform(
                        transform)
                    inkex.etree.SubElement(group, inkex.addNS('path', 'svg'),
                                           attrib)

                self.error("Optimized distance: %s. " %
                           (self.distance / self.options.units))
                self.error(
                    "Optimized parameter K: %s (the closer to 1.0 the better)."
                    % K)
                self.error("Time elapsed %s seconds." % (time.time() - time_))
            self.draw_pointer(c1, color="#000080", width=1, group=center_group)
            self.draw_pointer(c2, color="#000080", width=1, group=center_group)
        else:
            # Linear gear
            c1x, c1y = c1[0], c1[1]
            i = 0
            self.distance = self.options.linear_distance
            if self.options.standatd_distance and self.options.create_bearing_gear:
                self.distance = self.options.gear_r + self.options.bearings_d / 2

            while i <= self.options.rev * self.num:
                a = math.pi * 2 * i / self.num
                d = self.distance * a
                # Move c to 0
                transform = [[1, 0, -c1x], [0, 1, -c1y]]
                # Rotate to a
                transform = simpletransform.composeTransform(
                    [[math.cos(a), -math.sin(a), 0],
                     [math.sin(a), math.cos(a), 0]], transform)
                # Move 0 to c + d
                transform = simpletransform.composeTransform(
                    [[1, 0, c1x + d], [0, 1, c1y]], transform)
                attrib["transform"] = simpletransform.formatTransform(
                    transform)
                inkex.etree.SubElement(group, inkex.addNS('path', 'svg'),
                                       attrib)
                i += 1
Example #42
0
	def recursivelyTraverseSvg( self, aNodeList,
		matCurrent=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]],
		parent_visibility='visible', cloneTransform=None ):

		'''
		[ This too is largely lifted from eggbot.py ]

		Recursively walk the SVG document, building polygon vertex lists
		for each graphical element we support.

		Rendered SVG elements:
			<circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, <rect>

		Supported SVG elements:
			<group>, <use>

		Ignored SVG elements:
			<defs>, <eggbot>, <metadata>, <namedview>, <pattern>,
			processing directives

		All other SVG elements trigger an error (including <text>)
		'''

		for node in aNodeList:

			# Ignore invisible nodes
			v = node.get( 'visibility', parent_visibility )
			if v == 'inherit':
				v = parent_visibility
			if v == 'hidden' or v == 'collapse':
				pass

			# First apply the current matrix transform to this node's tranform
			matNew = simpletransform.composeTransform( matCurrent,
				simpletransform.parseTransform( node.get( "transform" ) ) )

			if node.tag == inkex.addNS( 'g', 'svg' ) or node.tag == 'g':

				self.recursivelyTraverseSvg( node, matNew, parent_visibility=v )

			elif node.tag == inkex.addNS( 'use', 'svg' ) or node.tag == 'use':

				# A <use> element refers to another SVG element via an xlink:href="#blah"
				# attribute.  We will handle the element by doing an XPath search through
				# the document, looking for the element with the matching id="blah"
				# attribute.  We then recursively process that element after applying
				# any necessary (x,y) translation.
				#
				# Notes:
				#  1. We ignore the height and width attributes as they do not apply to
				#     path-like elements, and
				#  2. Even if the use element has visibility="hidden", SVG still calls
				#     for processing the referenced element.  The referenced element is
				#     hidden only if its visibility is "inherit" or "hidden".

				refid = node.get( inkex.addNS( 'href', 'xlink' ) )
				if not refid:
					pass

				# [1:] to ignore leading '#' in reference
				path = '//*[@id="%s"]' % refid[1:]
				refnode = node.xpath( path )
				if refnode:
					x = float( node.get( 'x', '0' ) )
					y = float( node.get( 'y', '0' ) )
					# Note: the transform has already been applied
					if ( x != 0 ) or (y != 0 ):
						matNew2 = composeTransform( matNew, parseTransform( 'translate(%f,%f)' % (x,y) ) )
					else:
						matNew2 = matNew
					v = node.get( 'visibility', v )
					self.recursivelyTraverseSvg( refnode, matNew2,
						parent_visibility=v, cloneTransform=node.get( 'transform' ) )

			elif node.tag == inkex.addNS( 'path', 'svg' ):

				path_data = node.get( 'd')
				if path_data:
					self.addPathVertices( path_data, node, matNew, cloneTransform )

			elif node.tag == inkex.addNS( 'rect', 'svg' ) or node.tag == 'rect':

				# Manually transform
				#
				#    <rect x="X" y="Y" width="W" height="H"/>
				#
				# into
				#
				#    <path d="MX,Y lW,0 l0,H l-W,0 z"/>
				#
				# I.e., explicitly draw three sides of the rectangle and the
				# fourth side implicitly

				# Create a path with the outline of the rectangle
				x = float( node.get( 'x' ) )
				y = float( node.get( 'y' ) )
				if ( not x ) or ( not y ):
					pass
				w = float( node.get( 'width', '0' ) )
				h = float( node.get( 'height', '0' ) )
				a = []
				a.append( ['M ', [x, y]] )
				a.append( [' l ', [w, 0]] )
				a.append( [' l ', [0, h]] )
				a.append( [' l ', [-w, 0]] )
				a.append( [' Z', []] )
				self.addPathVertices( simplepath.formatPath( a ), node, matNew, cloneTransform )

			elif node.tag == inkex.addNS( 'line', 'svg' ) or node.tag == 'line':

				# Convert
				#
				#   <line x1="X1" y1="Y1" x2="X2" y2="Y2/>
				#
				# to
				#
				#   <path d="MX1,Y1 LX2,Y2"/>

				x1 = float( node.get( 'x1' ) )
				y1 = float( node.get( 'y1' ) )
				x2 = float( node.get( 'x2' ) )
				y2 = float( node.get( 'y2' ) )
				if ( not x1 ) or ( not y1 ) or ( not x2 ) or ( not y2 ):
					pass
				a = []
				a.append( ['M ', [x1, y1]] )
				a.append( [' L ', [x2, y2]] )
				self.addPathVertices( simplepath.formatPath( a ), node, matNew, cloneTransform )

			elif node.tag == inkex.addNS( 'polyline', 'svg' ) or node.tag == 'polyline':

				# Convert
				#
				#  <polyline points="x1,y1 x2,y2 x3,y3 [...]"/>
				#
				# to
				#
				#   <path d="Mx1,y1 Lx2,y2 Lx3,y3 [...]"/>
				#
				# Note: we ignore polylines with no points

				pl = node.get( 'points', '' ).strip()
				if pl == '':
					pass

				pa = pl.split()
				d = "".join( ["M " + pa[i] if i == 0 else " L " + pa[i] for i in range( 0, len( pa ) )] )
				self.addPathVertices( d, node, matNew, cloneTransform )

			elif node.tag == inkex.addNS( 'polygon', 'svg' ) or node.tag == 'polygon':

				# Convert
				#
				#  <polygon points="x1,y1 x2,y2 x3,y3 [...]"/>
				#
				# to
				#
				#   <path d="Mx1,y1 Lx2,y2 Lx3,y3 [...] Z"/>
				#
				# Note: we ignore polygons with no points

				pl = node.get( 'points', '' ).strip()
				if pl == '':
					pass

				pa = pl.split()
				d = "".join( ["M " + pa[i] if i == 0 else " L " + pa[i] for i in range( 0, len( pa ) )] )
				d += " Z"
				self.addPathVertices( d, node, matNew, cloneTransform )

			elif node.tag == inkex.addNS( 'ellipse', 'svg' ) or \
				node.tag == 'ellipse' or \
				node.tag == inkex.addNS( 'circle', 'svg' ) or \
				node.tag == 'circle':

					# Convert circles and ellipses to a path with two 180 degree arcs.
					# In general (an ellipse), we convert
					#
					#   <ellipse rx="RX" ry="RY" cx="X" cy="Y"/>
					#
					# to
					#
					#   <path d="MX1,CY A RX,RY 0 1 0 X2,CY A RX,RY 0 1 0 X1,CY"/>
					#
					# where
					#
					#   X1 = CX - RX
					#   X2 = CX + RX
					#
					# Note: ellipses or circles with a radius attribute of value 0 are ignored

					if node.tag == inkex.addNS( 'ellipse', 'svg' ) or node.tag == 'ellipse':
						rx = float( node.get( 'rx', '0' ) )
						ry = float( node.get( 'ry', '0' ) )
					else:
						rx = float( node.get( 'r', '0' ) )
						ry = rx
					if rx == 0 or ry == 0:
						pass

					cx = float( node.get( 'cx', '0' ) )
					cy = float( node.get( 'cy', '0' ) )
					x1 = cx - rx
					x2 = cx + rx
					d = 'M %f,%f ' % ( x1, cy ) + \
						'A %f,%f ' % ( rx, ry ) + \
						'0 1 0 %f,%f ' % ( x2, cy ) + \
						'A %f,%f ' % ( rx, ry ) + \
						'0 1 0 %f,%f' % ( x1, cy )
					self.addPathVertices( d, node, matNew, cloneTransform )

			elif node.tag == inkex.addNS( 'pattern', 'svg' ) or node.tag == 'pattern':

				pass

			elif node.tag == inkex.addNS( 'metadata', 'svg' ) or node.tag == 'metadata':

				pass

			elif node.tag == inkex.addNS( 'defs', 'svg' ) or node.tag == 'defs':

				pass

			elif node.tag == inkex.addNS( 'namedview', 'sodipodi' ) or node.tag == 'namedview':

				pass

			elif node.tag == inkex.addNS( 'eggbot', 'svg' ) or node.tag == 'eggbot':

				pass

			elif node.tag == inkex.addNS( 'text', 'svg' ) or node.tag == 'text':

				inkex.errormsg( 'Warning: unable to draw text, please convert it to a path first.' )

				pass

			elif not isinstance( node.tag, basestring ):

				pass

			else:

				inkex.errormsg( 'Warning: unable to draw object <%s>, please convert it to a path first.' % node.tag )
				pass
Example #43
0
def pattern(parent, id):
    '''Create a pattern group to hold a single pattern, parent should be the base group'''
    newPattern = addGroup(parent, id)
    newPattern.set(inkex.addNS('label', 'inkscape'), id)
    newPattern.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
    return newPattern
Example #44
0
    def effect(self):
        if len(self.options.ids)<2:
            inkex.errormsg(_("This extension requires two selected paths."))
            return
        self.prepareSelectionList()
        self.options.wave = (self.options.kind=="Ribbon")
        if self.options.copymode=="Single":
            self.options.repeat =False
            self.options.stretch=False
        elif self.options.copymode=="Repeated":
            self.options.repeat =True
            self.options.stretch=False
        elif self.options.copymode=="Single, stretched":
            self.options.repeat =False
            self.options.stretch=True
        elif self.options.copymode=="Repeated, stretched":
            self.options.repeat =True
            self.options.stretch=True

        bbox=simpletransform.computeBBox(self.patterns.values())
                    
        if self.options.vertical:
            #flipxy(bbox)...
            bbox=(-bbox[3],-bbox[2],-bbox[1],-bbox[0])

        width=bbox[1]-bbox[0]
        dx=width+self.options.space
        if dx < 0.01:
            exit(_("The total length of the pattern is too small :\nPlease choose a larger object or set 'Space between copies' > 0"))

        for id, node in self.patterns.iteritems():
            if node.tag == inkex.addNS('path','svg') or node.tag=='path':
                d = node.get('d')
                p0 = cubicsuperpath.parsePath(d)
                if self.options.vertical:
                    flipxy(p0)

                newp=[]
                for skelnode in self.skeletons.itervalues(): 
                    self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
                    if self.options.vertical:
                        flipxy(self.curSekeleton)
                    for comp in self.curSekeleton:
                        p=copy.deepcopy(p0)
                        self.skelcomp,self.lengths=linearize(comp)
                        #!!!!>----> TODO: really test if path is closed! end point==start point is not enough!
                        self.skelcompIsClosed = (self.skelcomp[0]==self.skelcomp[-1])

                        length=sum(self.lengths)
                        xoffset=self.skelcomp[0][0]-bbox[0]+self.options.toffset
                        yoffset=self.skelcomp[0][1]-(bbox[2]+bbox[3])/2-self.options.noffset


                        if self.options.repeat:
                            NbCopies=max(1,int(round((length+self.options.space)/dx)))
                            width=dx*NbCopies
                            if not self.skelcompIsClosed:
                                width-=self.options.space
                            bbox=bbox[0],bbox[0]+width, bbox[2],bbox[3]
                            new=[]
                            for sub in p:
                                for i in range(0,NbCopies,1):
                                    new.append(copy.deepcopy(sub))
                                    offset(sub,dx,0)
                            p=new

                        for sub in p:
                            offset(sub,xoffset,yoffset)

                        if self.options.stretch:
                            if not width:
                                exit(_("The 'stretch' option requires that the pattern must have non-zero width :\nPlease edit the pattern width."))
                            for sub in p:
                                stretch(sub,length/width,1,self.skelcomp[0])

                        for sub in p:
                            for ctlpt in sub:
                                self.applyDiffeo(ctlpt[1],(ctlpt[0],ctlpt[2]))

                        if self.options.vertical:
                            flipxy(p)
                        newp+=p

                node.set('d', cubicsuperpath.formatPath(newp))
Example #45
0
 def addText(self, node):
     for i in range(self.options.num):
         para = inkex.etree.SubElement(node, inkex.addNS('flowPara', 'svg'))
         para.text = self.makePara()
         inkex.etree.SubElement(node, inkex.addNS('flowPara', 'svg'))
Example #46
0
def patternPiece(parent, id, name, fabric=2, interfacing=0, lining=0):
    '''Create a pattern piece group to hold a single pattern piece, parent should be a pattern group'''
    newPatternPiece = addGroup(parent, id)
    newPatternPiece.set(inkex.addNS('label', 'inkscape'), name)
    newPatternPiece.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
    return newPatternPiece
Example #47
0
def newUseNode(id_, x, y, href):
    use = Element(addNS('use', 'svg'))
    for name, value in [('id', id_), ('x', str(x)), ('y', str(y)),
                        (addNS('href', 'xlink'), '#' + href)]:
        use.set(name, value)
    return use
Example #48
0
def base(parent, id):
    '''Create a base group to contain all patterns, parent should be the document'''
    newBase = addGroup(parent, id)
    newBase.set(inkex.addNS('label', 'inkscape'), id)
    newBase.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
    return newBase
Example #49
0
 def getParsedLabel(self):
     label = self.get(addNS('xmoto_label', 'xmoto'), '')
     parser = Factory().create('label_parser')
     return parser.parse(label)
Example #50
0
from collections import MutableMapping
from copy import deepcopy
import json
import re

import inkex
from stringcase import snakecase

from ..commands import layer_commands
from ..elements import EmbroideryElement, nodes_to_elements
from ..i18n import _
from ..svg.tags import SVG_GROUP_TAG, INKSCAPE_GROUPMODE, SVG_DEFS_TAG, EMBROIDERABLE_TAGS

SVG_METADATA_TAG = inkex.addNS("metadata", "svg")


def strip_namespace(tag):
    """Remove xml namespace from a tag name.

    >>> {http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd}namedview
    <<< namedview
    """

    match = re.match(r'^\{[^}]+\}(.+)$', tag)

    if match:
        return match.group(1)
    else:
        return tag

Example #51
0
        if g is None:
            return (None, None, None)

        try:
            circle = g.getCircleChild()
        except Exception, e:
            _id = g.get('id', '')

            logging.warning("Sprite [%s] is an empty layer. \
Let's delete it\n%s" % (_id, e))
            parent = g.getparent()
            parent.remove(g)
            return (None, None, None)

        use = g.find(addNS('use', 'svg'))
        if use is None:
            # deprecated, we no longer use images, uses instead
            image = g.find(addNS('image', 'svg'))
            if image is not None:
                g.remove(image)

        return (g, circle, use)

    def setNodeAsBitmap(self,
                        svg,
                        texName,
                        radius,
                        bitmaps,
                        label,
                        style,
Example #52
0
    def setNodeAsBitmap(self,
                        svg,
                        texName,
                        radius,
                        bitmaps,
                        label,
                        style,
                        scale=1.0,
                        _reversed=False,
                        rotation=0.0):
        if self.isSubLayer(type=self.BLOCK):
            # remove one of the two children
            children = self.getchildren()
            child = children[0]
            self.remove(self.getchildren()[0])

        (g, circle, use) = self.getImageNodes()

        if g is None:
            return

        # if the node has more than one circle, delete it
        circles = g.findall(addNS('path', 'svg'))
        if len(circles) > 1:
            for c in circles:
                if c == circle:
                    continue
                else:
                    g.remove(c)

        # set the xmoto_label on both the sublayer and the
        # circle (for backward compatibility)
        g.set(addNS('xmoto_label', 'xmoto'), label)

        circle.set(addNS('xmoto_label', 'xmoto'), label)
        circle.set('style', style)

        if g.get('style') is not None:
            del g.attrib['style']

        circle = convertToXmNode(circle, self.svg)
        circle.setNodeAsCircle(scale * radius)

        # set the circle transform to the layer
        transform = circle.get('transform')
        if transform is not None:
            g.set('transform', transform)
            del circle.attrib['transform']

        (x, y, cx, cy, width,
         height) = getImageDimensions(texName, scale, circle.getAABB())

        imageId = svg.addImage(texName, bitmaps, width, height)

        if imageId is None:
            return

        if use is None:
            try:
                use = newUseNode('image_' + circle.get('id'), x, y, imageId)
                # insert the use as the first child so that
                # it get displayed before the circle in inkscape
                g.insert(0, use)
            except Exception, e:
                logging.info("Can't create image for sprite %s.\n%s" %
                             (texName, e))
Example #53
0
    def effect(self):
        svg = self.document.getroot()
        width = self.svg.unittouu(svg.get('width'))
        height = self.svg.unittouu(svg.attrib['height'])
        layer = etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'), 'CriCut')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        x = 0
        each = ""
        obj_styles = {}
        identity = Transform("")
        #
        # For each unique line style, add it to a dictionary/set
        # so we can later use the id's to build a path
        for obj in svg.xpath('//svg:line|//svg:circle|//svg:rect',
                             namespaces=inkex.NSS):
            #inkex.utils.debug(obj)
            style = obj.get('style', '')
            matrix = obj.transform * Transform(identity)
            #style = style + formatTransform(matrix)
            id = obj.get('id')
            if not style in obj_styles:
                obj_styles[style] = set()
            obj_styles[style].add(id)

        ## For each dictionary
        ## Iterate it's set and output paths instead.
        for obj_each in obj_styles:
            M = ""
            style = ""
            for obj_set in obj_styles[obj_each]:
                p = "//*[@id='" + obj_set + "']"
                element = svg.xpath(p, namespaces=inkex.NSS)
                style = element[0].get('style', '')
                element_type = QName(element[0]).localname
                new_transform = element[0].transform * Transform(identity)
                newM = ""
                if (element_type == "rect"):
                    x = float(element[0].attrib['x'])
                    y = float(element[0].attrib['y'])
                    width = float(element[0].attrib['width'])
                    height = float(element[0].attrib['height'])
                    newM = " M " + str(x) + "," + str(y) + " " + str(
                        x + width) + "," + str(y) + " " + str(
                            x + width) + "," + str(y + height) + " " + str(
                                x) + "," + str(y + height) + " " + str(
                                    x) + "," + str(y) + " "

                if (element_type == "line"):
                    x1 = element[0].attrib['x1']
                    x2 = element[0].attrib['x2']
                    y1 = element[0].attrib['y1']
                    y2 = element[0].attrib['y2']
                    newM = " M " + x1 + "," + y1 + " L " + x1 + "," + y1 + " " + x2 + "," + y2 + " "

                if (element_type == "circle"):
                    cy = element[0].attrib['cy']
                    cx = element[0].attrib['cx']
                    r = float(element[0].attrib['r'])
                    newM += " M " + cx + " " + cy
                    newM += " m " + str(r * -1) + ",0 "
                    newM += " a " + str(r) + "," + str(r) + " 0 1,0 " + str(
                        r * 2) + ",0 "
                    newM += "a " + str(r) + "," + str(r) + " 0 1,0 " + str(
                        (r * 2) * -1) + ",0 z "

                p = CubicSuperPath(newM)
                p.transform(new_transform)
                newM = str(p)
                M += newM
            # obj_each

            attribs = {
                'd': M,
                'style': style
            }  ## , 'transform':formatTransform(new_transform) }
            ###inkex.addNS('label','inkscape'):name },
            etree.SubElement(layer, inkex.addNS('path', 'svg'), attribs)
Example #54
0
 def setStyleLabel(self, label, style):
     self.set(addNS('xmoto_label', 'xmoto'), label)
     self.set('style', style)
Example #55
0
    def effect(self):
        # Check version.
        scriptNodes = self.document.xpath(
            "//svg:script[@jessyink:version='1.5.6']", namespaces=inkex.NSS)

        if len(scriptNodes) != 1:
            inkex.errormsg(
                _(u"JessyInk_c 还未安装到这个SVG文件,或者版本不同. 请使用 “扩展” 菜单下 “JessyInk_c” 的 “安装/升级...” 命令进行JessyInk_c 的安装。\n\n"
                  ))

        # Remove old master slide property
        for node in self.document.xpath(
                "//svg:g[@jessyink:customKeyBindings='customKeyBindings']",
                namespaces=inkex.NSS):
            node.getparent().remove(node)

        # Set custom key bindings.
        nodeText = "function getCustomKeyBindingsSub()" + "\n"
        nodeText += "{" + "\n"
        nodeText += "	var keyDict = new Object();" + "\n"
        nodeText += "	keyDict[SLIDE_MODE] = new Object();" + "\n"
        nodeText += "	keyDict[INDEX_MODE] = new Object();" + "\n"
        nodeText += "	keyDict[DRAWING_MODE] = new Object();" + "\n"

        for key, value in list(self.slideKeyCodes.items()):
            nodeText += "	keyDict[SLIDE_MODE][" + key + "] = function() { " + value + " };" + "\n"

        for key, value in list(self.drawingKeyCodes.items()):
            nodeText += "	keyDict[DRAWING_MODE][" + key + "] = function() { " + value + " };" + "\n"

        for key, value in list(self.indexKeyCodes.items()):
            nodeText += "	keyDict[INDEX_MODE][" + key + "] = function() { " + value + " };" + "\n"

        nodeText += "	return keyDict;" + "\n"
        nodeText += "}" + "\n\n"

        # Set custom char bindings.
        nodeText += "function getCustomCharBindingsSub()" + "\n"
        nodeText += "{" + "\n"
        nodeText += "	var charDict = new Object();" + "\n"
        nodeText += "	charDict[SLIDE_MODE] = new Object();" + "\n"
        nodeText += "	charDict[INDEX_MODE] = new Object();" + "\n"
        nodeText += "	charDict[DRAWING_MODE] = new Object();" + "\n"

        for key, value in list(self.slideCharCodes.items()):
            nodeText += "	charDict[SLIDE_MODE][\"" + key + "\"] = function() { " + value + " };" + "\n"

        for key, value in list(self.drawingCharCodes.items()):
            nodeText += "	charDict[DRAWING_MODE][\"" + key + "\"] = function() { " + value + " };" + "\n"

        for key, value in list(self.indexCharCodes.items()):
            nodeText += "	charDict[INDEX_MODE][\"" + key + "\"] = function() { " + value + " };" + "\n"

        nodeText += "	return charDict;" + "\n"
        nodeText += "}" + "\n"

        # Create new script node
        scriptElm = inkex.etree.Element(inkex.addNS("script", "svg"))
        scriptElm.text = nodeText
        groupElm = inkex.etree.Element(inkex.addNS("g", "svg"))
        groupElm.set("{" + inkex.NSS["jessyink"] + "}customKeyBindings",
                     "customKeyBindings")
        groupElm.set(
            "onload",
            "this.getCustomCharBindings = function() { return getCustomCharBindingsSub(); }; this.getCustomKeyBindings = function() { return getCustomKeyBindingsSub(); };"
        )
        groupElm.append(scriptElm)
        self.document.getroot().append(groupElm)
    def effect(self):

        #{{{ Check that elements have been selected

        if len(self.options.ids) == 0:
            inkex.errormsg(_("Please select objects!"))
            return

        #}}}

        #{{{ Drawing styles

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

        facestyle = {
            'stroke': '#ff0000',
            'stroke-width': str(self.unittouu('1px')),
            'fill': 'none'
        }

        #}}}

        #{{{ Handle the transformation of the current group
        parentGroup = self.getParentNode(self.selected[self.options.ids[0]])

        trans = self.getGlobalTransform(parentGroup)
        invtrans = None
        if trans:
            invtrans = self.invertTransform(trans)

        #}}}

        #{{{ Recovery of the selected objects

        pts = []
        nodes = []
        seeds = []

        for id in self.options.ids:
            node = self.selected[id]
            nodes.append(node)
            bbox = simpletransform.computeBBox([node])
            if bbox:
                cx = 0.5 * (bbox[0] + bbox[1])
                cy = 0.5 * (bbox[2] + bbox[3])
                pt = [cx, cy]
                if trans:
                    simpletransform.applyTransformToPoint(trans, pt)
                pts.append(Point(pt[0], pt[1]))
                seeds.append(Point(cx, cy))

        #}}}

        #{{{ Creation of groups to store the result

        if self.options.diagramType != 'Delaunay':
            # Voronoi
            groupVoronoi = inkex.etree.SubElement(parentGroup,
                                                  inkex.addNS('g', 'svg'))
            groupVoronoi.set(inkex.addNS('label', 'inkscape'), 'Voronoi')
            if invtrans:
                simpletransform.applyTransformToNode(invtrans, groupVoronoi)
        if self.options.diagramType != 'Voronoi':
            # Delaunay
            groupDelaunay = inkex.etree.SubElement(parentGroup,
                                                   inkex.addNS('g', 'svg'))
            groupDelaunay.set(inkex.addNS('label', 'inkscape'), 'Delaunay')

        #}}}

        #{{{ Clipping box handling

        if self.options.diagramType != 'Delaunay':
            #Clipping bounding box creation
            gBbox = simpletransform.computeBBox(nodes)

            #Clipbox is the box to which the Voronoi diagram is restricted
            clipBox = ()
            if self.options.clipBox == 'Page':
                svg = self.document.getroot()
                w = self.unittouu(svg.get('width'))
                h = self.unittouu(svg.get('height'))
                clipBox = (0, w, 0, h)
            else:
                clipBox = (2 * gBbox[0] - gBbox[1], 2 * gBbox[1] - gBbox[0],
                           2 * gBbox[2] - gBbox[3], 2 * gBbox[3] - gBbox[2])

            #Safebox adds points so that no Voronoi edge in clipBox is infinite
            safeBox = (2 * clipBox[0] - clipBox[1],
                       2 * clipBox[1] - clipBox[0],
                       2 * clipBox[2] - clipBox[3],
                       2 * clipBox[3] - clipBox[2])
            pts.append(Point(safeBox[0], safeBox[2]))
            pts.append(Point(safeBox[1], safeBox[2]))
            pts.append(Point(safeBox[1], safeBox[3]))
            pts.append(Point(safeBox[0], safeBox[3]))

            if self.options.showClipBox:
                #Add the clip box to the drawing
                rect = inkex.etree.SubElement(groupVoronoi,
                                              inkex.addNS('rect', 'svg'))
                rect.set('x', str(clipBox[0]))
                rect.set('y', str(clipBox[2]))
                rect.set('width', str(clipBox[1] - clipBox[0]))
                rect.set('height', str(clipBox[3] - clipBox[2]))
                rect.set('style', simplestyle.formatStyle(linestyle))

        #}}}

        #{{{ Voronoi diagram generation

        if self.options.diagramType != 'Delaunay':
            vertices, lines, edges = voronoi.computeVoronoiDiagram(pts)
            for edge in edges:
                line = edge[0]
                vindex1 = edge[1]
                vindex2 = edge[2]
                if (vindex1 < 0) or (vindex2 < 0):
                    continue  # infinite lines have no need to be handled in the clipped box
                else:
                    segment = self.clipEdge(vertices, lines, edge, clipBox)
                    #segment = [vertices[vindex1],vertices[vindex2]] # deactivate clipping
                    if len(segment) > 1:
                        v1 = segment[0]
                        v2 = segment[1]
                        cmds = [['M', [v1[0], v1[1]]], ['L', [v2[0], v2[1]]]]
                        path = inkex.etree.Element(inkex.addNS('path', 'svg'))
                        path.set('d', simplepath.formatPath(cmds))
                        path.set('style', simplestyle.formatStyle(linestyle))
                        groupVoronoi.append(path)

        if self.options.diagramType != 'Voronoi':
            triangles = voronoi.computeDelaunayTriangulation(seeds)
            for triangle in triangles:
                p1 = seeds[triangle[0]]
                p2 = seeds[triangle[1]]
                p3 = seeds[triangle[2]]
                cmds = [['M', [p1.x, p1.y]], ['L', [p2.x, p2.y]],
                        ['L', [p3.x, p3.y]], ['Z', []]]
                path = inkex.etree.Element(inkex.addNS('path', 'svg'))
                path.set('d', simplepath.formatPath(cmds))
                path.set('style', simplestyle.formatStyle(facestyle))
                groupDelaunay.append(path)
    cc = ['white', 'black', 'grey']
    style = {
        'stroke': 'none',
        'stroke-width': '0',
        'fill': cc[c],
        'fill-opacity': str(0.5 if c == 2 else 1.0)
    }

    attribs = {
        'style': simplestyle.formatStyle(style),
        'height': str(h),
        'width': str(w),
        'x': str(x),
        'y': str(y)
    }
    circ = inkex.etree.SubElement(parent, inkex.addNS('rect', 'svg'), attribs)


#turn a 2D array of 1's and 0's into a set of black squares
def render_code(q, size, cx, cy, parent):

    for y in range(len(q)):
        for x in range(len(q[y])):
            if q[y][x] == None:
                draw_SVG_square((size * 1.1, size * 1.1),
                                (x * size + cx, y * size + cy), 2, parent)
            elif q[y][x]:  #A binary 1 is a filled square
                draw_SVG_square((size * 1.1, size * 1.1),
                                (x * size + cx, y * size + cy), 1, parent)

Example #58
0
    def recursivelyTraverseSvg(self,
                               nodeList,
                               matCurrent=[[1.0, 0.0, 0.0], [0.0, -1.0, 0.0]],
                               parent_visibility='visible'):
        """
    Recursively traverse the svg file to plot out all of the
    paths.  The function keeps track of the composite transformation
    that should be applied to each path.

    This function handles path, group, line, rect, polyline, polygon,
    circle, ellipse and use (clone) elements. Notable elements not
    handled include text.  Unhandled elements should be converted to
    paths in Inkscape.

    TODO: There's a lot of inlined code in the eggbot version of this
    that would benefit from the Entities method of dealing with things.
    """
        for node in nodeList:
            # Ignore invisible nodes
            v = node.get('visibility', parent_visibility)
            if v == 'inherit':
                v = parent_visibility
            if v == 'hidden' or v == 'collapse':
                pass

            # first apply the current matrix transform to this node's transform
            matNew = composeTransform(matCurrent,
                                      parseTransform(node.get("transform")))

            if node.tag == inkex.addNS('g', 'svg') or node.tag == 'g':
                if (node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer'):
                    layer_name = node.get(inkex.addNS('label', 'inkscape'))
                    if (self.pause_on_layer_change == 'true'):
                        self.entities.append(SvgLayerChange(layer_name))
                self.recursivelyTraverseSvg(node, matNew, parent_visibility=v)
            elif node.tag == inkex.addNS('use', 'svg') or node.tag == 'use':
                refid = node.get(inkex.addNS('href', 'xlink'))
                if refid:
                    # [1:] to ignore leading '#' in reference
                    path = '//*[@id="%s"]' % refid[1:]
                    refnode = node.xpath(path)
                    if refnode:
                        x = float(node.get('x', '0'))
                        y = float(node.get('y', '0'))
                        # Note: the transform has already been applied
                        if (x != 0) or (y != 0):
                            matNew2 = composeTransform(
                                matNew,
                                parseTransform('translate(%f,%f)' % (x, y)))
                        else:
                            matNew2 = matNew
                        v = node.get('visibility', v)
                        self.recursivelyTraverseSvg(refnode,
                                                    matNew2,
                                                    parent_visibility=v)
                    else:
                        pass
                else:
                    pass
            elif not isinstance(node.tag, basestring):
                pass
            else:
                entity = self.make_entity(node, matNew)
                if entity == None:
                    inkex.errormsg(
                        'Warning: unable to draw object, please convert it to a path first.'
                    )
Example #59
0
    def effect(self):

        if self.options.where_to_crop == 'selection':
            inkex.errormsg('Sory, the crop to selection is a TODO feature')

        # Get SVG document dimensions
        svg = self.document.getroot()
        self.width = width = inkex.unittouu(svg.get('width'))
        self.height = height = inkex.unittouu(svg.attrib['height'])

        # Convert parameters to user unit
        offset = inkex.unittouu(
            str(self.options.crop_offset) + self.options.unit)
        bt = inkex.unittouu(str(self.options.bleed_top) + self.options.unit)
        bb = inkex.unittouu(str(self.options.bleed_bottom) + self.options.unit)
        bl = inkex.unittouu(str(self.options.bleed_left) + self.options.unit)
        br = inkex.unittouu(str(self.options.bleed_right) + self.options.unit)
        # Bleed margin
        if bt < offset: bmt = 0
        else: bmt = bt - offset
        if bb < offset: bmb = 0
        else: bmb = bb - offset
        if bl < offset: bml = 0
        else: bml = bl - offset
        if br < offset: bmr = 0
        else: bmr = br - offset

        # Define the new document limits
        left = -offset
        right = width + offset
        top = -offset
        bottom = height + offset

        # Test if printing-marks layer existis
        layer = self.document.xpath(
            '//*[@id="printing-marks" and @inkscape:groupmode="layer"]',
            namespaces=inkex.NSS)
        if layer: svg.remove(layer[0])  # remove if it existis
        # Create a new layer
        layer = inkex.etree.SubElement(svg, 'g')
        layer.set('id', 'printing-marks')
        layer.set(inkex.addNS('label', 'inkscape'), 'Printing Marks')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        layer.set(inkex.addNS('insensitive', 'sodipodi'), 'true')

        # Crop Mark
        if self.options.crop_marks == True:
            # Create a group for Crop Mark
            g_attribs = {
                inkex.addNS('label', 'inkscape'): 'CropMarks',
                'id': 'CropMarks'
            }
            g_crops = inkex.etree.SubElement(layer, 'g', g_attribs)

            # Top left Mark
            self.draw_crop_line(0, top, 0, top - self.mark_size, 'cropTL1',
                                g_crops)
            self.draw_crop_line(left, 0, left - self.mark_size, 0, 'cropTL2',
                                g_crops)

            # Top right Mark
            self.draw_crop_line(width, top, width, top - self.mark_size,
                                'cropTR1', g_crops)
            self.draw_crop_line(right, 0, right + self.mark_size, 0, 'cropTR2',
                                g_crops)

            # Bottom left Mark
            self.draw_crop_line(0, bottom, 0, bottom + self.mark_size,
                                'cropBL1', g_crops)
            self.draw_crop_line(left, height, left - self.mark_size, height,
                                'cropBL2', g_crops)

            # Bottom right Mark
            self.draw_crop_line(width, bottom, width, bottom + self.mark_size,
                                'cropBR1', g_crops)
            self.draw_crop_line(right, height, right + self.mark_size, height,
                                'cropBR2', g_crops)

        # Bleed Mark
        if self.options.bleed_marks == True:
            # Create a group for Bleed Mark
            g_attribs = {
                inkex.addNS('label', 'inkscape'): 'BleedMarks',
                'id': 'BleedMarks'
            }
            g_bleed = inkex.etree.SubElement(layer, 'g', g_attribs)

            # Top left Mark
            self.draw_bleed_line(-bl, top - bmt, -bl,
                                 top - bmt - self.mark_size, 'bleedTL1',
                                 g_bleed)
            self.draw_bleed_line(left - bml, -bt, left - bml - self.mark_size,
                                 -bt, 'bleedTL2', g_bleed)

            # Top right Mark
            self.draw_bleed_line(width + br, top - bmt, width + br,
                                 top - bmt - self.mark_size, 'bleedTR1',
                                 g_bleed)
            self.draw_bleed_line(right + bmr, -bt,
                                 right + bmr + self.mark_size, -bt, 'bleedTR2',
                                 g_bleed)

            # Bottom left Mark
            self.draw_bleed_line(-bl, bottom + bmb, -bl,
                                 bottom + bmb + self.mark_size, 'bleedBL1',
                                 g_bleed)
            self.draw_bleed_line(left - bml, height + bb,
                                 left - bml - self.mark_size, height + bb,
                                 'bleedBL2', g_bleed)

            # Bottom right Mark
            self.draw_bleed_line(width + br, bottom + bmb, width + br,
                                 bottom + bmb + self.mark_size, 'bleedBR1',
                                 g_bleed)
            self.draw_bleed_line(right + bmr, height + bb,
                                 right + bmr + self.mark_size, height + bb,
                                 'bleedBR2', g_bleed)

        # Registration Mark
        if self.options.reg_marks == True:
            # Create a group for Registration Mark
            g_attribs = {
                inkex.addNS('label', 'inkscape'): 'RegistrationMarks',
                'id': 'RegistrationMarks'
            }
            g_center = inkex.etree.SubElement(layer, 'g', g_attribs)

            # Left Mark
            cx = max(bml + offset, self.min_mark_margin)
            self.draw_reg_marks(-cx - (self.mark_size / 2),
                                (height / 2) - self.mark_size * 1.5, '0',
                                'regMarkL', g_center)

            # Right Mark
            cx = max(bmr + offset, self.min_mark_margin)
            self.draw_reg_marks(width + cx + (self.mark_size / 2),
                                (height / 2) - self.mark_size * 1.5, '180',
                                'regMarkR', g_center)

            # Top Mark
            cy = max(bmt + offset, self.min_mark_margin)
            self.draw_reg_marks((width / 2) - self.mark_size * 1.5,
                                -cy - (self.mark_size / 2), '90', 'regMarkT',
                                g_center)

            # Bottom Mark
            cy = max(bmb + offset, self.min_mark_margin)
            self.draw_reg_marks((width / 2) - self.mark_size * 1.5,
                                height + cy + (self.mark_size / 2), '-90',
                                'regMarkB', g_center)

        # Star Target
        if self.options.star_target == True:
            # Create a group for Star Target
            g_attribs = {
                inkex.addNS('label', 'inkscape'): 'StarTarget',
                'id': 'StarTarget'
            }
            g_center = inkex.etree.SubElement(layer, 'g', g_attribs)

            if height < width:
                # Left Star
                cx = max(bml + offset, self.min_mark_margin)
                self.draw_star_target(-cx - (self.mark_size / 2), (height / 2),
                                      'starTargetL', g_center)
                # Right Star
                cx = max(bmr + offset, self.min_mark_margin)
                self.draw_star_target(width + cx + (self.mark_size / 2),
                                      (height / 2), 'starTargetR', g_center)
            else:
                # Top Star
                cy = max(bmt + offset, self.min_mark_margin)
                self.draw_star_target((width / 2), -cy - (self.mark_size / 2),
                                      'starTargetT', g_center)
                # Bottom Star
                cy = max(bmb + offset, self.min_mark_margin)
                self.draw_star_target((width / 2),
                                      height + cy + (self.mark_size / 2),
                                      'starTargetB', g_center)

        # Colour Bars
        if self.options.colour_bars == True:
            # Create a group for Colour Bars
            g_attribs = {
                inkex.addNS('label', 'inkscape'): 'ColourBars',
                'id': 'PrintingColourBars'
            }
            g_center = inkex.etree.SubElement(layer, 'g', g_attribs)

            if height > width:
                # Left Bars
                cx = max(bml + offset, self.min_mark_margin)
                self.draw_coluor_bars(-cx - (self.mark_size / 2), height / 2,
                                      90, 'PrintingColourBarsL', g_center)
                # Right Bars
                cx = max(bmr + offset, self.min_mark_margin)
                self.draw_coluor_bars(width + cx + (self.mark_size / 2),
                                      height / 2, 90, 'PrintingColourBarsR',
                                      g_center)
            else:
                # Top Bars
                cy = max(bmt + offset, self.min_mark_margin)
                self.draw_coluor_bars(width / 2, -cy - (self.mark_size / 2), 0,
                                      'PrintingColourBarsT', g_center)
                # Bottom Bars
                cy = max(bmb + offset, self.min_mark_margin)
                self.draw_coluor_bars(width / 2,
                                      height + cy + (self.mark_size / 2), 0,
                                      'PrintingColourBarsB', g_center)

        # Page Information
        if self.options.page_info == True:
            # Create a group for Page Information
            g_attribs = {
                inkex.addNS('label', 'inkscape'): 'PageInformation',
                'id': 'PageInformation'
            }
            g_pag_info = inkex.etree.SubElement(layer, 'g', g_attribs)
            y_margin = max(bmb + offset, self.min_mark_margin)
            txt_attribs = {
                'style':
                'font-size:12px;font-style:normal;font-weight:normal;fill:#000000;font-family:Bitstream Vera Sans,sans-serif;text-anchor:middle;text-align:center',
                'x': str(width / 2),
                'y': str(height + y_margin + self.mark_size + 20)
            }
            txt = inkex.etree.SubElement(g_pag_info, 'text', txt_attribs)
            txt.text = 'Page size: ' +\
                       str(round(inkex.uutounit(width,self.options.unit),2)) +\
                       'x' +\
                       str(round(inkex.uutounit(height,self.options.unit),2)) +\
                       ' ' + self.options.unit
Example #60
0
    def effect(self):
        svg = self.document.getroot()

        # ************ Layer 1 Definition ***************

        layer = etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'), 'Fretboard')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        # ************ Layer 2 Definition ***************

        layer2 = etree.SubElement(svg, 'g')
        layer2.set(inkex.addNS('label', 'inkscape'), 'Fret positions')
        layer2.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        # ************ Group Definitions ***************

        fb_id = svg.get_unique_id('fretboard')
        self.box = g = etree.SubElement(layer, 'g', {'id': fb_id})
        fp_id = svg.get_unique_id('fret-positions')
        self.box2 = g3 = etree.SubElement(layer2, 'g', {'id': fp_id})
        fm_id = svg.get_unique_id('fretmarkers')
        self.box4 = g4 = etree.SubElement(layer2, 'g', {'id': fm_id})

        # ************ Style Definition ***************

        fill_black_style = str(
            inkex.Style({
                'stroke': 'none',
                'fill': '#222222'
            }))
        fill_grey_style = str(
            inkex.Style({
                'stroke': 'none',
                'fill': '#aaaaaa'
            }))
        fill_lightgrey_style = str(
            inkex.Style({
                'stroke': 'none',
                'fill': '#dddddd'
            }))
        stroke_black_style = str(
            inkex.Style({
                'stroke': '#000000',
                'fill': 'none'
            }))
        stroke_red_style = str(
            inkex.Style({
                'stroke': '#ff0000',
                'fill': 'none'
            }))
        text_style = "font-family:DejaVu Sans;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-size:10px;"
        text_attributes = {
            'x': '12mm',
            'y': '10mm',
            inkex.addNS("space", "xml"): "preserve",
            'style': text_style
        }

        text = "Scalelenght : {}\n".format(self.options.scale)
        text += "Nut width : {}\n".format(self.options.lnut)
        text += "12th fret width : {}\n".format(self.options.l12)
        text += "Number of frets : {}\n".format(self.options.numfret)
        text += "Extension below last fret : {}\n".format(self.options.fbext)
        text += "Fret width : {}".format(self.options.fretwidth)

        fretboard = Fretboard(svg.unittouu(str(self.options.scale)))
        fretboard.width_nut = svg.unittouu(str(self.options.lnut))
        fretboard.width_12 = svg.unittouu(str(self.options.l12))
        fretboard.extension = svg.unittouu(str(self.options.fbext))
        fretboard.nb_frets = self.options.numfret
        fretboard.fret_width = svg.unittouu(str(self.options.fretwidth))

        fb_body_path = fretboard.svg_contour()
        nut_line = fretboard.svg_fret_centerline(0)
        bridge_line = fretboard.svg_h_line(
            fretboard.fb_width_at(fretboard.scale), fretboard.scale)

        # ************ Apply style to objects ***************

        fb_body_object = {
            'style': fill_black_style,
            'id': fb_id + '-shape',
            'd': fb_body_path
        }
        nut_line_object = {
            'style': stroke_black_style,
            'id': 'fret-0',
            'd': nut_line
        }
        bridge_line_object = {
            'style': stroke_black_style,
            'id': 'bridge-line',
            'd': bridge_line
        }

        # ************ Add objects to groups ***************

        etree.SubElement(g, inkex.addNS('path', 'svg'), fb_body_object)
        etree.SubElement(g, inkex.addNS('path', 'svg'), bridge_line_object)
        etree.SubElement(g3, inkex.addNS('path', 'svg'), bridge_line_object)
        etree.SubElement(g3, inkex.addNS('path', 'svg'), nut_line_object)

        t = etree.SubElement(layer2, inkex.addNS('text', 'svg'),
                             text_attributes)

        text = str(text).split("\n")
        y = 100
        for s in text:
            span = etree.SubElement(t, inkex.addNS('tspan', 'svg'), {
                'x': '12',
                'y': str(y),
                inkex.addNS("role", "sodipodi"): "line",
            })
            y += 24
            span.text = str(s)

        for index in range(1, self.options.numfret + 1):

            linefret_path = fretboard.svg_fret_centerline(index)
            fretpos_id = svg.get_unique_id('fretpos-' + str(index))
            linefret_atts = {
                'style': stroke_black_style,
                'id': fretpos_id,
                'd': linefret_path
            }
            etree.SubElement(g3, inkex.addNS('path', 'svg'), linefret_atts)

            line_path = fretboard.svg_fret_contour(index)
            curve_path = fretboard.svg_fret_end(index, 1.0)
            curve_path2 = fretboard.svg_fret_end(index, -1.0)
            fret_id = svg.get_unique_id('fret-' + str(index))
            self.fret = g2 = etree.SubElement(self.box, 'g', {'id': fret_id})

            fretbody_id = svg.get_unique_id('fret-' + str(index) + '-body')
            fretend_id1 = svg.get_unique_id('fret-' + str(index) + '-end1')
            fretend_id2 = svg.get_unique_id('fret-' + str(index) + '-end2')

            line_atts = {
                'style': fill_grey_style,
                'id': fretbody_id,
                'd': line_path
            }
            curve_atts = {
                'style': fill_lightgrey_style,
                'id': fretend_id1,
                'd': curve_path
            }
            curve2_atts = {
                'style': fill_lightgrey_style,
                'id': fretend_id2,
                'd': curve_path2
            }

            etree.SubElement(g2, inkex.addNS('path', 'svg'), line_atts)
            etree.SubElement(g2, inkex.addNS('path', 'svg'), curve_atts)
            etree.SubElement(g2, inkex.addNS('path', 'svg'), curve2_atts)

            # ************ Add inlay cross ***************
            val = index % 12
            if val in [0, 3, 5, 7, 9]:
                hline_cross_path, vline_cross_path = fretboard.svg_fret_cross(
                    index)
                fretpos_id = svg.get_unique_id('marker-cross-' + str(index))
                hline_atts = {
                    'style': stroke_red_style,
                    'id': fretpos_id,
                    'd': hline_cross_path
                }
                vline_atts = {
                    'style': stroke_red_style,
                    'id': fretpos_id,
                    'd': vline_cross_path
                }
                etree.SubElement(g4, inkex.addNS('path', 'svg'), hline_atts)
                etree.SubElement(g4, inkex.addNS('path', 'svg'), vline_atts)