BelfrySCAD / BOSL2

The Belfry OpenScad Library, v2.0. An OpenSCAD library of shapes, masks, and manipulators to make working with OpenSCAD easier. BETA
https://github.com/BelfrySCAD/BOSL2/wiki
BSD 2-Clause "Simplified" License
1.01k stars 115 forks source link

Assignments #1512

Open davidedelvento opened 1 day ago

davidedelvento commented 1 day ago

This is somewhat related to #1510 or rather to the solution/suggestion there to do something like

base=union([rect(20), right(15,rect(10))]);

which of course works fine, however I don't understand why and how, and that is preventing me from being able to proceed with my design. If my understanding is correct, in plain (non-BOSL) OpenSCAD I can't do either

a = square(10);

nor

b=union(){
    square(10);
    square(20);
};

(and that is very frustrating, but it is what it is)

In BOSL2 I can do

include <BOSL2/std.scad>
base=union([
    rect(20), 
    right(15,rect(10))
]);

and

    rect(20) 
    attach(BACK,BACK)
    rect(10);

but I cannot do

base=
    rect(20) 
    attach(BACK,BACK)
    rect(10);

and not even

base=union([
    rect(20) 
    attach(BACK,BACK)
    rect(10),
    circle(1)
]);

which seems just the same as the one that works!

What I don't understand is if I am making a syntactic error (and in which case what it is and how to fix it), or if I am completely misunderstanding the semantic. I guess the root of the confusion is that AFAICT you cannot assign "objects" to variables in OpenSCAD, but somewhat in BOSL2 you worked around that limitation in some circumstances (the one that works) but my attempt to generalize it in the way to make it really useful to me (by using attachments) breaks the workaround.

adrianVmariano commented 1 day ago

You need to make sure you understand the difference between modules and functions. When you write a=rect(10); you're getting a list of four points in a by running a function called rect(). When you write rect(10) you're running a module that creates geometry. They are two unrelated objects as far as OpenSCAD is concerned---only happenstance that they both in some sense generate rectangles. When you run rect(10) attach(RIGHT,LEFT) rect(3); the top level module is passing information to the child module (attach) which enables it to do the attachment. The result of the code fragment is geometry, not data. In OpenSCAD geometry cannot be saved in variables, it just gets created. So there is no way to save that somehow. Any time you see a sequence of invocations like foo() bar() baz() those are module invocations that can't be assigned to a variable.

There is no attach() function, only an attach module, so there is no way to attach point lists to each other to produce a new point list. In order to write an attach() function, all of the functions that generate point lists would have to also generate other metadata on their output, which would create a lot of complications.

davidedelvento commented 1 day ago

Thanks for your patience, speed to respond and help with this. I'll try to understand better the difference between modules and functions.

Besides the "happenstance that they both in some sense generate rectangles", the confusion is made stronger by the fact that they have a similar (if not identical) syntax and the very same name.

There is no attach() function, only an attach module, so there is no way to attach point lists to each other to produce a new point list.

I understand the complications and I am not advocating otherwise, but this is very unfortunate, given that I was planning to use use the attachments extensively for my needs as described in the other message -- and this is instead impossible, so I need to go back to compute translation and rotations (avoiding which was the first thing that drove me to BOSL, but I digress...)

Thanks again and (unless you want this as a reminder to say something about this in the documentation) you may now close the ticket

adrianVmariano commented 1 day ago

Yes, there is a question whether it would be better to name the functions differently from the modules. This seems less elegant, though, and makes it harder to flip things between module and function invocation. It's obviously no accident that the modules and function have identical syntax. Probably what's needed is not a tweak to the documentation but instead an entire tutorial about the module vs function situation and how they behave differently. I don't want to write it, though. If you want to step up, let me know. :)