### Understanding children()

DM
Daniel Miner
Tue, Nov 22, 2022 8:41 PM

I have a need for something and I think children() may help me but I have
not been able to figure it out.  For example, I want to create a module
that both adds (union) and subtracts (difference) something to/from an
existing object.  For example:

module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2)

{  translate (pos)
rotate (rot)
cylinder(d=dia, h=hgt);
}

module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2)
{  translate (pos)
rotate (rot)
translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2);
}

// mounting plate
difference()
{  union ()
{  cube ([30, 30, 3]);
washer([ 5,  5, 3]);
washer([25,  5, 3]);
washer([ 5, 25, 3]);
washer([25, 25, 3]);
}
screw_hole([ 5,  5, 0], hgt=6);
screw_hole([25,  5, 0], hgt=6);
screw_hole([ 5, 25, 0], hgt=6);
screw_hole([25, 25, 0], hgt=6);
}

But I'd like to have a module that could do both operations at once.
Something like this:

module screw_mount(pos=[0,0,0], rot=[0,0,0])

{
translate (pos)
rotate (rot)
difference()
{
union ()
{
cylinder (d=10, h=2);
children();
}
translate ([0, 0, -1]) cylinder (d=6, h=8);
}
}

// mounting plate
union ()
{  cube ([30, 30, 3]);
screw_mount ([ 5,  5, 3]);
screw_mount ([25,  5, 3]);
screw_mount ([ 5, 25, 3]);
screw_mount ([25, 25, 3]);
}

I know the above does NOT work maybe because I don't yet understand how
children work.
Or perhaps what I want to do can't be done.

Thanks in advance for any help.

• Dan
I have a need for something and I think children() may help me but I have not been able to figure it out. For example, I want to create a module that both adds (union) and subtracts (difference) something to/from an existing object. For example: module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2) > { translate (pos) > rotate (rot) > cylinder(d=dia, h=hgt); > } > > module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2) > { translate (pos) > rotate (rot) > translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2); > } > > // mounting plate > difference() > { union () > { cube ([30, 30, 3]); > washer([ 5, 5, 3]); > washer([25, 5, 3]); > washer([ 5, 25, 3]); > washer([25, 25, 3]); > } > screw_hole([ 5, 5, 0], hgt=6); > screw_hole([25, 5, 0], hgt=6); > screw_hole([ 5, 25, 0], hgt=6); > screw_hole([25, 25, 0], hgt=6); > } > But I'd like to have a module that could do both operations at once. Something like this: module screw_mount(pos=[0,0,0], rot=[0,0,0]) > { > translate (pos) > rotate (rot) > difference() > { > union () > { > cylinder (d=10, h=2); > children(); > } > translate ([0, 0, -1]) cylinder (d=6, h=8); > } > } > > // mounting plate > union () > { cube ([30, 30, 3]); > screw_mount ([ 5, 5, 3]); > screw_mount ([25, 5, 3]); > screw_mount ([ 5, 25, 3]); > screw_mount ([25, 25, 3]); > } > I know the above does NOT work maybe because I don't yet understand how children work. Or perhaps what I want to do can't be done. Thanks in advance for any help. - Dan
DP
David Phillip Oster
Tue, Nov 22, 2022 8:57 PM

Daniel Miner dgminer@gmail.com via

I have a need for something and I think children() may help me but I have

not been able to figure it out.  For example, I want to create a module
that both adds (union) and subtracts (difference) something to/from an
existing object.

Like this: ?

``````module mycube(){

translate([0,0,5])cube([20, 20, 10], center=true);

}

module myCylinder(){

translate([0, 0, -1])cylinder(d=10,h=20);

}

union(){

children();

}

} else {

difference(){

children();

}

}

}

for(i = [0:1]){

mycube();

myCylinder();

}

}
``````
Daniel Miner dgminer@gmail.com via <https://support.google.com/mail/answer/1311182?hl=en> emwd.com writes: I have a need for something and I think children() may help me but I have > not been able to figure it out. For example, I want to create a module > that both adds (union) and subtracts (difference) something to/from an > existing object. Like this: ? module mycube(){ translate([0,0,5])cube([20, 20, 10], center=true); } module myCylinder(){ translate([0, 0, -1])cylinder(d=10,h=20); } module addSub(isAdding=true) { if (isAdding) { union(){ children(); } } else { difference(){ children(); } } } for(i = [0:1]){ translate([i*30, 0, 0])addSub(isAdding = i){ mycube(); myCylinder(); } }
DM
Daniel Miner
Tue, Nov 22, 2022 9:08 PM

That's close but the result is just a union of the cube and cylinder.
With your example, I'd like the cylinder removed from the cube. Similar to:
difference () {cube; cylinder;}

On Tue, Nov 22, 2022 at 2:57 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

Daniel Miner dgminer@gmail.com via

I have a need for something and I think children() may help me but I have

not been able to figure it out.  For example, I want to create a module
that both adds (union) and subtracts (difference) something to/from an
existing object.

Like this: ?

`````` module mycube(){

translate([0,0,5])cube([20, 20, 10], center=true);

}

module myCylinder(){

translate([0, 0, -1])cylinder(d=10,h=20);

}

union(){

children();

}

} else {

difference(){

children();

}

}

}

for(i = [0:1]){

mycube();

myCylinder();

}

}
``````

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

DP
David Phillip Oster
Tue, Nov 22, 2022 9:31 PM

Run it - that's exactly what it does.

On Tue, Nov 22, 2022 at 1:13 PM Daniel Miner dgminer@gmail.com wrote:

That's close but the result is just a union of the cube and cylinder.
With your example, I'd like the cylinder removed from the cube. Similar to:
difference () {cube; cylinder;}

On Tue, Nov 22, 2022 at 2:57 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

Daniel Miner dgminer@gmail.com via

I have a need for something and I think children() may help me but I have

not been able to figure it out.  For example, I want to create a module
that both adds (union) and subtracts (difference) something to/from an
existing object.

Like this: ?

`````` module mycube(){

translate([0,0,5])cube([20, 20, 10], center=true);

}

module myCylinder(){

translate([0, 0, -1])cylinder(d=10,h=20);

}

union(){

children();

}

} else {

difference(){

children();

}

}

}

for(i = [0:1]){

mycube();

myCylinder();

}

}
``````

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

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

DP
David Phillip Oster
Tue, Nov 22, 2022 9:38 PM

have included a screenshot:
[image: Screenshot 2022-11-22 at 1.32.38 PM.png]

You can do more interesting things with the child array. Here is something
like a switch statement that uses integer cases:

scale = 1.3;

base = 4;

rookH = base*0.8;

bishopH = base;

pawnH = base*scale;

knightH = basescalescale;

queenH = basescalescalescalescale;

kingH = basescalescalescalescale*(1.15);

// alias 'children' to make the meaning clear

module switch(n)children([n]);

module bothMirror(vec3){ children(); mirror(vec3)children(); }

module frustum(h){

linear_extrude(height=h, scale=0.4)

``````square([5,5], center=true);
``````

}

module rook(){

frustum(rookH);

translate([0, 0, 2*rookH])mirror([0, 0, 1])frustum(rookH);

}

module knight(){

frustum(knightH);

translate([0, 0.4, 5.5])rotate([65, 0, 0])linear_extrude(height=4,
scale=0.4)

``````square([3,3], center=true);
``````

}

module pawn()frustum(pawnH);

module bishop(){
translate([0,0,bishopH])bothMirror([0,0,1])frustum(bishopH); }

module queen(){ frustum(queenH); rotate([0, 0, 45])frustum(queenH); }

module king()frustum(kingH);

module pieces(){

for (i = [0:7]) {

``````translate([i*8, -7, 0])pawn();

translate([i*8, 0, 0])switch(i){  // *this!*

rook();

knight();

bishop();

queen();

king();

bishop();

knight();

rook();

}
``````

}

}

scale([3,3,3])pieces();

addSub(isAdding=true) unions. addSub(isAdding=false) differences. I should have included a screenshot: [image: Screenshot 2022-11-22 at 1.32.38 PM.png] You can do more interesting things with the child array. Here is something like a switch statement that uses integer cases: scale = 1.3; base = 4; rookH = base*0.8; bishopH = base; pawnH = base*scale; knightH = base*scale*scale; queenH = base*scale*scale*scale*scale; kingH = base*scale*scale*scale*scale*(1.15); // alias 'children' to make the meaning clear module switch(n)children([n]); module bothMirror(vec3){ children(); mirror(vec3)children(); } module frustum(h){ linear_extrude(height=h, scale=0.4) square([5,5], center=true); } module rook(){ frustum(rookH); translate([0, 0, 2*rookH])mirror([0, 0, 1])frustum(rookH); } module knight(){ frustum(knightH); translate([0, 0.4, 5.5])rotate([65, 0, 0])linear_extrude(height=4, scale=0.4) square([3,3], center=true); } module pawn()frustum(pawnH); module bishop(){ translate([0,0,bishopH])bothMirror([0,0,1])frustum(bishopH); } module queen(){ frustum(queenH); rotate([0, 0, 45])frustum(queenH); } module king()frustum(kingH); module pieces(){ for (i = [0:7]) { translate([i*8, -7, 0])pawn(); translate([i*8, 0, 0])switch(i){ // *this!* rook(); knight(); bishop(); queen(); king(); bishop(); knight(); rook(); } } } scale([3,3,3])pieces();
DM
Daniel Miner
Tue, Nov 22, 2022 9:40 PM

I did run it.  See attached. I'm running:

version 2021.01

Is there a different version I should be running?

(I haven't looked at your 3rd message yet - doing that now.)

On Tue, Nov 22, 2022 at 3:32 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

Run it - that's exactly what it does.

On Tue, Nov 22, 2022 at 1:13 PM Daniel Miner dgminer@gmail.com wrote:

That's close but the result is just a union of the cube and cylinder.
With your example, I'd like the cylinder removed from the cube. Similar
to:
difference () {cube; cylinder;}

On Tue, Nov 22, 2022 at 2:57 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

Daniel Miner dgminer@gmail.com via

I have a need for something and I think children() may help me but I

have not been able to figure it out.  For example, I want to create a
module that both adds (union) and subtracts (difference) something to/from
an existing object.

Like this: ?

`````` module mycube(){

translate([0,0,5])cube([20, 20, 10], center=true);

}

module myCylinder(){

translate([0, 0, -1])cylinder(d=10,h=20);

}

union(){

children();

}

} else {

difference(){

children();

}

}

}

for(i = [0:1]){

mycube();

myCylinder();

}

}
``````

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

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

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

DP
David Phillip Oster
Tue, Nov 22, 2022 9:42 PM

On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner dgminer@gmail.com wrote:

I did run it.  See attached. I'm running:

version 2021.01

2022.03.14  for me.

On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner <dgminer@gmail.com> wrote: > I did run it. See attached. I'm running: > > version 2021.01 > 2022.03.14 for me.
DM
Daniel Miner
Tue, Nov 22, 2022 10:36 PM

I upgraded to  version 2022.11.18 but I still don't get the subtract
(difference) when I execute.

At least I now believe I understand how children() works - at least
partially.

However it seems like your example does not do what I need to do.
I need to remove a cylinder from the cube but it ALSO needs to subtract the
cylinder from a previously existing object.
My initial code like this:

module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2)

{  translate (pos)
rotate (rot)
translate ([-dia/2, -dia/2, 0])
cube ([dia, dia, hgt]);    // was: cylinder(d=dia, h=hgt);
}

module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2)
{  translate (pos)
rotate (rot)
translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2);
}

// mounting plate
difference()
{  union ()
{  cube ([30, 30, 3]);  // holes also cut in this object
washer([ 5,  5, 3]);
washer([25,  5, 3]);
washer([ 5, 25, 3]);
washer([25, 25, 3]);
}
screw_hole([ 5,  5, 0], hgt=6);
screw_hole([25,  5, 0], hgt=6);
screw_hole([ 5, 25, 0], hgt=6);
screw_hole([25, 25, 0], hgt=6);
}

Note the screw_hole goes through the washer AND the 30x30x3 plate (cube).

On Tue, Nov 22, 2022 at 3:43 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner dgminer@gmail.com wrote:

I did run it.  See attached. I'm running:

version 2021.01

2022.03.14  for me.

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

I upgraded to version 2022.11.18 but I still don't get the subtract (difference) when I execute. At least I now believe I understand how children() works - at least partially. However it seems like your example does not do what I need to do. I need to remove a cylinder from the cube but it ALSO needs to subtract the cylinder from a previously existing object. My initial code like this: module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2) > { translate (pos) > rotate (rot) > translate ([-dia/2, -dia/2, 0]) > cube ([dia, dia, hgt]); // was: cylinder(d=dia, h=hgt); > } > > module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2) > { translate (pos) > rotate (rot) > translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2); > } > > // mounting plate > difference() > { union () > { cube ([30, 30, 3]); // holes also cut in this object > washer([ 5, 5, 3]); > washer([25, 5, 3]); > washer([ 5, 25, 3]); > washer([25, 25, 3]); > } > screw_hole([ 5, 5, 0], hgt=6); > screw_hole([25, 5, 0], hgt=6); > screw_hole([ 5, 25, 0], hgt=6); > screw_hole([25, 25, 0], hgt=6); > } > Note the screw_hole goes through the washer AND the 30x30x3 plate (cube). On Tue, Nov 22, 2022 at 3:43 PM David Phillip Oster < davidphilliposter@gmail.com> wrote: > On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner <dgminer@gmail.com> wrote: > >> I did run it. See attached. I'm running: >> >> version 2021.01 >> > 2022.03.14 for me. > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
DM
Daniel Miner
Tue, Nov 22, 2022 10:43 PM

I'm getting closer.  This works for ONE screw_mount but not two because the
plate (cube) gets added again and that fills any previous hole.

module screw_mount(pos=[0,0,0], rot=[0,0,0])
{
difference()
{  union ()
{  children();
translate (pos) rotate (rot) cylinder (d=10, h=2);
}
translate (pos) rotate (rot) translate ([0, 0, -4]) cylinder (d=6,
h=8);
}
}

// mounting plate
union ()
{
screw_mount ([ 5,  5, 3]) cube ([30, 30, 3]);  // Only ONE is OK,
screw_mount ([25,  5, 3]) cube ([30, 30, 3]);  // but not when adding
a second or more...
//    screw_mount ([ 5, 25, 3]) cube ([30, 30, 3]);
//    screw_mount ([25, 25, 3]) cube ([30, 30, 3]);
}

On Tue, Nov 22, 2022 at 4:36 PM Daniel Miner dgminer@gmail.com wrote:

I upgraded to  version 2022.11.18 but I still don't get the subtract
(difference) when I execute.

At least I now believe I understand how children() works - at least
partially.

However it seems like your example does not do what I need to do.
I need to remove a cylinder from the cube but it ALSO needs to subtract
the cylinder from a previously existing object.
My initial code like this:

module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2)

{  translate (pos)
rotate (rot)
translate ([-dia/2, -dia/2, 0])
cube ([dia, dia, hgt]);    // was: cylinder(d=dia, h=hgt);
}

module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2)
{  translate (pos)
rotate (rot)
translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2);
}

// mounting plate
difference()
{  union ()
{  cube ([30, 30, 3]);  // holes also cut in this object
washer([ 5,  5, 3]);
washer([25,  5, 3]);
washer([ 5, 25, 3]);
washer([25, 25, 3]);
}
screw_hole([ 5,  5, 0], hgt=6);
screw_hole([25,  5, 0], hgt=6);
screw_hole([ 5, 25, 0], hgt=6);
screw_hole([25, 25, 0], hgt=6);
}

Note the screw_hole goes through the washer AND the 30x30x3 plate (cube).

On Tue, Nov 22, 2022 at 3:43 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner dgminer@gmail.com wrote:

I did run it.  See attached. I'm running:

version 2021.01

2022.03.14  for me.

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

I'm getting closer. This works for ONE screw_mount but not two because the plate (cube) gets added again and that fills any previous hole. module screw_mount(pos=[0,0,0], rot=[0,0,0]) { difference() { union () { children(); translate (pos) rotate (rot) cylinder (d=10, h=2); } translate (pos) rotate (rot) translate ([0, 0, -4]) cylinder (d=6, h=8); } } // mounting plate union () { screw_mount ([ 5, 5, 3]) cube ([30, 30, 3]); // Only ONE is OK, screw_mount ([25, 5, 3]) cube ([30, 30, 3]); // but not when adding a second or more... // screw_mount ([ 5, 25, 3]) cube ([30, 30, 3]); // screw_mount ([25, 25, 3]) cube ([30, 30, 3]); } On Tue, Nov 22, 2022 at 4:36 PM Daniel Miner <dgminer@gmail.com> wrote: > I upgraded to version 2022.11.18 but I still don't get the subtract > (difference) when I execute. > > At least I now believe I understand how children() works - at least > partially. > > However it seems like your example does not do what I need to do. > I need to remove a cylinder from the cube but it ALSO needs to subtract > the cylinder from a previously existing object. > My initial code like this: > > module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2) >> { translate (pos) >> rotate (rot) >> translate ([-dia/2, -dia/2, 0]) >> cube ([dia, dia, hgt]); // was: cylinder(d=dia, h=hgt); >> } >> >> module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2) >> { translate (pos) >> rotate (rot) >> translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2); >> } >> >> // mounting plate >> difference() >> { union () >> { cube ([30, 30, 3]); // holes also cut in this object >> washer([ 5, 5, 3]); >> washer([25, 5, 3]); >> washer([ 5, 25, 3]); >> washer([25, 25, 3]); >> } >> screw_hole([ 5, 5, 0], hgt=6); >> screw_hole([25, 5, 0], hgt=6); >> screw_hole([ 5, 25, 0], hgt=6); >> screw_hole([25, 25, 0], hgt=6); >> } >> > > Note the screw_hole goes through the washer AND the 30x30x3 plate (cube). > > On Tue, Nov 22, 2022 at 3:43 PM David Phillip Oster < > davidphilliposter@gmail.com> wrote: > >> On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner <dgminer@gmail.com> wrote: >> >>> I did run it. See attached. I'm running: >>> >>> version 2021.01 >>> >> 2022.03.14 for me. >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >
AM
Tue, Nov 22, 2022 10:54 PM

I haven't been paying close attention to what exactly you want to do, but
it sounds like maybe you want to have a module that subtracts children from
objects previously created in your model.  If that's the case, I think it's
basically impossible in regular OpenSCAD to do it---the only way to
subtract stuff is by using difference(), so the parent object and the
subtracted object must be wrapped in a difference().  If you want a module
that subtracts things from the calling environment without a difference()
in the calling environment you're out of luck.  You can sort of do this
using BOSL2 with the tagging feature, though you'll still need to call
diff() at the parent level outside the module.

On Tue, Nov 22, 2022 at 5:44 PM Daniel Miner dgminer@gmail.com wrote:

I'm getting closer.  This works for ONE screw_mount but not two because
the plate (cube) gets added again and that fills any previous hole.

module screw_mount(pos=[0,0,0], rot=[0,0,0])
{
difference()
{  union ()
{  children();
translate (pos) rotate (rot) cylinder (d=10, h=2);
}
translate (pos) rotate (rot) translate ([0, 0, -4]) cylinder (d=6,
h=8);
}
}

// mounting plate
union ()
{
screw_mount ([ 5,  5, 3]) cube ([30, 30, 3]);  // Only ONE is OK,
screw_mount ([25,  5, 3]) cube ([30, 30, 3]);  // but not when adding
a second or more...
//    screw_mount ([ 5, 25, 3]) cube ([30, 30, 3]);
//    screw_mount ([25, 25, 3]) cube ([30, 30, 3]);
}

On Tue, Nov 22, 2022 at 4:36 PM Daniel Miner dgminer@gmail.com wrote:

I upgraded to  version 2022.11.18 but I still don't get the subtract
(difference) when I execute.

At least I now believe I understand how children() works - at least
partially.

However it seems like your example does not do what I need to do.
I need to remove a cylinder from the cube but it ALSO needs to subtract
the cylinder from a previously existing object.
My initial code like this:

module washer (pos=[0,0,0], rot=[0,0,0], dia=9, hgt=2)

{  translate (pos)
rotate (rot)
translate ([-dia/2, -dia/2, 0])
cube ([dia, dia, hgt]);    // was: cylinder(d=dia, h=hgt);
}

module screw_hole (pos=[0,0,0], rot=[0,0,0], dia=5, hgt=2)
{  translate (pos)
rotate (rot)
translate ([0, 0, -1]) cylinder(d=dia, h=hgt+2);
}

// mounting plate
difference()
{  union ()
{  cube ([30, 30, 3]);  // holes also cut in this object
washer([ 5,  5, 3]);
washer([25,  5, 3]);
washer([ 5, 25, 3]);
washer([25, 25, 3]);
}
screw_hole([ 5,  5, 0], hgt=6);
screw_hole([25,  5, 0], hgt=6);
screw_hole([ 5, 25, 0], hgt=6);
screw_hole([25, 25, 0], hgt=6);
}

Note the screw_hole goes through the washer AND the 30x30x3 plate (cube).

On Tue, Nov 22, 2022 at 3:43 PM David Phillip Oster <
davidphilliposter@gmail.com> wrote:

On Tue, Nov 22, 2022 at 1:41 PM Daniel Miner dgminer@gmail.com wrote:

I did run it.  See attached. I'm running:

version 2021.01

2022.03.14  for me.