discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

algorithmically building children

DP
Douglas Peale
Wed, Mar 25, 2020 4:26 AM

I am attempting to use the library function "distribute()" on an algorithmically generated set of children. I get the impression
that I do not properly comprehend the concept of children.

Example code here:

include <../Libraries/BOSL-master/constants.scad>
use <../Libraries/BOSL-master/transforms.scad>

Drivers=[
        [3.81,34.55,7.18,13.9],//Largest Philips Jewlers Screwdriver
        [2.98,30.02,6.19,12.81],
        [2.38,25,5.52,11.62],
        [1.97,20.85,4.5,10.49],
        [1.57,18.47,3.85,9.46],
        [1.37,17.35,3.27,8.53] //Smallest Philips Jewlers Screwdriver
        ];

distribute(spacing=10,sizes=[for (Driver=Drivers) Driver[3]]){
/*    DriverHole(Driver=Drivers[0]);
    DriverHole(Driver=Drivers[1]);
    DriverHole(Driver=Drivers[2]);
    DriverHole(Driver=Drivers[3]);
    DriverHole(Driver=Drivers[4]);
    DriverHole(Driver=Drivers[5]);*/
    for(Driver=Drivers) DriverHole(Driver=Driver);
}

module DriverHole(Driver=[1,20,4,6],HeightOfRow=25,HandleHoleDepth=30){
    translate([0,0,-1])cylinder(d=Driver[0],h=HeightOfRow+1);
        //Transition to make it easier to put the screwdriver in the hole
    translate([0,0,HeightOfRow-.1])cylinder(d1=Driver[0],d2=Driver[2],h=(Driver[2]-Driver[0])/2+.2);
    translate([0,0,HeightOfRow+(Driver[2]-Driver[0])/2])cylinder(d=Driver[2],h=HandleHoleDepth+1);
}

The distribute function works when the commented lines are uncommented and the for statement line is commented out, but as is,
only a single one of the six objects appears.

I do not understand how to make the for statement generate the six children.

What is it I am not understanding about children? How do I algorithmically generate children?

Thanks.

I am attempting to use the library function "distribute()" on an algorithmically generated set of children. I get the impression that I do not properly comprehend the concept of children. Example code here: include <../Libraries/BOSL-master/constants.scad> use <../Libraries/BOSL-master/transforms.scad> Drivers=[         [3.81,34.55,7.18,13.9],//Largest Philips Jewlers Screwdriver         [2.98,30.02,6.19,12.81],         [2.38,25,5.52,11.62],         [1.97,20.85,4.5,10.49],         [1.57,18.47,3.85,9.46],         [1.37,17.35,3.27,8.53] //Smallest Philips Jewlers Screwdriver         ]; distribute(spacing=10,sizes=[for (Driver=Drivers) Driver[3]]){ /*    DriverHole(Driver=Drivers[0]);     DriverHole(Driver=Drivers[1]);     DriverHole(Driver=Drivers[2]);     DriverHole(Driver=Drivers[3]);     DriverHole(Driver=Drivers[4]);     DriverHole(Driver=Drivers[5]);*/     for(Driver=Drivers) DriverHole(Driver=Driver); } module DriverHole(Driver=[1,20,4,6],HeightOfRow=25,HandleHoleDepth=30){     translate([0,0,-1])cylinder(d=Driver[0],h=HeightOfRow+1);         //Transition to make it easier to put the screwdriver in the hole     translate([0,0,HeightOfRow-.1])cylinder(d1=Driver[0],d2=Driver[2],h=(Driver[2]-Driver[0])/2+.2);     translate([0,0,HeightOfRow+(Driver[2]-Driver[0])/2])cylinder(d=Driver[2],h=HandleHoleDepth+1); } The distribute function works when the commented lines are uncommented and the for statement line is commented out, but as is, only a single one of the six objects appears. I do not understand how to make the for statement generate the six children. What is it I am not understanding about children? How do I algorithmically generate children? Thanks.
NH
nop head
Wed, Mar 25, 2020 7:25 AM

You can't because for implicitly unions it results, so only ever makes
one child.

On Wed, 25 Mar 2020 at 04:27, Douglas Peale Douglas_Peale@comcast.net
wrote:

I am attempting to use the library function "distribute()" on an
algorithmically generated set of children. I get the impression
that I do not properly comprehend the concept of children.

Example code here:

include <../Libraries/BOSL-master/constants.scad>
use <../Libraries/BOSL-master/transforms.scad>

Drivers=[
[3.81,34.55,7.18,13.9],//Largest Philips Jewlers Screwdriver
[2.98,30.02,6.19,12.81],
[2.38,25,5.52,11.62],
[1.97,20.85,4.5,10.49],
[1.57,18.47,3.85,9.46],
[1.37,17.35,3.27,8.53] //Smallest Philips Jewlers Screwdriver
];

distribute(spacing=10,sizes=[for (Driver=Drivers) Driver[3]]){
/*    DriverHole(Driver=Drivers[0]);
DriverHole(Driver=Drivers[1]);
DriverHole(Driver=Drivers[2]);
DriverHole(Driver=Drivers[3]);
DriverHole(Driver=Drivers[4]);
DriverHole(Driver=Drivers[5]);*/
for(Driver=Drivers) DriverHole(Driver=Driver);
}

module DriverHole(Driver=[1,20,4,6],HeightOfRow=25,HandleHoleDepth=30){
translate([0,0,-1])cylinder(d=Driver[0],h=HeightOfRow+1);
//Transition to make it easier to put the screwdriver in the hole

translate([0,0,HeightOfRow-.1])cylinder(d1=Driver[0],d2=Driver[2],h=(Driver[2]-Driver[0])/2+.2);

translate([0,0,HeightOfRow+(Driver[2]-Driver[0])/2])cylinder(d=Driver[2],h=HandleHoleDepth+1);
}

The distribute function works when the commented lines are uncommented and
the for statement line is commented out, but as is,
only a single one of the six objects appears.

I do not understand how to make the for statement generate the six
children.

What is it I am not understanding about children? How do I algorithmically
generate children?

Thanks.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

You can't because *for* implicitly unions it results, so only ever makes one child. On Wed, 25 Mar 2020 at 04:27, Douglas Peale <Douglas_Peale@comcast.net> wrote: > I am attempting to use the library function "distribute()" on an > algorithmically generated set of children. I get the impression > that I do not properly comprehend the concept of children. > > Example code here: > > include <../Libraries/BOSL-master/constants.scad> > use <../Libraries/BOSL-master/transforms.scad> > > Drivers=[ > [3.81,34.55,7.18,13.9],//Largest Philips Jewlers Screwdriver > [2.98,30.02,6.19,12.81], > [2.38,25,5.52,11.62], > [1.97,20.85,4.5,10.49], > [1.57,18.47,3.85,9.46], > [1.37,17.35,3.27,8.53] //Smallest Philips Jewlers Screwdriver > ]; > > distribute(spacing=10,sizes=[for (Driver=Drivers) Driver[3]]){ > /* DriverHole(Driver=Drivers[0]); > DriverHole(Driver=Drivers[1]); > DriverHole(Driver=Drivers[2]); > DriverHole(Driver=Drivers[3]); > DriverHole(Driver=Drivers[4]); > DriverHole(Driver=Drivers[5]);*/ > for(Driver=Drivers) DriverHole(Driver=Driver); > } > > module DriverHole(Driver=[1,20,4,6],HeightOfRow=25,HandleHoleDepth=30){ > translate([0,0,-1])cylinder(d=Driver[0],h=HeightOfRow+1); > //Transition to make it easier to put the screwdriver in the hole > > translate([0,0,HeightOfRow-.1])cylinder(d1=Driver[0],d2=Driver[2],h=(Driver[2]-Driver[0])/2+.2); > > translate([0,0,HeightOfRow+(Driver[2]-Driver[0])/2])cylinder(d=Driver[2],h=HandleHoleDepth+1); > } > > The distribute function works when the commented lines are uncommented and > the for statement line is commented out, but as is, > only a single one of the six objects appears. > > I do not understand how to make the for statement generate the six > children. > > What is it I am not understanding about children? How do I algorithmically > generate children? > > Thanks. > > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
TP
Torsten Paul
Wed, Mar 25, 2020 9:05 AM

On 25.03.20 08:25, nop head wrote:

You can't because /for/ implicitly unions it results, so
only ever makes one child.

That is correct if you need to rely on the release version.

If you are ok with using the development snapshot, you can
enable the experimental feature "lazy union".

ciao,
Torsten.

On 25.03.20 08:25, nop head wrote: > You can't because /*for*/ implicitly unions it results, so > only ever makes one child. That is correct if you need to rely on the release version. If you are ok with using the development snapshot, you can enable the experimental feature "lazy union". ciao, Torsten.
JB
Jordan Brown
Wed, Mar 25, 2020 3:58 PM

On 3/25/2020 12:25 AM, nop head wrote:

You can't because /for/ implicitly unions it results, so only ever
makes one child.

More generally, all modules/operators make one child.

A "for" always makes one child.
An "if" always makes one child (even if it's false).
A module always makes one child (even if it doesn't generate any geometry).

module how_many(label, ) {
    echo(label, $children);
}

how_many("if") {
    if (true) cube();
    if (false) sphere();
}

how_many("for") {
    for (i=[0:10:20]) translate([i,i,i]) cube();
}

module empty() {
}

how_many("empty") {
    empty();
}

yields

ECHO: "if", 2
ECHO: "for", 1
ECHO: "empty", 1

I don't know the rules for the new lazy union mode that Paul describes.

(Note:  One might think that an empty module should yield no children,
but then you couldn't have a "placeholder" child in an invocation of a
module that takes multiple children with different purposes, where
children[1] and children[2] are not treated the same.)

On 3/25/2020 12:25 AM, nop head wrote: > You can't because /*for*/ implicitly unions it results, so only ever > makes one child. More generally, all modules/operators make one child. A "for" always makes one child. An "if" always makes one child (even if it's false). A module always makes one child (even if it doesn't generate any geometry). module how_many(label, ) { echo(label, $children); } how_many("if") { if (true) cube(); if (false) sphere(); } how_many("for") { for (i=[0:10:20]) translate([i,i,i]) cube(); } module empty() { } how_many("empty") { empty(); } yields ECHO: "if", 2 ECHO: "for", 1 ECHO: "empty", 1 I don't know the rules for the new lazy union mode that Paul describes. (Note:  One might think that an empty module should yield no children, but then you couldn't have a "placeholder" child in an invocation of a module that takes multiple children with different purposes, where children[1] and children[2] are not treated the same.)
RW
Rogier Wolff
Wed, Mar 25, 2020 4:06 PM

On Wed, Mar 25, 2020 at 03:58:31PM +0000, Jordan Brown wrote:

but then you couldn't have a "placeholder" child in an invocation of a
module that takes multiple children with different purposes, where
children[1] and children[2] are not treated the same.)

Like for example: "difference ()". Here the first and second (and
further) children are treated different.... Now in this specific case
it doesn't make sense for the first argument to be "null", but imagine
a reverse_difference () that unionizes all children2+ and subtracts
the first. Now having an if (we_need_the_hole) cylinder (); as the
first argument and the things where the axle needs to go through as
second third, etc aguments...

Roger. 

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
The plan was simple, like my brother-in-law Phil. But unlike
Phil, this plan just might work.

On Wed, Mar 25, 2020 at 03:58:31PM +0000, Jordan Brown wrote: > but then you couldn't have a "placeholder" child in an invocation of a > module that takes multiple children with different purposes, where > children[1] and children[2] are not treated the same.) Like for example: "difference ()". Here the first and second (and further) children are treated different.... Now in this specific case it doesn't make sense for the first argument to be "null", but imagine a reverse_difference () that unionizes all children2+ and subtracts the first. Now having an if (we_need_the_hole) cylinder (); as the first argument and the things where the axle needs to go through as second third, etc aguments... Roger. -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** The plan was simple, like my brother-in-law Phil. But unlike Phil, this plan just might work.
A
AKADAP
Wed, Mar 25, 2020 5:04 PM

From the responses I am getting, it looks to me that I can't do what I want

with the release version of OpenSCAD, and must use the unreleased version.
Is this a correct assumption?

Thanks.

--
Sent from: http://forum.openscad.org/

>From the responses I am getting, it looks to me that I can't do what I want with the release version of OpenSCAD, and must use the unreleased version. Is this a correct assumption? Thanks. -- Sent from: http://forum.openscad.org/
TP
Torsten Paul
Wed, Mar 25, 2020 6:28 PM

On 25.03.20 18:04, AKADAP wrote:

From the responses I am getting, it looks to me that I can't
do what I want with the release version of OpenSCAD, and must
use the unreleased version. Is this a correct assumption?

Correct. It's available in the development snapshots which can be
found at https://www.openscad.org/downloads.html#snapshots

Enable via Preferences->Features "lazy-union"

It's still experimental as there are a couple of things that need
to be clarified, so comments and suggestions are welcome. That
also means the behavior might change.

As the next release is supposed to be mostly bugfixes, it's
probably not going to include that change.

ciao,
Torsten.

On 25.03.20 18:04, AKADAP wrote: > From the responses I am getting, it looks to me that I can't > do what I want with the release version of OpenSCAD, and must > use the unreleased version. Is this a correct assumption? Correct. It's available in the development snapshots which can be found at https://www.openscad.org/downloads.html#snapshots Enable via Preferences->Features "lazy-union" It's still experimental as there are a couple of things that need to be clarified, so comments and suggestions are welcome. That also means the behavior might change. As the next release is supposed to be mostly bugfixes, it's probably not going to include that change. ciao, Torsten.
J
jon
Wed, Mar 25, 2020 6:37 PM

Does the compiler have source code pragmas, so that you can say "this
code uses lazy unions"?  This statement would both enable lazy unions
without having to go into the preferences/features, and document the
code so that users are not caught off guard.  If the requested feature
is not available, then a compile-time error could occur

Jon

On 3/25/2020 2:28 PM, Torsten Paul wrote:

Enable via Preferences->Features "lazy-union"

Does the compiler have source code pragmas, so that you can say "this code uses lazy unions"?  This statement would both enable lazy unions without having to go into the preferences/features, and document the code so that users are not caught off guard.  If the requested feature is not available, then a compile-time error could occur Jon On 3/25/2020 2:28 PM, Torsten Paul wrote: > Enable via Preferences->Features "lazy-union"
AC
A. Craig West
Wed, Mar 25, 2020 6:39 PM

Are you sure about the if (false) case? I'm sure I've used that
successfully to avoid creating a child

On Wed, 25 Mar 2020, 11:59 Jordan Brown, openscad@jordan.maileater.net
wrote:

On 3/25/2020 12:25 AM, nop head wrote:

You can't because for implicitly unions it results, so only ever makes
one child.

More generally, all modules/operators make one child.

A "for" always makes one child.
An "if" always makes one child (even if it's false).
A module always makes one child (even if it doesn't generate any geometry).

module how_many(label, ) {
echo(label, $children);
}

how_many("if") {
if (true) cube();
if (false) sphere();
}

how_many("for") {
for (i=[0:10:20]) translate([i,i,i]) cube();
}

module empty() {
}

how_many("empty") {
empty();
}

yields

ECHO: "if", 2
ECHO: "for", 1
ECHO: "empty", 1

I don't know the rules for the new lazy union mode that Paul describes.

(Note:  One might think that an empty module should yield no children, but
then you couldn't have a "placeholder" child in an invocation of a module
that takes multiple children with different purposes, where children[1] and
children[2] are not treated the same.)


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Are you sure about the if (false) case? I'm sure I've used that successfully to avoid creating a child On Wed, 25 Mar 2020, 11:59 Jordan Brown, <openscad@jordan.maileater.net> wrote: > On 3/25/2020 12:25 AM, nop head wrote: > > You can't because *for* implicitly unions it results, so only ever makes > one child. > > > More generally, all modules/operators make one child. > > A "for" always makes one child. > An "if" always makes one child (even if it's false). > A module always makes one child (even if it doesn't generate any geometry). > > module how_many(label, ) { > echo(label, $children); > } > > how_many("if") { > if (true) cube(); > if (false) sphere(); > } > > how_many("for") { > for (i=[0:10:20]) translate([i,i,i]) cube(); > } > > module empty() { > } > > how_many("empty") { > empty(); > } > > yields > > ECHO: "if", 2 > ECHO: "for", 1 > ECHO: "empty", 1 > > I don't know the rules for the new lazy union mode that Paul describes. > > (Note: One might think that an empty module should yield no children, but > then you couldn't have a "placeholder" child in an invocation of a module > that takes multiple children with different purposes, where children[1] and > children[2] are not treated the same.) > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
TP
Torsten Paul
Wed, Mar 25, 2020 6:43 PM

On 25.03.20 19:37, jon wrote:

Does the compiler have source code pragmas, so that you can
say "this code uses lazy unions"?

No, and I don't think it should have one.

ciao,
Torsten.

On 25.03.20 19:37, jon wrote: > Does the compiler have source code pragmas, so that you can > say "this code uses lazy unions"? No, and I don't think it should have one. ciao, Torsten.