From f527a114032ecea56edad4dcd6fdbb39abeec48e Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Sat, 7 Jan 2012 22:06:21 +0100 Subject: [PATCH 1/6] Added support for ellipse, polygon and polyline in importSVG --- src/Mod/Draft/importSVG.py | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index a45c3b5bf3..2b023b9b62 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -28,6 +28,7 @@ __url__ = ["http://free-cad.sourceforge.net"] ''' This script imports SVG files in FreeCAD. Currently only reads the following entities: paths, lines, arcs and rects. +currently unsupported: image, rect(rx,ry) ''' import xml.sax, string, FreeCAD, os, math, re, Draft @@ -287,7 +288,7 @@ class svgHandler(xml.sax.ContentHandler): pair = i.split(':') if len(pair)>1: data[pair[0]]=pair[1] - for k in ['x','y','x1','y1','x2','y2','width','height']: + for k in ['x','y','x1','y1','x2','y2','rx','ry','cx','cy','width','height']: if k in data: data[k] = getsize(data[k][0]) @@ -707,6 +708,59 @@ class svgHandler(xml.sax.ContentHandler): obj.Shape = sh self.format(obj) + # processing polylines and polygons + + if name == "polyline" or name == "polygon": + if not pathname: pathname = 'Polyline' + points=[] + for point in data['points']: + f = float(d) + points.append(f) +# except ValueError: +# if d[0].isdigit(): +# pathdata.append(d[:-1]) +# pathdata.append(d[-1]) +# else: +# pathdata.append(d[0]) +# pathdata.append(d[1:]) + lenpoints=len(points): + if lenpoints>=4 and lenpoints % 2 == 0: + lastvec = Vector(point[0],-point[1],0) + path=[] + if name == 'polygon': + points=points+points[:2] # emulate closepath + for svgx,svgy in zip(points[2::2],points[3::2]): + currentvec = Vector(svgx,-svgy,0) + if not fcvec.equals(lastvec,currentvec): + seg = Part.Line(lastvec,currentvec).toShape() + print "polyline seg ",lastvec,currentvec + lastvec = currentvec + path.append(seg) + if path: + sh = Part.Wire(path) + if self.fill: sh = Part.Face(sh) + sh = self.applyTrans(sh) + obj = self.doc.addObject("Part::Feature",pathname) + obj.Shape = sh + + # processing ellipses + + if (name == "ellipse") : + if not pathname: pathname = 'Ellipse' + c = Vector(float(data['cx'][0]),-float(data['cy'][0]),0) + rx = float(data['rx'][0]) + ry = float(data['ry'][0]) + sh = Part.Ellipse(c,rx,rx) + if self.fill: + sh = Part.Wire([sh]) + sh = Part.Face(sh) + sh.translate(c) + sh = self.applyTrans(sh) + obj = self.doc.addObject("Part::Feature",pathname) + obj.Shape = sh + self.format(obj) + + # processing circles if (name == "circle") and (not ("freecad:skip" in data)) : From 453e85b55c8f4829be69cd18892878db7119b974 Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Sat, 7 Jan 2012 22:45:09 +0100 Subject: [PATCH 2/6] fixed syntax error in importSVG --- src/Mod/Draft/importSVG.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index 2b023b9b62..4e95bf9206 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -723,7 +723,7 @@ class svgHandler(xml.sax.ContentHandler): # else: # pathdata.append(d[0]) # pathdata.append(d[1:]) - lenpoints=len(points): + lenpoints=len(points) if lenpoints>=4 and lenpoints % 2 == 0: lastvec = Vector(point[0],-point[1],0) path=[] From 447600bf5aae6857010624947975b895d9d1b040 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sun, 8 Jan 2012 13:40:30 -0200 Subject: [PATCH 3/6] added xml namespace to A3_Landscape template --- src/Mod/Drawing/Templates/A3_Landscape.svg | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Mod/Drawing/Templates/A3_Landscape.svg b/src/Mod/Drawing/Templates/A3_Landscape.svg index 4e2cdb854e..4a98aed921 100644 --- a/src/Mod/Drawing/Templates/A3_Landscape.svg +++ b/src/Mod/Drawing/Templates/A3_Landscape.svg @@ -8,6 +8,7 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:freecad="http://sourceforge.net/apps/mediawiki/free-cad/index.php?title=Svg_Namespace" width="420" height="297" version="1.1" From 432c22d9d722891a3a36a443d46778ebd993fb9b Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Sun, 8 Jan 2012 22:52:46 +0100 Subject: [PATCH 4/6] New Parser for path element in importSVG --- src/Mod/Draft/importSVG.py | 61 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index 4e95bf9206..b84a417603 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -229,6 +229,43 @@ def getrgb(color): g = str(hex(int(color[1]*255)))[2:].zfill(2) b = str(hex(int(color[2]*255)))[2:].zfill(2) return "#"+r+g+b + +def splitpathd(pathdstr): + whitespacechars = [' ','\t','\r','\n'] + commandchars = ['m','M','l','L','h','H','v','V','a','A','c','C','q','Q','s','S','t','T','z','Z'] + numberchars = ['e','E','+','-','.','0','1','2','3','4','5','6','7','8','9'] + dlist=[] + currentnumber='' + state='whitespace' + for dchar in pathdstr: + if dchar in commandchars: + if currentnumber: + dlist.append(float(currentnumber)) + currentnumber = '' + dlist.append(dchar) + state='whitespace' + elif state == 'whitespace': + if dchar in whitespacechars: + pass #continue + elif dchar in numberchars: + state = 'number' + currentnumber = dchar + else: + print 'unexpected char %s %d %s' % (dchar,ord(dchar),state) + elif state == 'number': + if dchar in numberchars: + currentnumber += dchar + elif dchar in whitespacechars: + dlist.append(float(currentnumber)) + currentnumber = '' + else: + print 'unexpected char %s %d %s' % (dchar,ord(dchar),state) + #End of string/list + if currentnumber: + dlist.append(float(currentnumber)) + currentnumber = '' + return dlist + class svgHandler(xml.sax.ContentHandler): "this handler parses the svg files and creates freecad objects" @@ -378,22 +415,7 @@ class svgHandler(xml.sax.ContentHandler): relative = False firstvec = None - pathdata = [] - for d in data['d']: - if (len(d) == 1) and (d in ['m','M','l','L','h','H','v','V','a','A','c','C','q','Q','s','S','t','T']): - pathdata.append(d) - else: - try: - f = float(d) - pathdata.append(f) - except ValueError: - if d[0].isdigit(): - pathdata.append(d[:-1]) - pathdata.append(d[-1]) - else: - pathdata.append(d[0]) - pathdata.append(d[1:]) - + pathdata = splitpathd(' '.join(data['d'])) # print "debug: pathdata:",pathdata if "freecad:basepoint1" in data: @@ -716,13 +738,6 @@ class svgHandler(xml.sax.ContentHandler): for point in data['points']: f = float(d) points.append(f) -# except ValueError: -# if d[0].isdigit(): -# pathdata.append(d[:-1]) -# pathdata.append(d[-1]) -# else: -# pathdata.append(d[0]) -# pathdata.append(d[1:]) lenpoints=len(points) if lenpoints>=4 and lenpoints % 2 == 0: lastvec = Vector(point[0],-point[1],0) From 43e186186a21f00d0e9b804aab598fa5e03833f4 Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Mon, 9 Jan 2012 09:19:35 +0100 Subject: [PATCH 5/6] Small fixes in importSVG --- src/Mod/Draft/importSVG.py | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index b84a417603..7157e659fc 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -27,8 +27,8 @@ __url__ = ["http://free-cad.sourceforge.net"] ''' This script imports SVG files in FreeCAD. Currently only reads the following entities: -paths, lines, arcs and rects. -currently unsupported: image, rect(rx,ry) +paths, lines, arcs ,rects, circles, ellipses, polygons, polylines. +currently unsupported: image, rounded rect(rx,ry), transform attribute?? ''' import xml.sax, string, FreeCAD, os, math, re, Draft @@ -325,7 +325,7 @@ class svgHandler(xml.sax.ContentHandler): pair = i.split(':') if len(pair)>1: data[pair[0]]=pair[1] - for k in ['x','y','x1','y1','x2','y2','rx','ry','cx','cy','width','height']: + for k in ['x','y','x1','y1','x2','y2','r','rx','ry','cx','cy','width','height']: if k in data: data[k] = getsize(data[k][0]) @@ -615,7 +615,7 @@ class svgHandler(xml.sax.ContentHandler): path = [] point = [] command = None - #elif (len(point)==6) and (command=="cubic"): + elif (command=="cubic") and (((smooth==False) and (len(point)==6)) or (smooth==True and (len(point)==4))) : if smooth: if relative: @@ -734,13 +734,11 @@ class svgHandler(xml.sax.ContentHandler): if name == "polyline" or name == "polygon": if not pathname: pathname = 'Polyline' - points=[] - for point in data['points']: - f = float(d) - points.append(f) + points=[float(d) for d in data['points']] + print points lenpoints=len(points) if lenpoints>=4 and lenpoints % 2 == 0: - lastvec = Vector(point[0],-point[1],0) + lastvec = Vector(points[0],-points[1],0) path=[] if name == 'polygon': points=points+points[:2] # emulate closepath @@ -762,10 +760,10 @@ class svgHandler(xml.sax.ContentHandler): if (name == "ellipse") : if not pathname: pathname = 'Ellipse' - c = Vector(float(data['cx'][0]),-float(data['cy'][0]),0) - rx = float(data['rx'][0]) - ry = float(data['ry'][0]) - sh = Part.Ellipse(c,rx,rx) + c = Vector(data.get('cx',0),-data.get('cy',0),0) + rx = data['rx'] + ry = data['ry'] + sh = Part.Ellipse(c,rx,ry).toShape() #needs a proxy object if self.fill: sh = Part.Wire([sh]) sh = Part.Face(sh) @@ -780,8 +778,8 @@ class svgHandler(xml.sax.ContentHandler): if (name == "circle") and (not ("freecad:skip" in data)) : if not pathname: pathname = 'Circle' - c = Vector(float(data['cx'][0]),-float(data['cy'][0]),0) - r = float(data['r'][0]) + c = Vector(data.get('cx',0),-data.get('cy',0),0) + r = data['r'] sh = Part.makeCircle(r) if self.fill: sh = Part.Wire([sh]) From 1c5f92bebed0bbbc9ea16b604823e98a203006f5 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 9 Jan 2012 10:43:20 -0200 Subject: [PATCH 6/6] small fix in Draft importSVG + removed unused blocks + added description strings --- src/Mod/Draft/importSVG.py | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py index 7157e659fc..3bf9408995 100644 --- a/src/Mod/Draft/importSVG.py +++ b/src/Mod/Draft/importSVG.py @@ -231,6 +231,7 @@ def getrgb(color): return "#"+r+g+b def splitpathd(pathdstr): + "returns a list with the elements contained in the d attribute of a path" whitespacechars = [' ','\t','\r','\n'] commandchars = ['m','M','l','L','h','H','v','V','a','A','c','C','q','Q','s','S','t','T','z','Z'] numberchars = ['e','E','+','-','.','0','1','2','3','4','5','6','7','8','9'] @@ -359,38 +360,7 @@ class svgHandler(xml.sax.ContentHandler): else: if name == "g": self.grouptransform.append(FreeCAD.Matrix()) - - ''' - print "existing grouptransform: ",self.grouptransform - print "existing transform: ",self.transform - if "translate" in tr: - i0 = tr.index("translate") - print "getting translate ",tr - if "translate" in self.transform: - self.transform['translate'] = self.transform['translate'].add(Vector(float(tr[i0+1]),-float(tr[i0+2]),0)) - else: - self.transform['translate'] = Vector(float(tr[i0+1]),-float(tr[i0+2]),0) - if "translate" in self.grouptransform: - print "adding to group ",self.grouptransform['translate'] - self.transform['translate'] = self.grouptransform['translate'].add(self.transform['translate']) - else: - if "translate" in self.grouptransform: - print "adding to group ",self.grouptransform['translate'] - self.transform['translate'] = self.grouptransform['translate'] - if "scale" in tr: - i0 = tr.index("scale") - if "scale" in self.transform: - self.transform['scale'] = self.transform['scale'].add(Vector(float(tr[i0+1]),float(tr[i0+2]),0)) - else: - print tr - self.transform['scale'] = Vector(float(tr[i0+1]),float(tr[i0+2]),0) - if "scale" in self.grouptransform: - self.transform['scale'] = self.transform['scale'].add(self.grouptransform['scale']) - else: - if "scale" in self.grouptransform: - self.transform['scale'] = self.grouptransform['scale'] - ''' - + if (self.style == 1): self.color = self.col self.width = self.lw