What is happening here?

classic Classic list List threaded Threaded
38 messages Options
12
Reply | Threaded
Open this post in threaded view
|

What is happening here?

devlaam
I have some difficulty with modules and child calls.

Suppose you want to repeat an object several times,
you can write:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        child(0);  }

   repeat_y()
   { cube(1); }

And if you have more objects to repeat you can extend it like:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   repeat_y()
   { cube(1);
     sphere(1); }

Up to here, no problems, suppose now, you want to repeat
in the other direction as well, so now we have:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
          for (j = [0:$children-1]) child(j); }

   repeat_x()
   { cube(1);
     sphere(1); }

Hey, where did the spheres go? We only see cubes! This can
be repaired with a union() in the base call,

   repeat_x()
   { union()
     { cube(1);
       sphere(1); } }

which is understandable but it is somewhat unexpected
that it is needed. However, an union() inside the repeat_x
module, i.e. the does NOT display the spheres:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union()
          { for (j = [0:$children-1]) child(j); } } }

   repeat_x()
   { cube(1);
     sphere(1); }

And even more strangely, the following (adding ';' to union() ) does:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union();
          for (j = [0:$children-1]) child(j); } }

You could even replace union(); with something like sin(1);
and it does still display the spheres. What is going on
behind the scene's? Is this intended behavior?
How should you predictably (and reliably) unify all child
objects before they are past on to the next module?
And why is this not done by the implicit 'union'
as a result of the 'for' loop?

Thank you for your insights.

Ruud








_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

David Powell
seem to think the  child() only accepts the first object as the child and not subsequent ones 


 repeat_x()
   { cubeandsphere();}

module cubeandsphere()
{ cube(1);
     sphere(1); }

iirc will work around it and draw both 

i would say its a bug 

Dave


On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming <[hidden email]> wrote:
I have some difficulty with modules and child calls.

Suppose you want to repeat an object several times,
you can write:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        child(0);  }

   repeat_y()
   { cube(1); }

And if you have more objects to repeat you can extend it like:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   repeat_y()
   { cube(1);
     sphere(1); }

Up to here, no problems, suppose now, you want to repeat
in the other direction as well, so now we have:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
          for (j = [0:$children-1]) child(j); }

   repeat_x()
   { cube(1);
     sphere(1); }

Hey, where did the spheres go? We only see cubes! This can
be repaired with a union() in the base call,

   repeat_x()
   { union()
     { cube(1);
       sphere(1); } }

which is understandable but it is somewhat unexpected
that it is needed. However, an union() inside the repeat_x
module, i.e. the does NOT display the spheres:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union()
          { for (j = [0:$children-1]) child(j); } } }

   repeat_x()
   { cube(1);
     sphere(1); }

And even more strangely, the following (adding ';' to union() ) does:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union();
          for (j = [0:$children-1]) child(j); } }

You could even replace union(); with something like sin(1);
and it does still display the spheres. What is going on
behind the scene's? Is this intended behavior?
How should you predictably (and reliably) unify all child
objects before they are past on to the next module?
And why is this not done by the implicit 'union'
as a result of the 'for' loop?

Thank you for your insights.

Ruud








_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
Even stranger this draws them both:

   module repeat_y()

{ for(i=[0:3])

translate([0,5*i,0])

for (j = [0:$children-1]) child(j); }


module repeat_x()

{ for(i=[0:3])

translate([5*i,0,0])

repeat_y()

for (j = [1:$children-1]) child(j); }


repeat_x()

{ cube(1);

sphere(1); }


I.e. just changed the loop in repeat_x to skip the first child so I expected to get just the sphere.



On 19 July 2013 13:31, David Powell <[hidden email]> wrote:
seem to think the  child() only accepts the first object as the child and not subsequent ones 


 repeat_x()
   { cubeandsphere();}

module cubeandsphere()
{ cube(1);
     sphere(1); }

iirc will work around it and draw both 

i would say its a bug 

Dave


On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming <[hidden email]> wrote:
I have some difficulty with modules and child calls.

Suppose you want to repeat an object several times,
you can write:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        child(0);  }

   repeat_y()
   { cube(1); }

And if you have more objects to repeat you can extend it like:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   repeat_y()
   { cube(1);
     sphere(1); }

Up to here, no problems, suppose now, you want to repeat
in the other direction as well, so now we have:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
          for (j = [0:$children-1]) child(j); }

   repeat_x()
   { cube(1);
     sphere(1); }

Hey, where did the spheres go? We only see cubes! This can
be repaired with a union() in the base call,

   repeat_x()
   { union()
     { cube(1);
       sphere(1); } }

which is understandable but it is somewhat unexpected
that it is needed. However, an union() inside the repeat_x
module, i.e. the does NOT display the spheres:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union()
          { for (j = [0:$children-1]) child(j); } } }

   repeat_x()
   { cube(1);
     sphere(1); }

And even more strangely, the following (adding ';' to union() ) does:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union();
          for (j = [0:$children-1]) child(j); } }

You could even replace union(); with something like sin(1);
and it does still display the spheres. What is going on
behind the scene's? Is this intended behavior?
How should you predictably (and reliably) unify all child
objects before they are past on to the next module?
And why is this not done by the implicit 'union'
as a result of the 'for' loop?

Thank you for your insights.

Ruud








_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
The problem seems to be that $children has the wrong value. At the top of repeat_x it is 2 but under the repeat_y it has become 1.

This fixes it:

   module repeat_x()

{ kids = $children;

     for(i=[0:3])

           translate([5*i,0,0])

                 repeat_y()

                      for(i = [0:kids - 1]) child(i);

}


The $ variables have dynamic scope so it seems the value in repeat_y overides the value in repeat_x. I think $children should have static scope.


On 19 July 2013 13:37, nop head <[hidden email]> wrote:
Even stranger this draws them both:

   module repeat_y()

{ for(i=[0:3])

translate([0,5*i,0])

for (j = [0:$children-1]) child(j); }


module repeat_x()

{ for(i=[0:3])

translate([5*i,0,0])

repeat_y()

for (j = [1:$children-1]) child(j); }


repeat_x()

{ cube(1);

sphere(1); }


I.e. just changed the loop in repeat_x to skip the first child so I expected to get just the sphere.



On 19 July 2013 13:31, David Powell <[hidden email]> wrote:
seem to think the  child() only accepts the first object as the child and not subsequent ones 


 repeat_x()
   { cubeandsphere();}

module cubeandsphere()
{ cube(1);
     sphere(1); }

iirc will work around it and draw both 

i would say its a bug 

Dave


On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming <[hidden email]> wrote:
I have some difficulty with modules and child calls.

Suppose you want to repeat an object several times,
you can write:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        child(0);  }

   repeat_y()
   { cube(1); }

And if you have more objects to repeat you can extend it like:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   repeat_y()
   { cube(1);
     sphere(1); }

Up to here, no problems, suppose now, you want to repeat
in the other direction as well, so now we have:

   module repeat_y()
   { for(i=[0:3])
      translate([0,5*i,0])
        for (j = [0:$children-1]) child(j);  }

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
          for (j = [0:$children-1]) child(j); }

   repeat_x()
   { cube(1);
     sphere(1); }

Hey, where did the spheres go? We only see cubes! This can
be repaired with a union() in the base call,

   repeat_x()
   { union()
     { cube(1);
       sphere(1); } }

which is understandable but it is somewhat unexpected
that it is needed. However, an union() inside the repeat_x
module, i.e. the does NOT display the spheres:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union()
          { for (j = [0:$children-1]) child(j); } } }

   repeat_x()
   { cube(1);
     sphere(1); }

And even more strangely, the following (adding ';' to union() ) does:

   module repeat_x()
   { for(i=[0:3])
      translate([5*i,0,0])
        repeat_y()
        { union();
          for (j = [0:$children-1]) child(j); } }

You could even replace union(); with something like sin(1);
and it does still display the spheres. What is going on
behind the scene's? Is this intended behavior?
How should you predictably (and reliably) unify all child
objects before they are past on to the next module?
And why is this not done by the implicit 'union'
as a result of the 'for' loop?

Thank you for your insights.

Ruud








_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

devlaam
I agree, if you try:

    module repeat_x()
    { for(i=[0:3])
       translate([5*i,0,0])
         repeat_y()
         { echo("repeat_x=",$children);
           cube(1);
           cylinder(2);
           { for (j = [0:$children-1]) child(j); } } }

you get:
   Compiling design (CSG Tree generation)...
   ECHO: "repeat_x=", 4
   WARNING: Child index (2) out of bounds (2 children)
   WARNING: Child index (3) out of bounds (2 children)
   ...

indicating that $children does not contain the size
of the child array, but of the local array. Even more,
$children seems also to contain a value if that is not
appropriate, for example if you add:

    repeat_x()
    { echo("top=",$children);
      cube(1);
      sphere(1); }

you get:
   Compiling design (CSG Tree generation)...
   ECHO: "repeat_x=", 4
   ECHO: "top=", 4
   WARNING: Child index (3) out of bounds (3 children)
   ...

So the value 4 is retained although it is meaningless
at the point of use.

Looks like a bug.


On 19-07-13 14:52, nop head wrote:

> The problem seems to be that $children has the wrong value. At the top
> of repeat_x it is 2 but under the repeat_y it has become 1.
>
> This fixes it:
>
>     module repeat_x()
>
> { kids = $children;
>
>       for(i=[0:3])
>
>             translate([5*i,0,0])
>
>                   repeat_y()
>
>                        for(i = [0:kids - 1]) child(i);
>
> }
>
>
> The $ variables have dynamic scope so it seems the value in repeat_y
> overides the value in repeat_x. I think $children should have static scope.
>
>
> On 19 July 2013 13:37, nop head <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Even stranger this draws them both:
>
>         module repeat_y()
>
>     { for(i=[0:3])
>
>     translate([0,5*i,0])
>
>     for (j = [0:$children-1]) child(j); }
>
>
>     module repeat_x()
>
>     { for(i=[0:3])
>
>     translate([5*i,0,0])
>
>     repeat_y()
>
>     for (j = [1:$children-1]) child(j); }
>
>
>     repeat_x()
>
>     { cube(1);
>
>     sphere(1); }
>
>
>     I.e. just changed the loop in repeat_x to skip the first child so I
>     expected to get just the sphere.
>
>
>
>     On 19 July 2013 13:31, David Powell <[hidden email]
>     <mailto:[hidden email]>> wrote:
>
>         seem to think the  child() only accepts the first object as the
>         child and not subsequent ones
>
>
>           repeat_x()
>             { cubeandsphere();}
>
>         module cubeandsphere()
>         { cube(1);
>               sphere(1); }
>
>         iirc will work around it and draw both
>
>         i would say its a bug
>
>         Dave
>
>
>         On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>         <[hidden email] <mailto:[hidden email]>> wrote:
>
>             I have some difficulty with modules and child calls.
>
>             Suppose you want to repeat an object several times,
>             you can write:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      child(0);  }
>
>                 repeat_y()
>                 { cube(1); }
>
>             And if you have more objects to repeat you can extend it like:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      for (j = [0:$children-1]) child(j);  }
>
>                 repeat_y()
>                 { cube(1);
>                   sphere(1); }
>
>             Up to here, no problems, suppose now, you want to repeat
>             in the other direction as well, so now we have:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      for (j = [0:$children-1]) child(j);  }
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                        for (j = [0:$children-1]) child(j); }
>
>                 repeat_x()
>                 { cube(1);
>                   sphere(1); }
>
>             Hey, where did the spheres go? We only see cubes! This can
>             be repaired with a union() in the base call,
>
>                 repeat_x()
>                 { union()
>                   { cube(1);
>                     sphere(1); } }
>
>             which is understandable but it is somewhat unexpected
>             that it is needed. However, an union() inside the repeat_x
>             module, i.e. the does NOT display the spheres:
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                      { union()
>                        { for (j = [0:$children-1]) child(j); } } }
>
>                 repeat_x()
>                 { cube(1);
>                   sphere(1); }
>
>             And even more strangely, the following (adding ';' to
>             union() ) does:
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                      { union();
>                        for (j = [0:$children-1]) child(j); } }
>
>             You could even replace union(); with something like sin(1);
>             and it does still display the spheres. What is going on
>             behind the scene's? Is this intended behavior?
>             How should you predictably (and reliably) unify all child
>             objects before they are past on to the next module?
>             And why is this not done by the implicit 'union'
>             as a result of the 'for' loop?
>
>             Thank you for your insights.
>
>             Ruud
>
>
>
>
>
>
>
>
>             _______________________________________________
>             OpenSCAD mailing list
>             [hidden email] <mailto:[hidden email]>
>             http://rocklinux.net/mailman/listinfo/openscad
>             http://openscad.org - https://flattr.com/thing/121566
>
>
>
>         _______________________________________________
>         OpenSCAD mailing list
>         [hidden email] <mailto:[hidden email]>
>         http://rocklinux.net/mailman/listinfo/openscad
>         http://openscad.org - https://flattr.com/thing/121566
>
>
>
>
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
$children is always the size of the child array, but as soon as you use repeat_y it is the number of children of repeat_y, even when accessed in repeat_x.



On 19 July 2013 14:31, Ruud Vlaming <[hidden email]> wrote:
I agree, if you try:

    module repeat_x()
    { for(i=[0:3])
       translate([5*i,0,0])
         repeat_y()
         { echo("repeat_x=",$children);
           cube(1);
           cylinder(2);
           { for (j = [0:$children-1]) child(j); } } }

you get:
   Compiling design (CSG Tree generation)...
   ECHO: "repeat_x=", 4
   WARNING: Child index (2) out of bounds (2 children)
   WARNING: Child index (3) out of bounds (2 children)
   ...

indicating that $children does not contain the size
of the child array, but of the local array. Even more,
$children seems also to contain a value if that is not
appropriate, for example if you add:

    repeat_x()
    { echo("top=",$children);
      cube(1);
      sphere(1); }

you get:
   Compiling design (CSG Tree generation)...
   ECHO: "repeat_x=", 4
   ECHO: "top=", 4
   WARNING: Child index (3) out of bounds (3 children)
   ...

So the value 4 is retained although it is meaningless
at the point of use.

Looks like a bug.


On 19-07-13 14:52, nop head wrote:
> The problem seems to be that $children has the wrong value. At the top
> of repeat_x it is 2 but under the repeat_y it has become 1.
>
> This fixes it:
>
>     module repeat_x()
>
> { kids = $children;
>
>       for(i=[0:3])
>
>             translate([5*i,0,0])
>
>                   repeat_y()
>
>                        for(i = [0:kids - 1]) child(i);
>
> }
>
>
> The $ variables have dynamic scope so it seems the value in repeat_y
> overides the value in repeat_x. I think $children should have static scope.
>
>
> On 19 July 2013 13:37, nop head <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Even stranger this draws them both:
>
>         module repeat_y()
>
>     { for(i=[0:3])
>
>     translate([0,5*i,0])
>
>     for (j = [0:$children-1]) child(j); }
>
>
>     module repeat_x()
>
>     { for(i=[0:3])
>
>     translate([5*i,0,0])
>
>     repeat_y()
>
>     for (j = [1:$children-1]) child(j); }
>
>
>     repeat_x()
>
>     { cube(1);
>
>     sphere(1); }
>
>
>     I.e. just changed the loop in repeat_x to skip the first child so I
>     expected to get just the sphere.
>
>
>
>     On 19 July 2013 13:31, David Powell <[hidden email]
>     <mailto:[hidden email]>> wrote:
>
>         seem to think the  child() only accepts the first object as the
>         child and not subsequent ones
>
>
>           repeat_x()
>             { cubeandsphere();}
>
>         module cubeandsphere()
>         { cube(1);
>               sphere(1); }
>
>         iirc will work around it and draw both
>
>         i would say its a bug
>
>         Dave
>
>
>         On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>         <[hidden email] <mailto:[hidden email]>> wrote:
>
>             I have some difficulty with modules and child calls.
>
>             Suppose you want to repeat an object several times,
>             you can write:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      child(0);  }
>
>                 repeat_y()
>                 { cube(1); }
>
>             And if you have more objects to repeat you can extend it like:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      for (j = [0:$children-1]) child(j);  }
>
>                 repeat_y()
>                 { cube(1);
>                   sphere(1); }
>
>             Up to here, no problems, suppose now, you want to repeat
>             in the other direction as well, so now we have:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      for (j = [0:$children-1]) child(j);  }
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                        for (j = [0:$children-1]) child(j); }
>
>                 repeat_x()
>                 { cube(1);
>                   sphere(1); }
>
>             Hey, where did the spheres go? We only see cubes! This can
>             be repaired with a union() in the base call,
>
>                 repeat_x()
>                 { union()
>                   { cube(1);
>                     sphere(1); } }
>
>             which is understandable but it is somewhat unexpected
>             that it is needed. However, an union() inside the repeat_x
>             module, i.e. the does NOT display the spheres:
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                      { union()
>                        { for (j = [0:$children-1]) child(j); } } }
>
>                 repeat_x()
>                 { cube(1);
>                   sphere(1); }
>
>             And even more strangely, the following (adding ';' to
>             union() ) does:
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                      { union();
>                        for (j = [0:$children-1]) child(j); } }
>
>             You could even replace union(); with something like sin(1);
>             and it does still display the spheres. What is going on
>             behind the scene's? Is this intended behavior?
>             How should you predictably (and reliably) unify all child
>             objects before they are past on to the next module?
>             And why is this not done by the implicit 'union'
>             as a result of the 'for' loop?
>
>             Thank you for your insights.
>
>             Ruud
>
>
>
>
>
>
>
>
>             _______________________________________________
>             OpenSCAD mailing list
>             [hidden email] <mailto:[hidden email]>
>             http://rocklinux.net/mailman/listinfo/openscad
>             http://openscad.org - https://flattr.com/thing/121566
>
>
>
>         _______________________________________________
>         OpenSCAD mailing list
>         [hidden email] <mailto:[hidden email]>


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

clothbot
Since it's the for loop operator that's getting confused, one work-around is to pull the repeat_y() call into the for loop:

--snip--

module repeat_y()
{ for(i=[0:3])
translate([0,5*i,0])
for (j = [0:$children-1]) child(j); }

module repeat_x()
{ for(i=[0:3])
translate([5*i,0,0])
for (j = [0:$children-1]) repeat_y() child(j); }

repeat_x()
{ cube(1);
sphere(1); }

--end-snip--

Andrew.

On 2013-07-19, at 9:40 AM, nop head <[hidden email]> wrote:

$children is always the size of the child array, but as soon as you use repeat_y it is the number of children of repeat_y, even when accessed in repeat_x.



On 19 July 2013 14:31, Ruud Vlaming <[hidden email]> wrote:
I agree, if you try:

    module repeat_x()
    { for(i=[0:3])
       translate([5*i,0,0])
         repeat_y()
         { echo("repeat_x=",$children);
           cube(1);
           cylinder(2);
           { for (j = [0:$children-1]) child(j); } } }

you get:
   Compiling design (CSG Tree generation)...
   ECHO: "repeat_x=", 4
   WARNING: Child index (2) out of bounds (2 children)
   WARNING: Child index (3) out of bounds (2 children)
   ...

indicating that $children does not contain the size
of the child array, but of the local array. Even more,
$children seems also to contain a value if that is not
appropriate, for example if you add:

    repeat_x()
    { echo("top=",$children);
      cube(1);
      sphere(1); }

you get:
   Compiling design (CSG Tree generation)...
   ECHO: "repeat_x=", 4
   ECHO: "top=", 4
   WARNING: Child index (3) out of bounds (3 children)
   ...

So the value 4 is retained although it is meaningless
at the point of use.

Looks like a bug.


On 19-07-13 14:52, nop head wrote:
> The problem seems to be that $children has the wrong value. At the top
> of repeat_x it is 2 but under the repeat_y it has become 1.
>
> This fixes it:
>
>     module repeat_x()
>
> { kids = $children;
>
>       for(i=[0:3])
>
>             translate([5*i,0,0])
>
>                   repeat_y()
>
>                        for(i = [0:kids - 1]) child(i);
>
> }
>
>
> The $ variables have dynamic scope so it seems the value in repeat_y
> overides the value in repeat_x. I think $children should have static scope.
>
>
> On 19 July 2013 13:37, nop head <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Even stranger this draws them both:
>
>         module repeat_y()
>
>     { for(i=[0:3])
>
>     translate([0,5*i,0])
>
>     for (j = [0:$children-1]) child(j); }
>
>
>     module repeat_x()
>
>     { for(i=[0:3])
>
>     translate([5*i,0,0])
>
>     repeat_y()
>
>     for (j = [1:$children-1]) child(j); }
>
>
>     repeat_x()
>
>     { cube(1);
>
>     sphere(1); }
>
>
>     I.e. just changed the loop in repeat_x to skip the first child so I
>     expected to get just the sphere.
>
>
>
>     On 19 July 2013 13:31, David Powell <[hidden email]
>     <mailto:[hidden email]>> wrote:
>
>         seem to think the  child() only accepts the first object as the
>         child and not subsequent ones
>
>
>           repeat_x()
>             { cubeandsphere();}
>
>         module cubeandsphere()
>         { cube(1);
>               sphere(1); }
>
>         iirc will work around it and draw both
>
>         i would say its a bug
>
>         Dave
>
>
>         On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>         <[hidden email] <mailto:[hidden email]>> wrote:
>
>             I have some difficulty with modules and child calls.
>
>             Suppose you want to repeat an object several times,
>             you can write:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      child(0);  }
>
>                 repeat_y()
>                 { cube(1); }
>
>             And if you have more objects to repeat you can extend it like:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      for (j = [0:$children-1]) child(j);  }
>
>                 repeat_y()
>                 { cube(1);
>                   sphere(1); }
>
>             Up to here, no problems, suppose now, you want to repeat
>             in the other direction as well, so now we have:
>
>                 module repeat_y()
>                 { for(i=[0:3])
>                    translate([0,5*i,0])
>                      for (j = [0:$children-1]) child(j);  }
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                        for (j = [0:$children-1]) child(j); }
>
>                 repeat_x()
>                 { cube(1);
>                   sphere(1); }
>
>             Hey, where did the spheres go? We only see cubes! This can
>             be repaired with a union() in the base call,
>
>                 repeat_x()
>                 { union()
>                   { cube(1);
>                     sphere(1); } }
>
>             which is understandable but it is somewhat unexpected
>             that it is needed. However, an union() inside the repeat_x
>             module, i.e. the does NOT display the spheres:
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                      { union()
>                        { for (j = [0:$children-1]) child(j); } } }
>
>                 repeat_x()
>                 { cube(1);
>                   sphere(1); }
>
>             And even more strangely, the following (adding ';' to
>             union() ) does:
>
>                 module repeat_x()
>                 { for(i=[0:3])
>                    translate([5*i,0,0])
>                      repeat_y()
>                      { union();
>                        for (j = [0:$children-1]) child(j); } }
>
>             You could even replace union(); with something like sin(1);
>             and it does still display the spheres. What is going on
>             behind the scene's? Is this intended behavior?
>             How should you predictably (and reliably) unify all child
>             objects before they are past on to the next module?
>             And why is this not done by the implicit 'union'
>             as a result of the 'for' loop?
>
>             Thank you for your insights.
>
>             Ruud
>
>
>
>
>
>
>
>
>             _______________________________________________
>             OpenSCAD mailing list
>             [hidden email] <mailto:[hidden email]>
>             http://rocklinux.net/mailman/listinfo/openscad
>             http://openscad.org - https://flattr.com/thing/121566
>
>
>
>         _______________________________________________
>         OpenSCAD mailing list
>         [hidden email] <mailto:[hidden email]>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566

--

"The future is already here.  It's just not very evenly distributed" -- William Gibson

Me: http://clothbot.com/wiki/




_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

devlaam
In reply to this post by nophead
On 19-07-13 15:40, nop head wrote:
> $children is always the size of the child array, but as soon as you use
> repeat_y it is the number of children of repeat_y, even when accessed in
> repeat_x.
No, it looks like $children is a copy of the size of the
child array of the last instantiated module. I do not completely
understand the code, but it seems $children has a more 'global'
nature. That is why it also retains its value, even when it has
no meaning (i.e., when there is no accompanying child array.)

If i had to fix it i would redesign the code, so i think it is best
if we await the return of Marius to see what his opinion is.
Up to then, i think your workaround, that is make a local copy
of $childeren is quite adequate. For special cases, you can
also defer the call to the next module, as Andrew pointed
out.

Thank you David, 'nope head' and Andrew for helping solve
this mystery.

Ruud


>
>
>
> On 19 July 2013 14:31, Ruud Vlaming <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     I agree, if you try:
>
>          module repeat_x()
>          { for(i=[0:3])
>             translate([5*i,0,0])
>               repeat_y()
>               { echo("repeat_x=",$children);
>                 cube(1);
>                 cylinder(2);
>                 { for (j = [0:$children-1]) child(j); } } }
>
>     you get:
>         Compiling design (CSG Tree generation)...
>         ECHO: "repeat_x=", 4
>         WARNING: Child index (2) out of bounds (2 children)
>         WARNING: Child index (3) out of bounds (2 children)
>         ...
>
>     indicating that $children does not contain the size
>     of the child array, but of the local array. Even more,
>     $children seems also to contain a value if that is not
>     appropriate, for example if you add:
>
>          repeat_x()
>          { echo("top=",$children);
>            cube(1);
>            sphere(1); }
>
>     you get:
>         Compiling design (CSG Tree generation)...
>         ECHO: "repeat_x=", 4
>         ECHO: "top=", 4
>         WARNING: Child index (3) out of bounds (3 children)
>         ...
>
>     So the value 4 is retained although it is meaningless
>     at the point of use.
>
>     Looks like a bug.
>
>
>     On 19-07-13 14:52, nop head wrote:
>      > The problem seems to be that $children has the wrong value. At
>     the top
>      > of repeat_x it is 2 but under the repeat_y it has become 1.
>      >
>      > This fixes it:
>      >
>      >     module repeat_x()
>      >
>      > { kids = $children;
>      >
>      >       for(i=[0:3])
>      >
>      >             translate([5*i,0,0])
>      >
>      >                   repeat_y()
>      >
>      >                        for(i = [0:kids - 1]) child(i);
>      >
>      > }
>      >
>      >
>      > The $ variables have dynamic scope so it seems the value in repeat_y
>      > overides the value in repeat_x. I think $children should have
>     static scope.
>      >
>      >
>      > On 19 July 2013 13:37, nop head <[hidden email]
>     <mailto:[hidden email]>
>      > <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>      >
>      >     Even stranger this draws them both:
>      >
>      >         module repeat_y()
>      >
>      >     { for(i=[0:3])
>      >
>      >     translate([0,5*i,0])
>      >
>      >     for (j = [0:$children-1]) child(j); }
>      >
>      >
>      >     module repeat_x()
>      >
>      >     { for(i=[0:3])
>      >
>      >     translate([5*i,0,0])
>      >
>      >     repeat_y()
>      >
>      >     for (j = [1:$children-1]) child(j); }
>      >
>      >
>      >     repeat_x()
>      >
>      >     { cube(1);
>      >
>      >     sphere(1); }
>      >
>      >
>      >     I.e. just changed the loop in repeat_x to skip the first
>     child so I
>      >     expected to get just the sphere.
>      >
>      >
>      >
>      >     On 19 July 2013 13:31, David Powell <[hidden email]
>     <mailto:[hidden email]>
>      >     <mailto:[hidden email]
>     <mailto:[hidden email]>>> wrote:
>      >
>      >         seem to think the  child() only accepts the first object
>     as the
>      >         child and not subsequent ones
>      >
>      >
>      >           repeat_x()
>      >             { cubeandsphere();}
>      >
>      >         module cubeandsphere()
>      >         { cube(1);
>      >               sphere(1); }
>      >
>      >         iirc will work around it and draw both
>      >
>      >         i would say its a bug
>      >
>      >         Dave
>      >
>      >
>      >         On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>      >         <[hidden email] <mailto:[hidden email]>
>     <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>      >
>      >             I have some difficulty with modules and child calls.
>      >
>      >             Suppose you want to repeat an object several times,
>      >             you can write:
>      >
>      >                 module repeat_y()
>      >                 { for(i=[0:3])
>      >                    translate([0,5*i,0])
>      >                      child(0);  }
>      >
>      >                 repeat_y()
>      >                 { cube(1); }
>      >
>      >             And if you have more objects to repeat you can extend
>     it like:
>      >
>      >                 module repeat_y()
>      >                 { for(i=[0:3])
>      >                    translate([0,5*i,0])
>      >                      for (j = [0:$children-1]) child(j);  }
>      >
>      >                 repeat_y()
>      >                 { cube(1);
>      >                   sphere(1); }
>      >
>      >             Up to here, no problems, suppose now, you want to repeat
>      >             in the other direction as well, so now we have:
>      >
>      >                 module repeat_y()
>      >                 { for(i=[0:3])
>      >                    translate([0,5*i,0])
>      >                      for (j = [0:$children-1]) child(j);  }
>      >
>      >                 module repeat_x()
>      >                 { for(i=[0:3])
>      >                    translate([5*i,0,0])
>      >                      repeat_y()
>      >                        for (j = [0:$children-1]) child(j); }
>      >
>      >                 repeat_x()
>      >                 { cube(1);
>      >                   sphere(1); }
>      >
>      >             Hey, where did the spheres go? We only see cubes!
>     This can
>      >             be repaired with a union() in the base call,
>      >
>      >                 repeat_x()
>      >                 { union()
>      >                   { cube(1);
>      >                     sphere(1); } }
>      >
>      >             which is understandable but it is somewhat unexpected
>      >             that it is needed. However, an union() inside the
>     repeat_x
>      >             module, i.e. the does NOT display the spheres:
>      >
>      >                 module repeat_x()
>      >                 { for(i=[0:3])
>      >                    translate([5*i,0,0])
>      >                      repeat_y()
>      >                      { union()
>      >                        { for (j = [0:$children-1]) child(j); } } }
>      >
>      >                 repeat_x()
>      >                 { cube(1);
>      >                   sphere(1); }
>      >
>      >             And even more strangely, the following (adding ';' to
>      >             union() ) does:
>      >
>      >                 module repeat_x()
>      >                 { for(i=[0:3])
>      >                    translate([5*i,0,0])
>      >                      repeat_y()
>      >                      { union();
>      >                        for (j = [0:$children-1]) child(j); } }
>      >
>      >             You could even replace union(); with something like
>     sin(1);
>      >             and it does still display the spheres. What is going on
>      >             behind the scene's? Is this intended behavior?
>      >             How should you predictably (and reliably) unify all child
>      >             objects before they are past on to the next module?
>      >             And why is this not done by the implicit 'union'
>      >             as a result of the 'for' loop?
>      >
>      >             Thank you for your insights.
>      >
>      >             Ruud
>      >
>      >
>      >
>      >
>      >
>      >
>      >
>      >
>      >             _______________________________________________
>      >             OpenSCAD mailing list
>      > [hidden email] <mailto:[hidden email]>
>     <mailto:[hidden email] <mailto:[hidden email]>>
>      > http://rocklinux.net/mailman/listinfo/openscad
>      > http://openscad.org - https://flattr.com/thing/121566
>      >
>      >
>      >
>      >         _______________________________________________
>      >         OpenSCAD mailing list
>      > [hidden email] <mailto:[hidden email]>
>     <mailto:[hidden email] <mailto:[hidden email]>>
>      > http://rocklinux.net/mailman/listinfo/openscad
>      > http://openscad.org - https://flattr.com/thing/121566
>      >
>      >
>      >
>      >
>      >
>      > _______________________________________________
>      > OpenSCAD mailing list
>      > [hidden email] <mailto:[hidden email]>
>      > http://rocklinux.net/mailman/listinfo/openscad
>      > http://openscad.org - https://flattr.com/thing/121566
>      >
>
>     _______________________________________________
>     OpenSCAD mailing list
>     [hidden email] <mailto:[hidden email]>
>     http://rocklinux.net/mailman/listinfo/openscad
>     http://openscad.org - https://flattr.com/thing/121566
>
>
>
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

Marius Kintel
Hi all,

There should be some test cases exercising the child behavior. If someone could write a minimal extension to an existing test or a minimal new one, it would be really helpful.

 -Marius

On 2013-07-20, at 12:57, Ruud Vlaming <[hidden email]> wrote:

> On 19-07-13 15:40, nop head wrote:
>> $children is always the size of the child array, but as soon as you use
>> repeat_y it is the number of children of repeat_y, even when accessed in
>> repeat_x.
> No, it looks like $children is a copy of the size of the
> child array of the last instantiated module. I do not completely
> understand the code, but it seems $children has a more 'global'
> nature. That is why it also retains its value, even when it has
> no meaning (i.e., when there is no accompanying child array.)
>
> If i had to fix it i would redesign the code, so i think it is best
> if we await the return of Marius to see what his opinion is.
> Up to then, i think your workaround, that is make a local copy
> of $childeren is quite adequate. For special cases, you can
> also defer the call to the next module, as Andrew pointed
> out.
>
> Thank you David, 'nope head' and Andrew for helping solve
> this mystery.
>
> Ruud
>
>
>>
>>
>>
>> On 19 July 2013 14:31, Ruud Vlaming <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>    I agree, if you try:
>>
>>         module repeat_x()
>>         { for(i=[0:3])
>>            translate([5*i,0,0])
>>              repeat_y()
>>              { echo("repeat_x=",$children);
>>                cube(1);
>>                cylinder(2);
>>                { for (j = [0:$children-1]) child(j); } } }
>>
>>    you get:
>>        Compiling design (CSG Tree generation)...
>>        ECHO: "repeat_x=", 4
>>        WARNING: Child index (2) out of bounds (2 children)
>>        WARNING: Child index (3) out of bounds (2 children)
>>        ...
>>
>>    indicating that $children does not contain the size
>>    of the child array, but of the local array. Even more,
>>    $children seems also to contain a value if that is not
>>    appropriate, for example if you add:
>>
>>         repeat_x()
>>         { echo("top=",$children);
>>           cube(1);
>>           sphere(1); }
>>
>>    you get:
>>        Compiling design (CSG Tree generation)...
>>        ECHO: "repeat_x=", 4
>>        ECHO: "top=", 4
>>        WARNING: Child index (3) out of bounds (3 children)
>>        ...
>>
>>    So the value 4 is retained although it is meaningless
>>    at the point of use.
>>
>>    Looks like a bug.
>>
>>
>>    On 19-07-13 14:52, nop head wrote:
>>> The problem seems to be that $children has the wrong value. At
>>    the top
>>> of repeat_x it is 2 but under the repeat_y it has become 1.
>>>
>>> This fixes it:
>>>
>>>    module repeat_x()
>>>
>>> { kids = $children;
>>>
>>>      for(i=[0:3])
>>>
>>>            translate([5*i,0,0])
>>>
>>>                  repeat_y()
>>>
>>>                       for(i = [0:kids - 1]) child(i);
>>>
>>> }
>>>
>>>
>>> The $ variables have dynamic scope so it seems the value in repeat_y
>>> overides the value in repeat_x. I think $children should have
>>    static scope.
>>>
>>>
>>> On 19 July 2013 13:37, nop head <[hidden email]
>>    <mailto:[hidden email]>
>>> <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>    Even stranger this draws them both:
>>>
>>>        module repeat_y()
>>>
>>>    { for(i=[0:3])
>>>
>>>    translate([0,5*i,0])
>>>
>>>    for (j = [0:$children-1]) child(j); }
>>>
>>>
>>>    module repeat_x()
>>>
>>>    { for(i=[0:3])
>>>
>>>    translate([5*i,0,0])
>>>
>>>    repeat_y()
>>>
>>>    for (j = [1:$children-1]) child(j); }
>>>
>>>
>>>    repeat_x()
>>>
>>>    { cube(1);
>>>
>>>    sphere(1); }
>>>
>>>
>>>    I.e. just changed the loop in repeat_x to skip the first
>>    child so I
>>>    expected to get just the sphere.
>>>
>>>
>>>
>>>    On 19 July 2013 13:31, David Powell <[hidden email]
>>    <mailto:[hidden email]>
>>>    <mailto:[hidden email]
>>    <mailto:[hidden email]>>> wrote:
>>>
>>>        seem to think the  child() only accepts the first object
>>    as the
>>>        child and not subsequent ones
>>>
>>>
>>>          repeat_x()
>>>            { cubeandsphere();}
>>>
>>>        module cubeandsphere()
>>>        { cube(1);
>>>              sphere(1); }
>>>
>>>        iirc will work around it and draw both
>>>
>>>        i would say its a bug
>>>
>>>        Dave
>>>
>>>
>>>        On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>>>        <[hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>            I have some difficulty with modules and child calls.
>>>
>>>            Suppose you want to repeat an object several times,
>>>            you can write:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     child(0);  }
>>>
>>>                repeat_y()
>>>                { cube(1); }
>>>
>>>            And if you have more objects to repeat you can extend
>>    it like:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     for (j = [0:$children-1]) child(j);  }
>>>
>>>                repeat_y()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            Up to here, no problems, suppose now, you want to repeat
>>>            in the other direction as well, so now we have:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     for (j = [0:$children-1]) child(j);  }
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                       for (j = [0:$children-1]) child(j); }
>>>
>>>                repeat_x()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            Hey, where did the spheres go? We only see cubes!
>>    This can
>>>            be repaired with a union() in the base call,
>>>
>>>                repeat_x()
>>>                { union()
>>>                  { cube(1);
>>>                    sphere(1); } }
>>>
>>>            which is understandable but it is somewhat unexpected
>>>            that it is needed. However, an union() inside the
>>    repeat_x
>>>            module, i.e. the does NOT display the spheres:
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                     { union()
>>>                       { for (j = [0:$children-1]) child(j); } } }
>>>
>>>                repeat_x()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            And even more strangely, the following (adding ';' to
>>>            union() ) does:
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                     { union();
>>>                       for (j = [0:$children-1]) child(j); } }
>>>
>>>            You could even replace union(); with something like
>>    sin(1);
>>>            and it does still display the spheres. What is going on
>>>            behind the scene's? Is this intended behavior?
>>>            How should you predictably (and reliably) unify all child
>>>            objects before they are past on to the next module?
>>>            And why is this not done by the implicit 'union'
>>>            as a result of the 'for' loop?
>>>
>>>            Thank you for your insights.
>>>
>>>            Ruud
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>            _______________________________________________
>>>            OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>>
>>>
>>>
>>>        _______________________________________________
>>>        OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>
>>    _______________________________________________
>>    OpenSCAD mailing list
>>    [hidden email] <mailto:[hidden email]>
>>    http://rocklinux.net/mailman/listinfo/openscad
>>    http://openscad.org - https://flattr.com/thing/121566
>>
>>
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> [hidden email]
>> http://rocklinux.net/mailman/listinfo/openscad
>> http://openscad.org - https://flattr.com/thing/121566
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
The issue is simply that variables prefixed with $ have a strange sort dynamic scope that makes no sense for $children. 

Anything under the tree of a module with children inherits $children from that module above, so in the parts of repeat_x() that are below its use of repeat_y() the value of $children is the value for repeat_y()'s children. 

As the number of children to repeat_y() is determined by a for loop using $children this is becomes a self referencing circular problem as well.

Here is a simplified version:

module y() {

   echo("y:",$children);

   for(i = [0:$children-1])

      child(i);

}


module x() {

   echo("x1:",$children);

   y()

      for(i = [0:$children-1]) {

         echo("x2:",$children);

         child(i);

      }

   echo("x3:",$children);

}


x() {

    cube();

    sphere();

}


ECHO: "x1:", 2

ECHO: "y:", 1

ECHO: "x2:", 1

ECHO: "x3:", 2


As you can x1 and x3 are correct but x2 under y is wrong.


This version


module y() {

    echo("y:",$children);

    for(i = [0:$children-1])

        child(i);

}



module x() {

     kids = $children;

     echo("x1:",kids,$children);

     y()

        for(i = [0:kids-1]) {

        echo("x2:",$children);

        child(i);

    }

    echo("x3:",$children);

}


x() {

    cube();

    sphere();

}



works on 2013.06.02


ECHO: "x1:", 2, 2

ECHO: "y:", 1

ECHO: "x2:", 1

ECHO: "x2:", 1

ECHO: "x3:", 2


but doesn't work on 2013.06.14


ECHO: "x1:", undef, 2

ECHO: "y:", 1

ECHO: "x3:", 2


So it appear you can't take a copy of $children in some versions, breaking the workaround. The other workaround of moving y() inside the for loop will work.


The dynamic scope makes sense for something like $fn but not children. That should have the scope of the module.



On 20 July 2013 12:03, Marius Kintel <[hidden email]> wrote:
Hi all,

There should be some test cases exercising the child behavior. If someone could write a minimal extension to an existing test or a minimal new one, it would be really helpful.

 -Marius

On 2013-07-20, at 12:57, Ruud Vlaming <[hidden email]> wrote:

> On 19-07-13 15:40, nop head wrote:
>> $children is always the size of the child array, but as soon as you use
>> repeat_y it is the number of children of repeat_y, even when accessed in
>> repeat_x.
> No, it looks like $children is a copy of the size of the
> child array of the last instantiated module. I do not completely
> understand the code, but it seems $children has a more 'global'
> nature. That is why it also retains its value, even when it has
> no meaning (i.e., when there is no accompanying child array.)
>
> If i had to fix it i would redesign the code, so i think it is best
> if we await the return of Marius to see what his opinion is.
> Up to then, i think your workaround, that is make a local copy
> of $childeren is quite adequate. For special cases, you can
> also defer the call to the next module, as Andrew pointed
> out.
>
> Thank you David, 'nope head' and Andrew for helping solve
> this mystery.
>
> Ruud
>
>
>>
>>
>>
>> On 19 July 2013 14:31, Ruud Vlaming <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>    I agree, if you try:
>>
>>         module repeat_x()
>>         { for(i=[0:3])
>>            translate([5*i,0,0])
>>              repeat_y()
>>              { echo("repeat_x=",$children);
>>                cube(1);
>>                cylinder(2);
>>                { for (j = [0:$children-1]) child(j); } } }
>>
>>    you get:
>>        Compiling design (CSG Tree generation)...
>>        ECHO: "repeat_x=", 4
>>        WARNING: Child index (2) out of bounds (2 children)
>>        WARNING: Child index (3) out of bounds (2 children)
>>        ...
>>
>>    indicating that $children does not contain the size
>>    of the child array, but of the local array. Even more,
>>    $children seems also to contain a value if that is not
>>    appropriate, for example if you add:
>>
>>         repeat_x()
>>         { echo("top=",$children);
>>           cube(1);
>>           sphere(1); }
>>
>>    you get:
>>        Compiling design (CSG Tree generation)...
>>        ECHO: "repeat_x=", 4
>>        ECHO: "top=", 4
>>        WARNING: Child index (3) out of bounds (3 children)
>>        ...
>>
>>    So the value 4 is retained although it is meaningless
>>    at the point of use.
>>
>>    Looks like a bug.
>>
>>
>>    On 19-07-13 14:52, nop head wrote:
>>> The problem seems to be that $children has the wrong value. At
>>    the top
>>> of repeat_x it is 2 but under the repeat_y it has become 1.
>>>
>>> This fixes it:
>>>
>>>    module repeat_x()
>>>
>>> { kids = $children;
>>>
>>>      for(i=[0:3])
>>>
>>>            translate([5*i,0,0])
>>>
>>>                  repeat_y()
>>>
>>>                       for(i = [0:kids - 1]) child(i);
>>>
>>> }
>>>
>>>
>>> The $ variables have dynamic scope so it seems the value in repeat_y
>>> overides the value in repeat_x. I think $children should have
>>    static scope.
>>>
>>>
>>> On 19 July 2013 13:37, nop head <[hidden email]
>>    <mailto:[hidden email]>
>>> <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>    Even stranger this draws them both:
>>>
>>>        module repeat_y()
>>>
>>>    { for(i=[0:3])
>>>
>>>    translate([0,5*i,0])
>>>
>>>    for (j = [0:$children-1]) child(j); }
>>>
>>>
>>>    module repeat_x()
>>>
>>>    { for(i=[0:3])
>>>
>>>    translate([5*i,0,0])
>>>
>>>    repeat_y()
>>>
>>>    for (j = [1:$children-1]) child(j); }
>>>
>>>
>>>    repeat_x()
>>>
>>>    { cube(1);
>>>
>>>    sphere(1); }
>>>
>>>
>>>    I.e. just changed the loop in repeat_x to skip the first
>>    child so I
>>>    expected to get just the sphere.
>>>
>>>
>>>
>>>    On 19 July 2013 13:31, David Powell <[hidden email]
>>    <mailto:[hidden email]>
>>>    <mailto:[hidden email]
>>    <mailto:[hidden email]>>> wrote:
>>>
>>>        seem to think the  child() only accepts the first object
>>    as the
>>>        child and not subsequent ones
>>>
>>>
>>>          repeat_x()
>>>            { cubeandsphere();}
>>>
>>>        module cubeandsphere()
>>>        { cube(1);
>>>              sphere(1); }
>>>
>>>        iirc will work around it and draw both
>>>
>>>        i would say its a bug
>>>
>>>        Dave
>>>
>>>
>>>        On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>>>        <[hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>            I have some difficulty with modules and child calls.
>>>
>>>            Suppose you want to repeat an object several times,
>>>            you can write:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     child(0);  }
>>>
>>>                repeat_y()
>>>                { cube(1); }
>>>
>>>            And if you have more objects to repeat you can extend
>>    it like:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     for (j = [0:$children-1]) child(j);  }
>>>
>>>                repeat_y()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            Up to here, no problems, suppose now, you want to repeat
>>>            in the other direction as well, so now we have:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     for (j = [0:$children-1]) child(j);  }
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                       for (j = [0:$children-1]) child(j); }
>>>
>>>                repeat_x()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            Hey, where did the spheres go? We only see cubes!
>>    This can
>>>            be repaired with a union() in the base call,
>>>
>>>                repeat_x()
>>>                { union()
>>>                  { cube(1);
>>>                    sphere(1); } }
>>>
>>>            which is understandable but it is somewhat unexpected
>>>            that it is needed. However, an union() inside the
>>    repeat_x
>>>            module, i.e. the does NOT display the spheres:
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                     { union()
>>>                       { for (j = [0:$children-1]) child(j); } } }
>>>
>>>                repeat_x()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            And even more strangely, the following (adding ';' to
>>>            union() ) does:
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                     { union();
>>>                       for (j = [0:$children-1]) child(j); } }
>>>
>>>            You could even replace union(); with something like
>>    sin(1);
>>>            and it does still display the spheres. What is going on
>>>            behind the scene's? Is this intended behavior?
>>>            How should you predictably (and reliably) unify all child
>>>            objects before they are past on to the next module?
>>>            And why is this not done by the implicit 'union'
>>>            as a result of the 'for' loop?
>>>
>>>            Thank you for your insights.
>>>
>>>            Ruud
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>            _______________________________________________
>>>            OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>>
>>>
>>>
>>>        _______________________________________________
>>>        OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>
>>    _______________________________________________
>>    OpenSCAD mailing list
>>    [hidden email] <mailto:[hidden email]>
>>    http://rocklinux.net/mailman/listinfo/openscad
>>    http://openscad.org - https://flattr.com/thing/121566
>>
>>
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> [hidden email]
>> http://rocklinux.net/mailman/listinfo/openscad
>> http://openscad.org - https://flattr.com/thing/121566
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

devlaam
In reply to this post by nophead
On 19-07-13 14:52, nop head wrote:
> This fixes it:
>     module repeat_x()
> { kids = $children;
>       for(i=[0:3])
>             translate([5*i,0,0])
>                   repeat_y()
>                        for(i = [0:kids - 1]) child(i);
> }

Did you actually try this fix? Although your analysis seems
correct (see my other post) this fix does not work in my
version of openSCAD (2013.06.19). It gives:
   Compiling design (CSG Tree generation)...
   Compiling design (CSG Products generation)...
   ERROR: CSG generation failed! (no top level object found)

Ruud

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

David Powell
In reply to this post by nophead
i wrote this lib function about a month ago , it does not use the $children and assumes it would do all child  items ,, although the tests only assume one and it works ok if that one is a module  
there's a test function   Cubic_and_Radial_Array_Test();   

 


// array functions
// by david powell 
// licence LGPL V2 or later 
//
// this lib provides 2 functions 
// Cubic_Array() , and Radial_Array()
//
//Cubic_Array(sx,sy,sz,nx,ny,nz,center){childobject}
//  produces a cubic grid of child objects 
//  sx,sy,sz = spacing for each axis 
//  nx,ny,nz and number of objects on each axis 
//  center = true/false on if geometery is centered or not 
//
//
//Radial_Array(a,n,r){child object}
// produces a clockwise radial array of child objects rotated around the local z axis   
// a= interval angle 
// n= number of objects 
// r= radius distance 
//
// remove // from following line to run test 
//Cubic_and_Radial_Array_Test();

module Cubic_and_Radial_Array_Test()
  {
//center referance point 
  translate([0,0,0])
#cube([5,5,5],center=true);

//cubic array  of  5*5*5 objects spaced 10*10*10 center relative
  Cubic_Array(10,10,10,5,5,5,center=true)
{
sphere(2.5,center=true,$fn=60);
}

//a linear array allong x can be derived from the cubic array simply 
translate([60,0,0])
   Cubic_Array(10,0,0,5,1,1,center=false)
{
cube([5,5,5],center=true);
//a linear array allong y can be derived from the cubic array simply 
translate([0,60,0])
   Cubic_Array(0,10,0,1,5,1,center=false)
{
cube([5,5,5],center=true);

//a linear array allong z can be derived from the cubic array simply 
translate([0,0,60])
   Cubic_Array(0,0,10,1,1,5,center=false)
{
cube([5,5,5],center=true);

//a grid  array allong x,y can be derived from the cubic array simply 
translate([0,0,-60])
   Cubic_Array(10,10,0,5,5,1,center=true)
{
cube([5,5,5],center=true);

//radial array of 32 objects rotated though 10 degrees 
  translate([0,0,0])
  Radial_Array(10,32,40)
{
cube([2,4,6],center=true);
}

// a radial array of linear arrays 

  rotate([45,45,45])
  Radial_Array(10,36,40)
{
translate([0,10,0])
    Cubic_Array(0,10,0,1,5,1,center=false)
{
cube([2,3,4],center=true);
}
}

}


// main lib modules
module Cubic_Array(sx,sy,sz,nx,ny,nz,center)
{
if (center==true)
{
translate([-(((nx+1)*sx)/2),-(((ny+1)*sy)/2),-(((nz+1)*sz)/2)])
{
for(x=[1:nx])
{
for(y=[1:ny])
{
for(z=[1:nz])
{
translate([x*sx,y*sy,z*sz])
child(center=true);
}
}
}
}
}
else
{
translate([0,0,0])
{
for(x=[1:nx])
{
for(y=[1:ny])
{
for(z=[1:nz])
{
translate([x*sx,y*sy,z*sz])
child();
}
}
}
}
}
}

//
//Radial_Array(a,n,r){child object}
// produces a clockwise radial array of child objects rotated around the local z axis   
// a= interval angle 
// n= number of objects 
// r= radius distance 
//
module Radial_Array(a,n,r)
{
 for (k=[0:n-1])
 {
 rotate([0,0,-(a*k)])
 translate([0,r,0])
 child();
 }
}



On Sat, Jul 20, 2013 at 1:06 PM, nop head <[hidden email]> wrote:
The issue is simply that variables prefixed with $ have a strange sort dynamic scope that makes no sense for $children. 

Anything under the tree of a module with children inherits $children from that module above, so in the parts of repeat_x() that are below its use of repeat_y() the value of $children is the value for repeat_y()'s children. 

As the number of children to repeat_y() is determined by a for loop using $children this is becomes a self referencing circular problem as well.

Here is a simplified version:

module y() {

   echo("y:",$children);

   for(i = [0:$children-1])

      child(i);

}


module x() {

   echo("x1:",$children);

   y()

      for(i = [0:$children-1]) {

         echo("x2:",$children);

         child(i);

      }

   echo("x3:",$children);

}


x() {

    cube();

    sphere();

}


ECHO: "x1:", 2

ECHO: "y:", 1

ECHO: "x2:", 1

ECHO: "x3:", 2


As you can x1 and x3 are correct but x2 under y is wrong.


This version


module y() {

    echo("y:",$children);

    for(i = [0:$children-1])

        child(i);

}



module x() {

     kids = $children;

     echo("x1:",kids,$children);

     y()

        for(i = [0:kids-1]) {

        echo("x2:",$children);

        child(i);

    }

    echo("x3:",$children);

}


x() {

    cube();

    sphere();

}



works on 2013.06.02


ECHO: "x1:", 2, 2

ECHO: "y:", 1

ECHO: "x2:", 1

ECHO: "x2:", 1

ECHO: "x3:", 2


but doesn't work on 2013.06.14


ECHO: "x1:", undef, 2

ECHO: "y:", 1

ECHO: "x3:", 2


So it appear you can't take a copy of $children in some versions, breaking the workaround. The other workaround of moving y() inside the for loop will work.


The dynamic scope makes sense for something like $fn but not children. That should have the scope of the module.



On 20 July 2013 12:03, Marius Kintel <[hidden email]> wrote:
Hi all,

There should be some test cases exercising the child behavior. If someone could write a minimal extension to an existing test or a minimal new one, it would be really helpful.

 -Marius

On 2013-07-20, at 12:57, Ruud Vlaming <[hidden email]> wrote:

> On 19-07-13 15:40, nop head wrote:
>> $children is always the size of the child array, but as soon as you use
>> repeat_y it is the number of children of repeat_y, even when accessed in
>> repeat_x.
> No, it looks like $children is a copy of the size of the
> child array of the last instantiated module. I do not completely
> understand the code, but it seems $children has a more 'global'
> nature. That is why it also retains its value, even when it has
> no meaning (i.e., when there is no accompanying child array.)
>
> If i had to fix it i would redesign the code, so i think it is best
> if we await the return of Marius to see what his opinion is.
> Up to then, i think your workaround, that is make a local copy
> of $childeren is quite adequate. For special cases, you can
> also defer the call to the next module, as Andrew pointed
> out.
>
> Thank you David, 'nope head' and Andrew for helping solve
> this mystery.
>
> Ruud
>
>
>>
>>
>>
>> On 19 July 2013 14:31, Ruud Vlaming <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>    I agree, if you try:
>>
>>         module repeat_x()
>>         { for(i=[0:3])
>>            translate([5*i,0,0])
>>              repeat_y()
>>              { echo("repeat_x=",$children);
>>                cube(1);
>>                cylinder(2);
>>                { for (j = [0:$children-1]) child(j); } } }
>>
>>    you get:
>>        Compiling design (CSG Tree generation)...
>>        ECHO: "repeat_x=", 4
>>        WARNING: Child index (2) out of bounds (2 children)
>>        WARNING: Child index (3) out of bounds (2 children)
>>        ...
>>
>>    indicating that $children does not contain the size
>>    of the child array, but of the local array. Even more,
>>    $children seems also to contain a value if that is not
>>    appropriate, for example if you add:
>>
>>         repeat_x()
>>         { echo("top=",$children);
>>           cube(1);
>>           sphere(1); }
>>
>>    you get:
>>        Compiling design (CSG Tree generation)...
>>        ECHO: "repeat_x=", 4
>>        ECHO: "top=", 4
>>        WARNING: Child index (3) out of bounds (3 children)
>>        ...
>>
>>    So the value 4 is retained although it is meaningless
>>    at the point of use.
>>
>>    Looks like a bug.
>>
>>
>>    On 19-07-13 14:52, nop head wrote:
>>> The problem seems to be that $children has the wrong value. At
>>    the top
>>> of repeat_x it is 2 but under the repeat_y it has become 1.
>>>
>>> This fixes it:
>>>
>>>    module repeat_x()
>>>
>>> { kids = $children;
>>>
>>>      for(i=[0:3])
>>>
>>>            translate([5*i,0,0])
>>>
>>>                  repeat_y()
>>>
>>>                       for(i = [0:kids - 1]) child(i);
>>>
>>> }
>>>
>>>
>>> The $ variables have dynamic scope so it seems the value in repeat_y
>>> overides the value in repeat_x. I think $children should have
>>    static scope.
>>>
>>>
>>> On 19 July 2013 13:37, nop head <[hidden email]
>>    <mailto:[hidden email]>
>>> <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>    Even stranger this draws them both:
>>>
>>>        module repeat_y()
>>>
>>>    { for(i=[0:3])
>>>
>>>    translate([0,5*i,0])
>>>
>>>    for (j = [0:$children-1]) child(j); }
>>>
>>>
>>>    module repeat_x()
>>>
>>>    { for(i=[0:3])
>>>
>>>    translate([5*i,0,0])
>>>
>>>    repeat_y()
>>>
>>>    for (j = [1:$children-1]) child(j); }
>>>
>>>
>>>    repeat_x()
>>>
>>>    { cube(1);
>>>
>>>    sphere(1); }
>>>
>>>
>>>    I.e. just changed the loop in repeat_x to skip the first
>>    child so I
>>>    expected to get just the sphere.
>>>
>>>
>>>
>>>    On 19 July 2013 13:31, David Powell <[hidden email]
>>    <mailto:[hidden email]>
>>>    <mailto:[hidden email]
>>    <mailto:[hidden email]>>> wrote:
>>>
>>>        seem to think the  child() only accepts the first object
>>    as the
>>>        child and not subsequent ones
>>>
>>>
>>>          repeat_x()
>>>            { cubeandsphere();}
>>>
>>>        module cubeandsphere()
>>>        { cube(1);
>>>              sphere(1); }
>>>
>>>        iirc will work around it and draw both
>>>
>>>        i would say its a bug
>>>
>>>        Dave
>>>
>>>
>>>        On Fri, Jul 19, 2013 at 1:12 PM, Ruud Vlaming
>>>        <[hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>            I have some difficulty with modules and child calls.
>>>
>>>            Suppose you want to repeat an object several times,
>>>            you can write:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     child(0);  }
>>>
>>>                repeat_y()
>>>                { cube(1); }
>>>
>>>            And if you have more objects to repeat you can extend
>>    it like:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     for (j = [0:$children-1]) child(j);  }
>>>
>>>                repeat_y()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            Up to here, no problems, suppose now, you want to repeat
>>>            in the other direction as well, so now we have:
>>>
>>>                module repeat_y()
>>>                { for(i=[0:3])
>>>                   translate([0,5*i,0])
>>>                     for (j = [0:$children-1]) child(j);  }
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                       for (j = [0:$children-1]) child(j); }
>>>
>>>                repeat_x()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            Hey, where did the spheres go? We only see cubes!
>>    This can
>>>            be repaired with a union() in the base call,
>>>
>>>                repeat_x()
>>>                { union()
>>>                  { cube(1);
>>>                    sphere(1); } }
>>>
>>>            which is understandable but it is somewhat unexpected
>>>            that it is needed. However, an union() inside the
>>    repeat_x
>>>            module, i.e. the does NOT display the spheres:
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                     { union()
>>>                       { for (j = [0:$children-1]) child(j); } } }
>>>
>>>                repeat_x()
>>>                { cube(1);
>>>                  sphere(1); }
>>>
>>>            And even more strangely, the following (adding ';' to
>>>            union() ) does:
>>>
>>>                module repeat_x()
>>>                { for(i=[0:3])
>>>                   translate([5*i,0,0])
>>>                     repeat_y()
>>>                     { union();
>>>                       for (j = [0:$children-1]) child(j); } }
>>>
>>>            You could even replace union(); with something like
>>    sin(1);
>>>            and it does still display the spheres. What is going on
>>>            behind the scene's? Is this intended behavior?
>>>            How should you predictably (and reliably) unify all child
>>>            objects before they are past on to the next module?
>>>            And why is this not done by the implicit 'union'
>>>            as a result of the 'for' loop?
>>>
>>>            Thank you for your insights.
>>>
>>>            Ruud
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>            _______________________________________________
>>>            OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>>
>>>
>>>
>>>        _______________________________________________
>>>        OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>    <mailto:[hidden email] <mailto:[hidden email]>>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> [hidden email] <mailto:[hidden email]>
>>> http://rocklinux.net/mailman/listinfo/openscad
>>> http://openscad.org - https://flattr.com/thing/121566
>>
>>    _______________________________________________
>>    OpenSCAD mailing list
>>    [hidden email] <mailto:[hidden email]>
>>    http://rocklinux.net/mailman/listinfo/openscad
>>    http://openscad.org - https://flattr.com/thing/121566
>>
>>
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> [hidden email]
>> http://rocklinux.net/mailman/listinfo/openscad
>> http://openscad.org - https://flattr.com/thing/121566
>
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
In reply to this post by devlaam
Yes I tested it. As I said in a later post it works on 2013.06.02 but not on 2013.06.14. There were some changes about how variables are evaluated and I don't think any version gets it completely correct yet.




On 20 July 2013 15:22, Ruud Vlaming <[hidden email]> wrote:
On 19-07-13 14:52, nop head wrote:
> This fixes it:
>     module repeat_x()
> { kids = $children;
>       for(i=[0:3])
>             translate([5*i,0,0])
>                   repeat_y()
>                        for(i = [0:kids - 1]) child(i);
> }

Did you actually try this fix? Although your analysis seems
correct (see my other post) this fix does not work in my
version of openSCAD (2013.06.19). It gives:
   Compiling design (CSG Tree generation)...
   Compiling design (CSG Products generation)...
   ERROR: CSG generation failed! (no top level object found)

Ruud

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

devlaam
On 20-07-13 16:42, nop head wrote:
> Yes I tested it. As I said in a later post it works on 2013.06.02 but
> not on 2013.06.14. There were some changes about how variables are
> evaluated and I don't think any version gets it completely correct yet.
Okay, i see it now, thanks. This one entered my email just recently.

It is a pity your workaround does not work for all versions,
for displacing the inner module call is not possible in
all situations. My code was just a simple example of something
i encountered when designing something.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
Yes not being able to copy the value of $children seems like another unrelated bug.


On 20 July 2013 15:48, Ruud Vlaming <[hidden email]> wrote:
On 20-07-13 16:42, nop head wrote:
> Yes I tested it. As I said in a later post it works on 2013.06.02 but
> not on 2013.06.14. There were some changes about how variables are
> evaluated and I don't think any version gets it completely correct yet.
Okay, i see it now, thanks. This one entered my email just recently.

It is a pity your workaround does not work for all versions,
for displacing the inner module call is not possible in
all situations. My code was just a simple example of something
i encountered when designing something.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
Seems to behave like $children is assigned a value after all the other local variables in the module. 


On 20 July 2013 15:50, nop head <[hidden email]> wrote:
Yes not being able to copy the value of $children seems like another unrelated bug.


On 20 July 2013 15:48, Ruud Vlaming <[hidden email]> wrote:
On 20-07-13 16:42, nop head wrote:
> Yes I tested it. As I said in a later post it works on 2013.06.02 but
> not on 2013.06.14. There were some changes about how variables are
> evaluated and I don't think any version gets it completely correct yet.
Okay, i see it now, thanks. This one entered my email just recently.

It is a pity your workaround does not work for all versions,
for displacing the inner module call is not possible in
all situations. My code was just a simple example of something
i encountered when designing something.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

Marius Kintel
Are you guys saying this is a regression which appeared _after_ the last public release? That would make sense as some experimental stuff were enabled post-release.

 -Marius
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

devlaam
In reply to this post by nophead
BTW, you have two nested for loops both with the
variable 'i' in there. But i assume this is just
a typo?

Ruud.

On 20-07-13 16:42, nop head wrote:

>     On 19-07-13 14:52, nop head wrote:
>      > This fixes it:
>      >     module repeat_x()
>      > { kids = $children;
>      >       for(i=[0:3])
variable i
>      >             translate([5*i,0,0])
>      >                   repeat_y()
>      >                        for(i = [0:kids - 1]) child(i);
variable i again!
>      > }

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

devlaam
In reply to this post by Marius Kintel
Just tested the official release:

  /Applications/Addon/OpenSCAD.app/Contents/MacOS/OpenSCAD --version
  OpenSCAD version 2013.06

seems to have the same problems. I dunno
about version 2013.06.02.

Ruud


On 20-07-13 16:59, Marius Kintel wrote:
> Are you guys saying this is a regression which appeared _after_ the last public release? That would make sense as some experimental stuff were enabled post-release.
>
>   -Marius
> _______________________________________________
> OpenSCAD mailing list
> [hidden email]
> http://rocklinux.net/mailman/listinfo/openscad
> http://openscad.org - https://flattr.com/thing/121566
>

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
Reply | Threaded
Open this post in threaded view
|

Re: What is happening here?

nophead
In reply to this post by devlaam
It is inside a new block so I don't think it is a problem, you get a new variable.


On 20 July 2013 16:15, Ruud Vlaming <[hidden email]> wrote:
BTW, you have two nested for loops both with the
variable 'i' in there. But i assume this is just
a typo?

Ruud.

On 20-07-13 16:42, nop head wrote:

>     On 19-07-13 14:52, nop head wrote:
>      > This fixes it:
>      >     module repeat_x()
>      > { kids = $children;
>      >       for(i=[0:3])
variable i
>      >             translate([5*i,0,0])
>      >                   repeat_y()
>      >                        for(i = [0:kids - 1]) child(i);
variable i again!
>      > }

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://rocklinux.net/mailman/listinfo/openscad
http://openscad.org - https://flattr.com/thing/121566
12