Discussion:
[OpenSCAD] How to handle this kind of flexibility?
Troberg
2018-11-22 09:06:30 UTC
Permalink
I have a laser cutter on the way, and in preparation for that, I've made a
couple of programs to cut pixel images. I firts run a small VB program which
translates the image to an array, so I can work with it in OpenSCAD.

Then, I make a module which loops through that image and places as scaled
copy of children() at each pixel position. The brighter the pixel, the
larger the scale (and thus the eventual hole cut).

That's nice and clean, and I can easily have square holes, round holes, star
shaped holes or whatever. With some parameters, I can even make the scaling
in only one direction, to crete a "blinds" effect.

Neat.

But, me being me, I couldn't stop thinking of possibilites.

So, I thought: "Wouldn't it be neat if I could change the shape of the pixel
hole depending on the value?". For example, start with a very thin + shape
for dark pixels, then move the four center vertices out towards the corners
for brighter pixels, making it look more like a four point star, through a
rhombus, an octagon and eventually a square for a white pixel.

Well, of course I can do that, but not in the same code. I can't send
paramaters to children(). I have to replace children() with a call to, for
example, mystarshape(). But, that comes with complications as well, as it
means that I will have to go into the module and change it if I wanted
another shape/logic, which makes for poor separation of concern.

Any thoughts on how to make a neat solution for this?



--
Sent from: http://forum.openscad.org/
nop head
2018-11-22 12:02:46 UTC
Permalink
You can pass parameters to children using $variables. You assign them in
the parent and they can be accessed in anything called from the parent,
including the children.
Post by Troberg
I have a laser cutter on the way, and in preparation for that, I've made a
couple of programs to cut pixel images. I firts run a small VB program which
translates the image to an array, so I can work with it in OpenSCAD.
Then, I make a module which loops through that image and places as scaled
copy of children() at each pixel position. The brighter the pixel, the
larger the scale (and thus the eventual hole cut).
That's nice and clean, and I can easily have square holes, round holes, star
shaped holes or whatever. With some parameters, I can even make the scaling
in only one direction, to crete a "blinds" effect.
Neat.
But, me being me, I couldn't stop thinking of possibilites.
So, I thought: "Wouldn't it be neat if I could change the shape of the pixel
hole depending on the value?". For example, start with a very thin + shape
for dark pixels, then move the four center vertices out towards the corners
for brighter pixels, making it look more like a four point star, through a
rhombus, an octagon and eventually a square for a white pixel.
Well, of course I can do that, but not in the same code. I can't send
paramaters to children(). I have to replace children() with a call to, for
example, mystarshape(). But, that comes with complications as well, as it
means that I will have to go into the module and change it if I wanted
another shape/logic, which makes for poor separation of concern.
Any thoughts on how to make a neat solution for this?
--
Sent from: http://forum.openscad.org/
_______________________________________________
OpenSCAD mailing list
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Troberg
2018-11-22 12:46:50 UTC
Permalink
Thanks, I had no idea about that. Will check!



--
Sent from: http://forum.openscad.org/
Troberg
2018-11-26 07:48:33 UTC
Permalink
Worked like a charm. I'll post my code here when I've cleaned up up a bit, as
It may be useful for someone else who wants to laser cut images.



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

shadowwynd
2018-11-22 12:17:25 UTC
Permalink
Personally, I think changing children to myShape would have the greater
flexibility.

However, if you wanted to stay with children(), and since we can't pass
parameters to the children, the first solution that popped into mind is to
use more children and build a ADC (Analog Digital Converter) to switch
between them (e.g. like a CASE or SWITCH statement). See the sample code
below. In this case, the number of children corresponds to the granularity
of the ADC. In the example below,

--------------------------

points = [15, 30, 100, 200, 60, 255, 178];
radius = 5;

module test_ADC()
{
ADC = 256/$children;

echo ($children, "-bit ADC, granularity =", ADC);

for (i = [0: len(points)-1])
{
x = floor(points[i]/ADC);
echo ("value=", points[i], " location= ", i*10, "Shape =", x );
translate ([i*10, 0, 0]) children(x);
}
}

module show_all_shapes()
{
for (i = [0: len(points)-1])
{
translate ([i*10, 0, 0]) children(i);
}
}

//show_all_shapes()
test_ADC()
{
circle (r=radius, $fn=3);
circle (r=radius, $fn=4);
circle (r=radius, $fn=5);
circle (r=radius, $fn=6);
circle (r=radius, $fn=8);
circle (r=radius, $fn=10);
square (radius*2, true);
}





--
Sent from: http://forum.openscad.org/
shadowwynd
2018-11-22 12:30:41 UTC
Permalink
Thanks, nophead! Picked up a new trick myself...

Sample code to pass with $variable is shown below.

----------------------

points = [15, 30, 100, 200, 60, 255, 178];

module test()
{
for (i = [0: len(points)-1])
{
$height = points[i];
translate ([i*10, 0, 0]) children();
}
}

test()
{
cylinder (r=5, h=$height);
}




--
Sent from: http://forum.openscad.org/
shadowwynd
2018-11-22 12:32:11 UTC
Permalink
Thanks, nophead! Picked up a new trick myself....

Example code for passing with $variable below:

points = [15, 30, 100, 200, 60, 255, 178];

module test()
{
for (i = [0: len(points)-1])
{
$height = points[i];
translate ([i*10, 0, 0]) children();
}
}

test()
{
cylinder (r=5, h=$height);
}




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