Closed abey79 closed 3 years ago
Yeah. I'm a fan of that. You don't need to worry about breaking changing moving the core idea over. And the firstsegment lastsegment is a good idea.
I don't love segment, not because it's not mapping a segment but because sometimes in some formats you would be exporting an point not a segment. You seem to have the same thing with LineCollection when it's really a collection of points. Lines have start and end points, and the first thing you're given isn't a segment it's a single start point.
Well LineCollection
is a collection of collection of point, to be precise, in the spirit of a "line" being a collection of point. Again, line is ambiguous and I'm not very fan of how I used it, but I think coherence is key here. You could say that in math, segments have end/start points while line are infinite things, so it's all blurry.
I'd be open to an alternative name for segment (it's not used much in the documentation, if at all -- just here and there in the code and not even in the API), but I can't think of anything better.
Most of the time we'd be doing a series of points from start point to end point. But, I wouldn't call the line (or several lines) in that block of text a line point, etc. Since it's really just a block of text probably describing a point in the series in most cases. I'd actually ditch the terminology maybe completely, and use the sort of html h1-h6 like tags.
preh1, posth1, joinh1... preh2, posth2, joinh2....
I get that that's awful, but as an example it would be maybe better to just number the things and have the parts within them. Since you only need a few different parts at each level.
Well the "line" terminology exists in vpype already (throughout the doc, in command names, etc). so I'd rather stick to it, as inopportune as it might be.
And I understand it needs to map the structure. So maybe even just make it refer more specifically to the internal workings of vpype and ditch my terms altogether.
document: header, footer collection: header, footer, join segment: header, footer, join
or whatever header and footer might be relevant there. Since the scheme only really works because vpype documents are so clearly organized into the three layer.
But, however it settles my course is pretty easy. Deprecate the module and point to the vpype commit that added similar functionality. So I'm certainly not going to step on your toes with regard to terms. I wrote this module basically to point out you should write this module. I'm not going to jinx that with some stubbornness.
level1, prologue, epilog level2, prologue, epilog level3, prologue, epilog
There's a lot of really good things to do there. The important bits is being able to know what each part is and fill it in with the data you need it to have in the way you need it to say that. You need to write this based on a template. Fitting well with vpype terms might be really important and something easy to remember would help. But, I'm kinda drawing blanks. I'm fine with segments. It makes enough sense and I recall what all the parts are.
You are right though that once you pick a name that is set in stone. So picking a bad name is an eyesore forever. I'm fine with all of the above. I can't think of better names. I'm apparently pretty good at some worse names.
Just as a small input from my side: One question you maybe should answer first would be what this plugin (or the functionality in vpype if integerated there) is supposed to be for.
If you want to do a gcode writer, then for example I don't understand why we need a join
part, but maybe I'm overlooking something for the gcode use case.
If this is supposed to be a "generic output plugin" which is fully configurable (to output anything, i.e. json), then at least the name is wrong. Also my gut-feeling tells me that the plugin will not be the right abstraction, there will always be cases of output formats which can not be modeled. So in the end the description language (so the tokens) get more and more complicated until you have approached a bad programming language.
Most likely I'm just not seeing it and there is a sweet spot of languages and output formats that can and should be supported...
Writing template outputs. It might even be able to do all the HPGL files. With join elements, it can do valid JSON, and likely most other formats. So long as they fit in a standardish ascii writing style with number written in a way printf could recognize. It'll work. Mostly it just needed to be broad enough to capture gcode syntax from basically every hobbyist who would have their own thing. Doing that, it makes for a solid enough scheme to let anybody write anything within the criteria that it's purely text based and it tends to accept elements in the right order to print them out in that way.
Even if you just pitched it for gcode and let it write everything from CSV to DXF (there's a pure text dxf), it would be fine. Likely he'd make up some term for it that works. Sure, for gcode, though really I could absolutely write SVG with it.
@theomega you raise good points: is the generic functionality really needed if so what should the name be (certainly not "gcode" since this is way too specific). I'm not too worried about either. For the former we'll see if this project gains traction and what are the use case, and it's name can easily be changed upon eventual integration in vpype (ie. it would not break user's config file if we allow for an alias pointing "gcode" top level key to the new one).
Another point you raise is whether the core approach is good or will become cluttered/limited/inadequate if/when the scope grows. For gcode and simple cases, I think it is (especially with #8). If we really wanted full flexibility, then using something like jinja template would probably be a better idea. Again, wait and see is the best attitude IMHO.
@tatarize for a HPGL support equivalent to the existing exporter, a much more refined transformation settings (with translate and rotate) would be needed. Other than that it would work probably fine.
I finished #8 in 0.4.0.
idx
and idy
) need to compound the fractional amounts in order to avoid compounding fractional errors. This happened in a lot of embroidery programs. Imagine you moved right 0.01 mm 1000 times, you traveled 10mm right? But, imagine you wrote these movements in a format that could only properly record movements 1 mm increments. You would naively round and int the value of dx which would go to 0. And do that 1000 times. The end result is that you would move right 0 mm. Which is 10 fewer millimeters than you were supposed to. If the rounding error is one-sided within relative movements, this is a risk._x
and _y
and _dx
and _dy
as well as values for the filename in the header. The index of anything within its relative level.vpype begin grid -o 25 25 10 10 circle 0 0 100 end gwrite --profile isvg test.svg
Okay.
The goal isn't to add everything and become a crappy programming language. It's just to be able to represent most forms here. Keeping in mind we are exactly limited to vpype's hierarchy. So we will only have these three levels. And we're writing out very specific code. We are limited to ascii and we're doing no calculations on the side of the profiles.
[gwrite.isvg]
header = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink">
"""
footer = "</svg>"
prelayer = '<g fill="none" stroke="black">'
preline = '<path d="M '
firstsegment = "{ix:d} {iy:d} l"
segment = "{idx:d} {idy:d} "
postline = '"/>'
postlayer = "</g>"
This is pretty hard to beat. This writes a highly specialized form of svg where we're doing relative integer moves in the mm range. Without losing steps. Which isn't always trivial to write correctly. But, writing svg in a couple lines is actually pretty cool.
I don't know anything else that couldn't be done here. It should capture nearly all ascii descriptions of vpype's structures.
Yes, gcode is a too specific for what it does. Since it can write svg, json, or whatever weird random format you come up with. But, I figure that switch could be made if it makes it into core.
The solutions in #8 really does make it a swiss army knife of writing. Most of the other writing code stuff is just for show. There was a chance somebody would need y then x as part of their code. And it lets us do away with relative and negates. So it's pretty much just a syntax language.
The many changes here have only served to simply it. (though I added some idx
and idy
values might seem unusual).
Another terminology point.
Like I could see this as:
document_start
, document_end
,
layer_start
, layer_end
, layer_join
,
lines_start
, lines_end
, lines_join
,
segment_first
, segment
, segment_last
<document_start>
<layer_start>
<lines_start>
<segment_first>
<segment>
<segment>
<segment_last>
<lines_end>
<lines_join>
<lines_start>
<segment_first>
<segment>
<segment>
<segment_last>
<lines_end>
<layer_end>
<layer_join>
<layer_start>
<lines_start>
<segment_first>
<segment>
<segment>
<segment_last>
<lines_end>
<lines_join>
<lines_start>
<segment_first>
<segment>
<segment>
<segment_last>
<lines_end>
<layer_end>
<document_end>
There's only the one document. So it doesn't need anything else. And the segments are self contained leaf-nodes. But, the layer and line levels are notably helpful. And to help with the confusion line
would be made lines
that or it could be made linecollection
and shortness be damned.
That's actually good enough, I'll go with that. Like zero ambiguity. Even the linecollection thing makes it really clear. Also, if other datatypes were added it would be obvious what their various write parts would be called.
Looks very good to me! This plug-in is becoming very neat. It might not appeal as much people who are on the opposite side of the artsy-nerdy spectrum as we are, but it should certainly serve them well too! :)
Hey, I just noticed that "linecollection" made it instead of "line". This is really unfortunate because it directly clashes with vpype.LineCollection
, which is the structure used for layers (again, consistently with the terminology of vpype's lines actually being polylines.
Just to clarify the current situation:
vpype doc | API container | vpype.gcode |
---|---|---|
losely defined as "geometries" or "pipeline's content" | vpype.Document (≈ Dict[int, vpype.LineCollection] ) |
document |
"layer" | vpype.LineCollection (≈ List[np.array(N, dtype=complex)] ) |
layer |
"line" (and sometimes "path") | np.array(N, dtype=complex) |
linecollection !!!! |
"segment" (rarely used) | n/a | segment |
The term LineCollection referring to something different should be avoided.
(Side note: FWIW, matplotlib also uses LineCollection to refer to a collection of polylines)
Yeah, okay, I switch it.
Okay, 0.7.0 is live.
Changed it to line.
In view of the possible future integration of this in vpype, I'd like to raise the point of terminology. It might sound like a bit of nitpicking but I guess these kinds of things are best done earlier than later.
Throughout vpype's code and documentation, the terminology
layer
(collection of line with, in the future, shared attribute and meant to be plotted with a specific color),line
(meaning actually a polyline, eg.linemerge
andvpype.LineCollection
), andsegment
(well, one straight segment of a line). In contrast, the terminology used here islayer
,block
, and themove
+line
combination. In my opinion, this is less than ideal. In particular, the use ofline
for something different than the rest of vpype is confusing and there would be benefit to harmonise the terminology. I would probably agree that some of the terminology choices made in vpype weren't the best, but I've always valued coherence more than perfection :)As a first proposal I submit the following:
Opinions?