discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Why is left_half not a full one half?

BR
Bob Roos
Sat, Sep 19, 2026 2:16 PM

Hello OpenSCAD,

OpenSCAD version 2026.09.09 (git 33e8fdd8)

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half()tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);//
/*
cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT);
right(L-T)fwd(T)cuboid([T,TH+2*T,W],rounding=T/2,anchor=BOTTOM+FRONT+LEFT);
#right(L)back(TH)cuboid([Hook+T,T,W],rounding=T/2,anchor=BOTTOM+FRONT+RIGHT);
*/

--
Best regards,
Bob                          mailto:roosbob@wybatap.com

Hello OpenSCAD, OpenSCAD version 2026.09.09 (git 33e8fdd8) // towel holder for cabinet door // Bob Roos // September 19, 2026 include <BOSL2/std.scad> //or screws or threading $fa = 1; $fs = 1; LHF = .28; // Layer height for faster build LH=.25; // Layer height after 1st layer FL=.2; // first layer T = 1.6; HD = 50; W = 20; L = 80; TH = 19; Hook = 4; left_half()tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);// /* cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT); right(L-T)fwd(T)cuboid([T,TH+2*T,W],rounding=T/2,anchor=BOTTOM+FRONT+LEFT); #right(L)back(TH)cuboid([Hook+T,T,W],rounding=T/2,anchor=BOTTOM+FRONT+RIGHT); */ -- Best regards, Bob mailto:roosbob@wybatap.com
BR
Bob Roos
Sat, Sep 19, 2026 2:30 PM

Hi Bob,

If BACK is removed from the anchor then the full 1/2 is generated

Saturday, September 19, 2026, 10:16:37 AM, you wrote:

Hello OpenSCAD,

OpenSCAD version 2026.09.09 (git 33e8fdd8)

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half()tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);//
/*
cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT);
right(L-T)fwd(T)cuboid([T,TH+2*T,W],rounding=T/2,anchor=BOTTOM+FRONT+LEFT);
#right(L)back(TH)cuboid([Hook+T,T,W],rounding=T/2,anchor=BOTTOM+FRONT+RIGHT);
*/

--
have Fun,
Bob                          mailto:roosbob@wybatap.com

Hi Bob, If BACK is removed from the anchor then the full 1/2 is generated Saturday, September 19, 2026, 10:16:37 AM, you wrote: > Hello OpenSCAD, > OpenSCAD version 2026.09.09 (git 33e8fdd8) > // towel holder for cabinet door > // Bob Roos > // September 19, 2026 > include <BOSL2/std.scad> //or screws or threading > $fa = 1; > $fs = 1; > LHF = .28; // Layer height for faster build > LH=.25; // Layer height after 1st layer > FL=.2; // first layer > T = 1.6; > HD = 50; > W = 20; > L = 80; > TH = 19; > Hook = 4; > left_half()tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);// > /* > cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT); > right(L-T)fwd(T)cuboid([T,TH+2*T,W],rounding=T/2,anchor=BOTTOM+FRONT+LEFT); > #right(L)back(TH)cuboid([Hook+T,T,W],rounding=T/2,anchor=BOTTOM+FRONT+RIGHT); > */ -- have Fun, Bob mailto:roosbob@wybatap.com
BR
Bob Roos
Sat, Sep 19, 2026 2:53 PM

Hi Bob,

I would really apreciate it someone would take out the comments for the bottom 3 parts and make them into attachments.

I am just not getting it and I needed to get this made today so back to waht I know works.

Thanks

Saturday, September 19, 2026, 10:16:37 AM, you wrote:

Hello OpenSCAD,

OpenSCAD version 2026.09.09 (git 33e8fdd8)

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half()tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);//
/*
cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT);
right(L-T)fwd(T)cuboid([T,TH+2*T,W],rounding=T/2,anchor=BOTTOM+FRONT+LEFT);
#right(L)back(TH)cuboid([Hook+T,T,W],rounding=T/2,anchor=BOTTOM+FRONT+RIGHT);
*/

--
have Fun,
Bob                          mailto:roosbob@wybatap.com

Hi Bob, I would really apreciate it someone would take out the comments for the bottom 3 parts and make them into attachments. I am just not getting it and I needed to get this made today so back to waht I know works. Thanks Saturday, September 19, 2026, 10:16:37 AM, you wrote: > Hello OpenSCAD, > OpenSCAD version 2026.09.09 (git 33e8fdd8) > // towel holder for cabinet door > // Bob Roos > // September 19, 2026 > include <BOSL2/std.scad> //or screws or threading > $fa = 1; > $fs = 1; > LHF = .28; // Layer height for faster build > LH=.25; // Layer height after 1st layer > FL=.2; // first layer > T = 1.6; > HD = 50; > W = 20; > L = 80; > TH = 19; > Hook = 4; > left_half()tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);// > /* > cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT); > right(L-T)fwd(T)cuboid([T,TH+2*T,W],rounding=T/2,anchor=BOTTOM+FRONT+LEFT); > #right(L)back(TH)cuboid([Hook+T,T,W],rounding=T/2,anchor=BOTTOM+FRONT+RIGHT); > */ -- have Fun, Bob mailto:roosbob@wybatap.com
JB
Jordan Brown
Sat, Sep 19, 2026 4:29 PM

Because BOSL2 defaults to using a 100-unit mask to implement left_half. 
It's centered on the origin, so that means that it extends to +/-50 in Y
and Z. (And to -100 in X, though that's not obvious from the docs.)

https://github.com/BelfrySCAD/BOSL2/wiki/partitions.scad#functionmodule-left_half

|s| Mask size to use. Use a number larger than twice your object's
largest axis. If you make this too large, OpenSCAD's preview rendering
may display the wrong half. (Module version) Default: 100

The caveat is a little wrong.  Preview gets it wrong if the camera is
inside the invisible shape - which is of course more likely if it's larger.

Why does it have such a limit?  Because OpenSCAD doesn't have infinite
objects, and doesn't have a native clipping operation.  You can only
implement "left half" in two ways:  you can intersect the object with a
big cube on the left, or you can subtract a big cube on the right from
the object.  In either case, if your cube isn't big enough, you won't
get the desired result.

include <BOSL2/std.scad>

left_half() sphere(60);

If BACK is removed from the anchor then the full 1/2 is generated

Because then the entire tube is inside +/-50 in Y.

I would really apreciate it someone would take out the comments for the bottom 3 parts and make them into attachments.

I assume that you want the ankle bone connected to the leg
bone half-tube connected to the long cuboid, connected to the shorter
cross-wise cuboid, connected to the small cuboid.

I don't think you can connect anything to the right side of the
half-tube, at least not easily.  Attachments are children of the thing
they are attached to, and so the entire assemblage would be processed by
the left_half(), which would throw away all of the cuboids.

You could certainly make an attachable half-tube module (or whatever
fraction you like), but that would be a lot of work for little gain. 
What you've done - arranging that the two parts meet at the origin -
seems like a good solution.

For the connections between the cuboids, here are two possible
solutions.  The first uses align(), which is cool but still seems a bit
magic to me.  The second explicitly uses position() and anchor=.

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half(s=150)
tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);

cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) {
align(RIGHT, FRONT, inside=true)
cuboid([T,TH+2*T,W],rounding=T/2) {
align(BACK, RIGHT, inside=true)
cuboid([Hook+T,T,W],rounding=T/2);
}
}

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half(s=150)
tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);

cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) {
position(RIGHT+FRONT)
cuboid([T,TH+2*T,W],rounding=T/2, anchor=FRONT+RIGHT) {
position(BACK+RIGHT)
cuboid([Hook+T,T,W],rounding=T/2,anchor=BACK+RIGHT);
}
}

Because BOSL2 defaults to using a 100-unit mask to implement left_half.  It's centered on the origin, so that means that it extends to +/-50 in Y and Z. (And to -100 in X, though that's not obvious from the docs.) https://github.com/BelfrySCAD/BOSL2/wiki/partitions.scad#functionmodule-left_half > |s| Mask size to use. Use a number larger than twice your object's > largest axis. If you make this too large, OpenSCAD's preview rendering > may display the wrong half. (Module version) Default: 100 > The caveat is a little wrong.  Preview gets it wrong if the camera is inside the invisible shape - which is of course more likely if it's larger. Why does it have such a limit?  Because OpenSCAD doesn't have infinite objects, and doesn't have a native clipping operation.  You can only implement "left half" in two ways:  you can intersect the object with a big cube on the left, or you can subtract a big cube on the right from the object.  In either case, if your cube isn't big enough, you won't get the desired result. include <BOSL2/std.scad> left_half() sphere(60); > If BACK is removed from the anchor then the full 1/2 is generated Because then the entire tube is inside +/-50 in Y. > I would really apreciate it someone would take out the comments for the bottom 3 parts and make them into attachments. I assume that you want the ankle bone connected to the leg bone half-tube connected to the long cuboid, connected to the shorter cross-wise cuboid, connected to the small cuboid. I don't think you *can* connect anything to the right side of the half-tube, at least not easily.  Attachments are children of the thing they are attached to, and so the entire assemblage would be processed by the left_half(), which would throw away all of the cuboids. You could certainly make an attachable half-tube module (or whatever fraction you like), but that would be a lot of work for little gain.  What you've done - arranging that the two parts meet at the origin - seems like a good solution. For the connections between the cuboids, here are two possible solutions.  The first uses align(), which is cool but still seems a bit magic to me.  The second explicitly uses position() and anchor=. // towel holder for cabinet door // Bob Roos // September 19, 2026 include <BOSL2/std.scad> //or screws or threading $fa = 1; $fs = 1; LHF = .28; // Layer height for faster build LH=.25; // Layer height after 1st layer FL=.2; // first layer T = 1.6; HD = 50; W = 20; L = 80; TH = 19; Hook = 4; left_half(s=150) tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2); cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) { align(RIGHT, FRONT, inside=true) cuboid([T,TH+2*T,W],rounding=T/2) { align(BACK, RIGHT, inside=true) cuboid([Hook+T,T,W],rounding=T/2); } } // towel holder for cabinet door // Bob Roos // September 19, 2026 include <BOSL2/std.scad> //or screws or threading $fa = 1; $fs = 1; LHF = .28; // Layer height for faster build LH=.25; // Layer height after 1st layer FL=.2; // first layer T = 1.6; HD = 50; W = 20; L = 80; TH = 19; Hook = 4; left_half(s=150) tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2); cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) { position(RIGHT+FRONT) cuboid([T,TH+2*T,W],rounding=T/2, anchor=FRONT+RIGHT) { position(BACK+RIGHT) cuboid([Hook+T,T,W],rounding=T/2,anchor=BACK+RIGHT); } }
JB
Jordan Brown
Sat, Sep 19, 2026 4:34 PM

On 9/19/2026 9:29 AM, Jordan Brown wrote:

The caveat is a little wrong.  Preview gets it wrong if the camera is
inside the invisible shape - which is of course more likely if it's
larger.

Here's a demonstration.  I set s=1000 in the call to left_half.

If I look at the model from far enough away, I get the expected shape:

But if I zoom in just a little, I get this:

This is covered in the FAQ: 
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/FAQ#Why_does_difference_(or_intersection)_sometimes_not_work_in_preview?

On 9/19/2026 9:29 AM, Jordan Brown wrote: > The caveat is a little wrong.  Preview gets it wrong if the camera is > inside the invisible shape - which is of course more likely if it's > larger. Here's a demonstration.  I set s=1000 in the call to left_half. If I look at the model from far enough away, I get the expected shape: But if I zoom in just a little, I get this: This is covered in the FAQ:  https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/FAQ#Why_does_difference_(or_intersection)_sometimes_not_work_in_preview?
AM
Adrian Mariano
Sat, Sep 19, 2026 5:33 PM

Why is it bad that align() seems like magic?  You wanna know exactly how it
works before you can use it?

If you use left_half() on something then it will apply to all children.
You could instead do you own manual left-half using diff() and you could
use tags to get the result you want.  That would be the way to do it fully
with attachments.

On Sat, Sep 19, 2026 at 12:39 PM Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:

Because BOSL2 defaults to using a 100-unit mask to implement left_half.
It's centered on the origin, so that means that it extends to +/-50 in Y
and Z. (And to -100 in X, though that's not obvious from the docs.)

https://github.com/BelfrySCAD/BOSL2/wiki/partitions.scad#functionmodule-left_half

s Mask size to use. Use a number larger than twice your object's largest
axis. If you make this too large, OpenSCAD's preview rendering may display
the wrong half. (Module version) Default: 100

The caveat is a little wrong.  Preview gets it wrong if the camera is
inside the invisible shape - which is of course more likely if it's larger.

Why does it have such a limit?  Because OpenSCAD doesn't have infinite
objects, and doesn't have a native clipping operation.  You can only
implement "left half" in two ways:  you can intersect the object with a big
cube on the left, or you can subtract a big cube on the right from the
object.  In either case, if your cube isn't big enough, you won't get the
desired result.

include <BOSL2/std.scad>

left_half() sphere(60);

If BACK is removed from the anchor then the full 1/2 is generated

Because then the entire tube is inside +/-50 in Y.

I would really apreciate it someone would take out the comments for the bottom 3 parts and make them into attachments.

I assume that you want the ankle bone connected to the leg bone half-tube
connected to the long cuboid, connected to the shorter cross-wise cuboid,
connected to the small cuboid.

I don't think you can connect anything to the right side of the
half-tube, at least not easily.  Attachments are children of the thing they
are attached to, and so the entire assemblage would be processed by the
left_half(), which would throw away all of the cuboids.

You could certainly make an attachable half-tube module (or whatever
fraction you like), but that would be a lot of work for little gain.  What
you've done - arranging that the two parts meet at the origin - seems like
a good solution.

For the connections between the cuboids, here are two possible solutions.
The first uses align(), which is cool but still seems a bit magic to me.
The second explicitly uses position() and anchor=.

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half(s=150)
tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);

cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) {
align(RIGHT, FRONT, inside=true)
cuboid([T,TH+2*T,W],rounding=T/2) {
align(BACK, RIGHT, inside=true)
cuboid([Hook+T,T,W],rounding=T/2);
}
}

// towel holder for cabinet door
// Bob Roos
// September 19, 2026

include <BOSL2/std.scad> //or screws or threading
$fa = 1;
$fs = 1;
LHF = .28;      // Layer height for faster build
LH=.25; // Layer height after 1st layer
FL=.2; // first layer

T = 1.6;
HD = 50;
W = 20;
L = 80;
TH = 19;
Hook = 4;

left_half(s=150)
tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2);

cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) {
position(RIGHT+FRONT)
cuboid([T,TH+2*T,W],rounding=T/2, anchor=FRONT+RIGHT) {
position(BACK+RIGHT)
cuboid([Hook+T,T,W],rounding=T/2,anchor=BACK+RIGHT);
}
}


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Why is it bad that align() seems like magic? You wanna know exactly how it works before you can use it? If you use left_half() on something then it will apply to all children. You could instead do you own manual left-half using diff() and you could use tags to get the result you want. That would be the way to do it fully with attachments. On Sat, Sep 19, 2026 at 12:39 PM Jordan Brown via Discuss < discuss@lists.openscad.org> wrote: > Because BOSL2 defaults to using a 100-unit mask to implement left_half. > It's centered on the origin, so that means that it extends to +/-50 in Y > and Z. (And to -100 in X, though that's not obvious from the docs.) > > > https://github.com/BelfrySCAD/BOSL2/wiki/partitions.scad#functionmodule-left_half > > s Mask size to use. Use a number larger than twice your object's largest > axis. If you make this too large, OpenSCAD's preview rendering may display > the wrong half. (Module version) Default: 100 > > > The caveat is a little wrong. Preview gets it wrong if the camera is > inside the invisible shape - which is of course more likely if it's larger. > > Why does it have such a limit? Because OpenSCAD doesn't have infinite > objects, and doesn't have a native clipping operation. You can only > implement "left half" in two ways: you can intersect the object with a big > cube on the left, or you can subtract a big cube on the right from the > object. In either case, if your cube isn't big enough, you won't get the > desired result. > > include <BOSL2/std.scad> > > left_half() sphere(60); > > > If BACK is removed from the anchor then the full 1/2 is generated > > > Because then the entire tube is inside +/-50 in Y. > > > I would really apreciate it someone would take out the comments for the bottom 3 parts and make them into attachments. > > > I assume that you want the ankle bone connected to the leg bone half-tube > connected to the long cuboid, connected to the shorter cross-wise cuboid, > connected to the small cuboid. > > I don't think you *can* connect anything to the right side of the > half-tube, at least not easily. Attachments are children of the thing they > are attached to, and so the entire assemblage would be processed by the > left_half(), which would throw away all of the cuboids. > > You could certainly make an attachable half-tube module (or whatever > fraction you like), but that would be a lot of work for little gain. What > you've done - arranging that the two parts meet at the origin - seems like > a good solution. > > For the connections between the cuboids, here are two possible solutions. > The first uses align(), which is cool but still seems a bit magic to me. > The second explicitly uses position() and anchor=. > > > // towel holder for cabinet door > // Bob Roos > // September 19, 2026 > > include <BOSL2/std.scad> //or screws or threading > $fa = 1; > $fs = 1; > LHF = .28; // Layer height for faster build > LH=.25; // Layer height after 1st layer > FL=.2; // first layer > > T = 1.6; > HD = 50; > W = 20; > L = 80; > TH = 19; > Hook = 4; > > left_half(s=150) > tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2); > > cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) { > align(RIGHT, FRONT, inside=true) > cuboid([T,TH+2*T,W],rounding=T/2) { > align(BACK, RIGHT, inside=true) > cuboid([Hook+T,T,W],rounding=T/2); > } > } > > > > > // towel holder for cabinet door > // Bob Roos > // September 19, 2026 > > include <BOSL2/std.scad> //or screws or threading > $fa = 1; > $fs = 1; > LHF = .28; // Layer height for faster build > LH=.25; // Layer height after 1st layer > FL=.2; // first layer > > T = 1.6; > HD = 50; > W = 20; > L = 80; > TH = 19; > Hook = 4; > > left_half(s=150) > tube(id=HD,wall=T,l=W,anchor=BACK+BOTTOM,rounding=T/2); > > cuboid([L,T,W],rounding=T/2,anchor=BOTTOM+BACK+LEFT,except=LEFT) { > position(RIGHT+FRONT) > cuboid([T,TH+2*T,W],rounding=T/2, anchor=FRONT+RIGHT) { > position(BACK+RIGHT) > cuboid([Hook+T,T,W],rounding=T/2,anchor=BACK+RIGHT); > } > } > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Sat, Sep 19, 2026 6:53 PM

Why is it bad that align() seems like magic?  You wanna know exactly how it works before you can use it?

Yeah, roughly. It’s a black box that definitely does useful stuff conveniently, but I haven’t really internalized what it means so I can’t use it confidently.

> Why is it bad that align() seems like magic? You wanna know exactly how it works before you can use it? Yeah, roughly. It’s a black box that definitely does useful stuff conveniently, but I haven’t really internalized what it *means* so I can’t use it confidently.
AM
Adrian Mariano
Sat, Sep 19, 2026 7:35 PM

I don't think align() should be hard to understand.  It exists because I
got tired of writing things like

thing() position(RIGHT) child(anchor=LEFT)

In a common scenario, the position(RIGHT) implies where you want the child,
so let's make that happen automatically without manually respecifying the
location (sign reversed) in the child's anchor.  That's if you want to
stack things.  If you want the child inside the parent that would be

thing() position(RIGHT) child(anchor=RIGHT)

which you can accomplish with the inside=true parameter to align().
Abstracting this kind of positioning means you can change

thing() { position(RIGHT) child(anchor=LEFT); position(LEFT);
child(anchor=RIGHT);}

into

thing() align([LEFT,RIGHT]) child();

Once you've got your child located on the right face of the parent you
might want to slide it around on the parent's face where you put
it---that's what the second parameter of align does.

I think align() is the most important and most useful object positioning
command in BOSL2.

Understanding HOW align() does this internally requires an understanding of
a bunch of BOSL2 anchoring internals that I suggest people generally not
attempt to understand.

On Sat, Sep 19, 2026 at 2:54 PM Jordan Brown openscad@jordan.maileater.net
wrote:

Why is it bad that align() seems like magic?  You wanna know exactly how

it works before you can use it?

Yeah, roughly. It’s a black box that definitely does useful stuff
conveniently, but I haven’t really internalized what it means so I can’t
use it confidently.

I don't think align() should be hard to understand. It exists because I got tired of writing things like thing() position(RIGHT) child(anchor=LEFT) In a common scenario, the position(RIGHT) implies where you want the child, so let's make that happen automatically without manually respecifying the location (sign reversed) in the child's anchor. That's if you want to stack things. If you want the child inside the parent that would be thing() position(RIGHT) child(anchor=RIGHT) which you can accomplish with the inside=true parameter to align(). Abstracting this kind of positioning means you can change thing() { position(RIGHT) child(anchor=LEFT); position(LEFT); child(anchor=RIGHT);} into thing() align([LEFT,RIGHT]) child(); Once you've got your child located on the right face of the parent you might want to slide it around on the parent's face where you put it---that's what the second parameter of align does. I think align() is the most important and most useful object positioning command in BOSL2. Understanding HOW align() does this internally requires an understanding of a bunch of BOSL2 anchoring internals that I suggest people generally not attempt to understand. On Sat, Sep 19, 2026 at 2:54 PM Jordan Brown <openscad@jordan.maileater.net> wrote: > > > Why is it bad that align() seems like magic? You wanna know exactly how > it works before you can use it? > > Yeah, roughly. It’s a black box that definitely does useful stuff > conveniently, but I haven’t really internalized what it *means* so I can’t > use it confidently. >