Closed elliotf closed 4 years ago
An SVG number can be in many different units, the dpi parameter helps to convert those to a common one. I think that's alright. The problem is rather that the numbers of the output gcode are not in mm or inch, but in simple dots
. Which is meaningless in respect the size of the original image... What if we introduce a command line parameter to set the unit of the gcode numbers? something like --unit=mm
And --unit=mm
would affect the output gcode, or how the svg units were interpreted?
It would affect the output gcode.
Actually, your example is quite complicated because it contains a viewBox
which is not handled either... Can we work with this for a moment? Should draw the same.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8"
version="1.1"
height="200mm"
width="200mm">
<g
transform="translate(0,0)"
id="layer1">
<rect
y="0"
x="0.00"
height="200mm"
width="200mm"
id="rect39"
style="fill:none;stroke:#000000;stroke-width:0.26458332" />
</g>
</svg>
Actually, that generates good gcode in mm-s. I'm confused now. Will have a look at the code. Maybe the only problem is with handling the viewBox
...
G17
G90
G0 Z10
G0 X0 Y0
M3
G4 P2000.000000
G00 Z10
G00 X0.0000 Y0.0000
G01 Z0 F10.00
G01 X200.0000 Y0.0000
G01 X200.0000 Y200.0000
G01 X0.0000 Y200.0000
G01 X0.0000 Y0.0000
G0 Z10
M5
M2
Ok, I was wrong. The output is actually in mm, so we do not need the extra command line option. I think the problem is with the viewBox
then, because the generated gcode is good without it.
It looks like the problem is not having units on the coordinates, I think. If there are no units on the coordinates, the software (rightly) assumes that the units are pixels, and so applies the DPI calculation. If the coordinates have mm
units on them, it does not appear to apply any calculation:
$ ./juicy-gcode -f ./empty-config.config square-treated-as-pixels-dpi-applied.svg
G00 X0.0000 Y0.0000
G01 X70.5556 Y0.0000
G01 X70.5556 Y70.5556
G01 X0.0000 Y70.5556
G01 X0.0000 Y0.0000
$ ./juicy-gcode -f ./empty-config.config square-without-viewbox-still-treated-as-pixels.svg
G00 X0.0000 Y0.0000
G01 X70.5556 Y0.0000
G01 X70.5556 Y70.5556
G01 X0.0000 Y70.5556
G01 X0.0000 Y0.0000
$ ./juicy-gcode -f ./empty-config.config square-works.svg
G00 X0.0000 Y0.0000
G01 X200.0000 Y0.0000
G01 X200.0000 Y200.0000
G01 X0.0000 Y200.0000
G01 X0.0000 Y0.0000
$ calc 200 / 70.5556
~2.83464388368889216448
$ calc 72 / 25.4
~2.83464566929133858268
If there was a way to look at the svg element's width
and height
and use those to infer the unit of each coordinate/attribute, that would be nice, or to provide some sort of argument to specify the format/unit of the svg that is being consumed, that would also work.
square-treated-as-pixels-dpi-applied.svg.txt square-without-viewbox-still-treated-as-pixels.svg.txt square-works.svg.txt
edit: example of svg's width/height attributes:
<svg width="104mm" height="130mm" viewBox="-52 -65 104 130" xmlns="http://www.w3.org/2000/svg" version="1.1">
<title>OpenSCAD Model</title>
I think I got something in the viewbox branch that solves the problem with the original SVG. Could you please give it a try?
The difference in your third SVG is that having defined the unit explicitely in rect
overwrites the scale implied by the viewBox
attribute. I think with my patch all will work properly. In the second example you dont define any unit, so the size of the rectangle should be (200/dpi) inch.
Ah, to be clear, my use case is to plot out drawings as generated by openscad. Openscad (and inkscape) seem to generate SVGs that have a unit on the SVG's width
and height
but none in the paths that they generate.
In my original example, the size was supposed to be 200mm by 200mm in a 350mm x 400mm area (the dimensions of my plotter). The viewbox branch came up with an interesting result that looks like it's using a dpi of 25
for mm dpi instead of 25.4
. I'd assume something is coercing 25.4
to an Int somewhere and dropping the decimal place(s).
$ cat simple-square-svg.txt
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg8"
version="1.1"
viewBox="0 0 400 350"
height="350mm"
width="400mm">
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0,0)"
id="layer1">
<rect
y="0"
x="0.00"
height="200.00"
width="200.00"
id="rect39"
style="fill:none;stroke:#000000;stroke-width:0.26458332" />
</g>
</svg>
$ ~/.local/bin/juicy-gcode -f ./empty-config.config simple-square-svg.txt
G00 X0.0000 Y0.0000
G01 X199.8486 Y0.0000
G01 X199.8486 Y199.9746
G01 X0.0000 Y199.9746
G01 X0.0000 Y0.0000
$ calc 25 / 25.4
~0.98425196850393700787
$ calc 199.8486 / 200
0.999243
You probably need to use -m
to get the good result. The branch gives the following result, which is pretty much what I expect. However, you are right, there is a loss of precision, what I can't explain right now :) I'll have a look
I found the problem, the SVG parser library that I use, returns an Int for document size, causing the precision loss. I added a workaround
Yes! That works! Yay! Thank you very much @domoszlai !
Great! Merged, try to release it ASAP.
Hello and thank you for this wonderful software!
I'm attempting to use this to plot a metric svg and am running into issues because -d assumes I'm using inches and does not support decimal values.
I would be able to do this if the
-d
option allowed decimal values, as I'd be able to put 25.4 in as the DPI (because 1 inch === 25.4mm) but the-d
option is of typeInt
and a naive replacement ofInt
withFloat
orDouble
led me down a path towards Graphics.Svg.CssTypes.toUserUnit expecting Int, which is pretty reasonable.I'm hoping I'm missing something simple here and that there's an easy way to provide svgs that are assuming the units are metric. :) I've attached the simple svg to provide an example of what I am trying to do.
Thank you again!
simple-square-svg.txt