def drawCircles(self, hole_diameter, diameter):
		# Attributes for the center hole, then create it, if diameter is 0, dont
		# create it
		circle_elements = []
		attributes = {
			'style': simplestyle.formatStyle({'stroke': 'none', 'fill': 'black'}),
			'r': str(hole_diameter / 2)
		}
		if self.options.hole_diameter > 0:
			circle_elements.append(attributes)

		# Attributes for the guide hole in the center hole, then create it
		attributes = {
			'style': simplestyle.formatStyle(
				{'stroke': 'white', 'fill': 'white', 'stroke-width': '0.1'}),
			'r': '1'
		}
		circle_elements.append(attributes)

		# Attributes for the outer rim, then create it
		attributes = {
			'style': simplestyle.formatStyle(
				{'stroke': 'black', 'stroke-width': '1', 'fill': 'none'}),
			'r': str(diameter / 2)
		}
		if self.options.diameter > 0:
			circle_elements.append(attributes)

		return circle_elements
Beispiel #2
0
 def do_entity():
     global style, layer
     if block != defs:                       # in a BLOCK
         layer = block
     elif vals[groups['8']]:                 # use Common Layer Name
         layer = layer_nodes[vals[groups['8']][0]]
     color = '#000000'                       # default color
     if vals[groups['8']]:
         if layer_colors.has_key(vals[groups['8']][0]):
             if colors.has_key(layer_colors[vals[groups['8']][0]]):
                 color = colors[layer_colors[vals[groups['8']][0]]]
     if vals[groups['62']]:                  # Common Color Number
         if colors.has_key(vals[groups['62']][0]):
             color = colors[vals[groups['62']][0]]
     style = simplestyle.formatStyle({'stroke': '%s' % color, 'fill': 'none'})
     w = 0.5                                 # default lineweight for POINT
     if vals[groups['370']]:                 # Common Lineweight
         if vals[groups['370']][0] > 0:
             w = 90.0/25.4*vals[groups['370']][0]/100.0
             if w < 0.5:
                 w = 0.5
             style = simplestyle.formatStyle({'stroke': '%s' % color, 'fill': 'none', 'stroke-width': '%.1f' % w})
     if vals[groups['6']]:                   # Common Linetype
         if linetypes.has_key(vals[groups['6']][0]):
             style += ';' + linetypes[vals[groups['6']][0]]
     entities[entity]()
Beispiel #3
0
    def write_month_header(self, g, m):
        txt_atts = {'style': simplestyle.formatStyle(self.style_month),
                    'x': str((self.month_w - self.day_w) / 2),
                    'y': str(self.day_h / 5 )}
        try:
            inkex.etree.SubElement(g, 'text', txt_atts).text = unicode(
                                                self.options.month_names[m-1],
                                                self.options.input_encode)
        except:
            inkex.errormsg(_('You must select a correct system encoding.'))
            exit(1)
        gw = inkex.etree.SubElement(g, 'g')
        week_x = 0
        if self.options.start_day=='sun':
            day_names = self.options.day_names[:]
        else:
            day_names = self.options.day_names[1:]
            day_names.append(self.options.day_names[0])

        if self.options.show_weeknr:
            day_names.insert(0, self.options.weeknr_name)

        for wday in day_names:
            txt_atts = {'style': simplestyle.formatStyle(self.style_day_name),
                        'x': str( self.day_w * week_x ),
                        'y': str( self.day_h ) }
            try:
                inkex.etree.SubElement(gw, 'text', txt_atts).text = unicode(
                                                    wday,
                                                    self.options.input_encode)
            except:
                inkex.errormsg(_('You must select a correct system encoding.'))
                exit(1)
            week_x += 1
Beispiel #4
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
    def effect(self):
        defs = self.xpathSingle('/svg//defs')
        if not defs:
            defs = self.document.createElement('svg:defs')
            self.document.documentElement.appendChile(defs)

        for id, node in self.selected.iteritems():
            mprops = ['marker', 'marker-start', 'marker-mid', 'marker-end']
            try:
                style = simplestyle.parseStyle(
                    node.attributes.getNamedItem('style').value)
            except:
                inkex.debug("No style attribute found for id: %s" % id)
                continue

            stroke = style.get('stroke', '#000000')

            for mprop in mprops:
                if style.has_key(mprop) and style[mprop] != 'none' and style[
                        mprop][:5] == 'url(#':
                    marker_id = style[mprop][5:-1]
                    try:
                        old_mnode = self.xpathSingle(
                            '/svg//marker[@id="%s"]' % marker_id)
                        if not self.options.modify:
                            mnode = old_mnode.cloneNode(True)
                        else:
                            mnode = old_mnode
                    except:
                        inkex.debug("unable to locate marker: %s" % marker_id)
                        continue

                    new_id = self.uniqueId(marker_id, not self.options.modify)

                    style[mprop] = "url(#%s)" % new_id
                    mnode.attributes.getNamedItem('id').value = new_id
                    mnode.attributes.getNamedItemNS(inkex.NSS['inkscape'],
                                                    'stockid').value = new_id
                    defs.appendChild(mnode)

                    children = inkex.xml.xpath.Evaluate(
                        '/svg//marker[@id="%s"]//*[@style]' % new_id,
                        self.document,
                        context=self.ctx)
                    for child in children:
                        cstyle = simplestyle.parseStyle(
                            child.attributes.getNamedItem('style').value)
                        if ('stroke' in cstyle and cstyle['stroke'] != 'none'
                            ) or 'stroke' not in cstyle:
                            cstyle['stroke'] = stroke
                        if ('fill' in cstyle and cstyle['fill'] != 'none'
                            ) or 'fill' not in cstyle:
                            cstyle['fill'] = stroke
                        child.attributes.getNamedItem(
                            'style').value = simplestyle.formatStyle(cstyle)
            node.attributes.getNamedItem(
                'style').value = simplestyle.formatStyle(style)
Beispiel #6
0
	def effect(self):
		for id, node in self.selected.iteritems():
			if node.tag == '{http://www.w3.org/2000/svg}path':
				path=node
				break
		else:
			sys.stderr.write('Need one path selected\n')
			return

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

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

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

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

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

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

				it+=1
Beispiel #7
0
def export_HATCH():
    # mandatory group codes : (10, 20, 70, 72, 92, 93) (x, y, fill, Edge Type, Path Type, Number of edges)
    if vals[groups['10']] and vals[groups['20']] and vals[groups['70']] and vals[groups['72']] and vals[groups['92']] and vals[groups['93']]:
        if len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(vals[groups['10']]):
            # optional group codes : (11, 21, 40, 50, 51, 73) (x, y, r, angle1, angle2, CCW)
            i10 = 1    # count start points
            i11 = 0    # count line end points
            i40 = 0    # count circles
            i72 = 0    # count edge type flags
            path = ''
            for i in range (0, len(vals[groups['93']])):
                xc = vals[groups['10']][i10]
                yc = vals[groups['20']][i10]
                if vals[groups['72']][i72] == 2:            # arc
                    rm = scale*vals[groups['40']][i40]
                    a1 = vals[groups['50']][i40]
                    path += 'M %f,%f ' % (xc + rm*math.cos(a1*math.pi/180.0), yc + rm*math.sin(a1*math.pi/180.0))
                else:
                    a1 = 0
                    path += 'M %f,%f ' % (xc, yc)
                for j in range(0, vals[groups['93']][i]):
                    if vals[groups['92']][i] & 2:           # polyline
                        if j > 0:
                            path += 'L %f,%f ' % (vals[groups['10']][i10], vals[groups['20']][i10])
                        if j == vals[groups['93']][i] - 1:
                            i72 += 1
                    elif vals[groups['72']][i72] == 2:      # arc
                        xc = vals[groups['10']][i10]
                        yc = vals[groups['20']][i10]
                        rm = scale*vals[groups['40']][i40]
                        a2 = vals[groups['51']][i40]
                        diff = (a2 - a1 + 360) % (360)
                        sweep = 1 - vals[groups['73']][i40] # sweep CCW
                        large = 0                           # large-arc-flag
                        if diff:
                            path += 'A %f,%f 0.0 %d %d %f,%f ' % (rm, rm, large, sweep, xc + rm*math.cos(a2*math.pi/180.0), yc + rm*math.sin(a2*math.pi/180.0))
                        else:
                            path += 'A %f,%f 0.0 %d %d %f,%f ' % (rm, rm, large, sweep, xc + rm*math.cos((a1+180.0)*math.pi/180.0), yc + rm*math.sin((a1+180.0)*math.pi/180.0))
                            path += 'A %f,%f 0.0 %d %d %f,%f ' % (rm, rm, large, sweep, xc + rm*math.cos(a1*math.pi/180.0), yc + rm*math.sin(a1*math.pi/180.0))
                        i40 += 1
                        i72 += 1
                    elif vals[groups['72']][i72] == 1:      # line
                        path += 'L %f,%f ' % (scale*(extrude*vals[groups['11']][i11] - xmin), height - scale*(vals[groups['21']][i11] - ymin))
                        i11 += 1
                        i72 += 1
                    i10 += 1
                path += "z "
            if vals[groups['70']][0]:
                style = simplestyle.formatStyle({'fill': '%s' % color})
            else:
                style = simplestyle.formatStyle({'fill': 'url(#Hatch)', 'fill-opacity': '1.0'})
            attribs = {'d': path, 'style': style}
            inkex.etree.SubElement(layer, 'path', attribs)
Beispiel #8
0
	def effect(self):
		self.checkopts()

		o = self.options.fbedges
		oNF,oBF,oNL,oBL = o,o,o,o

		if self.doMultiScale:
			strings, meta = ffproc.FindStringsMultiScale(self.options.strings,self.options.firstscalelength,
				self.options.lastscalelength,self.options.nutwidth,self.options.bridgewidth,
				self.options.perpdist,oNF,oBF,oNL,oBL)
		else:
			strings, meta = ffproc.FindStringsSingleScale(self.options.strings,self.options.scalelength,
				self.options.nutwidth,self.options.bridgewidth,
				oNF,oBF,oNL,oBL)
		
		frets = ffproc.FindFrets(strings, meta, self.scale, self.tuning, self.options.frets)
		
		edgepath = seg2path(meta[0]) + seg2path(meta[-1])
		stringpath = "".join([seg2path(s) for s in strings])
		fretpath = "".join(["".join([seg2path(f) for f in s]) for s in frets])
	
		group = self.document.createElement('svg:g')
		group.setAttribute('transform',"scale(%s,%s)" % (self.options.pxperunit,self.options.pxperunit))
		self.document.documentElement.appendChild(group)
		
		edge = self.document.createElement('svg:path')
		s = {'stroke-linejoin': 'miter', 'stroke-width': '0.01px', 
			'stroke-opacity': '1.0', 'fill-opacity': '1.0', 
			'stroke': '#0000FF', 'stroke-linecap': 'butt', 
			'fill': 'none'}
		edge.setAttribute('style', simplestyle.formatStyle(s))
		edge.setAttribute('d', edgepath)

		string = self.document.createElement('svg:path')
		s = {'stroke-linejoin': 'miter', 'stroke-width': '0.01px', 
			'stroke-opacity': '1.0', 'fill-opacity': '1.0', 
			'stroke': '#FF0000', 'stroke-linecap': 'butt', 
			'fill': 'none'}
		string.setAttribute('style', simplestyle.formatStyle(s))
		string.setAttribute('d', stringpath)

		fret = self.document.createElement('svg:path')
		s = {'stroke-linejoin': 'miter', 'stroke-width': '0.01px', 
			'stroke-opacity': '1.0', 'fill-opacity': '1.0', 
			'stroke': '#000000', 'stroke-linecap': 'butt', 
			'fill': 'none'}
		fret.setAttribute('style', simplestyle.formatStyle(s))
		fret.setAttribute('d', fretpath)

		group.appendChild(edge)
		group.appendChild(string)
		group.appendChild(fret)
Beispiel #9
0
	def effect(self):
		"""
		Effect behaviour.
		Overrides base class' method and draws something.
		"""

		# color
		self.options.dotFill = self.getColorString(self.options.dotFill)
		# constants
		self.dotStyle = simplestyle.formatStyle({'fill': self.options.dotFill,'stroke':'none'})
		self.scale = self.getUnittouu("1" + self.options.units)
		self.dotR = str(self.options.dotSize * (self.scale/2))
		self.computations(radians(self.options.angleOnFootside))

		# processing variables
		self.generatedCircles = []
		self.gridContainer =  self.current_layer

		self.generate()

		if self.options.variant == 'rectangle':
			self.removeGroups(1, 2)
		elif self.options.variant == 'hexagon1':
			self.removeGroups(0, 3)
		elif self.options.variant == 'hexagon2' or self.options.variant == 'snow2':
			for i in range(0, len(self.generatedCircles), 1):
				self.removeDots(i, (((i%2)+1)*2)%3, 3)
		elif self.options.variant == 'hexagon3':
			for i in range(0, len(self.generatedCircles), 2):
				self.removeDots(i, (i//2+1)%2, 2)
		elif self.options.variant == 'hexagon4':
			self.removeGroups(0, 4)
		elif self.options.variant == 'hexagon5' or self.options.variant == 'snow1':
			for i in range(0, len(self.generatedCircles), 2):
				self.removeDots(i, 1, 2)

		self.dotStyle = simplestyle.formatStyle({'fill': 'none','stroke':self.options.dotFill,'stroke-width':0.7})
		self.dotR = str((((self.options.innerDiameter * pi) / self.options.dotsPerCircle) / 2) * self.scale)
		self.generatedCircles = []
		if self.options.variant == 'snow2':
			self.options.dotsPerCircle = self.options.dotsPerCircle // 3
			self.computations(radians(self.options.angleOnFootside))
			self.generate()
		elif self.options.variant == 'snow1':
			self.generate()
			self.removeGroups(1, 2)
			for i in range(0, len(self.generatedCircles), 2):
				self.removeDots(i, i%4, 2)
			for i in range(0, len(self.generatedCircles), 2):
				self.removeDots(i, (i+1)%2, 2)
			for i in range(2, len(self.generatedCircles), 4):
				self.removeDots(i, 0, self.options.dotsPerCircle)
    def _merge_style(self, node, style):
        """Propagate style and transform to remove inheritance
        Originally from
        https://github.com/nikitakit/svg2sif/blob/master/synfig_prepare.py#L370
        """

        # Compose the style attribs
        this_style = simplestyle.parseStyle(node.get("style", ""))
        remaining_style = {}  # Style attributes that are not propagated

        # Filters should remain on the top ancestor
        non_propagated = ["filter"]
        for key in non_propagated:
            if key in this_style.keys():
                remaining_style[key] = this_style[key]
                del this_style[key]

        # Create a copy of the parent style, and merge this style into it
        parent_style_copy = style.copy()
        parent_style_copy.update(this_style)
        this_style = parent_style_copy

        # Merge in any attributes outside of the style
        style_attribs = ["fill", "stroke"]
        for attrib in style_attribs:
            if node.get(attrib):
                this_style[attrib] = node.get(attrib)
                del node.attrib[attrib]

        if (node.tag == addNS("svg", "svg")
            or node.tag == addNS("g", "svg")
            or node.tag == addNS("a", "svg")
            or node.tag == addNS("switch", "svg")):
            # Leave only non-propagating style attributes
            if len(remaining_style) == 0:
                if "style" in node.keys():
                    del node.attrib["style"]
            else:
                node.set("style", simplestyle.formatStyle(remaining_style))

        else:
            # This element is not a container

            # Merge remaining_style into this_style
            this_style.update(remaining_style)

            # Set the element's style attribs
            node.set("style", simplestyle.formatStyle(this_style))
Beispiel #11
0
 def addTextOnPath(self, node, x, y, text, id, anchor, startOffset, dy=0):
     new = inkex.etree.SubElement(node, inkex.addNS("textPath", "svg"))
     s = {
         "text-align": "center",
         "vertical-align": "bottom",
         "text-anchor": anchor,
         "font-size": str(self.options.fontsize),
         "fill-opacity": "1.0",
         "stroke": "none",
         "font-weight": "normal",
         "font-style": "normal",
         "fill": "#000000",
     }
     new.set("style", simplestyle.formatStyle(s))
     new.set(inkex.addNS("href", "xlink"), "#" + id)
     new.set("startOffset", startOffset)
     new.set("dy", str(dy))  # dubious merit
     # new.append(tp)
     if text[-2:] == "^2":
         appendSuperScript(new, "2")
         new.text = str(text)[:-2]
     else:
         new.text = str(text)
     # node.set('transform','rotate(180,'+str(-x)+','+str(-y)+')')
     node.set("x", str(x))
     node.set("y", str(y))
def createXAt(xp, coor):
    style = {'color':'#000000', 'fill':'none', 'stroke':'#000000', 
            'stroke-width':'1.1', 'stroke-linecap':'round'}
    path = 'M '+ str(coor[xp][0]) + ',' +  str(coor[xp][1]) + ' m 4,4 '\
    'l -8,-8 M '+ str(coor[xp][0]) + ',' +  str(coor[xp][1]) + ''\
    'm -4,4 l 8,-8'
    return {'d':path, 'style':simplestyle.formatStyle(style)}
	def effect(self):
		svg = self.document.getroot()
		width = float(self.document.getroot().get('width'))
		height = float(self.document.getroot().get('height'))
		
		group = inkex.etree.SubElement(self.current_layer, 'g', {
			inkex.addNS('label', 'inkscape') : 'Slider electrodes'
		})
		
		style = {
			'stroke'	: 'none',
			'fill'		: '#000000'
		}
		
		eWidth = width / self.options.count
		spikeWidth = 0.6 * eWidth
		
		for eid in range(self.options.count):
			if eid == 0:
				path = self.genPathString((eid * eWidth, 0, (eid + 1) * eWidth + 0.4 * spikeWidth, height), spikeWidth, first=True)
			elif eid == self.options.count - 1:
				path = self.genPathString((eid * eWidth - 0.4 * spikeWidth, 0, (eid + 1) * eWidth, height), spikeWidth, last=True)
			else:
				path = self.genPathString((eid * eWidth - 0.4 * spikeWidth, 0, (eid + 1) * eWidth + 0.4 * spikeWidth, height), spikeWidth)
		
			e = inkex.etree.SubElement(group, inkex.addNS('path', 'svg'), {
				'style' : simplestyle.formatStyle(style),
				'd' : path
			})
Beispiel #14
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)
def createCapoPos(coor):
    textstyle = {'font-size': '8',
        'font-family': 'Century Schoolbook L',
        'text-anchor': 'end',
        'fill': '#000000'}
    return { 'style':simplestyle.formatStyle(textstyle),
    'x': str(coor[0]-5), 'y': str(coor[1]+4) }
def leftFingerNumberAt(fp, coor):
    textstyle = {'font-size': '8',
        'font-family': 'Century Schoolbook L',
        'text-anchor': 'start',
        'fill': '#000000'}
    return { 'style':simplestyle.formatStyle(textstyle),
    'x': str(coor[fp[0]][fp[1]][0]), 'y': str(coor[fp[0]][fp[1]][1]) }
def createHeader(coor):
    textstyle = {'font-size': '18',
        'font-family': 'Linux Libertine O',
        'text-anchor': 'middle',
        'fill': '#000000'}
    return { 'style':simplestyle.formatStyle(textstyle),
    'x': str(coor[0]), 'y': str(coor[1]) }
Beispiel #18
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 effect(self):
        length = self.options.length
        spacing = self.options.spacing
        angle = radians(self.options.angle)

        # generate points: list of (x, y) pairs
        points = []
        x = 0
        tas = tan(angle) * spacing
        while x < length:
            # move along path, generating the next 'tooth'
            points.append((x, 0))
            points.append((x + tas, spacing))
            points.append((x + spacing, spacing))
            points.append((x + spacing + tas, 0))
            x += spacing * 2.0

        path = points_to_svgd(points)

        # 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"): "RackGear" + str(length), "transform": t}
        g = inkex.etree.SubElement(self.current_layer, "g", g_attribs)

        # Create SVG Path for gear
        style = {"stroke": "#000000", "fill": "none"}
        gear_attribs = {"style": simplestyle.formatStyle(style), "d": path}
        gear = inkex.etree.SubElement(g, inkex.addNS("path", "svg"), gear_attribs)
	def drawSegment(self, line_style, angle, segment_angle, outer_diameter, width):

		path = {'style': simplestyle.formatStyle(line_style)}
		path['d'] = ''
		outer_radius = outer_diameter / 2

		# Go to the first point in the segment
		path['d'] += self.parsePathData(
			'M', calculatePoint(angle, outer_radius - width))

		# Go to the second point in the segment
		path['d'] += self.parsePathData('L', calculatePoint(angle, outer_radius))

		# Go to the third point in the segment, draw an arc
		point = calculatePoint(angle + segment_angle, outer_radius)
		path['d'] += self.parsePathData('A', [outer_radius, outer_radius]) + \
					'0 0 1' + self.parsePathData(' ', point)

		# Go to the fourth point in the segment
		point = calculatePoint(angle + segment_angle, outer_radius - width)
		path['d'] += self.parsePathData('L', point)

		# Go to the beginning in the segment, draw an arc
		point = calculatePoint(angle, outer_radius - width)
		# 'Z' closes the path
		path['d'] += (self.parsePathData(
			'A',
			[outer_radius - width, outer_radius - width]) +
				'0 0 0' + self.parsePathData(' ', point) + ' Z')

		# Return the path
		return path
Beispiel #21
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 )
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 )
Beispiel #23
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 )
Beispiel #24
0
 def change_attribute(self, node, attribute):
     for key, value in attribute.items():
         if key == 'preserveAspectRatio':
             # set presentation attribute
             if value != "unset":
                 node.set(key, str(value))
             else:
                 if node.get(key):
                     del node.attrib[key]
         elif key == 'image-rendering':
             node_style = simplestyle.parseStyle(node.get('style'))
             if key not in node_style:
                 # set presentation attribute
                 if value != "unset":
                     node.set(key, str(value))
                 else:
                     if node.get(key):
                         del node.attrib[key]
             else:
                 # set style property
                 if value != "unset":
                     node_style[key] = str(value)
                 else:
                     del node_style[key]
                 node.set('style', simplestyle.formatStyle(node_style))
         else:
             pass
    def line(self,points):
        """
        Draw a line from point at (x1, y1) to point at (x2, y2).
        Style of line is hard coded and specified by 's'.
        """
        # define the motions
        path = ('M%.4f,%.4fL' % tuple(points[0][:2])) + 'L'.join([('%f,%f' % tuple(a[:2])) for a in points[1:]])

        # define the stroke style
        s = {'stroke-linejoin': 'miter', 
            'stroke-width': self.options.linewidth,
            'stroke-opacity': '1.0', 
            'fill-opacity': '1.0',
            'stroke': self.options.linecolor, 
            'stroke-linecap': 'round',
            'fill': 'none'
        }


        ## Attributes for new element
        attribs = {'style' : simplestyle.formatStyle(s),
                   'd' : path}

        ## Add new element
        inkex.etree.SubElement(self.current_layer, inkex.addNS('path', 'svg'), attribs)
    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()
Beispiel #27
0
    def effect(self):
        for id, node in self.selected.iteritems():
            if node.tagName == 'path':
                p = simplepath.parsePath(node.attributes.getNamedItem('d').value)
                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:
                    new = self.document.createElement('svg:path')
                    s = {'stroke-linejoin': 'miter', 'stroke-width': '1.0px', 
                        'stroke-opacity': '1.0', 'fill-opacity': '1.0', 
                        'stroke': '#000000', 'stroke-linecap': 'butt', 
                        'fill': 'none'}
                    new.setAttribute('style', simplestyle.formatStyle(s))
                    new.setAttribute('d', simplepath.formatPath(a))
                    node.parentNode.appendChild(new)
Beispiel #28
0
 def effect(self):
     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':self.iterate()}
     inkex.etree.SubElement(self.current_layer,inkex.addNS('path','svg'),attribs)
Beispiel #29
0
 def draw_crop_line(self, x1, y1, x2, y2, name, parent):
     style = { 'stroke': '#000000', 'stroke-width': str(self.stroke_width),
               'fill': 'none'}
     line_attribs = {'style': simplestyle.formatStyle(style),
                     'id': name,
                     'd': 'M '+str(x1)+','+str(y1)+' L '+str(x2)+','+str(y2)}
     inkex.etree.SubElement(parent, 'path', line_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
Beispiel #31
0
    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(unit_factor)
        # 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),
                'Root diameter:  %2.3f %s' %
                (root_radius * 2 / 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
#!/usr/bin/env python

# We will use the inkex module with the predefined Effect base class.
import inkex
# The simplestyle module provides functions for style parsing.
import simplestyle
from math import *
from collections import namedtuple

#Note: keep in mind that SVG coordinates start in the top-left corner i.e. with an inverted y-axis

# first define some SVG primitives (we do not use them all so a cleanup may be in order)
objStyle = simplestyle.formatStyle(
    {'stroke': '#000000',
    'stroke-width': 0.28,
    'fill': 'none'
    })

greenStyle = simplestyle.formatStyle(
    {'stroke': '#00ff00',
    'stroke-width': 0.28,
    'fill': 'none'
    })

def draw_SVG_square((w,h), (x,y), parent):
    attribs = {
        'style': objStyle,
        'height': str(h),
        'width': str(w),
        'x': str(x),
        'y': str(y)
Beispiel #33
0
def export_HATCH():
    # mandatory group codes : (10, 20, 70, 72, 92, 93) (x, y, fill, Edge Type, Path Type, Number of edges)
    if vals[groups['10']] and vals[groups['20']] and vals[
            groups['70']] and vals[groups['72']] and vals[
                groups['92']] and vals[groups['93']]:
        if len(vals[groups['10']]) > 1 and len(vals[groups['20']]) == len(
                vals[groups['10']]):
            # optional group codes : (11, 21, 40, 50, 51, 73) (x, y, r, angle1, angle2, CCW)
            i10 = 1  # count start points
            i11 = 0  # count line end points
            i40 = 0  # count circles
            i72 = 0  # count edge type flags
            path = ''
            for i in range(0, len(vals[groups['93']])):
                xc = vals[groups['10']][i10]
                yc = vals[groups['20']][i10]
                if vals[groups['72']][i72] == 2:  # arc
                    rm = scale * vals[groups['40']][i40]
                    a1 = vals[groups['50']][i40]
                    path += 'M %f,%f ' % (
                        xc + rm * math.cos(a1 * math.pi / 180.0),
                        yc + rm * math.sin(a1 * math.pi / 180.0))
                else:
                    a1 = 0
                    path += 'M %f,%f ' % (xc, yc)
                for j in range(0, vals[groups['93']][i]):
                    if vals[groups['92']][i] & 2:  # polyline
                        if j > 0:
                            path += 'L %f,%f ' % (vals[groups['10']][i10],
                                                  vals[groups['20']][i10])
                        if j == vals[groups['93']][i] - 1:
                            i72 += 1
                    elif vals[groups['72']][i72] == 2:  # arc
                        xc = vals[groups['10']][i10]
                        yc = vals[groups['20']][i10]
                        rm = scale * vals[groups['40']][i40]
                        a2 = vals[groups['51']][i40]
                        diff = (a2 - a1 + 360) % (360)
                        sweep = 1 - vals[groups['73']][i40]  # sweep CCW
                        large = 0  # large-arc-flag
                        if diff:
                            path += 'A %f,%f 0.0 %d %d %f,%f ' % (
                                rm, rm, large, sweep,
                                xc + rm * math.cos(a2 * math.pi / 180.0),
                                yc + rm * math.sin(a2 * math.pi / 180.0))
                        else:
                            path += 'A %f,%f 0.0 %d %d %f,%f ' % (
                                rm, rm, large, sweep, xc + rm * math.cos(
                                    (a1 + 180.0) * math.pi / 180.0),
                                yc + rm * math.sin(
                                    (a1 + 180.0) * math.pi / 180.0))
                            path += 'A %f,%f 0.0 %d %d %f,%f ' % (
                                rm, rm, large, sweep,
                                xc + rm * math.cos(a1 * math.pi / 180.0),
                                yc + rm * math.sin(a1 * math.pi / 180.0))
                        i40 += 1
                        i72 += 1
                    elif vals[groups['72']][i72] == 1:  # line
                        path += 'L %f,%f ' % (scale *
                                              (vals[groups['11']][i11] - xmin),
                                              height - scale *
                                              (vals[groups['21']][i11] - ymin))
                        i11 += 1
                        i72 += 1
                    i10 += 1
                path += "z "
            if vals[groups['70']][0]:
                style = simplestyle.formatStyle({'fill': '%s' % color})
            else:
                style = simplestyle.formatStyle({
                    'fill': 'url(#Hatch)',
                    'fill-opacity': '1.0'
                })
            attribs = {'d': path, 'style': style}
            inkex.etree.SubElement(layer, 'path', attribs)
        if id_ is not None:
            attribs.update({'id': id_})
        obj = inkex.etree.SubElement(parent, inkex.addNS('rect', 'svg'),
                                     attribs)
        return obj

    def draw_circle(self, (x, y), r, color, parent, id_):

        style = {
            'stroke': 'none',
            'stroke-width': '1',
            'fill': color,
            "mix-blend-mode": "multiply"
        }
        attribs = {
            'style': simplestyle.formatStyle(style),
            'cx': str(x),
            'cy': str(y),
            'r': str(r)
        }
        if id_ is not None:
            attribs.update({'id': id_})
        obj = inkex.etree.SubElement(parent, inkex.addNS('circle', 'svg'),
                                     attribs)
        return obj

    def draw_ellipse(self, (x, y), (r1, r2), color, parent, id_, transform):

        style = {
            'stroke': 'none',
            'stroke-width': '1',
class raster_to_svg_ordered_dithering(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)

        self.OptionParser.add_option(
            "-t",
            "--width",
            action="store",
            type="int",
            dest="width",
            default=200,
            help=
            "this variable will be used to resize the original selected image to a width of whatever \
                                     you enter and height proportional to the new width, thus maintaining the aspect ratio"
        )

    def getImagePath(self, node, xlink):

        absref = node.get(inkex.addNS('absref', 'sodipodi'))
        url = urlparse(xlink)
        href = url2pathname(url.path)

        path = ''

        if href is not None:
            path = os.path.realpath(href)
        if (not os.path.isfile(path)):
            if absref is not None:
                path = absref

        try:
            path = unicode(path, "utf-8")
        except TypeError:
            path = path

        if (not os.path.isfile(path)):
            inkex.errormsg(
                _("No xlink:href or sodipodi:absref attributes found, " +
                  "or they do not point to an existing file! Unable to find image file."
                  ))
            if path:
                inkex.errormsg(_("Sorry we could not locate %s") % str(path))
            return False

        if (os.path.isfile(path)):
            return path

    def getImageData(self, xlink):
        """
        Read, decode and return data of embedded image
        """
        comma = xlink.find(',')
        data = ''

        if comma > 0:
            data = base64.decodestring(xlink[comma:])
        else:
            inkex.errormsg(_("Failed to read embedded image data."))

        return data

    def getImage(self, node):
        """
        Parse link attribute of node and retrieve image data
        """
        xlink = node.get(inkex.addNS('href', 'xlink'))
        image = ''

        if xlink is None or xlink[:5] != 'data:':
            # linked bitmap image
            path = self.getImagePath(node, xlink)
            if path:
                image = Image.open(path)
        elif xlink[:4] == 'data':
            # embedded bitmap image
            data = self.getImageData(xlink)
            if data:
                image = Image.open(StringIO.StringIO(data))
        else:
            # unsupported type of link detected
            inkex.errormsg(_("Unsupported type of 'xlink:href'"))

        return image

    def draw_rectangle(self, (x, y), (l, b), color, parent, id_):

        style = {
            'stroke': 'none',
            'stroke-width': '1',
            'fill': color,
            "mix-blend-mode": "multiply"
        }
        attribs = {
            'style': simplestyle.formatStyle(style),
            'x': str(x),
            'y': str(y),
            'width': str(l),
            'height': str(b)
        }
        if id_ is not None:
            attribs.update({'id': id_})
        obj = inkex.etree.SubElement(parent, inkex.addNS('rect', 'svg'),
                                     attribs)
        return obj
Beispiel #36
0
    def effect(self):
        global debug

        if self.options.version:
            print __version__
            sys.exit(0)
        if self.options.invert is not None:
            self.invert_image = self.options.invert
        if self.options.remove is not None:
            self.replace_image = self.options.remove
        if self.options.megapixels is not None:
            self.megapixel_limit = self.options.megapixels
        if self.options.candidates is not None:
            self.candidates = self.options.candidates
        if self.options.despecle is not None:
            self.filter_median = self.options.despecle
        if self.options.equal_light is not None:
            self.filter_equal_light = self.options.equal_light
        if self.options.debug is not None: debug = self.options.debug

        self.calc_unit_factor()

        if not len(self.selected.items()):
            inkex.errormsg(_("Please select an image."))
            return

        for id, node in self.selected.iteritems():
            if debug:
                print >> self.tty, "id=" + str(id), "tag=" + str(node.tag)
            if node.tag != inkex.addNS('image', 'svg'):
                inkex.errormsg(
                    _("Object " + id + " is not an image. seen:" +
                      str(node.tag) + " expected:" +
                      inkex.addNS('image', 'svg') +
                      "\n Try - Object->Ungroup"))
                return
            # handle two cases. Embedded and linked images
            # <image .. xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAT8AA ..." preserveAspectRatio="none" height="432" width="425" transform="matrix(1,0,-0.52013328,0.85408511,0,0)"/>
            # <image  .. xlink:href="file:///home/jw/schaf.png"

            href = str(node.get(inkex.addNS('href', 'xlink')))

            # ######################
            #
            # dump the entire svg to file, so that we can examine what an image is.
            # f=open(self.dumpname, 'w')
            # f.write(href)
            # f.close()
            # if debug: print >>self.tty, "Dump written to "+self.dumpname
            #
            # ######################

            if href[:7] == 'file://':
                filename = href[7:]
                if debug: print >> self.tty, "linked image: =" + filename
            elif href[0] == '/' or href[0] == '.':
                filename = href
                if debug: print >> self.tty, "linked image path: =" + filename
            elif href[:11] == 'data:image/':
                l = href[11:].index(';')
                type = href[11:11 + l]  # 'png' 'jpeg'
                if debug: print >> self.tty, "embedded image: " + href[:11 + l]
                img = base64.decodestring(href[11 + l + 8:])
                f = tempfile.NamedTemporaryFile(mode="wb",
                                                suffix="." + type,
                                                delete=False)
                f.write(img)
                filename = f.name
                f.close()
            else:
                inkex.errormsg(
                    _("Neither file:// nor data:image/png; prefix. Cannot parse PNG image href "
                      + href))
                sys.exit(1)
            if debug: print >> self.tty, "filename=" + filename
            #
            path_svg, stroke_width, im_size = self.svg_centerline_trace(
                filename)
            xml = inkex.etree.fromstring(path_svg)
            try:
                path_d = xml.find('path').attrib['d']
            except:
                inkex.errormsg(
                    _("Couldn't trace the path. Please make sure that the checkbox for tracing bright lines is set correctly and that your drawing has enough contrast."
                      ))
                sys.exit(1)

            # images can also just have a transform attribute, and no x or y,
            # could be replaced by a (slower) call to command line, or by computeBBox from simpletransform
            x_off = float(node.get('x', 0))
            y_off = float(node.get('y', 0))
            sx = float(node.get('width')) / im_size[0]
            sy = float(node.get('height')) / im_size[1]
            if debug:
                print >> self.tty, "im_width ", node.get('width'), "sx=", sx
            if debug:
                print >> self.tty, "im_height ", node.get('height'), "sy=", sy
            if debug: print >> self.tty, "im_x ", x_off
            if debug: print >> self.tty, "im_y ", y_off
            if debug: print >> self.tty, "pixel_size= ", im_size
            ## map the coordinates of the returned pixel path to the coordinates of the original SVG image.
            matrix = "translate(%g,%g) scale(%g,%g)" % (x_off, y_off, sx, sy)
            #
            if href[:5] == 'data:':
                os.unlink(
                    filename
                )  ## it was a temporary file (representing an embedded image).
            #
            # Create SVG Path
            style = {
                'stroke': '#000000',
                'fill': 'none',
                'stroke-linecap': 'round',
                'stroke-width': stroke_width
            }
            if self.invert_image: style['stroke'] = '#777777'
            path_attr = {
                'style': simplestyle.formatStyle(style),
                'd': path_d,
                'transform': matrix
            }
            ## insert the new path object
            inkex.etree.SubElement(self.current_layer,
                                   inkex.addNS('path', 'svg'), path_attr)
            ## delete the old image object
            if self.replace_image: node.getparent().remove(node)
Beispiel #37
0
import simplestyle,inkex

def draw_SVG_square((w,h), (x,y), parent,fill= '#FF0000'):
            style = {   'stroke'        : 'none',
                        'stroke-width'  : '0.5',
                        'fill'          : fill
                    } 
            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 )

def draw_SVG_path(d, parent,fill= '#FF0000',strokeWidth="0.5"):
            style = {   'stroke'        : '#000000',
                        'stroke-width'  : strokeWidth,
                        'fill'          : fill
                    } 
            attribs = {
                'style'     : simplestyle.formatStyle(style),
                'd'    : str(d)
                    }
            circ = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), attribs )
       
def draw_SVG_line( (x1, y1), (x2, y2), style, name, parent):
    line_style   = { 'stroke': style.l_col,
                     'stroke-width':str(style.l_th),
                     'fill': style.l_fill
Beispiel #38
0
    def effect(self):

        poly = self.options.poly
        size = self.options.size

        eC = polyhedronData[poly]['edgeCoordinates']
        iEI = polyhedronData[poly]['insideEdgeIndices']
        oEI = polyhedronData[poly]['outsideEdgeIndices']
        oED = polyhedronData[poly]['outsideEdgeDegrees']
        sidelen = sqrt((eC[oEI[0][0]-1][0] - eC[oEI[0][1]-1][0])**2 + \
           (eC[oEI[0][0]-1][1] - eC[oEI[0][1]-1][1])**2)
        scale = size / sidelen

        #  Translate group, Rotate path.
        t = 'translate(' + str(self.view_center[0]) + ',' + str(
            self.view_center[1]) + ')'
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'Polygon ' + str(poly),
            'transform': t
        }
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        gsub_attribs = {
            inkex.addNS('label', 'inkscape'): 'Polygon ' + str(poly) + 'border'
        }
        gsub = inkex.etree.SubElement(g, 'g', gsub_attribs)

        # Create SVG Path for gear
        cutStyle = {'stroke': '#0000FF', 'fill': 'none'}
        perfStyle = {'stroke': '#FF0000', 'fill': 'none'}
        textStyle = {
            'font-size': str(size / 4),
            'font-family': 'arial',
            'text-anchor': 'middle',
            'text-align': 'center',
            'fill': '#222'
        }

        numOEI = len(oEI)
        for edgeIndex in range(numOEI):
            eX1 = eC[oEI[edgeIndex][0] - 1][0]
            eY1 = eC[oEI[edgeIndex][0] - 1][1]
            eX2 = eC[oEI[edgeIndex][1] - 1][0]
            eY2 = eC[oEI[edgeIndex][1] - 1][1]

            origin = (eX1 * scale, eY1 * scale)
            edgelen = sqrt((eX1 - eX2)**2 + (eY1 - eY2)**2)
            edgesize = size * (edgelen / sidelen)

            prevAngle = (oED[(edgeIndex - 1) % numOEI] + 180 -
                         oED[edgeIndex]) % 360
            nextAngle = (oED[edgeIndex] + 180 -
                         oED[(edgeIndex + 1) % numOEI]) % 360
            if angleOverride.has_key(poly):
                if angleOverride[poly].has_key('prev'):
                    if angleOverride[poly]['prev'].has_key(edgeIndex):
                        prevAngle = angleOverride[poly]['prev'][edgeIndex]
                if angleOverride[poly].has_key('next'):
                    if angleOverride[poly]['next'].has_key(edgeIndex):
                        nextAngle = angleOverride[poly]['next'][edgeIndex]
            trans = 'translate(' + str(origin[0]) + ',' + str(
                origin[1]) + ') rotate(' + str(
                    oED[edgeIndex]) + ') scale(' + str(edgesize / 100.0) + ')'

            limitAngle = min(prevAngle, nextAngle)
            tab = self.get_tab(limitAngle)
            slot = self.get_slot(limitAngle)

            # the "special" tabs are all skewed one way or the other, to
            # make room for tight turns.  This determines if it is the previous
            # or next angle that is the tight one, and flips the tab or slot if
            # needed.

            if (nextAngle == limitAngle):
                trans += ' translate(100.0, 0) scale(-1,1)'

            tab_group_attribs = {
                inkex.addNS('label', 'inkscape'): 'tab',
                'transform': trans
            }
            tab_group = inkex.etree.SubElement(gsub, 'g', tab_group_attribs)
            midX = (eX2 - eX1) / 2 + eX1
            midY = (eY2 - eY1) / 2 + eY1
            text_attrib = {
                'style': simplestyle.formatStyle(textStyle),
                'x': str(midX * scale),
                'y': str(midY * scale)
            }
            # inkex.etree.SubElement(gsub, 'text', text_attrib).text = str(edgeIndex)
            if ((edgeIndex % 2) == 0):
                edgetype = tab
            else:
                edgetype = slot

            for path in edgetype['cut']:
                gear_attribs = {
                    'style': simplestyle.formatStyle(cutStyle),
                    'd': path
                }
                gear = inkex.etree.SubElement(tab_group,
                                              inkex.addNS('path', 'svg'),
                                              gear_attribs)

            for path in edgetype['perf']:
                gear_attribs = {
                    'style': simplestyle.formatStyle(perfStyle),
                    'd': path
                }
                gear = inkex.etree.SubElement(tab_group,
                                              inkex.addNS('path', 'svg'),
                                              gear_attribs)

        gsub_attribs = {
            inkex.addNS('label', 'inkscape'): 'Polygon ' + str(poly) + 'inside'
        }
        gsub = inkex.etree.SubElement(g, 'g', gsub_attribs)

        for edge in iEI:
            points = [(eC[edge[0] - 1][0] * scale, eC[edge[0] - 1][1] * scale),
                      (eC[edge[1] - 1][0] * scale, eC[edge[1] - 1][1] * scale)]
            path = points_to_svgd(points)
            perf_attribs = {
                'style': simplestyle.formatStyle(perfStyle),
                'd': path
            }
            gear = inkex.etree.SubElement(gsub, inkex.addNS('path', 'svg'),
                                          perf_attribs)
def set_prop(node, prop, val):
    """Set style property on node."""
    sdict = simplestyle.parseStyle(node.get('style'))
    sdict[prop] = val
    node.set('style', simplestyle.formatStyle(sdict))
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
'''

import inkex
import simplestyle, sys
from simpletransform import computePointInNode
from math import *


def draw_SVG_tri((x1, y1), (x2, y2), (x3, y3), (ox, oy), width, name, parent):
    style = {'stroke': '#000000', 'stroke-width': str(width), 'fill': 'none'}
    tri_attribs = {
        'style':
        simplestyle.formatStyle(style),
        inkex.addNS('label', 'inkscape'):
        name,
        'd':
        'M ' + str(x1 + ox) + ',' + str(y1 + oy) + ' L ' + str(x2 + ox) + ',' +
        str(y2 + oy) + ' L ' + str(x3 + ox) + ',' + str(y3 + oy) + ' L ' +
        str(x1 + ox) + ',' + str(y1 + oy) + ' z'
    }
    inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'), tri_attribs)


def angle_from_3_sides(a, b, c):  #return the angle opposite side c
    cosx = (a * a + b * b - c * c) / (2 * a * b)  #use the cosine rule
    return acos(cosx)

Beispiel #41
0
    def effect(self):

        root = self.document.getroot()

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

            # Default settings for now
            stroke, fill, color = ('none', 'none', 'unknown')

            # Get the paths style attribute
            style = simplestyle.parseStyle(path.get('style', ''))
            # Obtain the fill color from the path's style attribute
            if 'fill' in style:
                color = style['fill']
                if self.options.fillRegions:
                    fill = color
                if self.options.outlineRegions:
                    stroke = color

            # Now add or change the fill color in the path's style
            style['fill'] = fill

            # Add or change the stroke behavior in the path's style
            style['stroke'] = stroke

            # And change the style attribute for the path
            path.set('style', simplestyle.formatStyle(style))

            # Create a group <g> element under the document root
            layer = inkex.etree.SubElement(root, inkex.addNS('g', 'svg'))

            # Add Inkscape layer attributes to this new group
            count += 1
            layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
            layer.set(inkex.addNS('label', 'inkscape'),
                      '{0:d} - {1}'.format(count, color))

            # Now move this path from where it was to being a child
            # of this new group/layer we just made
            layer.append(path)

        # Remove any image
        # For color scans, Trace Bitmap seems to put the
        # image in the same layer & group as the traced regions.
        # BUT, for gray scans, it seems to leave the image by
        # itself as a child of the root document

        if self.options.removeImage:
            for node in self.document.xpath('//svg:image',
                                            namespaces=inkex.NSS):
                parent = node.getparent()
                if (parent.tag == 'svg') or (parent.tag == inkex.addNS(
                        'svg', 'svg')):
                    parent.remove(node)
                else:
                    gparent = parent.getparent()
                    try:
                        gparent.remove(parent)
                    except:
                        parent.remove(node)

        inkex.errormsg(gettext.gettext('Finished.  Created %d layers') % count)
Beispiel #42
0
    def effect(self):
        """
        Fonction principale
        Surchage la fonction de la classe de base
        Dessine quelques elements sur le docuement SVG
        """

        # Recupere le document SVG principal
        svg = self.document.getroot()
        layer = self.current_layer

        # Recuperation de la hauteur et de la largeur de la feuille
        width = inkex.unittouu(svg.get('width'))
        height = inkex.unittouu(svg.attrib['height'])
        """
        §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
        LA RÈGLE
        §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
        """
        x_org = 10  #width / 20
        x_pas = width / 21
        y_org = 10  #height / 10
        y_pas = 20
        nLargeurTrait = 1

        # Center text horizontally with CSS style.
        textstyle = {'text-align' : 'left', \
                 'text-anchor': 'top', \
                 'font-size': '12pt', \
                 'fill':'rgb(0, 0, 0)'}

        ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
        ligne.set('x1', str(x_org))
        ligne.set('y1', str(y_org))
        ligne.set('x2', str(x_org + 20 * x_pas))
        ligne.set('y2', str(y_org))
        ligne.set('stroke', 'rgb(0, 0, 0)')
        ligne.set('stroke-width', str(nLargeurTrait))
        layer.append(ligne)

        for n in range(21):
            x_pos = x_org + n * x_pas
            ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
            ligne.set('x1', str(x_pos))
            ligne.set('y1', str(y_org))
            ligne.set('x2', str(x_pos))
            ligne.set('y2', str(y_org + y_pas))
            ligne.set('stroke', 'rgb(0, 0, 0)')
            ligne.set('stroke-width', str(nLargeurTrait))
            layer.append(ligne)

            # Creation d'un element texte
            texte = inkex.etree.Element(inkex.addNS('text', 'svg'))
            texte.text = str(n)

            # Set text position to center of document.
            textDecal = 4
            if n > 9:
                textDecal = 2 * textDecal
            texte.set('x', str(x_pos - textDecal))
            texte.set('y', str(y_org + 2 * y_pas))
            texte.set('style', simplestyle.formatStyle(textstyle))
            # Ajoute le texte au calque
            layer.append(texte)

        y_pas = 15
        for n in range(20):
            x_pos = x_org + x_pas / 2 + n * x_pas
            ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
            ligne.set('x1', str(x_pos))
            ligne.set('y1', str(y_org))
            ligne.set('x2', str(x_pos))
            ligne.set('y2', str(y_org + y_pas))
            ligne.set('stroke', 'rgb(0, 0, 0)')
            ligne.set('stroke-width', str(nLargeurTrait))
            layer.append(ligne)

        x_pas = width / 210
        y_pas = 10
        for n in range(200):
            x_pos = x_org + n * x_pas
            ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
            ligne.set('x1', str(x_pos))
            ligne.set('y1', str(y_org))
            ligne.set('x2', str(x_pos))
            ligne.set('y2', str(y_org + y_pas))
            ligne.set('stroke', 'rgb(0, 0, 0)')
            ligne.set('stroke-width', str(nLargeurTrait))
            layer.append(ligne)
        """
        §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
        LE RAPPORTEUR
        §§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
        """
        # Creation du demi-cercle
        x_org = width / 2
        x_pas = width / 21
        y_org = height / 2
        y_pas = 20
        nLargeurTrait = 1
        radius = x_org

        demicercle = inkex.etree.Element(inkex.addNS('path', 'svg'))

        f = (0.0, y_org)
        svgd = 'M %.3f,%.3f ' % f
        a = (x_org, x_org)
        b = (width, y_org)
        svgd += 'A %.3f,%.3f 0 1 1 ' % a
        svgd += '%.3f,%.3f ' % b
        svgd += 'z'

        demicercle.set('d', svgd)

        demicercle.set('fill', 'none')
        demicercle.set('stroke', 'rgb(0, 0, 0)')
        demicercle.set('stroke-width', str(nLargeurTrait))

        # Ajout du cercle sur le calque
        layer.append(demicercle)

        # graduations
        x_org = width / 2
        x_pas = width / 21
        y_org = height / 2
        y_pas = 20
        nLargeurTrait = 1
        radius = x_org

        angle_pas = 10
        coeff = 0.70
        for n in range(19):
            ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
            angle = radians(n * angle_pas)
            c = radius * cos(angle)
            s = radius * sin(angle)
            x1 = x_org + c
            y1 = y_org - s
            ligne.set('x1', str(x1))
            ligne.set('y1', str(y1))
            x2 = str(x_org + coeff * c)
            y2 = str(y_org - coeff * s)
            ligne.set('x2', x2)
            ligne.set('y2', y2)
            ligne.set('stroke', 'rgb(0, 0, 0)')
            ligne.set('stroke-width', str(nLargeurTrait))
            layer.append(ligne)

            # Creation d'un element texte
            texte = inkex.etree.Element(inkex.addNS('text', 'svg'))
            layer.append(texte)
            texte.text = str(10 * n)  # + '°'
            texte.set('style', simplestyle.formatStyle(textstyle))

            angle = radians(90 - n * angle_pas)
            f = (cos(angle), sin(angle), -sin(angle), cos(angle))
            matrix = 'matrix(%s, %s, %s, %s,0,0)' % f
            texte.set('transform', matrix)

            #texte.set('x', x2)
            #texte.set('y', y2)
            texte.set('x', '634')
            texte.set('y', '-290')

        angle_pas = 10
        coeff = 0.80
        for n in range(18):
            ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
            angle = radians(5 + n * angle_pas)
            c = radius * cos(angle)
            s = radius * sin(angle)
            x1 = x_org + c
            y1 = y_org - s
            ligne.set('x1', str(x1))
            ligne.set('y1', str(y1))
            x2 = x_org + coeff * c
            y2 = y_org - coeff * s
            ligne.set('x2', str(x2))
            ligne.set('y2', str(y2))
            ligne.set('stroke', 'rgb(0, 0, 0)')
            ligne.set('stroke-width', str(nLargeurTrait))
            layer.append(ligne)

        angle_pas = 1
        coeff = 0.95
        for n in range(180):
            ligne = inkex.etree.Element(inkex.addNS('line', 'svg'))
            angle = radians(n * angle_pas)
            c = radius * cos(angle)
            s = radius * sin(angle)
            x1 = x_org + c
            y1 = y_org - s
            ligne.set('x1', str(x1))
            ligne.set('y1', str(y1))
            x2 = x_org + coeff * c
            y2 = y_org - coeff * s
            ligne.set('x2', str(x2))
            ligne.set('y2', str(y2))
            ligne.set('stroke', 'rgb(0, 0, 0)')
            ligne.set('stroke-width', str(nLargeurTrait))
            layer.append(ligne)
    def recursiveFuseTransform(self,
                               node,
                               transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = composeTransform(transf,
                                  parseTransform(node.get("transform", None)))

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

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

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

                style['stroke-width'] = self.valWithUnit(stroke_width, unit)
                update = True

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

        node = ApplyTransform.objectToPath(node)

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

        elif node.tag == inkex.addNS('polygon', 'svg'):
            points = node.get('points')
            points = points.strip().split(' ')
            for k, p in enumerate(points):
                p = p.split(',')
                unit = self.getUnit(p[0])
                p = [self.getVal(p[0]), self.getVal(p[1])]
                applyTransformToPoint(transf, p)
                p = [
                    self.valWithUnit(p[0], unit),
                    self.valWithUnit(p[1], unit)
                ]
                p = ','.join(p)
                points[k] = p
            points = ' '.join(points)
            node.set('points', points)

        # if there is cx, there is also cy
        if 'cx' in node.attrib:
            cx = node.get('cx')
            cy = node.get('cy')
            unit = self.getUnit(cx)
            pt = [self.getVal(cx), self.getVal(cy)]
            applyTransformToPoint(transf, pt)
            node.set('cx', self.valWithUnit(pt[0], unit))
            node.set('cy', self.valWithUnit(pt[1], unit))

        if 'r' in node.attrib:
            unit = self.getUnit(node.get('r'))
            r = self.getVal(node.get('r'))
            # this is a circle: is the scale uniform?
            if transf[0][0] == transf[1][1]:
                r *= abs(transf[0][0])
                node.set('r', self.valWithUnit(r, unit))
            else:
                # transform is not uniform: go from circle to ellipse
                # NOTE!!! Inkscape currently applies this particular transform as soon as we touch the object.
                # therefore rx and ry are both assigned to r, otherwise the scaling is applied two times!
                # this is kind of a bug of the implementation
                rx = r  #*abs(transf[0][0])
                ry = r  #*abs(transf[1][1])
                node.set('rx', self.valWithUnit(rx, unit))
                node.set('ry', self.valWithUnit(ry, unit))
                del node.attrib['r']
                node.tag = inkex.addNS('ellipse', 'svg')

        if 'rx' in node.attrib:
            unit = self.getUnit(node.get('rx'))
            rx = self.getVal(node.get('rx')) * abs(transf[0][0])
            ry = self.getVal(node.get('ry')) * abs(transf[1][1])
            node.set('rx', self.valWithUnit(rx, unit))
            node.set('ry', self.valWithUnit(ry, unit))

        if 'x' in node.attrib:
            unit = self.getUnit(node.get('x'))
            x = self.getVal(node.get('x')) * transf[0][0]
            y = self.getVal(node.get('y')) * transf[1][1]
            node.set('x', self.valWithUnit(x, unit))
            node.set('y', self.valWithUnit(y, unit))

        if 'width' in node.attrib:
            unit = self.getUnit(node.get('width'))
            w = self.getVal(node.get('width')) * transf[0][0]
            h = self.getVal(node.get('height')) * transf[1][1]
            if w < 0:
                xUnit = self.getUnit(node.get('x'))
                x = self.getVal(node.get('x'))
                x += w
                w = -w
                node.set('x', self.valWithUnit(x, xUnit))
            if h < 0:
                yUnit = self.getUnit(node.get('y'))
                y = self.getVal(node.get('y'))
                y += h
                h = -h
                node.set('y', self.valWithUnit(y, yUnit))
            node.set('width', self.valWithUnit(w, unit))
            node.set('height', self.valWithUnit(h, unit))

        for child in node.getchildren():
            self.recursiveFuseTransform(child, transf)
Beispiel #44
0
  def effect(self):
    global debug

    if self.options.version:
      print __version__
      sys.exit(0)
    if self.options.invert         is not None: self.invert_image       = self.options.invert
    if self.options.remove         is not None: self.replace_image      = self.options.remove
    if self.options.megapixels     is not None: self.megapixel_limit    = self.options.megapixels
    if self.options.candidates     is not None: self.candidates         = self.options.candidates
    if self.options.despecle       is not None: self.filter_median      = self.options.despecle
    if self.options.equal_light    is not None: self.filter_equal_light = self.options.equal_light
    if self.options.hairline       is not None: self.hairline           = self.options.hairline
    if self.options.hairline_width is not None: self.hairline_width     = self.options.hairline_width
    # if self.options.debug          is not None: debug                   = self.options.debug
    # self.options.debug = True

    self.calc_unit_factor()

    cliprect = None
    if self.options.cliprect:
      for id, node in self.selected.iteritems():
        if node.tag == inkex.addNS('path','svg'):
          print >>sys.stderr, "Error: id="+str(id)+" is a path.\nNeed a rectangle object for clipping."
        if node.tag == inkex.addNS('rect','svg'):
          if debug: print >>self.tty, "cliprect: id="+str(id), "node="+str(node.tag)
          cliprect = {
            'x': float(node.get('x', 0)),
            'y': float(node.get('y', 0)),
            'w': float(node.get('width', 0)),
            'h': float(node.get('height', 0)),
            'node': node
          }
          if debug: print >>self.tty, "cliprect: id="+str(id), "cliprect="+str(cliprect)

    if not len(self.selected.items()):
      inkex.errormsg(_("Please select an image."))
      return

    if cliprect is not None and len(self.selected.items()) < 2:
      inkex.errormsg(_("Please select an image. Only a cliprect was selected."))
      return

    for id, node in self.selected.iteritems():
      if debug: print >>self.tty, "id="+str(id), "tag="+str(node.tag)
      if self.options.cliprect and node.tag == inkex.addNS('rect','svg'):
        continue
      if node.tag != inkex.addNS('image','svg'):
        inkex.errormsg(_("Object "+id+" is NOT an image. seen:"+str(node.tag)+" expected:"+inkex.addNS('image','svg')+"\n Try - Object->Ungroup"))
        return

      # images can also just have a transform attribute, and no x or y,
      # FIXME: should find the image transformation!
      # could be replaced by a (slower) call to command line, or by computeBBox from simpletransform
      svg_x_off = float(node.get('x', 0))
      svg_y_off = float(node.get('y', 0))
      svg_img_w = float(node.get('width',  0.001))
      svg_img_h = float(node.get('height', 0.001))
      if cliprect is not None:
        # normalize cliprect into range 0..1
        cliprect['x'] = cliprect['x'] - svg_x_off
        cliprect['y'] = cliprect['y'] - svg_y_off
        cliprect['x'] = cliprect['x'] / svg_img_w
        cliprect['y'] = cliprect['y'] / svg_img_h
        cliprect['w'] = cliprect['w'] / svg_img_w
        cliprect['h'] = cliprect['h'] / svg_img_h

      # handle two cases. Embedded and linked images
      # <image .. xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAT8AA ..." preserveAspectRatio="none" height="432" width="425" transform="matrix(1,0,-0.52013328,0.85408511,0,0)"/>
      # <image .. xlink:href="xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgAB..."
      # <image  .. xlink:href="file:///home/jw/schaf.png"

      href=str(node.get(inkex.addNS('href','xlink')))

      # ######################
      #
      # dump the entire svg to file, so that we can examine what an image is.
      # f=open(self.dumpname, 'w')
      # f.write(href)
      # f.close()
      # if debug: print >>self.tty, "Dump written to "+self.dumpname
      #
      # ######################

      if href[:7] == 'file://':
        filename=href[7:]
        if debug: print >>self.tty, "linked image: ="+filename
      elif href[0] == '/' or href[0] == '.':
        filename=href
        if debug: print >>self.tty, "linked image path: ="+filename
      elif href[:11] == 'data:image/':
        l = href[11:].index(';')
        type = href[11:11+l]			# 'png' 'jpeg'
        if debug: print >>self.tty, "embedded image: "+href[:11+l]
        img=base64.decodestring(href[11+l+8:])
        f=tempfile.NamedTemporaryFile(mode="wb", prefix='centerlinetrace', suffix="."+type, delete=False)
        f.write(img)
        filename=f.name
        f.close()
      else:
        inkex.errormsg(_("Neither file:// nor data:image/; prefix. Cannot parse PNG/JPEG image href "+href[:200]+"..."))
        sys.exit(1)
      if debug: print >>self.tty, "filename="+filename
      #
      path_svg,stroke_width,im_size = self.svg_centerline_trace(filename, cliprect)
      xml = inkex.etree.fromstring(path_svg)
      try:
        path_d=xml.find('path').attrib['d']
      except:
        inkex.errormsg(_("Couldn't trace the path. Please make sure that the checkbox for tracing bright lines is set correctly and that your drawing has enough contrast."))
        sys.exit(1)

      sx = svg_img_w/im_size[0]
      sy = svg_img_h/im_size[1]
      if debug: print >>self.tty, "svg_im_width ",  svg_img_w, "sx=",sx
      if debug: print >>self.tty, "svg_im_height ", svg_img_h, "sy=",sy
      if debug: print >>self.tty, "im_x ", svg_x_off
      if debug: print >>self.tty, "im_y ", svg_y_off
      if debug: print >>self.tty, "pixel_size= ", im_size
      ## map the coordinates of the returned pixel path to the coordinates of the original SVG image.
      if cliprect is not None:
        svg_x_off = max(svg_x_off, float(cliprect['node'].get('x', 0)))
        svg_y_off = max(svg_y_off, float(cliprect['node'].get('y', 0)))
      matrix = "translate(%g,%g) scale(%g,%g)" % (svg_x_off, svg_y_off, sx, sy)
      #
      if href[:5] == 'data:':
        os.unlink(filename) ## it was a temporary file (representing an embedded image).
      #
      # Create SVG Path
      if self.hairline:
        stroke_width = self.hairline_width * 96. / 25.4         # mm2px FIXME: 96dpi is just a default guess.
      else:
        stroke_width = stroke_width * 0.5 * (abs(sx) + abs(sy))
      style = { 'stroke': '#000000', 'fill': 'none', 'stroke-linecap': 'round', 'stroke-width': stroke_width }
      if self.invert_image: style['stroke'] = '#777777'
      path_attr = { 'style': simplestyle.formatStyle(style), 'd': path_d, 'transform': matrix }
      ## insert the new path object
      inkex.etree.SubElement(self.current_layer, inkex.addNS('path', 'svg'), path_attr)
      ## delete the old image object
      if self.replace_image:
        node.getparent().remove(node)
        if cliprect is not None:        # and its cliprect ...
          cliprect['node'].getparent().remove(cliprect['node'])
Beispiel #45
0
def draw_SVG_line(x1, y1, x2, y2, width, name, parent):
    style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill': 'none' }
    line_attribs = {'style':simplestyle.formatStyle(style),
                    inkex.addNS('label','inkscape'):name,
                    'd':'M '+str(x1)+','+str(y1)+' L '+str(x2)+','+str(y2)}
    inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs )
Beispiel #46
0
        'M ' + str(p1[0]) + ',' + str(p1[1]) + ' L ' + str(p2[0]) + ',' +
        str(p2[1]) + ' L ' + str(p3[0]) + ',' + str(p3[1]) + ' L ' +
        str(p1[0]) + ',' + str(p1[1]) + ' z'
    }
    inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'), tri_attribs)


#draw an SVG line segment between the given (raw) points
def draw_SVG_line((x1, y1), (x2, y2), style, name, parent):
    line_style = {
        'stroke': style.l_col,
        'stroke-width': str(style.l_th),
        'fill': style.l_fill
    }
    line_attribs = {
        'style': simplestyle.formatStyle(line_style),
        inkex.addNS('label', 'inkscape'): name,
        'd': 'M ' + str(x1) + ',' + str(y1) + ' L ' + str(x2) + ',' + str(y2)
    }
    inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'), line_attribs)


#lines from each vertex to a corresponding point in trilinears
def draw_vertex_lines(vert_mat, params, width, name, parent):
    for i in range(3):
        oppositepoint = get_cartesian_pt(vert_mat[i], params)
        draw_SVG_line(params[3][-i % 3], oppositepoint, width,
                      name + ':' + str(i), parent)


#MATHEMATICAL ROUTINES
Beispiel #47
0
    def effect(self):
        svg = self.document.getroot()

        # create new layers for dots and for numbers
        dotLayer = inkex.etree.SubElement(svg, 'g')
        dotLayer.set(inkex.addNS('label', 'inkscape'),
                     'ConnectTheDots dotLayer')
        dotLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        numberLayer = inkex.etree.SubElement(svg, 'g')
        numberLayer.set(inkex.addNS('label', 'inkscape'),
                        'ConnectTheDots numberLayer')
        numberLayer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        min_dist = float(self.options.dist)

        # iterate over every path, start numbering from 1 every time
        for id, path in self.selected.iteritems():
            if path.tag == 'path' or path.tag == inkex.addNS('path', 'svg'):
                # radius and fontsize as offsets to avoid placing numbers inside dots
                r = float(self.options.radius)
                f = 0.5 * int(self.options.fontsize)

                # iterate over vertices and draw dots on each as well as the number next to it
                d = path.get('d')
                vertices = simplepath.parsePath(d)

                dist = 2 ^ 32 - 1
                prev_x, prev_y = 0, 0
                count_idx = 0

                for idx, v in enumerate(vertices):
                    x, y = self.getXY(v)
                    if idx > 1:
                        dist = sqrt((x - prev_x)**2 + (y - prev_y)**2)

                    if (min_dist != -1):
                        if (dist <= min_dist):
                            prev_x, prev_y = x, y
                            continue
                    count_idx = count_idx + 1

                    # create dots
                    style = {
                        'stroke': 'none',
                        'stroke-width': '0',
                        'fill': '#000000'
                    }
                    name = 'pbn_%i' % count_idx
                    attributes = {
                        'style': simplestyle.formatStyle(style),
                        inkex.addNS('cx', 'sodipodi'): str(x),
                        inkex.addNS('cy', 'sodipodi'): str(y),
                        inkex.addNS('rx', 'sodipodi'): self.options.radius,
                        inkex.addNS('ry', 'sodipodi'): self.options.radius,
                        inkex.addNS('start', 'sodipodi'): str(0),
                        inkex.addNS('end', 'sodipodi'): str(2 * pi),
                        inkex.addNS('open', 'sodipodi'): 'false',
                        inkex.addNS('type', 'sodipodi'): 'arc',
                        inkex.addNS('label', 'inkscape'): name
                    }
                    dot = inkex.etree.SubElement(dotLayer,
                                                 inkex.addNS('path', 'svg'),
                                                 attributes)

                    if idx > 0 and idx < len(vertices) - 1:
                        # block two quadrants, one for the previous and one for the next
                        freeQuads = self.findFreeQuadrants(
                            (x, y), self.getXY(vertices[idx - 1]),
                            self.getXY(vertices[idx + 1]))
                    else:
                        # special case for end nodes, only block one quadrant
                        freeQuads = self.findFreeQuadrants(
                            (x, y), self.getXY(vertices[idx - 1]))

                    # randomly place number in one of the free quadrants
                    q = choice(freeQuads)
                    if q == self.TOP_RIGHT:
                        nx = x + 2 * r
                        ny = y + 2 * r + f
                        textAnchor = 'start'
                    elif q == self.TOP_LEFT:
                        nx = x - 2 * r
                        ny = y + r + f
                        textAnchor = 'end'
                    elif q == self.BOTTOM_LEFT:
                        nx = x - r
                        ny = y - r
                        textAnchor = 'end'
                    else:  # BOTTOM_RIGHT
                        nx = x + r
                        ny = y - r
                        textAnchor = 'start'

                    # create the number element
                    number = inkex.etree.Element(inkex.addNS('text', 'svg'))
                    number.text = str(count_idx)
                    number.set('x', str(nx))
                    number.set('y', str(ny))
                    number.set('font-size', self.options.fontsize)
                    number.set('text-anchor', textAnchor)
                    numberLayer.append(number)

                    # update previous point
                    prev_x, prev_y = x, y

                # hide the original path if specified in options
                if self.options.hidepath == 'true':
                    path.set('display', 'none')
Beispiel #48
0
def draw_SVG_rect(x,y,w,h, width, fill, name, parent):
    style = { 'stroke': '#000000', 'stroke-width':str(width), 'fill':fill}
    rect_attribs = {'style':simplestyle.formatStyle(style),
                    inkex.addNS('label','inkscape'):name,
                    'x':str(x), 'y':str(y), 'width':str(w), 'height':str(h)}
    inkex.etree.SubElement(parent, inkex.addNS('rect','svg'), rect_attribs )
Beispiel #49
0
#!/usr/bin/env python
# coding: utf8
# We will use the inkex module with the predefined Effect base class.
import inkex
# The simplestyle module provides functions for style parsing.

import simplestyle
import math

objStyle = simplestyle.formatStyle({
    'stroke': '#000000',
    'stroke-width': 0.1,
    'fill': 'none'
})


class inkcape_path:
    def __init__(self, Offset, group, Label=None):
        self.offsetX = Offset[0]
        self.offsetY = Offset[1]
        self.Path = ''
        self.group = group
        self.Label = Label

    def MoveTo(self, x, y):
        #Return string 'M X Y' where X and Y are updated values from parameters
        self.Path += ' M ' + str(round(x - self.offsetX, 3)) + ',' + str(
            round(y - self.offsetY, 3))

    def LineTo(self, x, y):
        #Return string 'L X Y' where X and Y are updated values from parameters
Beispiel #50
0
    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
        """

        # check for correct number of selected objects and return a translatable errormessage to the user
        if len(self.options.ids) != 2:
            inkex.errormsg(_("This extension requires two selected objects."))
            exit()
        # Convert color - which comes in as a long into a string like '#FFFFFF'
        self.options.strokeColour = self.getColorString(
            self.options.strokeColour)
        #
        path_stroke = self.options.strokeColour  # take color from tab3
        path_fill = 'none'  # no fill - just a line
        path_stroke_width = 0.6  # can also be in form '0.6mm'
        # gather incoming params and convert
        param1 = self.options.param1
        param2 = self.options.param2
        param3 = self.options.param3
        choice = self.options.achoice
        units2 = self.options.units2
        accuracy = self.options.accuracy  # although a string in inx - option parser converts to int.
        # calculate unit factor for units defined in dialog.
        unit_factor = self.calc_unit_factor()
        # what page are we on
        page_id = self.options.active_tab  # sometimes wrong the very first time

        # Do your thing - create some points or a path or whatever...
        points = []
        points.extend([(i * 2, i * 2) for i in range(0, param1)])
        points.append((param1, param1 * 2 + 5))
        #inkex.debug(points)
        path = points_to_svgd(points)
        #inkex.debug(path)
        bbox_center = points_to_bbox_center(points)
        # example debug
        # print >>self.tty, bbox_center
        # or
        # inkex.debug("bbox center %s" % bbox_center)

        # 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
        # This finds center of exisiting document page

        # This finds center of current view in inkscape
        t = 'translate(%s,%s)' % (self.view_center[0], self.view_center[1])
        # Make a nice useful name
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'useful name' + str(param1),
            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(param1) + '; with:' + str(param2)
        }
        # add the group to the document's current layer
        topgroup = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        # Create SVG Path under this top level group
        # define style using basic dictionary
        style = {
            'stroke': path_stroke,
            'fill': path_fill,
            'stroke-width': param2
        }
        # convert style into svg form (see import at top of file)
        mypath_attribs = {'style': simplestyle.formatStyle(style), 'd': path}
        # add path to scene
        squiggle = inkex.etree.SubElement(topgroup, inkex.addNS('path', 'svg'),
                                          mypath_attribs)

        # Add another feature in same group (under it)
        style = {
            'stroke': path_stroke,
            'fill': path_fill,
            'stroke-width': path_stroke_width
        }
        cs = param1 / 2  # centercross length
        cs2 = str(cs)
        d = 'M-' + cs2 + ',0L' + cs2 + ',0M0,-' + cs2 + 'L0,' + cs2  # 'M-10,0L10,0M0,-10L0,10'
        # or
        d = 'M %s,0 L %s,0 M 0,-%s L 0,%s' % (-cs, cs, cs, cs)
        # or
        d = 'M {0},0 L {1},0 M 0,{0} L 0,{1}'.format(-cs, cs)
        # or
        #d = 'M-10 0L10 0M0 -10L0 10' # commas superfluous, minimise spaces.
        cross_attribs = {
            inkex.addNS('label', 'inkscape'): 'Center cross',
            'style': simplestyle.formatStyle(style),
            'd': d
        }
        cross = inkex.etree.SubElement(topgroup, inkex.addNS('path', 'svg'),
                                       cross_attribs)

        # Add a precalculated svg circle
        style = {
            'stroke': path_stroke,
            'fill': path_fill,
            'stroke-width': self.getUnittouu(str(param2) + self.options.units)
        }
        draw_SVG_circle(topgroup, param1 * 4 * unit_factor, 0, 0, 'a circle',
                        style)

        # Add some super basic text (e.g. for debug)
        if choice:
            notes = [
                'a label: %d (%s) ' %
                (param1 * unit_factor, self.options.units), 'doc line'
            ]
            text_height = 12
            # position above
            y = -22
            for note in notes:
                self.add_text(topgroup, note, [0, y], text_height)
                y += text_height * 1.2
        #
        #more complex text
        font_height = min(
            32, max(10,
                    int(self.getUnittouu(str(param1) + self.options.units))))
        text_style = {
            'font-size': str(font_height),
            'font-family': 'arial',
            'text-anchor': 'middle',
            'text-align': 'center',
            'fill': path_stroke
        }
        text_atts = {
            'style': simplestyle.formatStyle(text_style),
            'x': str(44),
            'y': str(-15)
        }
        text = inkex.etree.SubElement(topgroup, 'text', text_atts)
        text.text = "%4.3f" % (param1 * param2)
Beispiel #51
0
import inkex
import simplestyle


from math import *
from collections import namedtuple


#Note: keep in mind that SVG coordinates start in the top-left corner i.e. with an inverted y-axis

errormsg = inkex.errormsg
debug = inkex.debug

default_style = simplestyle.formatStyle(
    {'stroke': '#000000',
    'stroke-width': '1',
    'fill': 'none'
    })

groove_style = simplestyle.formatStyle(
    {'stroke': '#0000FF',
    'stroke-width': '1',
    'fill': 'none'
    })

mark_style = simplestyle.formatStyle(
    {'stroke': '#00FF00',
    'stroke-width': '1',
    'fill': 'none'
    })
Beispiel #52
0
 if block != defs:  # in a BLOCK
     layer = block
 elif vals[groups['8']]:  # use Common Layer Name
     if not vals[groups['8']][0]:
         vals[groups['8']][0] = '0'  # use default name
     layer = layer_nodes[vals[groups['8']][0]]
 color = '#000000'  # default color
 if vals[groups['8']]:
     if layer_colors.has_key(vals[groups['8']][0]):
         if colors.has_key(layer_colors[vals[groups['8']][0]]):
             color = colors[layer_colors[vals[groups['8']][0]]]
 if vals[groups['62']]:  # Common Color Number
     if colors.has_key(vals[groups['62']][0]):
         color = colors[vals[groups['62']][0]]
 style = simplestyle.formatStyle({
     'stroke': '%s' % color,
     'fill': 'none'
 })
 w = 0.5  # default lineweight for POINT
 if vals[groups['370']]:  # Common Lineweight
     if vals[groups['370']][0] > 0:
         w = 96.0 / 25.4 * vals[groups['370']][0] / 100.0
         if w < 0.5:
             w = 0.5
         style = simplestyle.formatStyle({
             'stroke': '%s' % color,
             'fill': 'none',
             'stroke-width': '%.1f' % w
         })
 if vals[groups['6']]:  # Common Linetype
     if linetypes.has_key(vals[groups['6']][0]):
         style += ';' + linetypes[vals[groups['6']][0]]
Beispiel #53
0
    def effect(self):
        self.options.primaryr = self.unittouu(
            str(self.options.primaryr) + 'px')
        self.options.secondaryr = self.unittouu(
            str(self.options.secondaryr) + 'px')
        self.options.penr = self.unittouu(str(self.options.penr) + 'px')

        if self.options.secondaryr == 0:
            return
        if self.options.quality == 0:
            return

        if (self.options.gearplacement.strip(' ').lower().startswith('outside')
            ):
            a = self.options.primaryr + self.options.secondaryr
            flip = -1
        else:
            a = self.options.primaryr - self.options.secondaryr
            flip = 1

        ratio = a / self.options.secondaryr
        if ratio == 0:
            return
        scale = 2 * math.pi / (ratio * self.options.quality)

        rotation = -math.pi * self.options.rotation / 180

        new = inkex.etree.Element(inkex.addNS('path', 'svg'))
        s = {
            'stroke': '#000000',
            'fill': 'none',
            'stroke-width': str(self.unittouu('1px'))
        }
        new.set('style', simplestyle.formatStyle(s))

        pathString = ''
        maxPointCount = 1000

        for i in range(maxPointCount):

            theta = i * scale

            view_center = computePointInNode(list(self.view_center),
                                             self.current_layer)
            x = a * math.cos(theta + rotation) + \
                self.options.penr * math.cos(ratio * theta + rotation) * flip + \
                view_center[0]
            y = a * math.sin(theta + rotation) - \
                self.options.penr * math.sin(ratio * theta + rotation) + \
                view_center[1]

            dx = (-a * math.sin(theta + rotation) - \
                ratio * self.options.penr * math.sin(ratio * theta + rotation) * flip) * scale / 3
            dy = (a * math.cos(theta + rotation) - \
                ratio * self.options.penr * math.cos(ratio * theta + rotation)) * scale / 3

            if i <= 0:
                pathString += 'M ' + str(x) + ',' + str(y) + ' C ' + str(
                    x + dx) + ',' + str(y + dy) + ' '
            else:
                pathString += str(x - dx) + ',' + str(y - dy) + ' ' + str(
                    x) + ',' + str(y)

                if math.fmod(i / ratio, self.options.quality
                             ) == 0 and i % self.options.quality == 0:
                    pathString += 'Z'
                    break
                else:
                    if i == maxPointCount - 1:
                        pass  # we reached the allowed maximum of points, stop here
                    else:
                        pathString += ' C ' + str(x + dx) + ',' + str(y +
                                                                      dy) + ' '

        new.set('d', pathString)
        self.current_layer.append(new)
Beispiel #54
0
def set_style(node, style):
    '''
    Sugar coated way to set the style dict, for node
    '''
    node.attrib['style'] = simplestyle.formatStyle(style)
Beispiel #55
0
def propagate_attribs(node,
                      parent_style={},
                      parent_transform=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
    """Propagate style and transform to remove inheritance"""

    # Don't enter non-graphical portions of the document
    if (node.tag == addNS("namedview", "sodipodi")
            or node.tag == addNS("defs", "svg")
            or node.tag == addNS("metadata", "svg")
            or node.tag == addNS("foreignObject", "svg")):
        return

    # Compose the transformations
    if node.tag == addNS("svg", "svg") and node.get("viewBox"):
        vx, vy, vw, vh = [
            get_dimension(x) for x in node.get("viewBox").split()
        ]
        dw = get_dimension(node.get("width", vw))
        dh = get_dimension(node.get("height", vh))
        t = "translate(%f, %f) scale(%f, %f)" % (-vx, -vy, dw / vw, dh / vh)
        this_transform = simpletransform.parseTransform(t, parent_transform)
        this_transform = simpletransform.parseTransform(
            node.get("transform"), this_transform)
        del node.attrib["viewBox"]
    else:
        this_transform = simpletransform.parseTransform(
            node.get("transform"), parent_transform)

    # Compose the style attribs
    this_style = simplestyle.parseStyle(node.get("style", ""))
    remaining_style = {}  # Style attributes that are not propagated

    non_propagated = ["filter"
                      ]  # Filters should remain on the topmost ancestor
    for key in non_propagated:
        if key in this_style.keys():
            remaining_style[key] = this_style[key]
            del this_style[key]

    # Create a copy of the parent style, and merge this style into it
    parent_style_copy = parent_style.copy()
    parent_style_copy.update(this_style)
    this_style = parent_style_copy

    # Merge in any attributes outside of the style
    style_attribs = ["fill", "stroke"]
    for attrib in style_attribs:
        if node.get(attrib):
            this_style[attrib] = node.get(attrib)
            del node.attrib[attrib]

    if (node.tag == addNS("svg", "svg") or node.tag == addNS("g", "svg")
            or node.tag == addNS("a", "svg")
            or node.tag == addNS("switch", "svg")):
        # Leave only non-propagating style attributes
        if len(remaining_style) == 0:
            if "style" in node.keys():
                del node.attrib["style"]
        else:
            node.set("style", simplestyle.formatStyle(remaining_style))

        # Remove the transform attribute
        if "transform" in node.keys():
            del node.attrib["transform"]

        # Continue propagating on subelements
        for c in node.iterchildren():
            propagate_attribs(c, this_style, this_transform)
    else:
        # This element is not a container

        # Merge remaining_style into this_style
        this_style.update(remaining_style)

        # Set the element's style and transform attribs
        node.set("style", simplestyle.formatStyle(this_style))
        node.set("transform", simpletransform.formatTransform(this_transform))
    def effect(self):
        if not self.options.ids:
            inkex.errormsg(_("Please select an object"))
            exit()
        scale = self.unittouu('1px')  # convert to document units
        self.options.size *= scale
        self.options.border *= scale
        q = {
            'x': 0,
            'y': 0,
            'width': 0,
            'height': 0
        }  # query the bounding box of ids[0]
        for query in q.keys():
            p = Popen('inkscape --query-%s --query-id=%s "%s"' %
                      (query, self.options.ids[0], self.args[-1]),
                      shell=True,
                      stdout=PIPE,
                      stderr=PIPE)
            rc = p.wait()
            q[query] = scale * float(p.stdout.read())
        mat = simpletransform.composeParents(
            self.selected[self.options.ids[0]],
            [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
        defs = self.xpathSingle('/svg:svg//svg:defs')
        pattern = inkex.etree.SubElement(defs, inkex.addNS('pattern', 'svg'))
        pattern.set('id', 'Voronoi' + str(random.randint(1, 9999)))
        pattern.set('width', str(q['width']))
        pattern.set('height', str(q['height']))
        pattern.set(
            'patternTransform',
            'translate(%s,%s)' % (q['x'] - mat[0][2], q['y'] - mat[1][2]))
        pattern.set('patternUnits', 'userSpaceOnUse')

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

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

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

        # link selected object to pattern
        obj = self.selected[self.options.ids[0]]
        style = {}
        if obj.attrib.has_key('style'):
            style = simplestyle.parseStyle(obj.attrib['style'])
        style['fill'] = 'url(#%s)' % pattern.get('id')
        obj.attrib['style'] = simplestyle.formatStyle(style)
        if obj.tag == inkex.addNS('g', 'svg'):
            for node in obj:
                style = {}
                if node.attrib.has_key('style'):
                    style = simplestyle.parseStyle(node.attrib['style'])
                style['fill'] = 'url(#%s)' % pattern.get('id')
                node.attrib['style'] = simplestyle.formatStyle(style)
    def recursiveFuseTransform(self,
                               node,
                               transf=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]):
        transf = composeTransform(transf,
                                  parseTransform(node.get("transform", None)))

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

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

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

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

        node = ApplyTransform.objectToPath(node)

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

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

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

        for child in node.getchildren():
            self.recursiveFuseTransform(child, transf)
Beispiel #58
0
    def effect(self):
        exponent = self.options.exponent
        if exponent>= 0:
            exponent = 1.0 + exponent
        else:
            exponent = 1.0/(1.0 - exponent)
        steps = [1.0/(self.options.steps + 1.0)]
        for i in range(self.options.steps - 1):
            steps.append(steps[0] + steps[-1])
        steps = [step**exponent for step in steps]
            
        paths = {}            
        styles = {}
        for id in self.options.ids:
            node = self.selected[id]
            if node.tag ==inkex.addNS('path','svg'):
                paths[id] = cubicsuperpath.parsePath(node.get('d'))
                styles[id] = simplestyle.parseStyle(node.get('style'))
                trans = node.get('transform')
                if trans:
                    simpletransform.applyTransformToPath(simpletransform.parseTransform(trans), paths[id])
            else:
                self.options.ids.remove(id)

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

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

                    

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

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

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

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

        teeth = self.options.teeth
        pitch = self.unittouu( str(self.options.pitch) + self.options.unit)
        angle = self.options.angle  # Angle of tangent to tooth at circular pitch wrt radial line.
        centerdiameter = self.unittouu( str(self.options.centerdiameter) + self.options.unit)

        # print >>sys.stderr, "Teeth: %s\n"        % teeth

        two_pi = 2.0 * pi

        # Pitch (circular pitch): Length of the arc from one tooth to the next)
        # Pitch diameter: Diameter of pitch circle.
        pitch_diameter = float( teeth ) * pitch / pi
        pitch_radius   = pitch_diameter / 2.0

        # Base Circle
        base_diameter = pitch_diameter * cos( radians( angle ) )
        base_radius   = base_diameter / 2.0

        # Diametrial pitch: Number of teeth per unit length.
        pitch_diametrial = float( teeth )/ pitch_diameter

        # Addendum: Radial distance from pitch circle to outside circle.
        addendum = 1.0 / pitch_diametrial

        # Outer Circle
        outer_radius = pitch_radius + addendum
        outer_diameter = outer_radius * 2.0

        # Tooth thickness: Tooth width along pitch circle.
        tooth  = ( pi * pitch_diameter ) / ( 2.0 * float( teeth ) )

        # Undercut?
        undercut = (2.0 / ( sin( radians( angle ) ) ** 2))
        needs_undercut = teeth < undercut


        # Clearance: Radial distance between top of tooth on one gear to bottom of gap on another.
        clearance = 0.0

        # Dedendum: Radial distance from pitch circle to root diameter.
        dedendum = addendum + clearance

        # Root diameter: Diameter of bottom of tooth spaces. 
        root_radius =  pitch_radius - dedendum
        root_diameter = root_radius * 2.0

        half_thick_angle = two_pi / (4.0 * float( 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

        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
            outer1 = pitch1 + pitch_to_outer_angle

            pitch2 = c + half_thick_angle
            base2  = pitch2 + pitch_to_base_angle
            outer2 = pitch2 - pitch_to_outer_angle

            # Points
            b1 = point_on_circle( base_radius,  base1  )
            p1 = point_on_circle( pitch_radius, pitch1 )
            o1 = point_on_circle( outer_radius, outer1 )

            b2 = point_on_circle( base_radius,  base2  )
            p2 = point_on_circle( pitch_radius, pitch2 )
            o2 = point_on_circle( outer_radius, outer2 )

            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
                r1 = point_on_circle(root_radius, root1)
                r2 = point_on_circle(root_radius, root2)
                p_tmp = [r1,p1,o1,o2,p2,r2]
            else:
                r1 = point_on_circle(root_radius, base1)
                r2 = point_on_circle(root_radius, base2)
                p_tmp = [r1,b1,p1,o1,o2,p2,b2,r2]

            points.extend( p_tmp )

        path = points_to_svgd( points )

        # Embed gear in group to make animation easier:
        #  Translate group, Rotate path.
        view_center = computePointInNode(list(self.view_center), self.current_layer)
        t = 'translate(' + str( view_center[0] ) + ',' + str( view_center[1] ) + ')'
        g_attribs = {inkex.addNS('label','inkscape'):'Gear' + str( teeth ),
                     'transform':t }
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        # Create SVG Path for gear
        style = { 'stroke': '#000000', 'fill': 'none', 'stroke-width': str(self.unittouu('1px')) }
        gear_attribs = {'style':simplestyle.formatStyle(style), 'd':path}
        gear = inkex.etree.SubElement(g, inkex.addNS('path','svg'), gear_attribs )
        if(centerdiameter > 0.0):
            center_attribs = {'style':simplestyle.formatStyle(style), 
                inkex.addNS('cx','sodipodi')        :'0.0',
                inkex.addNS('cy','sodipodi')        :'0.0',
                inkex.addNS('rx','sodipodi')        :str(centerdiameter/2),
                inkex.addNS('ry','sodipodi')        :str(centerdiameter/2),
                inkex.addNS('type','sodipodi')      :'arc'
            }
            center = inkex.etree.SubElement(g, inkex.addNS('path','svg'), center_attribs )
    def effect(self):
        # Get access to main SVG document element and get its dimensions.
        svg = self.document.getroot()
        # getting the parent tag of the guide
        nv = self.document.xpath('/svg:svg/sodipodi:namedview',
                                 namespaces=inkex.NSS)[0]

        documentUnits = inkex.addNS('document-units', 'inkscape')
        # print  >> sys.stderr, nv.get(documentUnits)
        uunits = nv.get(documentUnits)
        message = "Units=" + uunits
        inkex.debug(message)

        # Get script's options value.
        stripwidth = self.unittouu(str(self.options.width) + uunits)
        striplength = self.unittouu(str(self.options.length) + uunits)

        cellheight = self.unittouu(str(self.options.cellheight) + uunits)
        cellwidth = self.unittouu(str(self.options.cellwidth) + uunits)

        scalecells = (self.options.scalecells)

        cellnumx = (self.options.cellnumx)
        cellnumy = (self.options.cellnumy)

        notchdepth = self.unittouu(str(self.options.notchdepth) + uunits)
        notchwidth = self.unittouu(str(self.options.notchwidth) + uunits)

        notchhorizontal = (self.options.notchhorizontal)
        notchvertical = (self.options.notchvertical)

        #		notch2depth=self.unittouu(str(self.options.notch2depth)+uunits)
        notch2width = self.unittouu(str(self.options.notch2width) + uunits)

        notch2depth = stripwidth / 2

        notchxcorner = (self.options.notchxcorner)
        notchycorner = (self.options.notchycorner)

        if scalecells:
            cellwidth = (striplength - 4 * notch2width) / cellnumx
            cellheight = (striplength - 4 * notch2width) / cellnumy
            notchxcorner = False
            notchycorner = False

        linewidth = self.unittouu(str(0.01) + uunits)

        distx = (striplength - cellnumx * cellwidth) / 2
        disty = (striplength - cellnumy * cellheight) / 2

        celldistx = (cellwidth - notchwidth) / 2
        celldisty = (cellheight - notch2width) / 2

        # getting the width and height attributes of the canvas
        width = float(self.unittouu(svg.attrib['width']))
        height = float(self.unittouu(svg.attrib['height']))

        # maxlength=max(width,height)
        # if striplength > maxlength:
        # factor=striplength/maxlength+1

        inkex.debug("document width=" + str(self.uutounit(width, uunits)))
        inkex.debug("document height=" + str(self.uutounit(height, uunits)))

        inkex.debug("strip length=" + str(self.uutounit(striplength, uunits)))
        inkex.debug("strip width=" + str(self.uutounit(stripwidth, uunits)))

        inkex.debug("cell width=" + str(self.uutounit(cellwidth, uunits)))
        inkex.debug("cell height=" + str(self.uutounit(cellheight, uunits)))

        inkex.debug("Number of cells horizontal=" + str(cellnumx))
        inkex.debug("Number of cells vertical  =" + str(cellnumy))

        inkex.debug("Depth of extra notch=" +
                    str(self.uutounit(notchdepth, uunits)))
        inkex.debug("Width of extra notch=" +
                    str(self.uutounit(notchwidth, uunits)))

        inkex.debug("Depth of notch for grid=" +
                    str(self.uutounit(notchdepth, uunits)))
        inkex.debug("Width of notch for grid=" +
                    str(self.uutounit(notchwidth, uunits)))

        inkex.debug("distx=" + str(self.uutounit(distx, uunits)))
        inkex.debug("disty=" + str(self.uutounit(disty, uunits)))

        inkex.debug("celldistx=" + str(self.uutounit(celldistx, uunits)))
        inkex.debug("celldisty=" + str(self.uutounit(celldisty, uunits)))

        parent = self.current_layer
        layername = ''
        if notchhorizontal:
            layername = layername + 'VLED '
        if notchvertical:
            layername = layername + 'HLED '

        # Create a new layer
        layer = inkex.etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'), layername + 'Long strips')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        grp_name = 'group_horizontal_strip_long'
        grp_attribs = {inkex.addNS('label', 'inkscape'): grp_name}
        grp = inkex.etree.SubElement(
            layer, 'g', grp_attribs)  #the group to put everything in

        style = {
            'stroke': '#000000',
            'stroke-width': str(linewidth),
            'fill': 'none'
        }

        for num in range(0, 2):
            pathstring = 'M ' + str(1) + ',' + str(1) + ' L '
            if notchxcorner:
                pathstring += str(stripwidth - 2 * notchdepth) + ',' + str(
                    1)  # Obere Querkante
                pathstring += ' L ' + str(stripwidth -
                                          2 * notchdepth) + ',' + str(
                                              notchwidth)  # Erste Kerbe aussen
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    notchwidth)  # Ausrueckung
            else:
                pathstring += str(stripwidth) + ',' + str(1)
            if notchhorizontal:
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    distx)  # Distance to corner
                y = distx
                for i in range(0, cellnumx):
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + celldistx)  # Abstand
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + celldistx)  # Einrueckung
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + celldistx +
                                                  notchwidth)  # Kerbe
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + celldistx + notchwidth)  # Ausrueckung
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + 2 * celldistx + notchwidth)  # Abstand
                    y = y + 2 * celldistx + notchwidth
            if notchxcorner:
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    striplength - notchwidth)  # Untere rechte Ecke
                pathstring += ' L ' + str(stripwidth -
                                          2 * notchdepth) + ',' + str(
                                              striplength -
                                              notchwidth)  # Untere rechte Ecke
                pathstring += ' L ' + str(
                    stripwidth - 2 * notchdepth) + ',' + str(
                        striplength)  # Untere rechte Ecke
            else:
                pathstring += ' L ' + str(stripwidth) + ',' + str(striplength)
            pathstring += ' L ' + str(1) + ',' + str(
                striplength)  # Linke untere Ecke

            y = striplength - distx + notch2width / 2

            pathstring += ' L ' + str(1) + ',' + str(y)  # Distance to corner
            pathstring += ' L ' + str(notch2depth) + ',' + str(
                y)  # Einrueckung

            for i in range(0, cellnumx):
                pathstring += ' L ' + str(notch2depth) + ',' + str(
                    y - notch2width)  # Kerbe
                pathstring += ' L ' + str(1) + ',' + str(
                    y - notch2width)  # Ausrueckung
                pathstring += ' L ' + str(1) + ',' + str(
                    y - notch2width - cellwidth + notch2width)  # Abstand
                pathstring += ' L ' + str(notch2depth) + ',' + str(
                    y - notch2width - cellwidth + notch2width)  # Einrueckung
                y = y - notch2width - cellwidth + notch2width

            pathstring += ' L ' + str(notch2depth) + ',' + str(
                y - notch2width)  # Kerbe
            pathstring += ' L ' + str(1) + ',' + str(
                y - notch2width)  # Ausrueckung

            pathstring += ' L ' + str(1) + ',' + str(1) + ' z'

            strip_transform = 'rotate(' + str(90) + ')'
            strip_transform += ' translate(' + str(
                stripwidth * num) + ',' + str(1) + ')'
            strip_attribs = {
                'style': simplestyle.formatStyle(style),
                inkex.addNS('label', 'inkscape'): "strip horizontal long",
                'transform': strip_transform,
                'd': pathstring
            }
            inkex.etree.SubElement(grp, inkex.addNS('path', 'svg'),
                                   strip_attribs)

        celldisty = (cellheight - notch2width - notchwidth) / 2

        grp_name = 'group_vertical_strip_long'
        grp_attribs = {inkex.addNS('label', 'inkscape'): grp_name}
        grp = inkex.etree.SubElement(
            layer, 'g', grp_attribs)  #the group to put everything in

        for num in range(0, 2):
            y = disty - notch2width / 2
            pathstring = 'M ' + str(1) + ',' + str(1)
            if notchycorner:
                pathstring += ' L ' + str(stripwidth -
                                          2 * notchdepth) + ',' + str(
                                              1)  # Obere Querkante
                pathstring += ' L ' + str(stripwidth - 2 *
                                          notchdepth) + ',' + str(notchwidth)
                pathstring += ' L ' + str(stripwidth) + ',' + str(notchwidth)
            else:
                pathstring += ' L ' + str(stripwidth) + ',' + str(1)
            pathstring += ' L ' + str(stripwidth) + ',' + str(
                y)  # Distance to corner

            for i in range(0, cellnumy):
                pathstring += ' L ' + str(stripwidth -
                                          notch2depth) + ',' + str(
                                              y)  # Einrueckung
                pathstring += ' L ' + str(stripwidth -
                                          notch2depth) + ',' + str(
                                              y + notch2width)  # Kerbe
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    y + notch2width)  # Ausrueckung
                if notchvertical:
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + notch2width + celldisty)  # Abstand
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + notch2width +
                                                  celldisty)  # Einrueckung
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + notch2width + celldisty +
                                                  notchwidth)  # Kerbe
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + notch2width + celldisty +
                        notchwidth)  # Ausrueckung
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    y + notch2width + 2 * celldisty + notchwidth)  # Abstand
                y = y + notch2width + 2 * celldisty + notchwidth

            pathstring += ' L ' + str(stripwidth - notch2depth) + ',' + str(
                y)  # Einrueckung
            pathstring += ' L ' + str(stripwidth - notch2depth) + ',' + str(
                y + notch2width)  # Kerbe
            pathstring += ' L ' + str(stripwidth) + ',' + str(
                y + notch2width)  # Ausrueckung

            if notchycorner:
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    striplength - notchwidth)  # Untere rechte Ecke
                pathstring += ' L ' + str(stripwidth -
                                          2 * notchdepth) + ',' + str(
                                              striplength -
                                              notchwidth)  # Untere rechte Ecke
                pathstring += ' L ' + str(
                    stripwidth - 2 * notchdepth) + ',' + str(
                        striplength)  # Untere rechte Ecke
            else:
                pathstring += ' L ' + str(stripwidth) + ',' + str(striplength)
            pathstring += ' L ' + str(1) + ',' + str(
                striplength)  # Linke untere Ecke
            pathstring += ' L ' + str(1) + ',' + str(1) + ' z'

            strip_transform = 'translate(' + str(
                num * stripwidth) + ',' + str(1) + ')'
            strip_attribs = {
                'style': simplestyle.formatStyle(style),
                inkex.addNS('label', 'inkscape'): "strip vertical long",
                'transform': strip_transform,
                'd': pathstring
            }
            inkex.etree.SubElement(grp, inkex.addNS('path', 'svg'),
                                   strip_attribs)

        # Create a new layer
        layer = inkex.etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'),
                  layername + 'Horizontal strips short')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        grp_name = 'group horizontal_strip_short'
        grp_attribs = {inkex.addNS('label', 'inkscape'): grp_name}
        grp = inkex.etree.SubElement(
            layer, 'g', grp_attribs)  #the group to put everything in
        striplength = cellnumx * cellwidth + 4 * notch2width
        distx = (striplength - cellnumx * cellwidth) / 2
        disty = (striplength - cellnumy * cellheight) / 2

        style = {
            'stroke': '#000000',
            'stroke-width': str(linewidth),
            'fill': 'none'
        }

        for num in range(1, cellnumy):

            pathstring = 'M ' + str(1) + ',' + str(1) + ' L '
            pathstring += str(stripwidth) + ',' + str(1)
            if notchhorizontal:
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    distx)  # Distance to corner
                y = distx
                for i in range(0, cellnumx):
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + celldistx)  # Abstand
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + celldistx)  # Einrueckung
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + celldistx +
                                                  notchwidth)  # Kerbe
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + celldistx + notchwidth)  # Ausrueckung
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + 2 * celldistx + notchwidth)  # Abstand
                    y = y + 2 * celldistx + notchwidth
            pathstring += ' L ' + str(stripwidth) + ',' + str(striplength)
            pathstring += ' L ' + str(1) + ',' + str(
                striplength)  # Linke untere Ecke

            y = striplength - distx + notch2width / 2

            pathstring += ' L ' + str(1) + ',' + str(y)  # Distance to corner
            pathstring += ' L ' + str(notch2depth) + ',' + str(
                y)  # Einrueckung

            for i in range(0, cellnumx):
                pathstring += ' L ' + str(notch2depth) + ',' + str(
                    y - notch2width)  # Kerbe
                pathstring += ' L ' + str(1) + ',' + str(
                    y - notch2width)  # Ausrueckung
                pathstring += ' L ' + str(1) + ',' + str(
                    y - notch2width - cellwidth + notch2width)  # Abstand
                pathstring += ' L ' + str(notch2depth) + ',' + str(
                    y - notch2width - cellwidth + notch2width)  # Einrueckung
                y = y - notch2width - cellwidth + notch2width

            pathstring += ' L ' + str(notch2depth) + ',' + str(
                y - notch2width)  # Kerbe
            pathstring += ' L ' + str(1) + ',' + str(
                y - notch2width)  # Ausrueckung

            pathstring += ' L ' + str(1) + ',' + str(1) + ' z'

            strip_transform = 'rotate(' + str(90) + ')'
            strip_transform += ' translate(' + str((num + 1) * stripwidth +
                                                   2) + ',' + str(1) + ')'
            stripname = "strip horizontal short" + str(num)
            strip_attribs = {
                'style': simplestyle.formatStyle(style),
                inkex.addNS('label', 'inkscape'): stripname,
                'transform': strip_transform,
                'd': pathstring
            }
            inkex.etree.SubElement(grp, inkex.addNS('path', 'svg'),
                                   strip_attribs)

        # Create a new layer
        layer = inkex.etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'),
                  layername + 'Vertical strips short')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')

        grp_name = 'group vertical_strip_short'
        grp_attribs = {inkex.addNS('label', 'inkscape'): grp_name}
        grp = inkex.etree.SubElement(
            layer, 'g', grp_attribs)  #the group to put everything in

        striplength = cellnumx * cellwidth + 4 * notch2width
        distx = (striplength - cellnumx * cellwidth) / 2
        disty = (striplength - cellnumy * cellheight) / 2

        striplength = cellnumy * cellheight + 4 * notch2width
        distx = (striplength - cellnumx * cellwidth) / 2
        disty = (striplength - cellnumy * cellheight) / 2

        celldisty = (cellheight - notch2width - notchwidth) / 2

        for num in range(1, cellnumx):
            y = disty - notch2width / 2
            pathstring = 'M ' + str(1) + ',' + str(1)
            pathstring += ' L ' + str(stripwidth) + ',' + str(1)
            pathstring += ' L ' + str(stripwidth) + ',' + str(
                y)  # Distance to corner

            for i in range(0, cellnumy):
                pathstring += ' L ' + str(stripwidth -
                                          notch2depth) + ',' + str(
                                              y)  # Einrueckung
                pathstring += ' L ' + str(stripwidth -
                                          notch2depth) + ',' + str(
                                              y + notch2width)  # Kerbe
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    y + notch2width)  # Ausrueckung
                if notchvertical:
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + notch2width + celldisty)  # Abstand
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + notch2width +
                                                  celldisty)  # Einrueckung
                    pathstring += ' L ' + str(stripwidth -
                                              notchdepth) + ',' + str(
                                                  y + notch2width + celldisty +
                                                  notchwidth)  # Kerbe
                    pathstring += ' L ' + str(stripwidth) + ',' + str(
                        y + notch2width + celldisty +
                        notchwidth)  # Ausrueckung
                pathstring += ' L ' + str(stripwidth) + ',' + str(
                    y + notch2width + 2 * celldisty + notchwidth)  # Abstand
                y = y + notch2width + 2 * celldisty + notchwidth

            pathstring += ' L ' + str(stripwidth - notch2depth) + ',' + str(
                y)  # Einrueckung
            pathstring += ' L ' + str(stripwidth - notch2depth) + ',' + str(
                y + notch2width)  # Kerbe
            pathstring += ' L ' + str(stripwidth) + ',' + str(
                y + notch2width)  # Ausrueckung

            pathstring += ' L ' + str(stripwidth) + ',' + str(striplength)
            pathstring += ' L ' + str(1) + ',' + str(
                striplength)  # Linke untere Ecke
            pathstring += ' L ' + str(1) + ',' + str(1) + ' z'

            strip_transform = 'translate(' + str((num + 1) * stripwidth +
                                                 10) + ',' + str(1) + ')'
            stripname = "strip vertical short" + str(num)
            strip_attribs = {
                'style': simplestyle.formatStyle(style),
                inkex.addNS('label', 'inkscape'): stripname,
                'transform': strip_transform,
                'd': pathstring
            }
            inkex.etree.SubElement(grp, inkex.addNS('path', 'svg'),
                                   strip_attribs)