summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2008-10-27 18:03:09 +0000
committerTed Gould <ted@canonical.com>2008-10-27 18:03:09 +0000
commit7dbe11bc23efa5f51a9b84e7d0f6dd16e63e0902 (patch)
tree7d3a2b95b84a03a19cb132cdf88bea0ab6dc4773 /share
parentMerging from trunk (diff)
downloadinkscape-7dbe11bc23efa5f51a9b84e7d0f6dd16e63e0902.tar.gz
inkscape-7dbe11bc23efa5f51a9b84e7d0f6dd16e63e0902.zip
From trunk
(bzr r6885)
Diffstat (limited to 'share')
-rw-r--r--share/extensions/dimension.py2
-rw-r--r--share/extensions/draw_from_triangle.inx78
-rw-r--r--share/extensions/draw_from_triangle.py474
-rwxr-xr-xshare/extensions/dxf_outlines.py4
-rw-r--r--share/extensions/polyhedron_3d.inx21
-rw-r--r--share/extensions/polyhedron_3d.py406
-rw-r--r--share/extensions/render_barcode.inx9
-rwxr-xr-xshare/extensions/simplestyle.py15
-rw-r--r--share/icons/icons.svg111
9 files changed, 848 insertions, 272 deletions
diff --git a/share/extensions/dimension.py b/share/extensions/dimension.py
index 4ff7148ef..0ff5cb7be 100644
--- a/share/extensions/dimension.py
+++ b/share/extensions/dimension.py
@@ -34,6 +34,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import sys, inkex, pathmodifier
from simpletransform import *
+import gettext
+_ = gettext.gettext
class Dimension(pathmodifier.PathModifier):
def __init__(self):
diff --git a/share/extensions/draw_from_triangle.inx b/share/extensions/draw_from_triangle.inx
new file mode 100644
index 000000000..7973cda8a
--- /dev/null
+++ b/share/extensions/draw_from_triangle.inx
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+ <_name>Draw From Triangle</_name>
+ <id>il.fromtriangle</id>
+ <dependency type="executable" location="extensions">draw_from_triangle.py</dependency>
+ <dependency type="executable" location="extensions">inkex.py</dependency>
+ <param name="tab" type="notebook">
+ <page name="common1" _gui-text="Common Objects">
+ <param name="circumcircle" type="boolean" _gui-text="Circumcircle"></param>
+ <param name="circumcentre" type="boolean" _gui-text="Circumcentre"></param>
+ <param name="incircle" type="boolean" _gui-text="Incircle"></param>
+ <param name="incentre" type="boolean" _gui-text="Incentre"></param>
+ <param name="contact_tri" type="boolean" _gui-text="Contact Triangle"></param>
+ <param name="excircles" type="boolean" _gui-text="Excircles"></param>
+ <param name="excentres" type="boolean" _gui-text="Excentres"></param>
+ <param name="extouch_tri" type="boolean" _gui-text="Extouch Triangle"></param>
+ <param name="excentral_tri" type="boolean" _gui-text="Excentral Triangle"></param>
+ <param name="orthocentre" type="boolean" _gui-text="Orthocentre"></param>
+ <param name="orthic_tri" type="boolean" _gui-text="Orthic Triangle"></param>
+ <param name="altitudes" type="boolean" _gui-text="Altitudes"></param>
+ <param name="anglebisectors" type="boolean" _gui-text="Angle Bisectors"></param>
+ <param name="centroid" type="boolean" _gui-text="Centroid"></param>
+ <param name="ninepointcentre" type="boolean" _gui-text="Nine-Point Centre"></param>
+ <param name="ninepointcircle" type="boolean" _gui-text="Nine-Point Circle"></param>
+ <param name="symmedians" type="boolean" _gui-text="Symmedians"></param>
+ <param name="sym_point" type="boolean" _gui-text="Symmedian Point"></param>
+ <param name="sym_tri" type="boolean" _gui-text="Symmedial Triangle"></param>
+ <param name="gergonne_pt" type="boolean" _gui-text="Gergonne Point"></param>
+ <param name="nagel_pt" type="boolean" _gui-text="Nagel Point"></param>
+ </page>
+ <page name="Custom" _gui-text="Custom Points and Options">
+ <param name="mode" type="optiongroup" _gui-text="Custom Point Specified By:">
+ <_option value="trilin">Trilinear Coordinates</_option>
+ <_option value="tcf">Triangle Function</_option>
+ </param>
+ <param name="cust_str" type="string" _gui-text="Point At">cos(a_a):cos(a_b):cos(a_c)</param>
+ <param name="cust_pt" type="boolean" _gui-text="Draw Marker At This Point"></param>
+ <param name="cust_radius" type="boolean" _gui-text="Draw Circle About This Point"></param>
+ <param name="radius" type="string" _gui-text="Radius / px">s_a*s_b*s_c/(4*area)</param>
+ <param name="isogonal_conj" type="boolean" _gui-text="Draw Isogonal Conjugate"></param>
+ <param name="isotomic_conj" type="boolean" _gui-text="Draw Isotomic Conjugate"></param>
+ <param name="report" type="boolean" _gui-text="Report this triangle's properties"></param>
+ </page>
+ <page name="Help" _gui-text="Help">
+ <param name="instructions" type="description">This extension draws constructions about a triangle defined by the first 3 nodes of a selected path. You may select one of preset objects or create your own ones.
+
+All units are the Inkscape's pixel unit. Angles are all in radians.
+You can specify a point by trilinear coordinates or by a triangle centre function.
+Enter as functions of the side length or angles.
+Trilinear elements should be separated by a colon: ':'.
+Side lengths are represented as 's_a', 's_b' and 's_c'.
+Angles corresponding to these are 'a_a', 'a_b', and 'a_c'.
+You can also use the semi-perimeter and area of the triangle as constants. Write 'area' or 'semiperim' for these.
+
+You can use any standard Python math function:
+ceil(x); fabs(x); floor(x); fmod(x,y); frexp(x); ldexp(x,i);
+modf(x); exp(x); log(x [, base]); log10(x); pow(x,y); sqrt(x);
+acos(x); asin(x); atan(x); atan2(y,x); hypot(x,y);
+cos(x); sin(x); tan(x); degrees(x); radians(x);
+cosh(x); sinh(x); tanh(x)
+
+Also available are the inverse trigonometric functions:
+sec(x); csc(x); cot(x)
+
+You can specify the radius of a circle about a custom point using an formula, which may also contain the side lengths, angles, etc. You can also plot the isogonal and isotomic conjugate of the point. Be aware that this may cause a divide-by-zero error for certain points.
+ </param>
+ </page>
+ </param>
+ <effect>
+ <object-type>all</object-type>
+ <effects-menu>
+ <submenu _name="Render"/>
+ </effects-menu>
+ </effect>
+ <script>
+ <command reldir="extensions" interpreter="python">draw_from_triangle.py</command>
+ </script>
+</inkscape-extension>
diff --git a/share/extensions/draw_from_triangle.py b/share/extensions/draw_from_triangle.py
new file mode 100644
index 000000000..b63d0f556
--- /dev/null
+++ b/share/extensions/draw_from_triangle.py
@@ -0,0 +1,474 @@
+#!/usr/bin/env python
+'''
+Copyright (C) 2007 John Beard john.j.beard@gmail.com
+
+##This extension allows you to draw various triangle constructions
+##It requires a path to be selected
+##It will use the first three nodes of this path
+
+## Dimensions of a triangle__
+#
+# /`__
+# / a_c``--__
+# / ``--__ s_a
+# s_b / ``--__
+# /a_a a_b`--__
+# /--------------------------------``B
+# A s_b
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+'''
+
+import inkex
+import simplestyle, sys, simplepath
+from math import *
+import gettext
+_ = gettext.gettext
+
+#DRAWING ROUTINES
+
+#draw an SVG triangle given in trilinar coords
+def draw_SVG_circle(rad, centre, params, style, name, parent):#draw an SVG circle with a given radius as trilinear coordinates
+ if rad == 0: #we want a dot
+ r = style.d_rad #get the dot width from the style
+ circ_style = { 'stroke':style.d_col, 'stroke-width':str(style.d_th), 'fill':style.d_fill }
+ else:
+ r = rad #use given value
+ circ_style = { 'stroke':style.c_col, 'stroke-width':str(style.c_th), 'fill':style.c_fill }
+
+ cx,cy = get_cartesian_pt(centre, params)
+ circ_attribs = {'style':simplestyle.formatStyle(circ_style),
+ inkex.addNS('label','inkscape'):name,
+ 'cx':str(cx), 'cy':str(cy),
+ 'r':str(r)}
+ inkex.etree.SubElement(parent, inkex.addNS('circle','svg'), circ_attribs )
+
+#draw an SVG triangle given in trilinar coords
+def draw_SVG_tri(vert_mat, params, style, name, parent):
+ p1,p2,p3 = get_cartesian_tri(vert_mat, params) #get the vertex matrix in cartesian points
+ tri_style = { 'stroke': style.l_col, 'stroke-width':str(style.l_th), 'fill': style.l_fill }
+ tri_attribs = {'style':simplestyle.formatStyle(tri_style),
+ inkex.addNS('label','inkscape'):name,
+ 'd':'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
+
+def distance( (x0,y0),(x1,y1)):#find the pythagorean distance
+ return sqrt( (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1) )
+
+def vector_from_to( (x0,y0),(x1,y1) ):#get the vector from (x0,y0) to (x1,y1)
+ return (x1-x0, y1-y0)
+
+def get_cartesian_pt( t, p):#get the cartesian coordinates from a trilinear set
+ denom = p[0][0]*t[0] + p[0][1]*t[1] + p[0][2]*t[2]
+ c1 = p[0][1]*t[1]/denom
+ c2 = p[0][2]*t[2]/denom
+ return ( c1*p[2][1][0]+c2*p[2][0][0], c1*p[2][1][1]+c2*p[2][0][1] )
+
+def get_cartesian_tri( ((t11,t12,t13),(t21,t22,t23),(t31,t32,t33)), params):#get the cartesian points from a trilinear vertex matrix
+ p1=get_cartesian_pt( (t11,t12,t13), params )
+ p2=get_cartesian_pt( (t21,t22,t23), params )
+ p3=get_cartesian_pt( (t31,t32,t33), params )
+ return (p1,p2,p3)
+
+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)
+
+def translate_string(string, os): #translates s_a, a_a, etc to params[x][y], with cyclic offset
+ string = string.replace('s_a', 'params[0]['+str((os+0)%3)+']') #replace with ref. to the relvant values,
+ string = string.replace('s_b', 'params[0]['+str((os+1)%3)+']') #cycled by i
+ string = string.replace('s_c', 'params[0]['+str((os+2)%3)+']')
+ string = string.replace('a_a', 'params[1]['+str((os+0)%3)+']')
+ string = string.replace('a_b', 'params[1]['+str((os+1)%3)+']')
+ string = string.replace('a_c', 'params[1]['+str((os+2)%3)+']')
+ string = string.replace('area','params[4][0]')
+ string = string.replace('semiperim','params[4][1]')
+ return string
+
+def pt_from_tcf( tcf , params):#returns a trilinear triplet from a triangle centre function
+ trilin_pts=[]#will hold the final points
+ for i in range(3):
+ temp = tcf #read in the tcf
+ temp = translate_string(temp, i)
+ func = eval('lambda params: ' + temp.strip('"')) #the function leading to the trilinar element
+ trilin_pts.append(func(params))#evaluate the function for the first trilinear element
+ return trilin_pts
+
+#SVG DATA PROCESSING
+
+def get_n_points_from_path( node, n):#returns a list of first n points (x,y) in an SVG path-representing node
+
+ p = simplepath.parsePath(node.get('d')) #parse the path
+
+ xi = [] #temporary storage for x and y (will combine at end)
+ yi = []
+
+ for cmd,params in p: #a parsed path is made up of (cmd, params) pairs
+ defs = simplepath.pathdefs[cmd]
+ for i in range(defs[1]):
+ if defs[3][i] == 'x' and len(xi) < n:#only collect the first three
+ xi.append(params[i])
+ elif defs[3][i] == 'y' and len(yi) < n:#only collect the first three
+ yi.append(params[i])
+
+ if len(xi) == n and len(yi) == n:
+ points = [] # returned pairs of points
+ for i in range(n):
+ points.append( [ xi[i], yi[i] ] )
+ else:
+ #inkex.errormsg(_('Error: Not enough nodes to gather coordinates.')) #fail silently and exit, rather than invoke an error console
+ return [] #return a blank
+
+ return points
+
+#EXTRA MATHS FUNCTIONS
+def sec(x):#secant(x)
+ if x == pi/2 or x==-pi/2 or x == 3*pi/2 or x == -3*pi/2: #sec(x) is undefined
+ return 100000000000
+ else:
+ return 1/cos(x)
+
+def csc(x):#cosecant(x)
+ if x == 0 or x==pi or x==2*pi or x==-2*pi: #csc(x) is undefined
+ return 100000000000
+ else:
+ return 1/sin(x)
+
+def cot(x):#cotangent(x)
+ if x == 0 or x==pi or x==2*pi or x==-2*pi: #cot(x) is undefined
+ return 100000000000
+ else:
+ return 1/tan(x)
+
+def report_properties( params ):#report to the Inkscape console using errormsg
+ inkex.errormsg(_("Side Length 'a'/px: " + str( params[0][0] ) ))
+ inkex.errormsg(_("Side Length 'b'/px: " + str( params[0][1] ) ))
+ inkex.errormsg(_("Side Length 'c'/px: " + str( params[0][2] ) ))
+ inkex.errormsg(_("Angle 'A'/radians:" + str( params[1][0] ) ))
+ inkex.errormsg(_("Angle 'B'/radians: " + str( params[1][1] ) ))
+ inkex.errormsg(_("Angle 'C'/radians: " + str( params[1][2] ) ))
+ inkex.errormsg(_("Semiperimeter/px: " + str( params[4][1] ) ))
+ inkex.errormsg(_("Area /px^2: " + str( params[4][0] ) ))
+ return
+
+
+class Style(object): #container for style information
+ def __init__(self, options):
+ #dot markers
+ self.d_rad = 4 #dot marker radius
+ self.d_th = 2 #stroke width
+ self.d_fill= '#aaaaaa' #fill colour
+ self.d_col = '#000000' #stroke colour
+
+ #lines
+ self.l_th = 2
+ self.l_fill= 'none'
+ self.l_col = '#000000'
+
+ #circles
+ self.c_th = 2
+ self.c_fill= 'none'
+ self.c_col = '#000000'
+
+class Draw_From_Triangle(inkex.Effect):
+ def __init__(self):
+ inkex.Effect.__init__(self)
+ self.OptionParser.add_option("--tab",
+ action="store", type="string",
+ dest="tab", default="sampling",
+ help="The selected UI-tab when OK was pressed")
+#PRESET POINT OPTIONS
+ self.OptionParser.add_option("--circumcircle",
+ action="store", type="inkbool",
+ dest="do_circumcircle", default=False)
+ self.OptionParser.add_option("--circumcentre",
+ action="store", type="inkbool",
+ dest="do_circumcentre", default=False)
+ self.OptionParser.add_option("--incircle",
+ action="store", type="inkbool",
+ dest="do_incircle", default=False)
+ self.OptionParser.add_option("--incentre",
+ action="store", type="inkbool",
+ dest="do_incentre", default=False)
+ self.OptionParser.add_option("--contact_tri",
+ action="store", type="inkbool",
+ dest="do_contact_tri", default=False)
+ self.OptionParser.add_option("--excircles",
+ action="store", type="inkbool",
+ dest="do_excircles", default=False)
+ self.OptionParser.add_option("--excentres",
+ action="store", type="inkbool",
+ dest="do_excentres", default=False)
+ self.OptionParser.add_option("--extouch_tri",
+ action="store", type="inkbool",
+ dest="do_extouch_tri", default=False)
+ self.OptionParser.add_option("--excentral_tri",
+ action="store", type="inkbool",
+ dest="do_excentral_tri", default=False)
+ self.OptionParser.add_option("--orthocentre",
+ action="store", type="inkbool",
+ dest="do_orthocentre", default=False)
+ self.OptionParser.add_option("--orthic_tri",
+ action="store", type="inkbool",
+ dest="do_orthic_tri", default=False)
+ self.OptionParser.add_option("--altitudes",
+ action="store", type="inkbool",
+ dest="do_altitudes", default=False)
+ self.OptionParser.add_option("--anglebisectors",
+ action="store", type="inkbool",
+ dest="do_anglebisectors", default=False)
+ self.OptionParser.add_option("--centroid",
+ action="store", type="inkbool",
+ dest="do_centroid", default=False)
+ self.OptionParser.add_option("--ninepointcentre",
+ action="store", type="inkbool",
+ dest="do_ninepointcentre", default=False)
+ self.OptionParser.add_option("--ninepointcircle",
+ action="store", type="inkbool",
+ dest="do_ninepointcircle", default=False)
+ self.OptionParser.add_option("--symmedians",
+ action="store", type="inkbool",
+ dest="do_symmedians", default=False)
+ self.OptionParser.add_option("--sym_point",
+ action="store", type="inkbool",
+ dest="do_sym_pt", default=False)
+ self.OptionParser.add_option("--sym_tri",
+ action="store", type="inkbool",
+ dest="do_sym_tri", default=False)
+ self.OptionParser.add_option("--gergonne_pt",
+ action="store", type="inkbool",
+ dest="do_gergonne_pt", default=False)
+ self.OptionParser.add_option("--nagel_pt",
+ action="store", type="inkbool",
+ dest="do_nagel_pt", default=False)
+#CUSTOM POINT OPTIONS
+ self.OptionParser.add_option("--mode",
+ action="store", type="string",
+ dest="mode", default='trilin')
+ self.OptionParser.add_option("--cust_str",
+ action="store", type="string",
+ dest="cust_str", default='s_a')
+ self.OptionParser.add_option("--cust_pt",
+ action="store", type="inkbool",
+ dest="do_cust_pt", default=False)
+ self.OptionParser.add_option("--cust_radius",
+ action="store", type="inkbool",
+ dest="do_cust_radius", default=False)
+ self.OptionParser.add_option("--radius",
+ action="store", type="string",
+ dest="radius", default='s_a')
+ self.OptionParser.add_option("--isogonal_conj",
+ action="store", type="inkbool",
+ dest="do_isogonal_conj", default=False)
+ self.OptionParser.add_option("--isotomic_conj",
+ action="store", type="inkbool",
+ dest="do_isotomic_conj", default=False)
+ self.OptionParser.add_option("--report",
+ action="store", type="inkbool",
+ dest="report", default=False)
+
+
+ def effect(self):
+
+ so = self.options #shorthand
+
+ pts = [] #initialise in case nothing is selected and following loop is not executed
+ for id, node in self.selected.iteritems():
+ if node.tag == inkex.addNS('path','svg'):
+ pts = get_n_points_from_path( node, 3 ) #find the (x,y) coordinates of the first 3 points of the path
+
+
+ if len(pts) == 3: #if we have right number of nodes, else skip and end program
+ st = Style(so)#style for dots, lines and circles
+
+ #CREATE A GROUP TO HOLD ALL GENERATED ELEMENTS IN
+ #Hold relative to point A (pt[0])
+ group_translation = 'translate(' + str( pts[0][0] ) + ','+ str( pts[0][1] ) + ')'
+ group_attribs = {inkex.addNS('label','inkscape'):'TriangleElements',
+ 'transform':group_translation }
+ layer = inkex.etree.SubElement(self.current_layer, 'g', group_attribs)
+
+ #GET METRICS OF THE TRIANGLE
+ #vertices in the local coordinates (set pt[0] to be the origin)
+ vtx = [[0,0],
+ [pts[1][0]-pts[0][0],pts[1][1]-pts[0][1]],
+ [pts[2][0]-pts[0][0],pts[2][1]-pts[0][1]]]
+
+ s_a = distance(vtx[1],vtx[2])#get the scalar side lengths
+ s_b = distance(vtx[0],vtx[1])
+ s_c = distance(vtx[0],vtx[2])
+ sides=(s_a,s_b,s_c)#side list for passing to functions easily and for indexing
+
+ a_a = angle_from_3_sides(s_b, s_c, s_a)#angles in radians
+ a_b = angle_from_3_sides(s_a, s_c, s_b)
+ a_c = angle_from_3_sides(s_a, s_b, s_c)
+ angles=(a_a,a_b,a_c)
+
+ ab = vector_from_to(vtx[0], vtx[1]) #vector from a to b
+ ac = vector_from_to(vtx[0], vtx[2]) #vector from a to c
+ bc = vector_from_to(vtx[1], vtx[2]) #vector from b to c
+ vecs= (ab,ac) # vectors for finding cartesian point from trilinears
+
+ semiperim = (s_a+s_b+s_c)/2.0 #semiperimeter
+ area = sqrt( semiperim*(semiperim-s_a)*(semiperim-s_b)*(semiperim-s_c) ) #area of the triangle by heron's formula
+ uvals = (area, semiperim) #useful values
+
+ params = (sides, angles, vecs, vtx, uvals) #all useful triangle parameters in one object
+
+ if so.report:
+ report_properties( params )
+
+ #BEGIN DRAWING
+ if so.do_circumcentre or so.do_circumcircle:
+ r = s_a*s_b*s_c/(4*area)
+ pt = (cos(a_a),cos(a_b),cos(a_c))
+ if so.do_circumcentre:
+ draw_SVG_circle(0, pt, params, st, 'Circumcentre', layer)
+ if so.do_circumcircle:
+ draw_SVG_circle(r, pt, params, st, 'Circumcircle', layer)
+
+ if so.do_incentre or so.do_incircle:
+ pt = [1,1,1]
+ if so.do_incentre:
+ draw_SVG_circle(0, pt, params, st, 'Incentre', layer)
+ if so.do_incircle:
+ r = area/semiperim
+ draw_SVG_circle(r, pt, params, st, 'Incircle', layer)
+
+ if so.do_contact_tri:
+ t1 = s_b*s_c/(-s_a+s_b+s_c)
+ t2 = s_a*s_c/( s_a-s_b+s_c)
+ t3 = s_a*s_b/( s_a+s_b-s_c)
+ v_mat = ( (0,t2,t3),(t1,0,t3),(t1,t2,0))
+ draw_SVG_tri(v_mat, params, st,'ContactTriangle',layer)
+
+ if so.do_extouch_tri:
+ t1 = (-s_a+s_b+s_c)/s_a
+ t2 = ( s_a-s_b+s_c)/s_b
+ t3 = ( s_a+s_b-s_c)/s_c
+ v_mat = ( (0,t2,t3),(t1,0,t3),(t1,t2,0))
+ draw_SVG_tri(v_mat, params, st,'ExtouchTriangle',layer)
+
+ if so.do_orthocentre:
+ pt = pt_from_tcf('cos(a_b)*cos(a_c)', params)
+ draw_SVG_circle(0, pt, params, st, 'Orthocentre', layer)
+
+ if so.do_orthic_tri:
+ v_mat = [[0,sec(a_b),sec(a_c)],[sec(a_a),0,sec(a_c)],[sec(a_a),sec(a_b),0]]
+ draw_SVG_tri(v_mat, params, st,'OrthicTriangle',layer)
+
+ if so.do_centroid:
+ pt = [1/s_a,1/s_b,1/s_c]
+ draw_SVG_circle(0, pt, params, st, 'Centroid', layer)
+
+ if so.do_ninepointcentre or so.do_ninepointcircle:
+ pt = [cos(a_b-a_c),cos(a_c-a_a),cos(a_a-a_b)]
+ if so.do_ninepointcentre:
+ draw_SVG_circle(0, pt, params, st, 'NinePointCentre', layer)
+ if so.do_ninepointcircle:
+ r = s_a*s_b*s_c/(8*area)
+ draw_SVG_circle(r, pt, params, st, 'NinePointCircle', layer)
+
+ if so.do_altitudes:
+ v_mat = [[0,sec(a_b),sec(a_c)],[sec(a_a),0,sec(a_c)],[sec(a_a),sec(a_b),0]]
+ draw_vertex_lines( v_mat, params, st, 'Altitude', layer)
+
+ if so.do_anglebisectors:
+ v_mat = ((0,1,1),(1,0,1),(1,1,0))
+ draw_vertex_lines(v_mat,params, st, 'AngleBisectors', layer)
+
+ if so.do_excircles or so.do_excentres or so.do_excentral_tri:
+ v_mat = ((-1,1,1),(1,-1,1),(1,1,-1))
+ if so.do_excentral_tri:
+ draw_SVG_tri(v_mat, params, st,'ExcentralTriangle',layer)
+ for i in range(3):
+ if so.do_excircles:
+ r = area/(semiperim-sides[i])
+ draw_SVG_circle(r, v_mat[i], params, st, 'Excircle:'+str(i), layer)
+ if so.do_excentres:
+ draw_SVG_circle(0, v_mat[i], params, st, 'Excentre:'+str(i), layer)
+
+ if so.do_sym_tri or so.do_symmedians:
+ v_mat = ((0,s_b,s_c), (s_a, 0, s_c), (s_a, s_b, 0))
+ if so.do_sym_tri:
+ draw_SVG_tri(v_mat, params, st,'SymmedialTriangle',layer)
+ if so.do_symmedians:
+ draw_vertex_lines(v_mat,params, st, 'Symmedian', layer)
+
+ if so.do_sym_pt:
+ pt = (s_a,s_b,s_c)
+ draw_SVG_circle(0, pt, params, st, 'SymmmedianPoint', layer)
+
+ if so.do_gergonne_pt:
+ pt = pt_from_tcf('1/(s_a*(s_b+s_c-s_a))', params)
+ draw_SVG_circle(0, pt, params, st, 'GergonnePoint', layer)
+
+ if so.do_nagel_pt:
+ pt = pt_from_tcf('(s_b+s_c-s_a)/s_a', params)
+ draw_SVG_circle(0, pt, params, st, 'NagelPoint', layer)
+
+ if so.do_cust_pt or so.do_cust_radius or so.do_isogonal_conj or so.do_isotomic_conj:
+ pt = []#where we will store the point in trilinears
+ if so.mode == 'trilin':#if we are receiving from trilinears
+ for i in range(3):
+ strings = so.cust_str.split(':')#get split string
+ strings[i] = translate_string(strings[i],0)
+ func = eval('lambda params: ' + strings[i].strip('"')) #the function leading to the trilinar element
+ pt.append(func(params)) #evaluate the function for the trilinear element
+ else:#we need a triangle function
+ string = so.cust_str #don't need to translate, as the pt_from_tcf function does that for us
+ pt = pt_from_tcf(string, params)#get the point from the tcf directly
+
+ if so.do_cust_pt:#draw the point
+ draw_SVG_circle(0, pt, params, st, 'CustomTrilinearPoint', layer)
+ if so.do_cust_radius:#draw the circle with given radius
+ strings = translate_string(so.radius,0)
+ func = eval('lambda params: ' + strings.strip('"')) #the function leading to the radius
+ r = func(params)
+ draw_SVG_circle(r, pt, params, st, 'CustomTrilinearCircle', layer)
+ if so.do_isogonal_conj:
+ isogonal=[0,0,0]
+ for i in range (3):
+ isogonal[i] = 1/pt[i]
+ draw_SVG_circle(0, isogonal, params, st, 'CustomIsogonalConjugate', layer)
+ if so.do_isotomic_conj:
+ isotomic=[0,0,0]
+ for i in range (3):
+ isotomic[i] = 1/( params[0][i]*params[0][i]*pt[i] )
+ draw_SVG_circle(0, isotomic, params, st, 'CustomIsotomicConjugate', layer)
+
+
+e = Draw_From_Triangle()
+e.affect()
+
diff --git a/share/extensions/dxf_outlines.py b/share/extensions/dxf_outlines.py
index 5826be693..ca3777627 100755
--- a/share/extensions/dxf_outlines.py
+++ b/share/extensions/dxf_outlines.py
@@ -22,12 +22,14 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import inkex, simplepath, cubicsuperpath, dxf_templates, math
+import gettext
+_ = gettext.gettext
try:
from numpy import *
from numpy.linalg import solve
except:
- inkex.errormsg("Failed to import the numpy or numpy.linalg modules. These modules are required by this extension. Please install them and try again.")
+ inkex.errormsg(_("Failed to import the numpy or numpy.linalg modules. These modules are required by this extension. Please install them and try again."))
inkex.sys.exit()
def pointdistance((x1,y1),(x2,y2)):
diff --git a/share/extensions/polyhedron_3d.inx b/share/extensions/polyhedron_3d.inx
index 3ef24399e..17c80814e 100644
--- a/share/extensions/polyhedron_3d.inx
+++ b/share/extensions/polyhedron_3d.inx
@@ -8,21 +8,21 @@
<page name="common" _gui-text="Model File">
<param name="obj" type="optiongroup" appearance="minimal" _gui-text="Object:">
<_option value="cube">Cube</_option>
- <_option value="t_cube">Truncated Cube</_option>
- <_option value="sn_cube">Snub Cube</_option>
+ <_option value="trunc_cube">Truncated Cube</_option>
+ <_option value="snub_cube">Snub Cube</_option>
<_option value="cuboct">Cuboctohedron</_option>
<_option value="tet">Tetrahedron</_option>
- <_option value="t_tet">Truncated Tetrahedron</_option>
+ <_option value="trunc_tet">Truncated Tetrahedron</_option>
<_option value="oct">Octahedron</_option>
- <_option value="t_oct">Truncated Octahedron</_option>
+ <_option value="trunc_oct">Truncated Octahedron</_option>
<_option value="icos">Icosahedron</_option>
- <_option value="t_icos">Truncated Icosahedron</_option>
- <_option value="s_t_icos">Small Triambic Icosahedron</_option>
+ <_option value="trunc_icos">Truncated Icosahedron</_option>
+ <_option value="small_triam_icos">Small Triambic Icosahedron</_option>
<_option value="dodec">Dodecahedron</_option>
- <_option value="t_dodec">Truncated Dodecahedron</_option>
- <_option value="sn_dodec">Snub Dodecahedron</_option>
- <_option value="g_dodec">Great Dodecahedron</_option>
- <_option value="g_s_dodec">Great Stellated Dodecahedron</_option>
+ <_option value="trunc_dodec">Truncated Dodecahedron</_option>
+ <_option value="snub_dodec">Snub Dodecahedron</_option>
+ <_option value="great_dodec">Great Dodecahedron</_option>
+ <_option value="great_stel_dodec">Great Stellated Dodecahedron</_option>
<_option value="from_file">Load From File</_option>
</param>
<param name="spec_file" type="string" _gui-text="Filename:">great_rhombicuboct.obj</param>
@@ -84,7 +84,6 @@
<_option value="max">Maximum</_option>
<_option value="min">Minimum</_option>
<_option value="mean">Mean</_option></param>
- <param name="norm" type="boolean" _gui-text="Report Normal Vector Information">0</param>
</page>
</param>
<effect>
diff --git a/share/extensions/polyhedron_3d.py b/share/extensions/polyhedron_3d.py
index fca66b113..a6a33ccdf 100644
--- a/share/extensions/polyhedron_3d.py
+++ b/share/extensions/polyhedron_3d.py
@@ -26,12 +26,12 @@ Copyright (C) 2007 John Beard john.j.beard@gmail.com
#f 1 2 3
#Edges are given by a list of vertices. These will be broken down
-#into adjacent pairs. Each edge can connect only two vertices
+#into adjacent pairs automatically.
#l 1 2 3
#Faces are rendered according to the painter's algorithm and perhaps
#back-face culling, if selected. The parameter to sort the faces by
-#is user-selectable
+#is user-selectable between max, min and average z-value of the vertices
######LICENCE#######
This program is free software; you can redistribute it and/or modify
@@ -50,16 +50,23 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import inkex
-import simplestyle, sys, simplepath, re
+import simplestyle, sys, re
from math import *
-import gettext
-_ = gettext.gettext
try:
from numpy import *
except:
inkex.errormsg(_("Failed to import the numpy module. This module is required by this extension. Please install them and try again. On a Debian-like system this can be done with the command, sudo apt-get install python-numpy."))
sys.exit()
+#FILE IO ROUTINES
+def get_filename(self_options):
+ if self_options.obj == 'from_file':
+ file = self_options.spec_file
+ else:
+ file = self_options.obj + '.obj'
+
+ return file
+
def objfile(name):
import os.path
if __name__ == '__main__':
@@ -75,30 +82,25 @@ def get_obj_data(obj, name):
#regular expressions
getname = '(.[nN]ame:\\s*)(.*)'
- floating = '([\-\+\\d*\.e]*)'
+ floating = '([\-\+\\d*\.e]*)' #a possibly non-integer number, with +/- and exponent.
getvertex = '(v\\s+)'+floating+'\\s+'+floating+'\\s+'+floating
getedgeline = '(l\\s+)(.*)'
getfaceline = '(f\\s+)(.*)'
- getnextint = '(\\d+)([/\\d]*)(.*)'#we need to deal with 133\343\123 or 123\\456 as one item
-
- obj.vtx = []
- obj.edg = []
- obj.fce = []
- obj.name=''
+ getnextint = '(\\d+)([/\\d]*)(.*)'#we need to deal with 123\343\123 or 123\\456 as equivalent to 123 (we are ignoring the other options in the obj file)
for line in infile:
- if line[0]=='#': #we have a comment line
- m = re.search(getname, line)
+ if line[0]=='#': #we have a comment line
+ m = re.search(getname, line) #check to see if this line contains a name
if m:
- obj.name = m.group(2)
- elif line[0:1] == 'v': #we have a vertex (maybe)
- m = re.search(getvertex, line)
- if m: #we have a valid vertex
+ obj.name = m.group(2) #if it does, set the property
+ elif line[0] == 'v': #we have a vertex (maybe)
+ m = re.search(getvertex, line) #check to see if this line contains a valid vertex
+ if m: #we have a valid vertex
obj.vtx.append( [float(m.group(2)), float(m.group(3)), float(m.group(4)) ] )
- elif line[0:1] == 'l':#we have a line (maybe)
- m = re.search(getedgeline, line)
- if m:#we have a line beginning 'l '
- vtxlist = []#buffer
+ elif line[0] == 'l': #we have a line (maybe)
+ m = re.search(getedgeline, line) #check to see if this line begins 'l '
+ if m: #we have a line beginning 'l '
+ vtxlist = [] #buffer
while line:
m2 = re.search(getnextint, line)
if m2:
@@ -109,9 +111,9 @@ def get_obj_data(obj, name):
if len(vtxlist) > 1:#we need at least 2 vertices to make an edge
for i in range (len(vtxlist)-1):#we can have more than one vertex per line - get adjacent pairs
obj.edg.append( ( vtxlist[i], vtxlist[i+1] ) )#get the vertex pair between that vertex and the next
- elif line[0:1] == 'f':#we have a face (maybe)
+ elif line[0] == 'f': #we have a face (maybe)
m = re.search(getfaceline, line)
- if m:#we have a line beginning 'l '
+ if m: #we have a line beginning 'f '
vtxlist = []#buffer
while line:
m2 = re.search(getnextint, line)
@@ -120,12 +122,14 @@ def get_obj_data(obj, name):
line = m2.group(3)#remainder
else:
line = None
- if len(vtxlist) > 2:#we need at least 3 vertices to make an edge
+ if len(vtxlist) > 2: #we need at least 3 vertices to make an edge
obj.fce.append(vtxlist)
- if obj.name == '':#no name was found, use filename, without extension
+ if obj.name == '':#no name was found, use filename, without extension (.obj)
obj.name = name[0:-4]
+#RENDERING AND SVG OUTPUT FUNCTIONS
+
def draw_SVG_dot((cx, cy), st, name, parent):
style = { 'stroke': '#000000', 'stroke-width':str(st.th), 'fill': st.fill, 'stroke-opacity':st.s_opac, 'fill-opacity':st.f_opac}
circ_attribs = {'style':simplestyle.formatStyle(style),
@@ -135,8 +139,7 @@ def draw_SVG_dot((cx, cy), st, name, parent):
inkex.etree.SubElement(parent, inkex.addNS('circle','svg'), circ_attribs )
def draw_SVG_line((x1, y1),(x2, y2), st, name, parent):
- #sys.stderr.write(str(p1))
- style = { 'stroke': '#000000', 'stroke-width':str(st.th)}
+ style = { 'stroke': '#000000', 'stroke-width':str(st.th), 'stroke-linecap':st.linecap}
line_attribs = {'style':simplestyle.formatStyle(style),
inkex.addNS('label','inkscape'):name,
'd':'M '+str(x1)+','+str(-y1)+' L '+str(x2)+','+str(-y2)}
@@ -157,12 +160,95 @@ def draw_SVG_poly(pts, face, st, name, parent):
inkex.addNS('label','inkscape'):name,'d': d}
inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs )
+def draw_edges( edge_list, pts, st, parent ):
+ for edge in edge_list:#for every edge
+ pt_1 = pts[ edge[0]-1 ][0:2] #the point at the start
+ pt_2 = pts[ edge[1]-1 ][0:2] #the point at the end
+ name = 'Edge'+str(edge[0])+'-'+str(edge[1])
+ draw_SVG_line(pt_1,pt_2,st, name, parent)#plot edges
+
+def draw_faces( faces_data, pts, obj, shading, fill_col,st, parent):
+ for face in faces_data:#for every polygon that has been sorted
+ if shading:
+ st.fill = get_darkened_colour(fill_col, face[1]/pi)#darken proportionally to angle to lighting vector
+ else:
+ st.fill = get_darkened_colour(fill_col, 1)#do not darken colour
+
+ face_no = face[3]#the number of the face to draw
+ draw_SVG_poly(pts, obj.fce[ face_no ], st, 'Face:'+str(face_no), parent)
+
+def get_darkened_colour( (r,g,b), factor):
+#return a hex triplet of colour, reduced in lightness proportionally to a value between 0 and 1
+ return '#' + "%02X" % floor( factor*r ) \
+ + "%02X" % floor( factor*g ) \
+ + "%02X" % floor( factor*b ) #make the colour string
+
+def make_rotation_log(options):
+#makes a string recording the axes and angles of each roation, so an object can be repeated
+ return options.r1_ax+str('%.2f'%options.r1_ang)+':'+\
+ options.r2_ax+str('%.2f'%options.r2_ang)+':'+\
+ options.r3_ax+str('%.2f'%options.r3_ang)+':'+\
+ options.r1_ax+str('%.2f'%options.r4_ang)+':'+\
+ options.r2_ax+str('%.2f'%options.r5_ang)+':'+\
+ options.r3_ax+str('%.2f'%options.r6_ang)
+
+#MATHEMATICAL FUNCTIONS
+def get_angle( vector1, vector2 ): #returns the angle between two vectors
+ return acos( dot(vector1, vector2) )
+
+def length(vector):#return the pythagorean length of a vector
+ return sqrt(dot(vector,vector))
+
+def normalise(vector):#return the unit vector pointing in the same direction as the argument
+ return vector / length(vector)
+
def get_normal( pts, face): #returns the normal vector for the plane passing though the first three elements of face of pts
#n = pt[0]->pt[1] x pt[0]->pt[3]
a = (array(pts[ face[0]-1 ]) - array(pts[ face[1]-1 ]))
b = (array(pts[ face[0]-1 ]) - array(pts[ face[2]-1 ]))
return cross(a,b).flatten()
+
+def get_unit_normal(pts, face, cw_wound): #returns the unit normal for the plane passing through the first three points of face, taking account of winding
+ if cw_wound:
+ winding = -1 #if it is clockwise wound, reverse the vecotr direction
+ else:
+ winding = 1 #else leave alone
+
+ return winding*normalise(get_normal(pts, face))
+
+def rotate( matrix, angle, axis ):#choose the correct rotation matrix to use
+ if axis == 'x':
+ matrix = rot_x(matrix, angle)
+ elif axis == 'y':
+ matrix = rot_y(matrix, angle)
+ elif axis == 'z':
+ matrix = rot_z(matrix, angle)
+ return matrix
+
+def rot_z( matrix , a):#rotate around the z-axis by a radians
+ trans_mat = mat(array( [[ cos(a) , -sin(a) , 0 ],
+ [ sin(a) , cos(a) , 0 ],
+ [ 0 , 0 , 1 ]]))
+ return trans_mat*matrix
+
+def rot_y( matrix , a):#rotate around the y-axis by a radians
+ trans_mat = mat(array( [[ cos(a) , 0 , sin(a) ],
+ [ 0 , 1 , 0 ],
+ [-sin(a) , 0 , cos(a) ]]))
+ return trans_mat*matrix
+def rot_x( matrix , a):#rotate around the x-axis by a radians
+ trans_mat = mat(array( [[ 1 , 0 , 0 ],
+ [ 0 , cos(a) ,-sin(a) ],
+ [ 0 , sin(a) , cos(a) ]]))
+ return trans_mat*matrix
+
+def get_transformed_pts( vtx_list, trans_mat):#translate the points according to the matrix
+ transformed_pts = []
+ for vtx in vtx_list:
+ transformed_pts.append((trans_mat * mat(vtx).T).T.tolist()[0] )#transform the points at add to the list
+ return transformed_pts
+
def get_max_z(pts, face): #returns the largest z_value of any point in the face
max_z = pts[ face[0]-1 ][2]
for i in range(1, len(face)):
@@ -183,54 +269,71 @@ def get_cent_z(pts, face): #returns the centroid z_value of any point in the fac
sum += pts[ face[i]-1 ][2]
return sum/len(face)
-def length(vector):#return the pythagorean length of a vector
- return sqrt(dot(vector,vector))
-
-def rot_z( matrix , a):
- trans_mat = mat(array( [[ cos(a) , -sin(a) , 0 ],
- [ sin(a) , cos(a) , 0 ],
- [ 0 , 0 , 1 ]]))
- return trans_mat*matrix
+def get_z_sort_param(pts, face, method): #returns the z-sorting parameter specified by 'method' ('max', 'min', 'cent')
+ z_sort_param = ''
+ if method == 'max':
+ z_sort_param = get_max_z(pts, face)
+ elif method == 'min':
+ z_sort_param = get_min_z(pts, face)
+ else:
+ z_sort_param = get_cent_z(pts, face)
+ return z_sort_param
+
+#OBJ DATA MANIPULATION
+def remove_duplicates(list):#removes the duplicates from a list
+ list.sort()#sort the list
+
+ last = list[-1]
+ for i in range(len(list)-2, -1, -1):
+ if last==list[i]:
+ del list[i]
+ else:
+ last = list[i]
+ return list
-def rot_y( matrix , a):
- trans_mat = mat(array( [[ cos(a) , 0 , sin(a) ],
- [ 0 , 1 , 0 ],
- [-sin(a) , 0 , cos(a) ]]))
- return trans_mat*matrix
-
-def rot_x( matrix , a):
- trans_mat = mat(array( [[ 1 , 0 , 0 ],
- [ 0 , cos(a) ,-sin(a) ],
- [ 0 , sin(a) , cos(a) ]]))
- return trans_mat*matrix
-
def make_edge_list(face_list):#make an edge vertex list from an existing face vertex list
edge_list = []
for i in range(len(face_list)):#for every face
edges = len(face_list[i]) #number of edges around that face
for j in range(edges):#for every vertex in that face
- edge_list.append( [face_list[i][j], face_list[i][(j+1)%edges] ] )#get the vertex pair between that vertex and the next
-
- for i in range(len(edge_list)):
- edge_list[i].sort()#sort the entries of the entries
- edge_list.sort()#sort the list
-
- last = edge_list[-1] #delete duplicate entries
- for i in range(len(edge_list)-2, -1, -1):
- if last==edge_list[i]:
- del edge_list[i]
- else:
- last=edge_list[i]
- return edge_list
+ new_edge = [face_list[i][j], face_list[i][(j+1)%edges] ]
+ new_edge.sort() #put in ascending order of vertices (to ensure we spot duplicates)
+ edge_list.append( new_edge )#get the vertex pair between that vertex and the next
+
+ return remove_duplicates(edge_list)
class Style(object): #container for style information
- def __init__(self):
- None
+ def __init__(self,options):
+ self.th = options.th
+ self.fill= '#ff0000'
+ self.col = '#000000'
+ self.r = 2
+ self.f_opac = str(options.f_opac/100.0)
+ self.s_opac = str(options.s_opac/100.0)
+ self.linecap = 'round'
+ self.linejoin = 'round'
class Obj(object): #a 3d object defined by the vertices and the faces (eg a polyhedron)
#edges can be generated from this information
def __init__(self):
- None
+ self.vtx = []
+ self.edg = []
+ self.fce = []
+ self.name=''
+
+ def set_type(self, options):
+ if options.type == 'face':
+ if self.fce != []:
+ self.type = 'face'
+ else:
+ inkex.errormsg(_('No face data found in specified file\n'))
+ self.type = 'error'
+ else:
+ if self.edg != []:
+ self.type = 'edge'
+ else:
+ inkex.errormsg(_('No edge data found in specified file\n'))
+ obj.type = 'error'
class Poly_3D(inkex.Effect):
def __init__(self):
@@ -338,170 +441,75 @@ class Poly_3D(inkex.Effect):
def effect(self):
- so = self.options
+ so = self.options#shorthand
- st = Style()
- st.th = so.th
- st.fill= '#ff0000'
- st.col = '#000000'
- st.r = 2
- st.f_opac = str(so.f_opac/100.0)
- st.s_opac = str(so.s_opac/100.0)
- st.linecap = 'round'
- st.linejoin = 'round'
+ #INITIALISE AND LOAD DATA
- file = ''
- if so.obj == 'cube':
- file = 'cube.obj'
- elif so.obj == 't_cube':
- file = 'trunc_cube.obj'
- elif so.obj == 'sn_cube':
- file = 'snub_cube.obj'
- elif so.obj == 'cuboct':
- file = 'cuboct.obj'
- elif so.obj == 'tet':
- file = 'tet.obj'
- elif so.obj == 't_tet':
- file = 'trunc_tet.obj'
- elif so.obj == 'oct':
- file = 'oct.obj'
- elif so.obj == 't_oct':
- file = 'trunc_oct.obj'
- elif so.obj == 'icos':
- file = 'icos.obj'
- elif so.obj == 't_icos':
- file = 'trunc_icos.obj'
- elif so.obj == 's_t_icos':
- file = 'small_triam_icos.obj'
- elif so.obj == 'g_s_dodec':
- file = 'great_stel_dodec.obj'
- elif so.obj == 'dodec':
- file = 'dodec.obj'
- elif so.obj == 'sn_dodec':
- file = 'snub_dodec.obj'
- elif so.obj == 'g_dodec':
- file = 'great_dodec.obj'
- elif so.obj == 't_dodec':
- file = 'trunc_dodec.obj'
- elif so.obj == 'from_file':
- file = so.spec_file
-
obj = Obj() #create the object
- get_obj_data(obj, file)
+ file = get_filename(so)#get the file to load data from
+ get_obj_data(obj, file)#load data from the obj file
+ obj.set_type(so)#set the type (face or edge) as per the settings
- obj.type=''
- if so.type == 'face':
- if len(obj.fce) > 0:
- obj.type = 'face'
- else:
- sys.stderr.write('No face data found in specified file\n')
- obj.type = 'error'
- else:
- if len(obj.edg) > 0:
- obj.type = 'edge'
- else:
- sys.stderr.write('No edge data found in specified file\n')
- obj.type = 'error'
+ st = Style(so) #initialise style
+ fill_col = (so.f_r, so.f_g, so.f_b) #colour tuple for the face fill
+ lighting = normalise( (so.lv_x,-so.lv_y,so.lv_z) ) #unit light vector
- trans_mat = mat(identity(3, float)) #init. trans matrix as identity matrix
+ #INKSCAPE GROUP TO CONTAIN THE POLYHEDRON
- #perform rotations
+ #Put in in the centre of the current view
+ poly_transform = 'translate(' + str( self.view_center[0]) + ',' + str( self.view_center[1]) + ')'
+ #we will put all the rotations in the object name, so it can be repeated in
+ poly_name = obj.name+':'+make_rotation_log(so)
+ poly_attribs = {inkex.addNS('label','inkscape'):poly_name,
+ 'transform':poly_transform }
+ poly = inkex.etree.SubElement(self.current_layer, 'g', poly_attribs)#the group to put everything in
+
+ #TRANFORMATION OF THE OBJECT (ROTATION, SCALE, ETC)
+
+ trans_mat = mat(identity(3, float)) #init. trans matrix as identity matrix
for i in range(1, 7):#for each rotation
axis = eval('so.r'+str(i)+'_ax')
angle = eval('so.r'+str(i)+'_ang') *pi/180
- if axis == 'x':
- trans_mat = rot_x(trans_mat, angle)
- elif axis == 'y':
- trans_mat = rot_y(trans_mat, angle)
- elif axis == 'z':
- trans_mat = rot_z(trans_mat, angle)
-
- # Embed points in group
- #Put in in the centre of the current view
- t = 'translate(' + str( self.view_center[0]) + ',' + str( self.view_center[1]) + ')'
- #we will put all the rotations in the object name, so it can be repeated in future
- proj_attribs = {inkex.addNS('label','inkscape'):obj.name+':'+so.r1_ax+str('%.2f'%so.r1_ang)+':'+
- so.r2_ax+str('%.2f'%so.r2_ang)+':'+
- so.r3_ax+str('%.2f'%so.r3_ang)+':'+
- so.r1_ax+str('%.2f'%so.r4_ang)+':'+
- so.r2_ax+str('%.2f'%so.r5_ang)+':'+
- so.r3_ax+str('%.2f'%so.r6_ang),
- 'transform':t }
- proj = inkex.etree.SubElement(self.current_layer, 'g', proj_attribs)#the group to put everything in
-
- vp_pts=[] #the points as projected in the z-axis onto the viewplane
+ trans_mat = rotate(trans_mat, angle, axis)
+ trans_mat = trans_mat*so.scl #scale by linear factor (do this only after the transforms to reduce round-off)
- for i in range(len(obj.vtx)):
- vp_pts.append((so.scl* (trans_mat * mat(obj.vtx[i]).T)).T.tolist()[0] )#transform the points at add to vp_pts
+ transformed_pts = get_transformed_pts(obj.vtx, trans_mat) #the points as projected in the z-axis onto the viewplane
- lighting = [so.lv_x,-so.lv_y,so.lv_z] #direction of light vector
- lighting = lighting/length(lighting) #normalise
+ #RENDERING OF THE OBJECT
if so.show == 'vtx':
- for i in range(len(vp_pts)):
- draw_SVG_dot([vp_pts[i][0],vp_pts[i][1]], st, 'Point'+str(i), proj)#plot points
+ for i in range(len(transformed_pts)):
+ draw_SVG_dot([transformed_pts[i][0],transformed_pts[i][1]], st, 'Point'+str(i), poly)#plot points using transformed_pts x and y coords
elif so.show == 'edg':
- if obj.type == 'face':#we must generate the edge list
+ if obj.type == 'face':#we must generate the edge list from the faces
edge_list = make_edge_list(obj.fce)
else:#we already have an edge list
edge_list = obj.edg
- for i in range(len(edge_list)):#for every edge
- pt_1 = vp_pts[ edge_list[i][0]-1 ] #the point at the start
- pt_2 = vp_pts[ edge_list[i][1]-1 ] #the point at the end
-
- draw_SVG_line((pt_1[0], pt_1[1]),
- (pt_2[0], pt_2[1]),
- st, 'Edge', proj)#plot edges
+ draw_edges( edge_list, transformed_pts, st, poly)
elif so.show == 'fce':
if obj.type == 'face':#we have a face list
-
- if so.cw_wound: rev = -1 #if cw wound, reverse normals
- else: rev = 1
-
+
z_list = []
for i in range(len(obj.fce)):
- norm = get_normal(vp_pts, obj.fce[i])#get the normal to the face
- norm = rev*norm / length(norm)#normalise and reverse if needed
- angle = acos( dot(norm, lighting) )#get the angle between the normal and the lighting vector
-
-
- if so.z_sort =='max':
- z_sort_param = get_max_z(vp_pts, obj.fce[i])
- elif so.z_sort == 'min':
- z_sort_param = get_min_z(vp_pts, obj.fce[i])
- else:
- z_sort_param = get_cent_z(vp_pts, obj.fce[i])
+ face = obj.fce[i] #the face we are dealing with
+ norm = get_unit_normal(transformed_pts, face, so.cw_wound) #get the normal vector to the face
+ angle = get_angle( norm, lighting )#get the angle between the normal and the lighting vector
+ z_sort_param = get_z_sort_param(transformed_pts, face, so.z_sort)
- if so.norm:#if a log of normals is required
- if i == 0:
- sys.stderr.write('Normal Vectors for each face are: \n\n')
- sys.stderr.write('Face '+str(i)+': ' + str(norm) + '\n')
-
- if so.back: # draw all polygons
- z_list.append((z_sort_param, angle, norm, i) )
- elif norm[2] > 0:#ignore backwards-facing faces (back face cull)
- z_list.append((z_sort_param, angle, norm, i) ) #record the maximum z-value of the face and angle to light, along with the face ID and normal
+ if so.back or norm[2] > 0: # include all polygons or just the front-facing ones as needed
+ z_list.append((z_sort_param, angle, norm, i))#record the maximum z-value of the face and angle to light, along with the face ID and normal
z_list.sort(lambda x, y: cmp(x[0],y[0])) #sort by ascending sort parameter of the face
-
- for i in range(len(z_list)):#for every polygon that has been sorted
- if so.shade:
- st.fill = '#' + "%02X" % floor( z_list[i][1]*so.f_r/pi ) \
- + "%02X" % floor( z_list[i][1]*so.f_g/pi ) \
- + "%02X" % floor( z_list[i][1]*so.f_b/pi ) #make the colour string
- else:
- st.fill = '#' + '%02X' % so.f_r + '%02X' % so.f_g + '%02X' % so.f_b #opaque
-
- face_no = z_list[i][3]#the number of the face to draw
- draw_SVG_poly(vp_pts, obj.fce[ face_no ], st, 'Face:'+str(face_no), proj)
- else:
- sys.stderr.write('Face Data Not Found. Ensure file contains face data, and check the file is imported as "Face-Specifed" under the "Model File" tab.\n')
+ draw_faces( z_list, transformed_pts, obj, so.shade, fill_col, st, poly)
+
+ else:#we cannot generate a list of faces from the edges without a lot of computation
+ inkex.errormsg(_('Face Data Not Found. Ensure file contains face data, and check the file is imported as "Face-Specifed" under the "Model File" tab.\n'))
else:
- sys.stderr.write('Internal Error. No view type selected\n')
+ inkex.errormsg(_('Internal Error. No view type selected\n'))
if __name__ == '__main__':
e = Poly_3D()
diff --git a/share/extensions/render_barcode.inx b/share/extensions/render_barcode.inx
index a7f738d41..610c8bf19 100644
--- a/share/extensions/render_barcode.inx
+++ b/share/extensions/render_barcode.inx
@@ -5,16 +5,15 @@
<dependency type="executable" location="extensions">inkex.py</dependency>
<dependency type="executable" location="extensions">render_barcode.py</dependency>
<param name="type" type="enum" _gui-text="Barcode Type:">
- <item value="ean13">EAN13</item>
<item value="ean8">EAN8</item>
- <item value="ean13">UPC-A</item>
- <item value="ean13">UPC-E</item>
- <item value="ean13">UPC-5</item>
+ <item value="ean13">EAN13</item>
+ <item value="upca">UPC-A</item>
+ <item value="upce">UPC-E</item>
<item value="code39">Code39</item>
<item value="code39ext">Code39Ext</item>
<item value="code93">Code93</item>
<item value="code128">Code128</item>
- <item value="rm4scc">RM4SCC</item>
+ <item value="rm4scc">RM4CC / RM4SCC</item>
</param>
<param name="text" type="string" _gui-text="Barcode Data:"></param>
<param name="height" type="int" _gui-text="Bar Height:" min="20" max="80">30</param>
diff --git a/share/extensions/simplestyle.py b/share/extensions/simplestyle.py
index 012ea5c77..356d75581 100755
--- a/share/extensions/simplestyle.py
+++ b/share/extensions/simplestyle.py
@@ -191,6 +191,21 @@ def parseColor(c):
c=svgcolors[c]
if c.startswith('#') and len(c)==4:
c='#'+c[1:2]+c[1:2]+c[2:3]+c[2:3]+c[3:]+c[3:]
+ elif c.startswith('rgb('):
+ # remove the rgb(...) stuff
+ tmp = c.strip()[4:-1]
+ numbers = [number.strip() for number in tmp.split(',')]
+ converted_numbers = []
+ if len(numbers) == 3:
+ for num in numbers:
+ if num.endswith(r'%'):
+ converted_numbers.append( int(int(num[0:-1])*255/100))
+ else:
+ converted_numbers.append(int(num))
+ return tuple(converted_numbers)
+ else:
+ return (0,0,0)
+
r=int(c[1:3],16)
g=int(c[3:5],16)
b=int(c[5:],16)
diff --git a/share/icons/icons.svg b/share/icons/icons.svg
index 6c004ca15..5e1b6078d 100644
--- a/share/icons/icons.svg
+++ b/share/icons/icons.svg
@@ -37,10 +37,6 @@
<stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7774" />
<stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7776" />
</linearGradient>
-<linearGradient inkscape:collect="always" id="linearGradient7716">
-<stop style="stop-color:#000000;stop-opacity:1;" offset="0" id="stop7718" />
-<stop style="stop-color:#000000;stop-opacity:0;" offset="1" id="stop7720" />
-</linearGradient>
<linearGradient inkscape:collect="always" id="linearGradient5602">
<stop style="stop-color:#cccccc;stop-opacity:1" offset="0" id="stop5604" />
<stop style="stop-color:#000000;stop-opacity:1" offset="1" id="stop5606" />
@@ -511,7 +507,6 @@
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5704" id="linearGradient5389" gradientUnits="userSpaceOnUse" x1="113.7436" y1="149.37389" x2="123.97673" y2="167.55257" />
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5734" id="linearGradient5391" gradientUnits="userSpaceOnUse" x1="283.98041" y1="25.257681" x2="279.47864" y2="21.160408" />
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5704" id="linearGradient5393" gradientUnits="userSpaceOnUse" x1="279.64499" y1="22.038395" x2="283.10538" y2="25.592152" />
-<linearGradient inkscape:collect="always" xlink:href="#linearGradient5663" id="linearGradient5577" gradientUnits="userSpaceOnUse" x1="872" y1="66" x2="865.5" y2="57.5" />
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5602" id="radialGradient5579" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,1.666667,0,-148.5)" cx="842.25" cy="222.75" fx="842.7534" fy="222.75" r="0.75" />
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5740" id="linearGradient5581" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.845525,0,0,3.663228,882.7464,-542.9603)" x1="18.508638" y1="218.88832" x2="17.150238" y2="214.55122" />
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5740" id="linearGradient5583" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.388986,0,0,2.194866,891.1676,-224.2946)" x1="15.741557" y1="213.87196" x2="19.382519" y2="219.41841" />
@@ -644,7 +639,6 @@
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5704" id="linearGradient5857" gradientUnits="userSpaceOnUse" x1="31.372471" y1="132.94643" x2="36.186733" y2="138.5" />
<linearGradient inkscape:collect="always" xlink:href="#linearGradient3480" id="linearGradient5859" gradientUnits="userSpaceOnUse" gradientTransform="translate(-1.5,7.5244)" x1="34.519402" y1="137.51648" x2="42.183006" y2="137.47379" />
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5204" id="linearGradient5861" gradientUnits="userSpaceOnUse" x1="13.479776" y1="86.265739" x2="17.629627" y2="92.007393" />
-<radialGradient inkscape:collect="always" xlink:href="#linearGradient7716" id="radialGradient7722" cx="373.9964" cy="138.4813" fx="373.9964" fy="138.4813" r="1.507797" gradientUnits="userSpaceOnUse" />
<radialGradient inkscape:collect="always" xlink:href="#linearGradient7772" id="radialGradient7778" cx="375.0941" cy="137.9821" fx="375.0941" fy="137.9821" r="1.111868" gradientUnits="userSpaceOnUse" />
<radialGradient inkscape:collect="always" xlink:href="#linearGradient7780" id="radialGradient7786" cx="375.0941" cy="137.9821" fx="375.0941" fy="137.9821" r="1.111868" gradientUnits="userSpaceOnUse" />
<radialGradient inkscape:collect="always" xlink:href="#linearGradient7788" id="radialGradient7794" cx="375.0941" cy="137.9821" fx="375.0941" fy="137.9821" r="1.111868" gradientUnits="userSpaceOnUse" />
@@ -654,8 +648,9 @@
<radialGradient inkscape:collect="always" xlink:href="#linearGradient7820" id="radialGradient7826" cx="375.0941" cy="137.9821" fx="375.0941" fy="137.9821" r="1.111868" gradientUnits="userSpaceOnUse" />
<radialGradient inkscape:collect="always" xlink:href="#linearGradient7828" id="radialGradient7834" cx="375.0941" cy="137.9821" fx="375.0941" fy="137.9821" r="1.111868" gradientUnits="userSpaceOnUse" />
<radialGradient inkscape:collect="always" xlink:href="#linearGradient7836" id="radialGradient7842" cx="375.0941" cy="137.9821" fx="375.0941" fy="137.9821" r="1.111868" gradientUnits="userSpaceOnUse" />
+<linearGradient inkscape:collect="always" xlink:href="#linearGradient5663" id="linearGradient5376" gradientUnits="userSpaceOnUse" x1="872" y1="66" x2="865.5" y2="57.5" gradientTransform="translate(20,0)" />
</defs>
-<sodipodi:namedview inkscape:guide-bbox="true" inkscape:current-layer="g5078" inkscape:grid-bbox="true" inkscape:pageopacity="1.0000000" pagecolor="#e8e8e4" snaptoguides="true" showguides="true" inkscape:window-y="0" inkscape:window-x="0" inkscape:window-height="1000" inkscape:window-width="1225" inkscape:cy="1067.296" inkscape:cx="387.9922" inkscape:zoom="2.567223" gridtolerance="6" snaptogrid="false" showgrid="true" id="base" inkscape:document-units="px" inkscape:grid-points="true" guidetolerance="8" fill="#8ab3de" stroke="#646464" inkscape:object-nodes="true" objecttolerance="11" inkscape:snap-bbox="false" inkscape:snap-nodes="true" inkscape:bbox-nodes="true" inkscape:bbox-paths="true" inkscape:snap-global="true">
+<sodipodi:namedview inkscape:guide-bbox="true" inkscape:current-layer="svg1" inkscape:grid-bbox="true" inkscape:pageopacity="1.0000000" pagecolor="#e8e8e4" snaptoguides="true" showguides="true" inkscape:window-y="0" inkscape:window-x="0" inkscape:window-height="1000" inkscape:window-width="1225" inkscape:cy="1184.005" inkscape:cx="636.4626" inkscape:zoom="3.242702" gridtolerance="6" snaptogrid="false" showgrid="true" id="base" inkscape:document-units="px" inkscape:grid-points="true" guidetolerance="8" fill="#8ab3de" stroke="#646464" inkscape:object-nodes="true" objecttolerance="11" inkscape:snap-bbox="false" inkscape:snap-nodes="true" inkscape:bbox-nodes="true" inkscape:bbox-paths="true" inkscape:snap-global="true">
<inkscape:grid type="xygrid" id="grid9252" originx="0px" originy="0px" spacingx="0.5px" spacingy="0.5px" empspacing="2" visible="true" enabled="false" />
<sodipodi:guide orientation="0,1" position="630.08101,968.02815" id="guide4946" />
<sodipodi:guide orientation="0,1" position="618.47896,943.93157" id="guide4948" />
@@ -702,7 +697,7 @@ http://www.inkscape.org/</dc:description>
<path style="fill:url(#linearGradient3737)" class="shade" d="M 8.9,61.7 C 6.3,71.1 22.3,70.9 31.2,74.4 32.7,73.5 33.5,72.4 32.4,71.4 25.2,67.8 11,67.8 8.9,61.7 z M 120,62.7 C 117.3,71.6 94.5,75 86.6,79.7 85.5,80.8 86.2,81.8 87.5,82.8 97.3,77.9 123.2,74.1 120,62.7 z M 44.3,73.7 C 41.1,73.7 39.1,75.3 44.9,77.4 52.6,78 63.7,81.1 66.1,82.1 69.8,75.5 45.1,73.7 44.3,73.7 z M 23.2,82.2 C 21.9,83.1 21.2,84.1 22.3,85.1 25.8,88.8 43.8,92.2 47.5,95.8 48.4,94.6 48.7,93.4 47.6,92.2 44.2,88.8 28.2,85.6 23.2,82.2 z M 103,91.3 C 102.3,92.1 101.7,93 101.5,94 101.5,96.1 116.9,97.4 116.9,93.4 116.6,92.7 116.3,92 115.7,91.3 112.9,92.9 106,92.5 103,91.3 z M 95.6,91.7 C 92.2,98.8 84.3,94.2 75.8,102.8 74.4,104.3 75.2,105.1 76.5,105.8 85.2,97.6 93.2,102.9 96.2,94 96.4,93.1 96.2,92.4 95.6,91.7 z M 41.6,98.7 C 39.2,101.9 35,104 32,101.4 31.7,101.2 31.5,100.9 31.3,100.6 30.2,102 30.2,103.5 32,105.1 35.6,108.2 41.3,104.3 43,99.9 42.7,99.4 42.1,99 41.6,98.7 z M 98.3,99.7 C 96,103.4 100.6,106.4 104.7,104.1 105.3,103.4 105.2,102 104.1,100.6 101.7,101.8 99.4,101.1 98.3,99.7 z M 43.9,103.6 C 43,104.7 42.7,106 43.8,107.2 47.4,110.8 55.8,107.3 57.3,115.8 58.4,121.9 72,118.7 78.8,113.8 80.3,112.16 79.6,111.1 78.3,110.3 71.2,115.1 58.3,118 57.3,112.2 55.8,103.7 47.5,107.1 43.9,103.6 z" id="path46" />
<path id="icecap" class="full-specularity" style="fill:url(#linearGradient3739)" d="M 70.5,15.5 86.8,32.1 C 88.3,33.6 88.3,36.7 87.4,37.6 L 79.3,31 77.7,40.7 71,37.1 60.1,44 56.5,29.5 50.7,42.1 36.2,42 C 33.4,42 33.8,39.1 36.7,36.2 42.4,29.9 53.5,19.2 57,15.5 60.6,11.8 66.9,11.9 70.5,15.5 z" />
</g>
-<use x="0" y="0" xlink:href="#path4893" id="use4911" transform="matrix(0,1,1,0,805.5171,-805.2431)" width="1250" height="1250" />
+<use x="0" y="0" xlink:href="#path4893" id="use4911" transform="matrix(0,1,1,0,825.5171,-825.2431)" width="1250" height="1250" />
<g transform="translate(839.0362,80.70908)" id="layer1" />
<g style="stroke:#000000;stroke-opacity:1" transform="translate(-251.412,135.0283)" id="simplify" inkscape:label="#simplify">
<path id="path10936" style="fill:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4" d="M 486.953,205.5 501.953,205.5 M 501.953,201.4255 C 495.453,205.9255 493.453,194.4542 486.953,200.4255 M 486.953,193.6678 C 488.953,198.6678 489.0896,191.5995 490.953,190.6678 492.953,189.6678 493.2942,193.6914 493.953,195.6678 494.953,198.6678 495.953,192.6678 497.953,191.6678 500.7814,190.2536 497.953,198.6678 501.953,194.6678" />
@@ -984,8 +979,8 @@ http://www.inkscape.org/</dc:description>
</g>
<g id="node_cusp" transform="translate(665,-119.9465)">
<rect y="175" x="-45" height="16" width="16" id="rect3216" style="color:#000000;fill:none;stroke:none;stroke-width:1;marker:none;display:inline" />
-<path style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -44.50979,175.5032 C -37.52207,175.5032 -37.53892,185.5192 -37.53892,187.5192 -33.0238,185 -30.0238,181 -29.5041,175.5032" id="path3226" sodipodi:nodetypes="ccc" />
-<rect y="103.933" x="-161.2208" height="4.232837" width="4.189415" id="rect3224" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" transform="matrix(0.707109,-0.707105,0.707109,0.707105,0,0)" />
+<path style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -44.50979,175.5032 C -37.52207,175.5032 -37.53892,184.6391 -37.53892,186.6391 -33.0238,184.1199 -30.0238,181 -29.5041,175.5032" id="path3226" sodipodi:nodetypes="ccc" />
+<rect y="103.5115" x="-160.3997" height="3.831147" width="3.791844" id="rect3224" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:0.9051018;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" transform="matrix(0.7071088,-0.7071048,0.7071088,0.7071048,0,0)" />
</g>
<g id="node_smooth" transform="translate(684.986,-119.9465)">
<path style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -44.41296,176.5635 C -44.94008,180.0159 -43.54193,185.457 -37.54193,185.457 -31.54193,185.457 -29.98307,179.8869 -30.45595,176.4345" id="path3254" sodipodi:nodetypes="csc" />
@@ -993,20 +988,19 @@ http://www.inkscape.org/</dc:description>
<use transform="translate(0.0140001,-3.0535)" x="0" y="0" xlink:href="#rect4374" id="use5742" width="1250" height="1250" />
</g>
<g id="node_symmetric" transform="translate(705.0198,-119.9465)" inkscape:label="#node_symmetric">
-<path style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -42.44776,186.5 -31.55518,186.5" id="path10665" sodipodi:nodetypes="cc" />
-<path style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -44.41296,176.5635 C -44.94008,180.0159 -43.02606,185.543 -37.02606,185.543 -31.02606,185.543 -29.0373,180.0159 -29.51018,176.5635" id="path10667" sodipodi:nodetypes="csc" />
+<path id="path10667" style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -44.41296,176.5635 C -44.94008,180.0159 -43.02606,186.0936 -37.02606,186.0936 -31.02606,186.0936 -29.0373,180.0159 -29.51018,176.5635 M -42.44776,186.1975 -31.55518,186.1975" sodipodi:nodetypes="csccc" />
<rect y="175" x="-45" height="16" width="16" id="rect10669" style="color:#000000;fill:none;stroke:none;stroke-width:1;marker:none;display:inline" />
<rect y="-39.47938" x="-188.4831" height="4.950177" width="4.966394" id="rect10671" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000015;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" transform="matrix(2.790265e-6,-1,1,-2.867107e-6,0,0)" />
-<rect style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect10673" width="2.067648" height="2.017743" x="-44.54361" y="185.4978" />
-<rect style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect10675" width="2.022052" height="2.026662" x="-31.53185" y="185.4733" />
+<rect style="color:#000000;fill:#ffffff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect10673" width="2.067648" height="2.017743" x="-44.54361" y="185.2228" ry="1.008872" rx="1.008872" />
+<rect style="color:#000000;fill:#ffffff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect10675" width="2.022052" height="2.026662" x="-31.53185" y="185.1983" ry="1.011026" rx="1.011026" />
</g>
-<g id="node_curve" transform="translate(724.9762,-119.9465)">
+<g id="node_curve" transform="translate(744.9762,-119.9465)">
<path style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -42.38772,188.4395 C -42.38772,181.4395 -38.41209,177.6123 -31.41209,177.6123" id="path10679" sodipodi:nodetypes="cc" />
<rect y="175" x="-45" height="16" width="16" id="rect10681" style="color:#000000;fill:none;stroke:none;stroke-width:1;marker:none;display:inline" />
<use transform="translate(-4.9762,-0.0534998)" x="0" y="0" xlink:href="#rect4374" id="use5745" width="1250" height="1250" />
<use transform="translate(5.981293,-11.02417)" x="0" y="0" xlink:href="#rect4374" id="use5747" width="1250" height="1250" />
</g>
-<g id="node_line" transform="translate(744.9762,-119.9465)">
+<g id="node_line" transform="translate(764.9762,-119.9465)">
<path style="fill:none;stroke:#646464;stroke-width:1.0000004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -42.5,188.5 -31.5,177.5" id="path4418" sodipodi:nodetypes="cc" />
<rect y="175" x="-45" height="16" width="16" id="rect4420" style="color:#000000;fill:none;stroke:none;stroke-width:1;marker:none;display:inline" />
<use transform="translate(-5.018707,-0.0241656)" x="0" y="0" xlink:href="#rect4374" id="use5756" width="1250" height="1250" />
@@ -2197,11 +2191,11 @@ http://www.inkscape.org/</dc:description>
<use x="0" y="0" xlink:href="#path7204" id="use3823" transform="matrix(1,0,0,-1,-819.959,351)" width="1250" height="1250" />
<use x="0" y="0" xlink:href="#g3813" id="use3728" transform="translate(-720.4065,259.3541)" width="1250" height="1250" />
<use height="1250" width="1250" transform="matrix(0.866026,0.5,-0.5,0.866026,-450.7461,-366.064)" id="use3744" xlink:href="#g3813" y="0" x="0" />
-<g transform="translate(64.4787,-188)" id="nodes_show_handles">
+<g transform="translate(84.4787,-188)" id="nodes_show_handles">
<rect style="opacity:0;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.8;marker:none;visibility:visible;display:inline;overflow:visible" id="rect3742" width="12" height="12" x="735" y="57" transform="translate(-64.4787,188)" />
<path style="color:#000000;fill:none;stroke:#909090;stroke-width:1.0000004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" d="M 682.0213,245.5 C 678.5213,246 673.5213,249.5 673.5213,253.5" id="path4641" sodipodi:nodetypes="cc" />
<path style="color:#000000;fill:none;stroke:#646464;stroke-width:1.0000004;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" d="M 673.0213,247.5 673.0213,253.5" id="path4638" sodipodi:nodetypes="cc" />
-<use transform="translate(703.5311,60.02666)" x="0" y="0" xlink:href="#rect10675" id="use3738" width="1250" height="1250" />
+<use transform="translate(703.5311,60.30166)" x="0" y="0" xlink:href="#rect10675" id="use3738" width="1250" height="1250" />
<use transform="translate(704.4975,77.02417)" x="0" y="0" xlink:href="#use5758" id="use4635" width="1250" height="1250" />
</g>
<g style="display:inline" id="remove_overlaps" transform="translate(-48,41)">
@@ -2749,13 +2743,13 @@ http://www.inkscape.org/</dc:description>
<rect style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="rect4579" width="4.069275" height="4.069275" x="-39.06561" y="185.0237" />
<rect y="180.9545" x="-43.13489" height="4.069275" width="4.069275" id="rect4581" style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
-<g id="edit_next_parameter" inkscape:label="#g10193">
+<g id="edit_next_parameter" inkscape:label="#g10193" transform="translate(20,0)">
<path style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#4d4d4d;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" d="M 761.9292,60.21135 C 761.5878,61.39286 761.4946,62.3835 761.5011,63.20978 761.5077,64.03606 761.6167,64.69823 761.7564,65.22109 762.0358,66.2668 762.4196,66.76142 762.7922,66.84248 763.1648,66.92354 764.0584,66.69636 764.9435,66.40187 765.3861,66.25463 765.8255,66.09125 766.196,65.9186 766.5666,65.74595 766.8671,65.56494 767.048,65.34354 766.4063,64.64298 765.4475,64.04417 764.4271,63.34698 763.9169,62.99839 763.396,62.61954 762.9432,62.13023 762.4904,61.64091 762.1008,61.0399 761.9292,60.21135 z M 764.4579,59.01822 C 764.2129,59.7969 764.3097,60.67268 764.6999,61.36216 765.0313,61.94976 765.5572,62.39261 766.1623,62.67942 766.6964,62.92688 767.2804,63.04656 767.9134,63.0393 767.2183,62.61982 766.613,62.21989 766.1246,61.81109 765.6363,61.40228 765.2668,60.98517 765.0109,60.58979 764.4991,59.79903 764.4542,59.10024 764.4579,59.01822 z M 767.2562,57.98462 C 766.778,58.99773 766.8948,59.70934 767.2669,60.18111 767.639,60.65288 768.2666,60.91061 768.9902,61.0957 768.3331,60.58465 767.8453,59.85018 767.5652,59.20611 767.2851,58.56204 767.214,58.01559 767.2562,57.98462 z M 770.782,55.78203 C 770.2055,56.1138 770.2762,57.16371 770.004,57.54492 769.478,58.28155 768.9415,58.39158 769.2239,58.98036 769.5903,59.74429 769.7493,59.35851 770.7399,59.45409 771.0491,59.48392 771.9668,60.4286 772.2901,60.37037 771.3092,58.83005 770.7454,57.38913 770.782,55.78203 z" id="path9858" inkscape:path-effect="#path-effect9860" inkscape:original-d="M 762.7922,66.84248 C 763.6022,63.11924 765.4886,60.07306 771.5388,58.08446" sodipodi:nodetypes="cc" />
<path sodipodi:nodetypes="cc" id="path9256" d="M 762.5,68.5 C 763.3058,62.01571 768.0747,58.5078 773.5,57.5" style="fill:none;stroke:#008000;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" />
<rect style="fill:none;stroke:none;stroke-width:1;marker:none;display:inline" id="rect9258" width="16" height="16" x="759.9762" y="55.0535" />
<use transform="translate(760,-189)" x="0" y="0" xlink:href="#g6043" id="use9872" width="1250" height="1250" />
-<use height="1250" width="1250" id="use10185" xlink:href="#rect10675" y="0" x="0" transform="translate(805.0318,-128.9733)" />
-<use transform="translate(793.0318,-116.9733)" x="0" y="0" xlink:href="#rect10675" id="use10187" width="1250" height="1250" />
+<use height="1250" width="1250" id="use10185" xlink:href="#rect10675" y="0" x="0" transform="translate(805.0318,-128.6983)" />
+<use transform="translate(793.0318,-116.6983)" x="0" y="0" xlink:href="#rect10675" id="use10187" width="1250" height="1250" />
</g>
<g id="grid_xy">
<path sodipodi:nodetypes="cc" id="path5235" d="M 305.5,421.5 305.5,436.5" style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
@@ -2847,7 +2841,7 @@ http://www.inkscape.org/</dc:description>
<path sodipodi:nodetypes="ccccccccccccccccccccccccccccc" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none" d="M 905.9609,256.0794 905.9609,255.0794 906.9609,255.0794 906.9609,254.0794 907.9609,254.0794 907.9609,253.0794 908.9609,253.0794 908.9609,255.0794 925.0391,255.0794 925.0391,253.0794 926.0391,253.0794 926.0391,254.0794 927.0391,254.0794 927.0391,255.0794 928.0391,255.0794 928.0391,256.0794 927.0391,256.0794 927.0391,257.0794 926.0391,257.0794 926.0391,258.0794 925.0391,258.0794 925.0391,256.0794 908.9609,256.0794 908.9609,258.0794 907.9609,258.0794 907.9609,257.0794 906.9609,257.0794 906.9609,256.0794 905.9609,256.0794 z" id="path12946" />
<rect style="opacity:0.5513197;color:#000000;fill:none;stroke:none;stroke-width:1px;marker:none;display:inline" id="rect12948" width="24" height="24" x="905" y="240" />
</g>
-<g id="nodes_show_helperpath" transform="translate(835.0187,-120.9465)">
+<g id="nodes_show_helperpath" transform="translate(855.0187,-120.9465)">
<path style="fill:#ffffff;fill-opacity:0.75;fill-rule:evenodd;stroke:#ff0000;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M -42.51871,188.4465 C -42.51871,182.9474 -41.84309,175.4698 -31.51871,177.4465 -29.7078,177.7932 -31.18387,189.1883 -42.51871,188.4465" id="path4756" sodipodi:nodetypes="csc" />
<rect y="175" x="-45" height="16" width="16" id="rect4758" style="fill:none;stroke:none;stroke-width:1;marker:none;display:inline" />
<use transform="translate(-4.9762,-0.0534998)" x="0" y="0" xlink:href="#rect4374" id="use4760" width="1250" height="1250" />
@@ -2870,20 +2864,20 @@ http://www.inkscape.org/</dc:description>
</g>
</g>
</g>
-<path style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 835,62 C 833,64 830,63.5 827,60.5" id="path4828" sodipodi:nodetypes="cc" />
-<use x="0" y="0" xlink:href="#path4828" id="use4830" transform="matrix(0,1,1,0,765.5,-765)" width="1250" height="1250" />
-<g inkscape:label="#nodeedit-clippath" id="nodeedit-clippath" transform="translate(60,0)">
+<path style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="M 855,62 C 853,64 850,63.5 847,60.5" id="path4828" sodipodi:nodetypes="cc" />
+<use x="0" y="0" xlink:href="#path4828" id="use4830" transform="matrix(0,1,1,0,785.5,-785)" width="1250" height="1250" />
+<g inkscape:label="#nodeedit-clippath" id="nodeedit-clippath" transform="translate(80,0)">
<path style="fill:none;stroke:#00ff00;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" d="M 762.5,68.5 C 763.3058,62.01571 768.0747,58.5078 773.5,57.5" id="path4813" sodipodi:nodetypes="cc" />
<rect y="55.0535" x="759.9762" height="16" width="16" id="rect4815" style="fill:none;stroke:none;marker:none;display:inline" />
-<use transform="translate(805.0318,-128.9733)" x="0" y="0" xlink:href="#rect10675" id="use4819" width="1250" height="1250" />
-<use height="1250" width="1250" id="use4821" xlink:href="#rect10675" y="0" x="0" transform="translate(793.0318,-116.9733)" />
+<use transform="translate(805.0318,-128.6983)" x="0" y="0" xlink:href="#rect10675" id="use4819" width="1250" height="1250" />
+<use height="1250" width="1250" id="use4821" xlink:href="#rect10675" y="0" x="0" transform="translate(793.0318,-116.6983)" />
</g>
-<path sodipodi:nodetypes="cc" id="path4893" d="M 875,62 C 873,64 869,63 865,58" style="fill:none;stroke:url(#linearGradient5577);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
-<g transform="translate(100,0)" id="nodeedit-mask" inkscape:label="">
+<path sodipodi:nodetypes="cc" id="path4893" d="M 895,62 C 893,64 889,63 885,58" style="fill:none;stroke:url(#linearGradient5376);stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+<g transform="translate(120,0)" id="nodeedit-mask" inkscape:label="">
<path sodipodi:nodetypes="cc" id="path4899" d="M 762.5,68.5 C 763.3058,62.01571 768.0747,58.5078 773.5,57.5" style="fill:none;stroke:#0000ff;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" />
<rect style="fill:none;stroke:none;marker:none;display:inline" id="rect4901" width="16" height="16" x="759.9762" y="55.0535" />
-<use height="1250" width="1250" id="use4903" xlink:href="#rect10675" y="0" x="0" transform="translate(805.0318,-128.9733)" />
-<use transform="translate(793.0318,-116.9733)" x="0" y="0" xlink:href="#rect10675" id="use4905" width="1250" height="1250" />
+<use height="1250" width="1250" id="use4903" xlink:href="#rect10675" y="0" x="0" transform="translate(805.0318,-128.6983)" />
+<use transform="translate(793.0318,-116.6983)" x="0" y="0" xlink:href="#rect10675" id="use4905" width="1250" height="1250" />
</g>
<g id="draw_erase" transform="translate(1.5,359.5)">
<rect style="color:#000000;fill:none;stroke:none;stroke-width:1.0000001;marker:none;display:inline" id="rect7418" width="24" height="24" x="450" y="115" />
@@ -3127,30 +3121,35 @@ http://www.inkscape.org/</dc:description>
<rect inkscape:label="#rect5080-7" style="fill:none;stroke:none;stroke-width:1;marker:none;display:inline" id="tweak_blur_mode" width="16" height="16" x="-64.90511" y="221.0282" />
<g id="g7655" style="fill:#000000" transform="translate(-436.7857,84.59235)">
<path inkscape:tile-y0="136.8702" inkscape:tile-x0="373.9822" inkscape:tile-h="2.223736" inkscape:tile-w="2.223736" inkscape:tile-cy="137.9821" inkscape:tile-cx="375.0941" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" sodipodi:ry="1.111868" sodipodi:rx="1.111868" sodipodi:cy="137.9821" sodipodi:cx="375.0941" id="path7657" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" sodipodi:type="arc" transform="matrix(1.20571,0,0,1.20571,-78.25832,-27.88514)" />
-<path transform="matrix(1.188922,0,0,1.188922,-63.09951,-25.56857)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7660" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.180543,0,0,1.180543,-57.00309,-21.38516)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7662" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.088184,0,0,1.088184,-22.35986,-5.61394)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7664" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.188915,0,0,1.188915,-69.00487,-25.56775)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7666" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.20571,0,0,1.20571,-66.44314,-27.88514)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7668" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.093412,0,0,1.093412,-36.13602,-6.3353)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7670" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.184974,0,0,1.184974,-70.48049,-15.94187)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7672" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.111722,0,0,1.111722,-37.0964,-14.9165)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7674" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.181829,0,0,1.181829,-69.30058,-21.56258)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7676" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.485788,0,0,1.485788,-180.3604,-63.50353)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7818);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7678" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.485788,0,0,1.485788,-180.3597,-57.44874)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7802);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7680" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.485788,0,0,1.485788,-177.4064,-63.50356)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7682" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.485788,0,0,1.485788,-174.4526,-63.50354)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7834);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7684" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.485788,0,0,1.485788,-180.3605,-60.47619)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7810);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7686" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.4858,0,0,1.4858,-177.4101,-57.45014)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7794);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7688" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.485788,0,0,1.485788,-174.4524,-60.47613)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7842);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7692" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.492675,0,0,1.492675,-177.0357,-58.39903)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7786);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7694" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.191739,0,0,1.191739,-64.1566,-13.84799)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7696" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.181973,0,0,1.181973,-57.53942,-15.52772)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7698" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.20571,0,0,1.20571,-78.25832,-15.77568)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7700" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.193386,0,0,1.193386,-70.68201,-14.07527)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7702" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.121575,0,0,1.121575,-40.79199,-4.166495)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7704" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(1.20571,0,0,1.20571,-66.44314,-15.77568)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7706" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-<path transform="matrix(6.75293,0,0,6.75293,-2153.081,-787.2478)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7778);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7690" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 A 1.111868,1.111868 0 1 1 373.9822,137.9821 1.111868,1.111868 0 1 1 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
-</g>
+<path transform="matrix(1.188922,0,0,1.188922,-63.09951,-25.56857)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7660" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.180543,0,0,1.180543,-57.00309,-21.38516)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7662" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.088184,0,0,1.088184,-22.35986,-5.61394)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7664" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.188915,0,0,1.188915,-69.00487,-25.56775)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7666" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.20571,0,0,1.20571,-66.44314,-27.88514)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7668" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.093412,0,0,1.093412,-36.13602,-6.3353)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7670" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.184974,0,0,1.184974,-70.48049,-15.94187)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7672" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.111722,0,0,1.111722,-37.0964,-14.9165)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7674" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.181829,0,0,1.181829,-69.30058,-21.56258)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7676" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.485788,0,0,1.485788,-180.3604,-63.50353)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7818);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7678" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.485788,0,0,1.485788,-180.3597,-57.44874)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7802);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7680" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.485788,0,0,1.485788,-177.4064,-63.50356)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7826);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7682" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.485788,0,0,1.485788,-174.4526,-63.50354)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7834);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7684" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.485788,0,0,1.485788,-180.3605,-60.47619)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7810);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7686" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.4858,0,0,1.4858,-177.4101,-57.45014)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7794);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7688" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.485788,0,0,1.485788,-174.4524,-60.47613)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7842);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7692" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.492675,0,0,1.492675,-177.0357,-58.39903)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7786);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7694" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.191739,0,0,1.191739,-64.1566,-13.84799)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7696" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.181973,0,0,1.181973,-57.53942,-15.52772)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7698" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.20571,0,0,1.20571,-78.25832,-15.77568)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7700" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.193386,0,0,1.193386,-70.68201,-14.07527)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7702" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.121575,0,0,1.121575,-40.79199,-4.166495)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7704" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(1.20571,0,0,1.20571,-66.44314,-15.77568)" sodipodi:type="arc" style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7706" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+<path transform="matrix(6.75293,0,0,6.75293,-2153.081,-787.2478)" sodipodi:type="arc" style="color:#000000;fill:url(#radialGradient7778);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.2773579;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="use7690" sodipodi:cx="375.0941" sodipodi:cy="137.9821" sodipodi:rx="1.111868" sodipodi:ry="1.111868" d="M 376.206,137.9821 C 376.206,138.5959 375.7078,139.094 375.0941,139.094 374.4803,139.094 373.9822,138.5959 373.9822,137.9821 373.9822,137.3684 374.4803,136.8702 375.0941,136.8702 375.7078,136.8702 376.206,137.3684 376.206,137.9821 z" inkscape:tile-x0="373.9822" inkscape:tile-y0="136.8702" />
+</g>
+</g>
+<g inkscape:label="#node_symmetric" transform="translate(725.0198,-119.9465)" id="node_auto">
+<path sodipodi:nodetypes="csc" id="path5383" d="M -44.41296,176.5635 C -44.94008,180.0159 -43.02606,185.9502 -37.02606,185.9502 -31.02606,185.9502 -29.0373,180.0159 -29.51018,176.5635" style="fill:none;stroke:#646464;stroke-width:1.0000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none" />
+<rect style="color:#000000;fill:none;stroke:none;stroke-width:1;marker:none;display:inline" id="rect5385" width="16" height="16" x="-45" y="175" />
+<rect transform="matrix(2.790265e-6,-1,1,-2.867107e-6,0,0)" style="color:#000000;fill:#6464ff;fill-opacity:0.3921569;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.0000015;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;display:inline" id="rect5387" width="4.966394" height="4.950177" x="-188.4831" y="-39.47938" ry="2.475089" />
</g>
</svg>