./dev |
Original theme by orderedlist (CC-BY-SA)
Where applicable, all content is licensed under a CC-BY-SA.
|
At one point, I had good success with an Inkscape plugin called Gcodetools but it seems to have succumbed to bit-rot and doesn't work on my current Ubuntu installation (16.04).
I'm settling on a rough toolchain that takes some base format (PostScript/PDF/SVG/etc.), converts to "GNUPlot format" then converts to GCocde.
Orig -> SVG
Create object in whatever tool and export to SVGSVG -> PS
Use rsvg-convert
to convert from SVG to PostScriptPS -> GP
Use pstoedit
to convert to "gnuplot" polygon formatGP -> GCode
Order the polygons properly, removing duplicate boundaries and convert to GCode using clipcli
, convert from GNUPlot format to GCode using gp2ngc
and then rescale using other cli GCode tools.Some tools of relevance are:
Under Ubuntu, some of the tools can be installed via:
sudo apt-get install pstoedit librsvg2-bin
Though this is pretty hodge-podge, there are a few things to consider:
pstoedit
loses units when converting to RS274
GCode. I believe this only considers PostScript with "pixel" units, regardless of original units, then converts a pixel to 1/72 inches. A post scale has to be done if using pstoedit
to rescale to the appropriate unitspstoedit
is used, this creates a problem when trying to cut out shapes in the correct order. clipcli
has an option to print out polygons in 'tree' order which should print the inner polygons first.grecode
as linked above.The following is an example script to convert an input SVG file into GCode:
inpsvg="$1"
sf=`echo '72/25.4' | bc -l`
premul=`echo 1000000 | bc -l`
invmul=`echo "1/$premul" | bc -l`
frapid=""
fslow="F800"
S="1.0"
if [[ "$inpsvg" == "" ]] ; then
echo "provide input svg"
exit 1
fi
rawtype=`file $inpsvg`
checktype=`file -b $inpsvg | cut -f1 -d' '`
if [[ "$checktype" != "SVG" ]] ; then
echo -e "file $inpsvg is of type:\n\n$rawtype\n\nNnot an SVG file? Exiting.\n"
exit 1
fi
bn=`basename $inpsvg .svg`
# causes duplicate paths otherwise
#
sed -i 's/fill="[^"]*"/fill="none"/g' $inpsvg
echo "creating $bn.ps"
rsvg-convert -f ps -o $bn.ps $inpsvg
pstoedit -f gnuplot $bn.ps $bn.gp
clipcli -s $bn.gp -F -x $premul -T > ${bn}-ord.gp
sfx_slow="$frapid S$S"
sfx_rapid="$fslow S0"
echo gp2ngc -i ${bn}-ord.gp -s "$invmul" --sfx-rapid "$sfx_rapid" --sfx-slow "$sfx_slow" -o ${bn}.ngc
gp2ngc -i ${bn}-ord.gp --sfx-rapid "$sfx_rapid" --sfx-slow "$sfx_slow" | ngc_scale -s "$invmul" > ${bn}.ngc
In theory, pstoedit
can be used to create GCode but pstoedit
converts to the RS274
standard. Among other things, the RS274
includes variables so a substitution step needs to be involved in order to "normalize" to something that other GCode interpreters can understand (for example, the smoothieboard or grbl).
There's still the problem of polygon ordering but assuming that's not an issue, the following is a "hacky" script does the substitution (no nested expressions, no non-trivial functions, run at your own risk):
#!/usr/bin/python
#
# regexp substitution of variables.
# Uses Python's "eval" to evaluate interior
# after variable substitution.
#
# AGPLv3 license
#
import sys
import re
= {}
var_map
# variable decleration
#
= re.compile( r'\s*#(\d+)\s*=\s*([^\s]+)\s*(\([^\)]*\))?\s*$' )
var_decl_pat
# not [], [], not []
#
= re.compile( r'([^\[]*)\[([^\]]*)\]([^\[]*)' )
expr_pat
# not #*, #\d+, not #*
#
= re.compile( r'([^#]*)(#\d+)([^#]*)' )
var_sub_pat
# consider comments separately to avoid matching '#' and
# other special characters
#
= re.compile( r'\([^\)]*\)' )
comment_pat
= 0
line_no for line in sys.stdin:
+= 1
line_no
= line.rstrip()
line = ""
comments for (comment) in re.findall(comment_pat, line):
= comments + comment
comments
= re.sub(comment_pat, '', line)
line = re.match(var_decl_pat, line)
m if m:
"#" + str(m.group(1)) ] = str(m.group(2))
var_map[ continue
= ""
varsub_line for (pfx, var_subs, sfx) in re.findall(var_sub_pat, line):
if var_subs in var_map:
pass
else:
print " ERROR on line", line_no, ", no variable mapping for", var_subs
1)
sys.exit(continue
+= pfx
varsub_line += var_map[var_subs]
varsub_line += sfx
varsub_line
if varsub_line == "":
= line
varsub_line
= re.search(expr_pat, varsub_line)
xpr_match if not xpr_match:
print varsub_line + comments
continue
= ""
cur_line for (pfx, xpr, sfx) in re.findall(expr_pat, varsub_line):
= eval(xpr)
xpr_val += pfx + str(xpr_val) + sfx
cur_line
print cur_line + comments