plottertools / vpype-gcode

gcode extension for vpype
MIT License
37 stars 7 forks source link

[discussion] Terminology #7

Closed abey79 closed 3 years ago

abey79 commented 3 years ago

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 and vpype.LineCollection), and segment (well, one straight segment of a line). In contrast, the terminology used here is layer, block, and the move + line combination. In my opinion, this is less than ideal. In particular, the use of line 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:

header/footer
prelayer/postlayer/layerjoin
preline/postline/linejoin
firstsegment*/segment/lastsegment*/segmentjoin

* firstsegment and lastsegment would default to segment if missing

Opinions?

tatarize commented 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.

abey79 commented 3 years ago

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.

tatarize commented 3 years ago

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.

abey79 commented 3 years ago

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.

tatarize commented 3 years ago

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.

tatarize commented 3 years ago

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.

tatarize commented 3 years ago

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.

theomega commented 3 years ago

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...

tatarize commented 3 years ago

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.

abey79 commented 3 years ago

@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.

tatarize commented 3 years ago

I finished #8 in 0.4.0.

tatarize commented 3 years ago

Okay.

tatarize commented 3 years ago

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).

tatarize commented 3 years ago

Another terminology point.

Like I could see this as:

<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.

tatarize commented 3 years ago

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.

abey79 commented 3 years ago

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! :)

abey79 commented 3 years ago

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)

tatarize commented 3 years ago

Yeah, okay, I switch it.

tatarize commented 3 years ago

Okay, 0.7.0 is live.

Changed it to line.