SVG import

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: SVG import

Postby shoogen » Wed Jan 11, 2012 11:09 am

I don't like crafting Regular Expression very much, so i first implemented a kind of state machine. Besides of beeing slower, that should do the job.

I think that the handling of the transform attribute needs some care.
1. getMatrix
translate and scale don't check if the optional argument for the y-Axis is present or not.
rotate doesn't hanle the axis of rotation (stationary point)
skewX and skewY are missing.
The pareser seems to rely on sax for splitting the transfortmations from the 'transform-list" (string) into the "tr" list.
To me that current parser does not seem suitable to handle lists with more than one transformation and transformations with a variable number of arguments.

2.
i saw some highly reused code:

Code: Select all

 for i in range(len(self.grouptransform)):
    print "applying group transform: ",self.grouptransform[-i-1]
    sh = sh.transformGeometry(self.grouptransform[-i-1])
I would rather recommend to iterate over the list items

Code: Select all

for transformation in self.grouptransform[::-1]:
     print "applying group transform: ",transformation
     sh = sh.transformGeometry(transformation)
Futhermore support for the 'use' element which would also imply handling the 'defs' is missing. (One would use inkscape to replace them with plain copies)
SAX seems to have Problems with CDATA in the xml code. (This is a bit more serious as is breaks parsing)

For testing i have modifiled some examples from the w3c and put them into one file.

Code: Select all

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg  xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs> <rect id="MyRect" x="0" y="0" width="60" height="10"/> </defs> 
       <rect x=".1" y=".1" width="99.8" height="29.8" fill="none" stroke="blue" stroke-width=".2" />
  <use xlink:href="#MyRect" transform="translate(20,2.5) rotate(10)" />
<path class="bezierpath" d="M100,200 C100,100 250,100 250,200 S400,300 400,200" />
<rect class="Border" x="400" y="100" width="100" height="100" />
<polyline class="Connect" points="120,200 120,120" />
<polyline class="Connect" points="250,100 250,200" />
<polyline class="Connect" points="250,200 250,300" />
<polygon class="Connect" points="800,100 300,200 500,800" />
<ellipse transform="translate(900 200) rotate(-30)"  rx="250" ry="100"  fill="none" stroke="blue" stroke-width="20"  />
<rect x="21" y="21" width="80" height="60"  fill="none" stroke="blue" stroke-width="2"/>
<g transform="translate(-10,-20) scale(2) rotate(45) translate(5,10)"> <rect x="100" y="100" width="400" height="20" rx="10" fill="green" /> </g>
<rect x="200" y="300" width="100" height="100" rx="10" fill="green" />
<g transform="translate(700 450) rotate(-30)"> <rect x="0" y="0" width="400" height="200" rx="50"  fill="none" stroke="purple" stroke-width="30" /></g>

<circle class="EndPoint" cx="100" cy="200" r="10" /><circle class="EndPoint" cx="250" cy="200" r="10" /><circle class="EndPoint" cx="400" cy="200" r="10" /><circle class="CtlPoint" cx="100" cy="100" r="10" /><circle class="CtlPoint" cx="250" cy="100" r="10" /><circle class="CtlPoint" cx="400" cy="300" r="10" /><circle class="AutoCtlPoint" cx="250" cy="300" r="9" />
<text class="Label" x="25" y="120">M100,200 C100,100 250,100 250,200</text>
<text class="Label" x="325" y="350" style="text-anchor:middle">S400,300 400,200</text>
  <path d="M200,400 h-150 a150,150 0 1,0 150,-150 z"  fill="red" stroke="blue" stroke-width="5" />
  <path d="M275,375 v-150 a150,150 0 0,0 -150,150 z"  fill="yellow" stroke="blue" stroke-width="5" />
  <path d="M400,350 l 50,-25 a25,25 -30 0,1 50,-25 l 50,-25 a25,50 -30 0,1 50,-25 l 50,-25 a25,75 -30 0,1 50,-25 l 50,-25 a25,100 -30 0,1 50,-25 l 50,-25"     fill="none" stroke="red" stroke-width="5"  />
</svg>
User avatar
yorik
Site Admin
Posts: 11645
Joined: Tue Feb 17, 2009 9:16 pm
Location: São Paulo, Brazil
Contact:

Re: SVG import

Postby yorik » Wed Jan 11, 2012 12:58 pm

wow, I hadn't met that <use> object before... extremely useful! Indeed then we must parse the <defs> too. And indeed a lot of other attributes are not supported, basically because until now neither me nor anybody else seem to have needed it... Maybe this would be the time to build a more flexible and easy to extend parser?

About the things that you see that can be coded better, I'll be glad if you propose better solutions (and I can learn something from it too!)

*EDIT* ah, I have a couple of old test files here too: http://yorik.uncreated.net/archive/pack ... tfiles.zip
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: SVG import

Postby shoogen » Fri Jan 13, 2012 4:01 pm

hi Yorik
I finished the reimplementation of the parser for the 'transform' attribute and included the fix for the empty 'style' attribute.
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: SVG import

Postby shoogen » Sun Jan 15, 2012 9:58 am

Does anyone know a way to create elliptical arcs in python?
I can imagine to create an circular arc and apply scaling and rotation afterwards. But this approach seems rather messy to me.
http://www.opencascade.org/org/gettings ... i/appli11/ looks interesting.
jmaustpc
Posts: 9619
Joined: Tue Jul 26, 2011 6:28 am
Location: Australia

Re: SVG import

Postby jmaustpc » Sun Jan 15, 2012 12:53 pm

shoogen wrote:Does anyone know a way to create elliptical arcs in python?
I can imagine to create an circular arc and apply scaling and rotation afterwards. But this approach seems rather messy to me.
http://www.opencascade.org/org/gettings ... i/appli11/ looks interesting.

Go to Part wb, create primitives, create ellipse, then look at the python console and you will see an answer.

The Angle0=0.00 and Angle1=360.00 create a full ellipse, adjust this start and finish value for a section of the ellipse.
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: SVG import

Postby shoogen » Tue Jan 17, 2012 3:33 pm

I got it

Code: Select all

Part.show(Part.Arc(Part.Ellipse(),1.5,4.5).toShape())
Last edited by shoogen on Tue Jan 17, 2012 4:14 pm, edited 1 time in total.
wmayer
Site Admin
Posts: 15279
Joined: Thu Feb 19, 2009 10:32 am

Re: SVG import

Postby wmayer » Tue Jan 17, 2012 4:11 pm

Apparently you're interested in the direct geometry not the shape!? So, you can also create an arc of an ellipse this way:

Code: Select all

e=Part.Ellipse()
...
a=Part.Arc(e,0,2)
The range [0,2] gives the domain where the arc should be defined.
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: SVG import

Postby shoogen » Tue Jan 17, 2012 4:19 pm

wmayer wrote:

Code: Select all

e=Part.Ellipse()
...
a=Part.Arc(e,0,2)
The range [0,2] gives the domain where the arc should be defined.
Thank You!
but souldn't that be [0,2*pi]

And did not quite understand what you mean with geometry here. I need an 'edge' for every elliptical arc so buildup are 'wire'
wmayer
Site Admin
Posts: 15279
Joined: Thu Feb 19, 2009 10:32 am

Re: SVG import

Postby wmayer » Tue Jan 17, 2012 4:36 pm

Thank You!
but souldn't that be [0,2*pi]
No, the range [0,2] was just an example for an arc because you didn't want a full ellipse.
And did not quite understand what you mean with geometry here. I need an 'edge' for every elliptical arc so buildup are 'wire'
Unfortunately you have edited your previous posting. There you said you wanted a trimmed curve. And a curve is a geometry, not a shape.

FYI, OCC terminology distinguishes between geometry and shape. A geometry is a point, a curve (circle, line, ellipse, ...) or a surface (plane, cone, cylinder, ...). And a shape tells something about the topology. They have vertex, edge, wire, face, shell, solid, compound and the rarely used compound solid. The three shapes vertex, edge and face are the direct topological counterpart for geometries point, curve and surface. For edge and face you can also set the domain if needed. Then wire is a set of connected edges, shell a set of connected faces, a solid is a closed shell and a compound is just a container for arbitrary shapes.
User avatar
shoogen
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: SVG import

Postby shoogen » Fri Jan 20, 2012 9:17 pm

The ellipse related features (rounded rectangle and elliptical arcs in path) are completed and ready for testing.
https://github.com/5263/free-cad/raw/sv ... portSVG.py