svg export issues

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
seb_kuzminsky
Posts: 11
Joined: Thu Feb 09, 2012 5:41 am

svg export issues

Post by seb_kuzminsky »

Hi folks, I'm a developer from the LinuxCNC project, just starting out hacking on FreeCAD. I'm working on a project that will require a bunch of 2d parts cut out of sheets of material (probably plywood cut on a big CNC router). I'm trying to use FreeCAD for the CAD and PyCAM for the CAM, with SVG as the interchange format between them.

I'm trying to stay away from DXF, which seems to be the traditional 2d CAD interchange format, because it seems a bit like the MS Word .doc of CAD formats: run by closed-source software giants, and spottily reverse-engineered by the open-source community.

So to this end, I'm trying to make FreeCAD's SVG export do what I want.

My branch is here: http://git.highlab.com/?p=freecad.git;a ... svg-export

I've made two changes in that branch so far:

The first change fixes a bug that would change the coordinates of all the exported sketch. FreeCAD uses mm internally, SVG uses "px", aka "user units", which by convention are 90 dpi (and you can use fractional px units, so the resolution is not *limited* to 90 dpi). The first commit scales all FreeCAD's mm coordinates by 1/25.4 inch/mm * 90 px/inch, so that the coordinates in the SVG file correspond to the coordinates in the sketch. I think this is a fairly uncontroversial change.

The second commit is maybe more questionable. The old (current!) SVG export code translates the sketch so that it fits in the top-right quadrant of the coordinate plane, which is what SVG viewers typically show the user. This is certainly the right thing to do if the goal is to print the SVG file, or display it on the screen. However, sometimes the user (me!) wants the actual coordinates specified in the sketch, for feeding to a CAM program! So the second commit does away with the translating of the sketch to fit on the printed page.

Maybe the right approach for that second commit would be to add a new file-type as an option for Export: "untranslated" SVG, or "literal" SVG, or something.

Or maybe I should give up this Quixotic quest and use some other 2d format...

Anyway, feedback is always welcome, and please consider pulling the first commit at least.
User avatar
shoogen
Veteran
Posts: 2823
Joined: Thu Dec 01, 2011 5:24 pm

Re: svg export issues

Post by shoogen »

Free cad mirrors arround the x-axis because the coordinate system of SVG meant for computer display.
This has not only implications to the quadrant the drawing is in, but it also changes the direction of rotation.
I think you missed 'Dimension', 'Annotation' and circles in your changes.
As far as I remember there is also C++ SVG export code. I don't if it is usend when exporting a drawing or not. Maybe yorik or werner have an idea.
Even If it not used one might want to consider to match coordinate handling with that C++ Code.
I might be a lot cleaner not to do the (user_unit/inch)/(mm/inch) for every single coordinate in the code, but to use a group transform instead.
Drawing Mode: (current mode)

Code: Select all

# writing paths
for ob in exportList:
                svg.write('<g transform="translate('+str(-minx)+','+str(-miny+(2*margin))+') scale(1,-1)">\n')
                svg.write(Draft.getSVG(ob))
                svg.write('</g>\n')
literal Mode:

Code: Select all

# writing paths
for ob in exportList:
                svg.write('<g transform="scale(3.5433070866141732,-3.5433070866141732)">\n')
                svg.write(Draft.getSVG(ob))
                svg.write('</g>\n')
(I omitted the changes for the view box)

Note to self: https://sourceforge.net/apps/mediawiki/ ... cape_(SVG)
seb_kuzminsky
Posts: 11
Joined: Thu Feb 09, 2012 5:41 am

Re: svg export issues

Post by seb_kuzminsky »

I spoke to the W3C about the trouble I'm having with SVG, and got some great advise. Brian Birtles and Tab Atkins were most helpful. I didn't realize that the author of the SVG file gets to pick the physical size of the user units!

Here's the thread: http://lists.w3.org/Archives/Public/www ... /0039.html

So the user can specify the physical size of the image by setting the <svg> width and height attributes using physical units, then can specify how that size maps to user units by setting the <svg> viewBox attribute. Makes sense!

Here's a commit that implements these suggestions for our SVG export: http://git.highlab.com/?p=freecad.git;a ... 92c96ff17e

There is still some confusion about the <g transform="translate...">, I think it's probably a mistake to translate the drawing, but the above commit, as it stands, is in the right direction.
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: svg export issues

Post by yorik »

Hi all,
Great to see you guys tackle that svg issue!

The Draft SVG export code actually serves 2 purposes:
- directly export objects in the 3D view to a SVG file
- put Draft objects on a Drawing page (from the Drawing workbench).

So it's important not to change units at that moment, because they must match the way other parts of freecad output to the Drawing view (basically one 3d unit is one svg unit). So I think shoogen's approach is indeed best, is to embed everything that goes directly to export (in importSVG.py) in a scale node. Additionally, in the future other users might want other kinds of scaling, and then it will be easy to implement. The scaling could even be a preferences setting, so that solves the problem once and for all.

But your latest commit seems ok for me.

If I understand well your intention is to obtain totally "unscaled" representation of objects, right? SVG is a very "visual" format, contains a lot of "dirt"... What about getting data directly from the 3D geometry? FreeCAD has a couple of very cool methods to project 3D stuff to 2D planes, this would give you very clean data... And, if your end application uses the same python version as FreeCAD, you can "import FreeCAD" inside, open a file, and project its contents on a plane.

But I might be talking nonsense, not very used to CNC... Have you talked to Dan Falck? he's working on a very interesting-looking CAM module for FreeCAD...
seb_kuzminsky
Posts: 11
Joined: Thu Feb 09, 2012 5:41 am

Re: svg export issues

Post by seb_kuzminsky »

Hi Yorick!

My primary goal is to be able to draw precise 2d geometry in FreeCAD, and export it to a CAM program in such a way that what I sketched in FreeCAD shows up unchanged in the CAM program.

A secondary goal is to use an open standard for the 2d interchange format, and I picked SVG because it seems to be the best one that's supported by both FreeCAD and PyCAM.

I understand that not everyone thinks that SVG is the right answer for 2d CAD data interchange. And I understand (now) that SVG is used for other things inside FreeCAD that we must not break. So maybe I'm on a fools errand, but I'm not convinced of the error of my ways just yet! I still want to try to make SVG work for 2d CAD interchange, without breaking other uses of the format. I don't really understand the other use cases of SVG export in FreeCAD, so I'm going to focus on what I want, and maybe others can clue me in on how my proposed changes would break existing functionality.

The current behavior of FreeCAD's SVG export fails at my primary goal above: the SVG that FreeCAD exports contains paths that have the same shape as the sketch, but translated and scaled. So it looks right if you open the SVG in Inkscape (for example), but if you feed it to CAM, it comes out wrong. I actually cut an incorrect part because of this. (Which is not a showstopper, I expect to cut plenty of bad parts figuring this out...)

There are two problems with FreeCAD's current SVGs, relative to my goal:

1. FreeCAD units are lost when exporting to SVG, so the size (scale factor) of the paths in the SVG are dependent on the SVG viewer.

2. FreeCAD translates the model when exporting to SVG such that all coordinates are non-negative and the model rests against the positive X axis and the positive Y axis (ie, the model is in the bottom left of the top-right quadrant of the cartesian plane). This looks good when printing and displaying, but it's no good for CAM. Specifically, it results in misalignment when you try to process related sketches independently. For example, I have a FreeCAD model with two sketches, one geometrically inside the other (imagine the inner and outer paths of the letter "O"). When I export them to SVG and load them into CAM, they are no longer aligned correctly - the inner sketch has been translated down and to the left relative to the outer sketch, so that their minimum X coordinates and their minimum Y coordinates are all 0.

The fix that I'm proposing for Problem 1 is in the svg-export-2 branch that I posted above: http://git.highlab.com/?p=freecad.git;a ... 7ebaf8ab8f. The key part of this change is specifying the <svg> 'width' and 'height' values in mm units, instead of the old behavior, which was specifying them without units, which defaults to user units ('px'). Providing physical units to the width and height, in combination with the user-unit width and height of the <svg> 'viewBox' attribute, is SVG-speak for specifying the scaling from SVG user units ('px') to real, physical units in this case FreeCAD's mm. (Oops, i see now that that commit also moves the viewBox, that was unintentional...)

The fix I'm proposing for Problem 2 above is simply to remove the translation (on line 978, here: http://git.highlab.com/?p=freecad.git;a ... 8ab8f#l978). This translation is currently extra work that the SVG exporter does, and it messes up the alignment of the exported sketches.

Ok, that's my motivation and a possible path forward towards my personal goal. I have no idea how these changes would interact with other goals for the SVG exporter. Or even if my personal goal would not be better accomplished in some other way. Any feedback is welcome.
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: svg export issues

Post by yorik »

Okay, I think I see better. Indeed, the way you present things, why not? Even if not made directly for CAD, SVG format has a lot of advantages, being of no big firm being the main one...

I think we could do 2 things:
1) put the mm units in the svg page definition. We must test a bit, though, to see if it doesn't break anything but I believe it won't. In any case this will only affect when you export objects directly from the 3D view, not the Drawing module (The drawing module relies exclusively on the code in Draft.py, not in importSVG.py)
2) Add a preference option so users can choose between "normal" export and "CNC" export. In the latter case, all translations and scalings would be removed. Since they happen all in the importSVG.py file IIRC, that should be easy to do too.
What do you think? Would that be OK for you?

I've a terrible amount of work on the table these weeks, so I'm afraid I can't touch that immediately, but if you're keen to try, it's not too hard. You must basically 1) compile and install the FreeCAD Qt plugin, 2) edit the Draft/Resources/ui/prefs-import.ui with Qt Designer, add a preference setting 3) recompile the Draft_rc.py with pyrcc4 and 4) in the importSVG code, make all the translations happen only if the preference is set or not.

Otherwise if you can wait I can do that too later.

@shoogen, the C++ svg export code in the drawing module is the main way to put shapes on a 2D view. The python exporter in Draft existed before that module, because there was no other way to export svg files, then after the drawing module was born I adapted the python code so it could also output its results to the Drawing module, because the C++ one lacked some features important for me, such as having fillable closed paths. The C++ shape-to-svg translator uses an OpenCascade functionality that projects a shape on a plane, and calculates all the hidden lines removal. But it creates a bunch of disconnected lines, which is hard to work with afterwards...
seb_kuzminsky
Posts: 11
Joined: Thu Feb 09, 2012 5:41 am

Re: svg export issues

Post by seb_kuzminsky »

Thanks for the suggestions Yorik, I've implemented it, the new code is available here: http://git.highlab.com/?p=freecad.git;a ... g-export-3

Here are the results of this branch (I couldnt figure out how to attach the pics to this post): http://highlab.com/~seb/freecad-svg-export/

I updated issue 591 in the tracker with some additional info: https://sourceforge.net/apps/mantisbt/f ... php?id=591

Please consider pulling the svg-export-3 branch :-)
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: svg export issues

Post by yorik »

Great! Seems perfect.
How do I pull your branch from git? I tried adding your repo as remote but doesn't seem to work... (Sorry, Git half-newbie here)
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: svg export issues

Post by yorik »

Oh, shoogen has pulled it already :) now it's easy
User avatar
yorik
Founder
Posts: 13640
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels
Contact:

Re: svg export issues

Post by yorik »

Done! I tested a bit, all seems just perfect! Congrats & thanks to both of you!
Post Reply