@kaalleen gcode varies so very much from machine to machine that you actually need a more extreme version of your same general idea of a general writer. But, rather than using % formatting or replace() you need to use .format() and give the user lots of different expectant operands and allow the end user the ability to format the lines in their entirety. If you check the vpype-gcode specifics you'll see that doing it like this you can make the output so general as to be able to export valid JSON with the gcode writer.
The biggest trick is that the .format() command doesn't require that you use all of the elements you give it in the text. So rather than hard coding something as %3fX the user would define their gcode settings toml for the entire line.
custom_stitch.replace("%X", str("%.3f" % x)).replace("%Y", str("%.3f" % y)).replace("%Z", str("%.1f" % z)).split('\\n') This is the absolute wrong way to do it. You can have them define the lines and then format it in the writer as:
if seg_write is not None:
output.write(
seg_write.format(
x=x,
y=y,
dx=dx,
dy=dy,
_x=-x,
_y=-y,
_dx=-dx,
_dy=-dy,
ix=xx,
iy=yy,
idx=idx,
idy=idy,
index=segment_index,
)
)
With the operands:
index: index of the particular coordinate pair. eg {index:d}
x absolute position x in floating point number. eg {x:.4f}
y absolute position y in floating point number. eg {y:g}
dx relative position x in floating point number. eg {dx:f}
dy relative position y in floating point number. eg {dy:.2f}
_x negated absolute position x in floating point number. eg {_x:.4f}
_y negated absolute position y in floating point number. eg {_y:g}
_dx negated relative position x in floating point number. eg {_dx:f}
_dy negated relative position y in floating point number. eg {_dy:.2f}
ix absolute position x in integer number. eg {ix:d}
iy absolute position y in integer number. eg {iy:d}
idx relative position x in integer number. eg {idx:d}
idy relative position y in integer number. eg {idy:d}
Note: idx and idy are properly guarded against compounding fractional rounding errors. Moving 0.1 units 1000 times results in a location 100 units away and not zero.
Then seg_write can be formatted with rather classic output values eg.
[gwrite.gcode]
document_start = "G20\nG17\nG90\n"
segment_first = "G00 X{x:.4f} Y{y:.4f}\n"
segment = "G01 X{x:.4f} Y{y:.4f}\n"
document_end = "M2\n"
unit = "mm"
or
[gwrite.gcode_relative]
document_start = "G20\nG17\nG91\n"
segment_first = "G00 X{dx:.4f} Y{dy:.4f}\n"
segment = "G01 X{dx:.4f} Y{dy:.4f}\n"
document_end = "M2\n"
unit = "mm"
To work, which is consequently a valid json writer.
Without something so very general that can write literally any ascii format from CSV to HPGL to SVG it's really going to be hard to write a clean gcode writer since gcode varies so very much. It's not too hard to see how to adapt this to writing anything in a custom output type, and really isn't limited to gcode. It would do wonders for that really sloppy gcode writer in inkstitch/pyembroidery and generally bring things a bit closer to compatibility so if the weird game of telephone ever ends it wouldn't break things.
Adapt the Gcode-writing scheme from
vpype-gcode
( https://github.com/tatarize/vpype-gcode ) to pyembroidery scheme.@kaalleen gcode varies so very much from machine to machine that you actually need a more extreme version of your same general idea of a general writer. But, rather than using
% formatting
orreplace()
you need to use.format()
and give the user lots of different expectant operands and allow the end user the ability to format the lines in their entirety. If you check the vpype-gcode specifics you'll see that doing it like this you can make the output so general as to be able to export valid JSON with the gcode writer.The biggest trick is that the
.format()
command doesn't require that you use all of the elements you give it in the text. So rather than hard coding something as %3fX the user would define their gcode settings toml for the entire line.custom_stitch.replace("%X", str("%.3f" % x)).replace("%Y", str("%.3f" % y)).replace("%Z", str("%.1f" % z)).split('\\n')
This is the absolute wrong way to do it. You can have them define the lines and then format it in the writer as:With the operands:
Then seg_write can be formatted with rather classic output values eg.
or
It even permits things as extreme as:
To work, which is consequently a valid json writer.
Without something so very general that can write literally any ascii format from CSV to HPGL to SVG it's really going to be hard to write a clean gcode writer since gcode varies so very much. It's not too hard to see how to adapt this to writing anything in a custom output type, and really isn't limited to gcode. It would do wonders for that really sloppy gcode writer in inkstitch/pyembroidery and generally bring things a bit closer to compatibility so if the weird game of telephone ever ends it wouldn't break things.