Thursday 20 June 2013

Inkscape makes complex SVG files

Now we've got a working SVG-to-GCode converter working, it's time to think about calibrating the CNC machine. So we drew a simple grid of dots, spaced 0.1" apart (standard breadboard distance) and saved the SVG before running through our gcode generator. And something peculiar happened; it didn't quite work.
All the x axis values for every dot were the same.

When we looked at the svg file, every single dot had the same x-axis value, irrespective of where it appeared on the screen:


Our entire group of dots still had a "master translation" applied to the entire group, but this didn't explain why all the x-axis values were the same for every dot.


Further investigation revealed that every dot had it's own individual transformation matrix applied to it:


Now it's worth noting that our PCB svg (generated by loading a PDF, generated by CutePDF from inside ExpressPCB) is noticeably different to this latest file: this file we created by drawing a circle then copy-and-pasting the dot(s) repeatedly until we had a grid of 6x6 drill holes. In the PDF, every shape was a "path" - even the circles that made up our drill holes. In this file, we had "circle objects" rather than paths and it was each of these objects that had an inline transformation.

Now what we really should be doing is updating our g-code generator to parse all different types of svg files. But then we're in danger of spending more time building our tools instead of getting something working to enable us to drill some copper boards and - ultimately - make batches of PCBs. So for now, we just use the Inkscape menu - Path -> Object to path - and turn all our circles into paths. Saving the file as a plain svg seems to fix the problem: every drill hole is now a path and there are no nasty inline transformations to deal with

 <g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(0,-962.35975)">
    <path inkscape:connector-curvature="0" style="fill:#000000;stroke:none" d="m 3.5433072,1050.5905 c 0,0.9785 -0.793196,1.7717 -1.7716532,1.7717 -0.97845717,0 -1.7716535523622,-0.7932 -1.7716535523622,-1.7717 0,-0.9784 0.7931963823622,-1.7716 1.7716535523622,-1.7716 0.9784572,0 1.7716532,0.7932 1.7716532,1.7716 z" id="path2985" />
    <path inkscape:connector-curvature="0" style="fill:#ff0000;stroke:none" d="m 12.543307,1050.5905 c 0,0.9785 -0.793196,1.7717 -1.771653,1.7717 C 9.7931964,1052.3622 9,1051.569 9,1050.5905 c 0,-0.9784 0.7931964,-1.7716 1.771654,-1.7716 0.978457,0 1.771653,0.7932 1.771653,1.7716 z" id="path2987" />
 
</g>

But there's still one last thing.
As you can see from the svg snippet above, the holes are now correctly spaced (the difference between x values is 12.54-3.54 = 9 pixels and at 90dpi, 9 pixels = 9*25.4/90 = 2.54mm or 0.1") but their absolute location is still incorrect (3.54 pixels = 3.54*24.5/90 = 1mm). Our first drill hole should be a 0,0 but the x-axis value is 1mm.

Even applying the "master translation" doesn't fix this, since the x-part of the command translate(0,-962.35975) is zero.

So what's going on?
If we read the path co-ordinates that follow the m command in the svg attribute, it looks like the path is being drawn from the right-most side of the path, to the left (the x-part of each of the first few curve points is negative, suggesting the path is being drawn from right-to-left).

Now we've no idea if this is going to be consistent for all shapes drawn in future, or what happens if the user were to copy and paste, then rotate or flip their image before exporting as svg. So the easiest solution we can think of is to place a dot at 0,0 and give it it's own unique special colouring (we're thinking black for now).

After parsing the entire document, we should have a set of co-ordinates for our black dot (the origin) which we can then add/subtract from every other dot on the board, to get the correct, absolute position for all our drills holes.

Watch this space........

No comments:

Post a Comment