discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

How to handle this kind of flexibility?

T
Troberg
Thu, Nov 22, 2018 9:06 AM

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/

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/
NH
nop head
Thu, Nov 22, 2018 12:02 PM

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.

On Thu, 22 Nov 2018, 09:07 Troberg <troberg.anders@gmail.com wrote:

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
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

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. On Thu, 22 Nov 2018, 09:07 Troberg <troberg.anders@gmail.com wrote: > 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 > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
S
shadowwynd
Thu, Nov 22, 2018 12:17 PM

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/

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/
S
shadowwynd
Thu, Nov 22, 2018 12:30 PM

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/

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/
S
shadowwynd
Thu, Nov 22, 2018 12:32 PM

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/

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/
T
Troberg
Thu, Nov 22, 2018 12:46 PM

Thanks, I had no idea about that. Will check!

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

Thanks, I had no idea about that. Will check! -- Sent from: http://forum.openscad.org/
T
Troberg
Mon, Nov 26, 2018 7:48 AM

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/

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/