LDraw.org Discussion Forums
Instruction making rant - Printable Version

+- LDraw.org Discussion Forums (https://forums.ldraw.org)
+-- Forum: LDraw Programs (https://forums.ldraw.org/forum-7.html)
+--- Forum: LDraw File Processing and Conversion (https://forums.ldraw.org/forum-22.html)
+--- Thread: Instruction making rant (/thread-24051.html)

Pages: 1 2


RE: Instruction making rant - N. W. Perry - 2020-05-28

(2020-05-28, 11:51)Philippe Hurbain Wrote: As you say, it does work but you must "re-add" all parts between store and retrieve after the retrieve (tedious I agree). What really annoys me is "submodel wih moving parts" (eg. submodel where you must push pins after attaching to the main model), I have no other solution than to make two different submodels Sad

So the command would have to be placed in the submodel, and would apply indefinitely (n=0, perhaps)…then be released somehow in the containing model. Maybe a FLOAT | UNFLOAT pair would allow this, and it looks like you would need to use an ID system to keep track of them. This could be similar to how LDCad handles group IDs (with local and global ones), so that they can be recursive.

My first thought was to make n take the form (a,b,c…), where each member in the set refers to a higher containing model. So if you had a sub-submodel, you could float a part in the sub-submodel, as well as in its containing submodel, then release it in the main model by having a setting of (0,0,2). (The 2 means the part is released in the step after the submodel is placed.)

But that method wouldn't allow for multiple instances of a submodel. With UNFLOAT, as with FLOAT, it would apply only to the next type 1 line, so it would release the floating part only in that instance of the submodel.


RE: Instruction making rant - Daniel R - 2020-05-28

(2020-05-28, 15:32)N. W. Perry Wrote: My first thought was to make n take the form (a,b,c…), where each member in the set refers to a higher containing model. So if you had a sub-submodel, you could float a part in the sub-submodel, as well as in its containing submodel, then release it in the main model by having a setting of (0,0,2). (The 2 means the part is released in the step after the submodel is placed.)

But that method wouldn't allow for multiple instances of a submodel. With UNFLOAT, as with FLOAT, it would apply only to the next type 1 line, so it would release the floating part only in that instance of the submodel.

This syntax also does not allow to edit instruction easily. Suppose you move some subassembly into a new subfile. Then you would have to think whether to edit this tuples or not. That is manual editing, which is error-prone and time-consuming. I suggest marking the target step instead of hard-coding numbers in the first step.


RE: Instruction making rant - N. W. Perry - 2020-05-28

(2020-05-28, 15:53)Daniel R Wrote: This syntax also does not allow to edit instruction easily. Suppose you move some subassembly into a new subfile. Then you would have to think whether to edit this tuples or not. That is manual editing, which is error-prone and time-consuming. I suggest marking the target step instead of hard-coding numbers in the first step.

On the other hand, at least it's edit-able. If you get into recursive IDs, then manual editing—or rather, user comprehensibility—get a bit muddier.

But why would it have to be manual editing? There's nothing about this idea that says it has to be; I'm always assuming that editing programs would (continue to) provide a good user interface to the underlying commands. At the same time, it is a goal to have the syntax be more human-digestible than the current system of buffer exchange. And of course, manual editing will still always be an option; and if that's the case, I think recursive IDs would be far more error-prone and time consuming to manually edit than simple command line parameters. Wink

Be that as it may, it does seem clear that ID'd command pairs are necessary once we get into submodels, so the tuples would probably never become necessary. (Only unless you wanted to offer the option of a simpler syntax for when recursive IDs aren't necessary. To that end, the ID itself could be an optional parameter; if absent, the program would use the command line parameter to release the float, and if present, the software would automatically generate a paired UNFLOAT command and use that instead. Although that may be a bit like installing a steam engine in an automobile as a fallback for the internal combustion engine!)


RE: Instruction making rant - Daniel R - 2020-05-28

(2020-05-28, 16:37)N. W. Perry Wrote: But why would it have to be manual editing? There's nothing about this idea that says it has to be; I'm always assuming that editing programs would (continue to) provide a good user interface to the underlying commands.

By manual I meant "requiring human intervention", not "requiring to edit text file without visual editor". Suppose you have a FLOAT with n=3. Then you insert a step after this one. Now the part unfloats in the step previous to the original one. And it needs a human to correct that.
I can't think how a good editor would help here (but maybe it could! would you offer an explanation? Smile


RE: Instruction making rant - N. W. Perry - 2020-05-28

(2020-05-28, 13:43)Daniel R Wrote: The only thing you did not address is that the number n needs to be (manually) changed if you insert a step in the middle.

Why would it have to be changed manually? The program could automatically account for step inserts that affect any active float commands (and whether it does so could be a user-configurable option). So the reason I don't address it is that the software would. (EDIT: This is expanded on in another reply.)

That's not to say I still think this is the best way, as it's clear there are advantages to the ID and target method. I guess I'm just not understanding the drawback about manual editing. After all, everything in the code needs to be edited if it's changed, but if for example we move or rotate a part, we rely on the software to handle it, we don't worry that we'd have to manually edit the matrix! :-)


RE: Instruction making rant - N. W. Perry - 2020-05-28

(2020-05-28, 16:47)Daniel R Wrote: By manual I meant "requiring human intervention", not "requiring to edit text file without visual editor". Suppose you have a FLOAT with n=3. Then you insert a step after this one. Now the part unfloats in the step previous to the original one. And it needs a human to correct that.
I can't think how a good editor would help here (but maybe it could! would you offer an explanation? Smile

I imagine the program would have to store a list of each float command, the step number in which it's placed, and the step number in which it's released. So if a float command is placed in step s and has n=3, that means it's released in step number <s+2>, or <s+(n-1)>. This is how the editor would know whether to draw the part in its floating position, or its permanent one, according to the step number currently being viewed.

Whenever a step is inserted, the program would check the list of float commands and see whether the new step falls within any range of <s> and <s+(n-1)>. If so, it would automatically increment n, or ignore it, or ask the user, according to the configured preference.


RE: Instruction making rant - Merlijn Wissink - 2020-05-31

(2020-05-28, 14:45)N. W. Perry Wrote: Oh yes, I see what you mean now. I agree that it would be nice not to have to re-insert any parts, including the ones that are being moved. My FLOAT method would do that, since it only affects the next line. And it works similarly to your END idea, except that FLOAT automatically lasts for just a single step, unless you specify otherwise with the n parameter.

I think no matter the implementation or how it works, there must be an explicit end to whatever 'store' command is being used. Implicit ends are just too vague and keep too many edge cases open. For example, what *if* you actually want to hide/move all parts placed in multiple previous steps?

I feel like people are overthinking it a bit. What does buffer exchange (or, at least a replacement for it, whatever you wanna call it) need to do?
  • Simply put: it needs to place parts in temporary positions, with the ability to either hide them (arrows, helper parts) or place them in a final position.
What are the major limitations that the current implementation has (without hacking or abusing the system of course)?
  • It doesn't work through multiple steps.
  • It doesn't work through submodels.
  • A part has only two states: start and end (you can't have a part go through multiple positions until final position).
How can this be solved? Simply place both all positions of the part(s) together in the same command and give the command an (optional?) name to call. This takes care of all the above points and is much more robust (assuming good software implementation of course).

Let's make an example. I'm just using semi-random terminology here, probably can be improved, but it's not about the specifics here Wink

Code:
0 BUFFER DEF START "Name"
// parts
0 BUFFER POS
// parts
0 BUFFER POS
// parts
0 BUFFER DEF END

The idea here is, a BUFFER command (I still don't like the name, but I can't come up with a better one) has a required START and END. If there are no POS arguments within the buffer, this means that once the BUFFER is 'retrieved' all parts disappear, e.g. for using arrows or helper parts. The POS commands are used to place bricks in their next or final position. There can be multiple POS commands for various positions. There is also a name for the buffer definition. I guess this can be either an explicit string name, or just an integer ID or even A/B/C... like current buffer exchange.

How to use it further on the model? I can think of various options. For example, simply:

Code:
0 BUFFER "Name" NEXT

This moves the previously defined buffer to its next position (the next POS command, if any).

This takes care of all the above defined points:
  • Parts can be placed in temporary positions, and they can be moved to another positions, or disappear.
  • It works through multiple steps, because there is an explicit start and end and a name to call the buffer.
  • It works through submodels, because there is a name to call the buffer and the next positions are stored within the buffer (no need to rely on any meta-steps within the submodel that then need to be hidden or whatever)
  • A part can have multiple states instead of one or two.
  • And as a bonus, because all positions are defined together, it's very simple (relatively) to edit any of the parts within the buffer because they are grouped together.



RE: Instruction making rant - Daniel R - 2020-05-31

I like the idea with NEXT. But would you allow the parts in between the POS sections to be different (like different count or different references)? Because if so, what would you display in the PLI (and on which step)?


RE: Instruction making rant - Merlijn Wissink - 2020-05-31

(2020-05-31, 12:38)Daniel R Wrote: I like the idea with NEXT. But would you allow the parts in between the POS sections to be different (like different count or different references)? Because if so, what would you display in the PLI (and on which step)?

My idea was that the PLI would be based on the first (mandatory) set of pieces (thus, the ones before any optional POS commands). Any new pieces that appear in extra POS commands should be ignored in the PLI. They shouldn't be there in the first place anyway, but it can be gracefully handled by simply not showing them in PLI (they will of course show up in the assembly).

If you're hinting towards adding pieces to an existing buffer that need to be replaced together (e.g. you're adding a door to a model, then attach pieces to the door in the next step and only then close the door in the third step), that is indeed something that I honestly haven't thought about in my initial post. That's a good point  Undecided 

I think the most logical way to solve that with the idea I posted above is by simply using multiple buffer definitions.

Thus, something like this:
Code:
0 BUFFER DEF START A
// Door in open position
0 BUFFER POS
// Door in closed position
0 BUFFER DEF END

0 STEP

0 BUFFER DEF START B
// Parts attached to open door
0 BUFFER POS
// Parts attached to closed door
0 BUFFER DEF END

0 STEP

0 BUFFER A NEXT
0 BUFFER B NEXT

Or, maybe by extending the buffer definition in some way, maybe something like this:

Code:
0 BUFFER DEF START A
// Door in open position
0 BUFFER POS
// Door in closed position
0 BUFFER DEF END

0 STEP

0 BUFFER EXT START A
// Parts attached to open door
0 BUFFER POS
// Parts attached to closed door
0 BUFFER EXT END

0 STEP

0 BUFFER A NEXT


I personally like the first one more, because it leaves less room for error. Though, it does make me wonder how that would need to be implemented in CAD software, since it's difficult to place parts in their final positions, while the final position of the previous buffer isn't visible yet (if that sentence makes sense, maybe I should make a visual example?). On the other hand, I don't know how much of an edge case this is, because I think most buffers will be used for simple stuff. On the other, other hand a more flexible buffer exchange like this with support for multiple positions of course might make more complicated buffer exchanges possible so...

If anyone has any good or better ideas, sure post them  Smile


RE: Instruction making rant - Daniel R - 2020-05-31

(2020-05-31, 13:17)Merlijn Wissink Wrote: If anyone has any good or better ideas, sure post them  Smile

I have posted my suggested syntax in this topic. It is not ideal either as honestly is requires more boilerplate i.e. compared to the yours (and also I have not received any other comments but I'm sure there'll be other issues). But it addresses several issues I see here.

(2020-05-31, 13:17)Merlijn Wissink Wrote: They shouldn't be there in the first place anyway, but it can be gracefully handled by simply not showing them in PLI.

In my opinion that is not a good behaviors for an interface. If something should not be used, it should not be allowed by the compiler. And moreover, the syntax should not encourage you to write something which should not be used. Here you suggest that "// parts" are most likely Ldraw type 1 lines, that is, references. That allows to have different sets of references in different sections (which, again, I think should be prohibited by the compiler or LDCad). That's why I suggest a "MOVE GROUP" meta which is not a type 1 line and inherently does not allow to change parts used.

(2020-05-31, 13:17)Merlijn Wissink Wrote: (you're adding a door to a model, then attach pieces to the door in the next step and only then close the door in the third step)

That is the case I was thinking about, yes. However rare, I think it should be supported.

(2020-05-31, 13:17)Merlijn Wissink Wrote: I think the most logical way to solve that with the idea I posted above is by simply using multiple buffer definitions.

That is fine but bloats the code, requiring unnecessary many intermediate buffers in case there are many steps in between. Also making it very hard for manual editing.
Use of groups solves this, as it is allowed to add parts to existing group in many places (on different steps).

(2020-05-31, 13:17)Merlijn Wissink Wrote: Or, maybe by extending the buffer definition in some way, maybe something like this

That is essentially what I propose but again, without new type 1 lines with new positions, but with new command which only allows to set new position.

(2020-05-31, 13:17)Merlijn Wissink Wrote: I personally like the first one more, because it leaves less room for error.
I am not sure how Smile



I would also love to hear any suggestions and critics


RE: Instruction making rant - N. W. Perry - 2020-05-31

(2020-05-31, 7:45)Merlijn Wissink Wrote: I think no matter the implementation or how it works, there must be an explicit end to whatever 'store' command is being used. Implicit ends are just too vague and keep too many edge cases open. For example, what *if* you actually want to hide/move all parts placed in multiple previous steps?

I agree. I think it's clear by now that an END is necessary to allow nesting across submodels, etc. The question remaining is simply what the fallback behavior would be if a START is added without an END, and/or what the default location of an END would be for programs that automatically generate the pair.

Quote:I feel like people are overthinking it a bit. What does buffer exchange (or, at least a replacement for it, whatever you wanna call it) need to do?
  • Simply put: it needs to place parts in temporary positions, with the ability to either hide them (arrows, helper parts) or place them in a final position.
What are the major limitations that the current implementation has (without hacking or abusing the system of course)?
  • It doesn't work through multiple steps.
  • It doesn't work through submodels.
  • A part has only two states: start and end (you can't have a part go through multiple positions until final position).

Well, I'm not sure whether I believe in the concept of over-thinking. Wink But what is possible is that some of our previous thoughts can now be dismissed. I can say that your list of considerations is pretty much identical to mine. I would also add the following two requirements for what the replacement would need to do:
  • There should only be as many file references (type 1 lines) as are actually used in the model
  • It should be easily understandable to the user what the syntax is and how the commands work in the code
What other avenues have we considered that can now be discounted?

Quote:How can this be solved? Simply place both all positions of the part(s) together in the same command and give the command an (optional?) name to call. This takes care of all the above points and is much more robust (assuming good software implementation of course).

Yes, again I fully agree. This is how my idea of FLOAT works.

Quote:Let's make an example. I'm just using semi-random terminology here, probably can be improved, but it's not about the specifics here Wink

Code:
0 BUFFER DEF START "Name"
// parts
0 BUFFER POS
// parts
0 BUFFER POS
// parts
0 BUFFER DEF END

Same example using my envisioned syntax:

Code:
0 !FLOAT [id=x] [color] [matrix] [file reference]
1 [file reference line-part or submodel]

0 !FLOAT [x] [new color] [new matrix] [new file reference]

0 !FLOAT [x] [new color] [new matrix] [new file reference]

0 !UNFLOAT [x]

No reason it couldn't be done your way, where the arguments to FLOAT are a separate, commented line rather than command line parameters. And the parameters could be mutually optional, so you provide only what's changed (position, or color, or file reference) instead of the whole line.

Quote:The idea here is, a BUFFER command (I still don't like the name, but I can't come up with a better one)…

Why not FLOAT? Possible conflict with the mathematical meaning?

Quote:…has a required START and END. If there are no POS arguments within the buffer, this means that once the BUFFER is 'retrieved' all parts disappear, e.g. for using arrows or helper parts. The POS commands are used to place bricks in their next or final position. There can be multiple POS commands for various positions. There is also a name for the buffer definition. I guess this can be either an explicit string name, or just an integer ID or even A/B/C... like current buffer exchange.

How to use it further on the model? I can think of various options. For example, simply:

Code:
0 BUFFER "Name" NEXT

This moves the previously defined buffer to its next position (the next POS command, if any).

For my system, you'd just call a new FLOAT command on the same id, and provide whatever has changed in the arguments to that new command (new color, new rotation matrix, etc.). I would think you can even hide a part by specifying an invisible color.

Quote:This takes care of all the above defined points:
  • Parts can be placed in temporary positions, and they can be moved to another positions, or disappear.
  • It works through multiple steps, because there is an explicit start and end and a name to call the buffer.
  • It works through submodels, because there is a name to call the buffer and the next positions are stored within the buffer (no need to rely on any meta-steps within the submodel that then need to be hidden or whatever)
  • A part can have multiple states instead of one or two.
  • And as a bonus, because all positions are defined together, it's very simple (relatively) to edit any of the parts within the buffer because they are grouped together.

This is good, we seem to be on the same page. My idea and yours work almost exactly the same way, the only difference is in our names for things. Smile


RE: Instruction making rant - N. W. Perry - 2020-05-31

(2020-05-31, 13:17)Merlijn Wissink Wrote: If you're hinting towards adding pieces to an existing buffer that need to be replaced together (e.g. you're adding a door to a model, then attach pieces to the door in the next step and only then close the door in the third step), that is indeed something that I honestly haven't thought about in my initial post. That's a good point  Undecided 

This is no problemo for FLOAT. The code would look like this:

Code:
0 !FLOAT [id=a]
// Door in open position
1 [door in closed position]

0 STEP

0 !FLOAT [id=b]
// Part attached to open door
1 [part attached to closed door]
0 !FLOAT [id=c]
// Part attached to open door
1 [part attached to closed door]

0 STEP

0 !UNFLOAT [a]
0 !UNFLOAT [b]
0 !UNFLOAT [c]

Obviously that's very bloaty, but that's why we have groups. So FLOAT should be able to reference a group just as well as a part or submodel, and thus eliminate all those extra FLOAT commands (but replace them with grouping metas). That would look like this:

Code:
0 !FLOAT
// [color] [matrix] [group id=a] <-- matrix here is door group in open position
0 GROUP_NEXT [id=a] <-- simplified pseudo-code for LDCad's group meta
1 [door in closed position]

0 STEP

0 GROUP_NEXT [a]
1 [part attached to door]
0 GROUP_NEXT [a]
1 [part attached to door]

0 STEP

0 !UNFLOAT [group id=a]



RE: Instruction making rant - N. W. Perry - 2020-05-31

(2020-05-31, 13:51)Daniel R Wrote: Here you suggest that "// parts" are most likely Ldraw type 1 lines, that is, references. That allows to have different sets of references in different sections (which, again, I think should be prohibited by the compiler or LDCad). That's why I suggest a "MOVE GROUP" meta which is not a type 1 line and inherently does not allow to change parts used.

Now that I look again, it may actually be the opposite problem: the parts are only placed in commented ("//') lines that would be ignored in programs not supporting the buffer metas. They are never explicitly placed in the model as type 1 lines, so would simply be missing if viewed in another program.

I agree that there should be one, and only one, type 1 line for each instance of a part or submodel (or group) in a model. This reduces code bloat from repeated type 1 lines, and also means the PLI would by default display the actual piece count.
[/quote]


RE: Instruction making rant - Daniel R - 2020-06-02

(2020-05-31, 18:54)N. W. Perry Wrote: Same example using my envisioned syntax:

Code:
0 !FLOAT [id=x] [color] [matrix] [file reference]
1 [file reference line-part or submodel]

0 !FLOAT [x] [new color] [new matrix] [new file reference]

0 !FLOAT [x] [new color] [new matrix] [new file reference]

0 !UNFLOAT [x]

Now I like this, with explicit UNFLOAT marker in the target step instead of step counting Smile With support for both parts and groups this is reasonably succinct and powerful.

Moreover, if I understand correctly that the first (and only) type 1 is describing the part in its final position, while all the FLOAT lines describe intermediate positions, this syntax solves the problem of compatibility with other editors which do not support this meta (that is a problem for BUFEXCHG, REMOVE GROUP and two other suggestions in this thread). I didn't think about it before, this is cool.

(2020-05-31, 18:54)N. W. Perry Wrote: And the parameters could be mutually optional, so you provide only what's changed (position, or color, or file reference) instead of the whole line.

I support making them optional. Also it would be a good thing to discourage users from actually changing reference and color. By the way, I can't find any reasonable use for change of color. Is there one? I am not saying it should not be supported.

After some thought I understood that it sometimes necessary to replace the reference: this is needed for flexible parts. Because moving path points by some FLOAT/MOVEGROUP would work only in simple cases, in more complex cases you would need different number of path points, therefore, new submodel. It is still not clear how the fallback code should be handled in case we allow to FLOAT individual path points.


RE: Instruction making rant - Roland Melkert - 2020-06-02

(2020-06-02, 21:26)Daniel R Wrote: I support making them optional. Also it would be a good thing to discourage users from actually changing reference and color. By the way, I can't find any reasonable use for change of color. Is there one? I am not saying it should not be supported.

After some thought I understood that it sometimes necessary to replace the reference: this is needed for flexible parts. Because moving path points by some FLOAT/MOVEGROUP would work only in simple cases, in more complex cases you would need different number of path points, therefore, new submodel. It is still not clear how the fallback code should be handled in case we allow to FLOAT individual path points.

Inventing new metas might be fun, but these kinds of metas (begin end etc) are a nightmare to parse while reading LDraw content.

It is mentioned above the new meta should be able to reference groups, but personally I think it should be an extension on existing existing group mechanics.

This will make parsing the meta alot easier, even more so if you limit to a single one using a submeta.

e.g.

Code:
0 STEP
0 !SOMENEWMETA FLOAT [target=engineBlock] [pos=100 100 100] [color=4] [ori=1 0 0 0 1 0 0 0 1]
........
0 STEP
0 !SOMENEWMETA FLOAT [target=engineBlock]

Where "engineBlock" is a group name.

The first float 'overrides' position, color and rotation. Just use the parameters which are needed all others initialize with the current values.

The second float uses all default parameters, so it returns the group to its original place, color and rotation.

And if the thing you are floating is a single, once used reference, you could also do something like:

0 !SOMENEWMETA FLOAT [targetKind=ldrRef] [target=3001.dat] [pos=100 100 100] [color=4] [ori=1 0 0 0 1 0 0 0 1]

This implies that if omitted the targetKind parameter defaults to "group"

my 2cts


RE: Instruction making rant - Daniel R - 2020-06-02

(2020-06-02, 22:12)Roland Melkert Wrote: Inventing new metas might be fun, but these kinds of metas (begin end etc) are a nightmare to parse while reading LDraw content.

This discussion may be confusing but I think it arrived to a one or two new metas (depending on whether to support only groups or groups and simple references too) which do not behave like a begin and end but only affect one next line.


RE: Instruction making rant - N. W. Perry - 2020-06-03

(2020-06-02, 21:26)Daniel R Wrote: Moreover, if I understand correctly that the first (and only) type 1 is describing the part in its final position, while all the FLOAT lines describe intermediate positions, this syntax solves the problem of compatibility with other editors which do not support this meta (that is a problem for BUFEXCHG, REMOVE GROUP and two other suggestions in this thread). I didn't think about it before, this is cool.

Yes, exactly. With only one type 1 line per instance of the part, then with editors that don't support the meta, the worst case scenario is your model just displays as finished. It bothered me about buffer exchange that it hardcodes parts into the file that don't actually appear in the model.


Quote:I support making them optional. Also it would be a good thing to discourage users from actually changing reference and color. By the way, I can't find any reasonable use for change of color. Is there one? I am not saying it should not be supported.

I haven't thought of a reason for color, but somebody someday might want to be able to, and as it's just a single integer, it's not any trouble to include the possibility. And I can't immediately see a reason to specifically exclude the possibility; what would it break?

(Actually, there is one reason I thought of: use an invisible color to temporarily hide the part. But there are probably better ways to achieve this.)

Quote:After some thought I understood that it sometimes necessary to replace the reference: this is needed for flexible parts. Because moving path points by some FLOAT/MOVEGROUP would work only in simple cases, in more complex cases you would need different number of path points, therefore, new submodel. It is still not clear how the fallback code should be handled in case we allow to FLOAT individual path points.

Yes, flexible parts was the use case for changing the reference. I hadn't thought about using FLOAT commands inside flexible path subfiles, but I suppose you could. My first thought is that you would just have different subfiles for different states of the flexible part, but if we follow on to Roland's suggested structure, perhaps you could allow path caps and path points as possible target types for FLOAT.

As for the fallback, I think it would just continue to describe the part in its finished state. If you're using an editor that doesn't understand FLOAT, then you're already ignoring all but the final positions of things, so there'd be no need to provide fallback code for interim states of flexible parts.

(2020-06-02, 22:12)Roland Melkert Wrote: Inventing new metas might be fun, but these kinds of metas (begin end etc) are a nightmare to parse while reading LDraw content.

It is mentioned above the new meta should be able to reference groups, but personally I think it should be an extension on existing existing group mechanics.

This will make parsing the meta alot easier, even more so if you limit to a single one using a submeta.

That's helpful to know, since as I say, I don't necessarily understand all that goes into making these things work. I'm just able to picture how I'd like them to be. :-) But it did seem to me that having a single command would be easier to parse than keeping track of possibly-nested pairs of commands (like with multiple buffers currently).

It makes sense to build off the existing groups structure; since they are recursive, then FLOAT would be, too—you would still be able to have different float states across submodels, no? But I didn't want to assume that it would be directly based on LDCad, so I imagined the syntax as a similar but separate system.

Quote:The first float 'overrides' position, color and rotation. Just use the parameters which are needed all others initialize with the current values.

The second float uses all default parameters, so it returns the group to its original place, color and rotation.

"Override" is a good term to describe the purpose of the meta. Perhaps that could be its name?

I like the elegance of just omitting all parameters to return everything to its default. That supports the idea of making them optional; just include what you want to change. It also keeps the code tidy.

(2020-06-02, 23:44)Daniel R Wrote: This discussion may be confusing but I think it arrived to a one or two new metas (depending on whether to support only groups or groups and simple references too) which do not behave like a begin and end but only affect one next line.

I had one other meta in mind, to handle the HIDEALL scenario (where the main model is temporarily hidden to isolate a sub-build that is not a submodel). That doesn't necessarily have to be part of this line of inquiry, although perhaps it could exists as a second submeta to OVERRIDE.


RE: Instruction making rant - N. W. Perry - 2020-07-03

(2020-06-02, 22:12)Roland Melkert Wrote:
Code:
0 STEP
0 !SOMENEWMETA FLOAT [target=engineBlock] [pos=100 100 100] [color=4] [ori=1 0 0 0 1 0 0 0 1]
........
0 STEP
0 !SOMENEWMETA FLOAT [target=engineBlock]

Where "engineBlock" is a group name.

The first float 'overrides' position, color and rotation. Just use the parameters which are needed all others initialize with the current values.

The second float uses all default parameters, so it returns the group to its original place, color and rotation.

And if the thing you are floating is a single, once used reference, you could also do something like:

0 !SOMENEWMETA FLOAT [targetKind=ldrRef] [target=3001.dat] [pos=100 100 100] [color=4] [ori=1 0 0 0 1 0 0 0 1]

This implies that if omitted the targetKind parameter defaults to "group"

my 2cts

Idea: Suppose you want to float a single instance of a multiple-used reference?

Perhaps it could be that if targetKind is omitted and target is not, then target is assumed to refer to a group name and the float command acts on that group. (Presumably a group ID could also be given, helpful if a group name is later changed.)

If targetKind and target are both omitted, then the float command acts on (and only on) the following type 1 line.

Alternatively (or additionally), there could be a targetKind value of "next" that would do the same thing.

And for targetKind=ldrRef, perhaps that could be assumed whenever the value of target ends with .ldr or .dat. What I'm getting at is that the targetKind parameter could often be omitted altogether, and its value determined by other context. That makes hand-editing a little quicker (and the targetKind parameter could always be auto-generated upon saving).


So in summary, what possible values for targetKind are there?
  • "group" (default if the value of target is a group name or ID)
  • "ldrRef" (default if the value of target ends with .ldr or .dat)—this acts on all instances of the specified part or submodel
  • "next" (default if target parameter is absent)—this acts on the following type 1 line only, and could also be extended to apply to path point or path cap metas if placed within a flexible content section
Others? Perhaps "step"—acting on any float-able objects up to the next STEP command? Indeed, this could conceivably replace ROTSTEP altogether. And if there are other LPub-type metas used, like callouts or sub-builds, they could also be positioned using float commands. (I know there's a difference between rotating the view and rotating the parts themselves, but perhaps the latter makes more sense for an editing tool anyway.)