discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

How to work with images?

BS
Bob Seidensticker
Mon, Mar 1, 2021 8:40 PM

The surface_image.scad example was helpful in showing how surface() works.
But what I'd like to do is have the image in an array so I can access each
pixel in turn. Is there any way to do that?

Thanks.

The surface_image.scad example was helpful in showing how surface() works. But what I'd like to do is have the image in an array so I can access each pixel in turn. Is there any way to do that? Thanks.
RD
Revar Desmera
Mon, Mar 1, 2021 10:50 PM

OpenSCAD does not let you read file or image data into an array.  You CAN write an external program to read a file and output an OpenSCAD script with an array of that data, though.

-Revar

On Mar 1, 2021, at 12:40 PM, Bob Seidensticker crossexaminedblog@gmail.com wrote:


The surface_image.scad example was helpful in showing how surface() works. But what I’d like to do is have the image in an array so I can access each pixel in turn. Is there any way to do that?

Thanks.


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

OpenSCAD does not let you read file or image data into an array. You CAN write an external program to read a file and output an OpenSCAD script with an array of that data, though. -Revar > On Mar 1, 2021, at 12:40 PM, Bob Seidensticker <crossexaminedblog@gmail.com> wrote: > >  > The surface_image.scad example was helpful in showing how surface() works. But what I’d like to do is have the image in an array so I can access each pixel in turn. Is there any way to do that? > > Thanks. > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
S
Seidensticker
Tue, Mar 2, 2021 2:12 AM

If I understand your point, you're talking about a separate program outside
of OpenSCAD that creates an OpenSCAD script with all the operations in
response to the pixels in the image. Is that right? I hadn't thought of
that. Thanks for the suggestion.

But that raises another question. What I have in mind would be perhaps just
one operation per pixel, but if the image is even as small as 100x100,
that's 10,000 pixels, which would produce a script with 10,000 operations.
Does OpenSCAD have limitations on how long a script can be? Or is the only
downside that it might take a long time?

Or maybe OpenSCAD isn't the tool for me. Are there other 3D printing tools
that are driven with scripts?

Thanks for the help,
Bob

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

If I understand your point, you're talking about a separate program outside of OpenSCAD that creates an OpenSCAD script with all the operations in response to the pixels in the image. Is that right? I hadn't thought of that. Thanks for the suggestion. But that raises another question. What I have in mind would be perhaps just one operation per pixel, but if the image is even as small as 100x100, that's 10,000 pixels, which would produce a script with 10,000 operations. Does OpenSCAD have limitations on how long a script can be? Or is the only downside that it might take a long time? Or maybe OpenSCAD isn't the tool for me. Are there other 3D printing tools that are driven with scripts? Thanks for the help, Bob -- Sent from: http://forum.openscad.org/
RD
Revar Desmera
Tue, Mar 2, 2021 6:16 AM

While OpenSCAD does have loop limitations, it’s mostly limiting a single loop to 10000 iterations, as I recall.  My BOSL2 library has a data based equivalent to surface() called heightfield(), that I’ve fed 100x100 grids of function generated data to, with reasonable speed.

https://github.com/revarbat/BOSL2/wiki/shapes.scad#functionmodule-heightfield

-Revar

On Mar 1, 2021, at 6:13 PM, Seidensticker crossexaminedblog@gmail.com wrote:

If I understand your point, you're talking about a separate program outside of OpenSCAD that creates an OpenSCAD script with all the operations in response to the pixels in the image. Is that right? I hadn't thought of that. Thanks for the suggestion.

But that raises another question. What I have in mind would be perhaps just one operation per pixel, but if the image is even as small as 100x100, that's 10,000 pixels, which would produce a script with 10,000 operations. Does OpenSCAD have limitations on how long a script can be? Or is the only downside that it might take a long time?

Or maybe OpenSCAD isn't the tool for me. Are there other 3D printing tools that are driven with scripts?

Thanks for the help,
Bob
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

While OpenSCAD does have loop limitations, it’s mostly limiting a single loop to 10000 iterations, as I recall. My BOSL2 library has a data based equivalent to `surface()` called `heightfield()`, that I’ve fed 100x100 grids of function generated data to, with reasonable speed. https://github.com/revarbat/BOSL2/wiki/shapes.scad#functionmodule-heightfield -Revar > On Mar 1, 2021, at 6:13 PM, Seidensticker <crossexaminedblog@gmail.com> wrote: > > If I understand your point, you're talking about a separate program outside of OpenSCAD that creates an OpenSCAD script with all the operations in response to the pixels in the image. Is that right? I hadn't thought of that. Thanks for the suggestion. > > But that raises another question. What I have in mind would be perhaps just one operation per pixel, but if the image is even as small as 100x100, that's 10,000 pixels, which would produce a script with 10,000 operations. Does OpenSCAD have limitations on how long a script can be? Or is the only downside that it might take a long time? > > Or maybe OpenSCAD isn't the tool for me. Are there other 3D printing tools that are driven with scripts? > > Thanks for the help, > Bob > Sent from the OpenSCAD mailing list archive at Nabble.com. > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
T
Troberg
Tue, Mar 2, 2021 4:49 PM

RevarBat wrote

OpenSCAD does not let you read file or image data into an array.  You CAN
write an external program to read a file and output an OpenSCAD script
with an array of that data, though.

Yep, that's how I did it. It became pretty slow if you have larger
resolutions, though.

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

RevarBat wrote > OpenSCAD does not let you read file or image data into an array. You CAN > write an external program to read a file and output an OpenSCAD script > with an array of that data, though. Yep, that's how I did it. It became pretty slow if you have larger resolutions, though. -- Sent from: http://forum.openscad.org/
M
MichaelAtOz
Wed, Mar 3, 2021 1:44 AM

Seidensticker wrote

What I have in mind would be perhaps just
one operation per pixel, but if the image is even as small as 100x100,
that's 10,000 pixels, which would produce a script with 10,000 operations.
Does OpenSCAD have limitations on how long a script can be? Or is the only
downside that it might take a long time?

I decided to test this.

At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy.
It renders in 15.5 hours using 26GB memory.
It took ~90s to export as stl.
The render view panel is laggy, but works.

At 100x100, 10,000 cubes, it previews promptly, view panel is responsive.
It renders in 17m 40s, using 3GB, render view panel is responsive.


OpenSCAD Admin - email* me if you need anything,  or if I've done something stupid...

  • on the Forum, click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

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

Seidensticker wrote > What I have in mind would be perhaps just > one operation per pixel, but if the image is even as small as 100x100, > that's 10,000 pixels, which would produce a script with 10,000 operations. > Does OpenSCAD have limitations on how long a script can be? Or is the only > downside that it might take a long time? I decided to test this. At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy. It renders in 15.5 hours using 26GB memory. It took ~90s to export as stl. The render view panel is laggy, but works. At 100x100, 10,000 cubes, it previews promptly, view panel is responsive. It renders in 17m 40s, using 3GB, render view panel is responsive. ----- OpenSCAD Admin - email* me if you need anything, or if I've done something stupid... * on the Forum, click on my MichaelAtOz label, there is a link to email me. Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. -- Sent from: http://forum.openscad.org/
A
adrianv
Wed, Mar 3, 2021 2:45 AM

Wouldn't it be a much better strategy to use a single polyhedron to represent
the image data?  Would be much more managable, I would think.

MichaelAtOz wrote

Seidensticker wrote

What I have in mind would be perhaps just
one operation per pixel, but if the image is even as small as 100x100,
that's 10,000 pixels, which would produce a script with 10,000
operations.
Does OpenSCAD have limitations on how long a script can be? Or is the
only
downside that it might take a long time?

I decided to test this.

At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy.
It renders in 15.5 hours using 26GB memory.
It took ~90s to export as stl.
The render view panel is laggy, but works.

At 100x100, 10,000 cubes, it previews promptly, view panel is responsive.
It renders in 17m 40s, using 3GB, render view panel is responsive.


OpenSCAD Admin - email* me if you need anything,  or if I've done
something stupid...

  • on the Forum, click on my MichaelAtOz label, there is a link to email
    me.

Unless specifically shown otherwise above, my contribution is in the
Public Domain; to the extent possible under law, I have waived all
copyright and related or neighbouring rights to this work. Obviously
inclusion of works of previous authors is not included in the above.

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


OpenSCAD mailing list

Discuss@.openscad

Wouldn't it be a much better strategy to use a single polyhedron to represent the image data? Would be much more managable, I would think. MichaelAtOz wrote > Seidensticker wrote >> What I have in mind would be perhaps just >> one operation per pixel, but if the image is even as small as 100x100, >> that's 10,000 pixels, which would produce a script with 10,000 >> operations. >> Does OpenSCAD have limitations on how long a script can be? Or is the >> only >> downside that it might take a long time? > > I decided to test this. > > > > At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy. > It renders in 15.5 hours using 26GB memory. > It took ~90s to export as stl. > The render view panel is laggy, but works. > > At 100x100, 10,000 cubes, it previews promptly, view panel is responsive. > It renders in 17m 40s, using 3GB, render view panel is responsive. > > > > ----- > OpenSCAD Admin - email* me if you need anything, or if I've done > something stupid... > > * on the Forum, click on my MichaelAtOz label, there is a link to email > me. > > Unless specifically shown otherwise above, my contribution is in the > Public Domain; to the extent possible under law, I have waived all > copyright and related or neighbouring rights to this work. Obviously > inclusion of works of previous authors is not included in the above. > > -- > Sent from: http://forum.openscad.org/ > _______________________________________________ > OpenSCAD mailing list > Discuss@.openscad > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org -- Sent from: http://forum.openscad.org/
JB
Jordan Brown
Wed, Mar 3, 2021 5:47 AM

On 3/2/2021 5:44 PM, MichaelAtOz wrote:

At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy.
It renders in 15.5 hours using 26GB memory.
It took ~90s to export as stl.
The render view panel is laggy, but works.

At 100x100, 10,000 cubes, it previews promptly, view panel is responsive.
It renders in 17m 40s, using 3GB, render view panel is responsive.

I had the same thought as Adrian, that a polyhedron would perform better
than a huge union.

I did something slightly different (mostly because I didn't think enough
about what yours meant, and didn't try yours until I'd already written
mine), but the results surprised me.

What I did was to take an (x+1) by (y+1) array of points and connect the
adjoining points with triangles, plus added a body below it.

That's a simpler structure than yours.  It has approximately (x+1)*(y+1)
points, where I think yours has four times that, because each of your
data items is a cube rather than a point.

With a 501x501 array, it previews in ~15s and renders in the same. 
Viewing is slightly laggy.  Maybe 12s of that was generating the data,
and the remaining 3s was rendering it.

But of course that is what we call "cheating".  It's one object.  If I
union it with a cube(10), a 101x101 array takes 24s to render.  A
201x201 array takes 1m45s.  That suggests that it's proportional to the
number of points, suggesting that 501x501 will take about 11m.  But I'm
not that patient right now.

We have no calibration factor for your system versus mine.  Mine is a
pretty low-end desktop from maybe five years ago.  Render for your
program for a 21x21 grid takes 1m33s.

Here's what 101x101 looks like:

But it's a lot prettier with a trig function supplying the data:

I learned a new thing about polyhedra:  it isn't enough to cover the
entire shape in faces; the vertices apparently have to connect.  CGAL
didn't like it when the bottom was just one square.  I made it happy by
making the bottom be a (2x+2y) - gon with very boring vertices.

Here's the program, in case anybody is interested:

x=100;
y=100;
base = 1;
randmax = 10;
image = [ for(xi=[0:x])
[ for(yi=[0:y]) rands(0,randmax,1)[0] ],
];
//image = [ for(xi=[0:x])
//            [ for(yi=[0:y]) let(r=max(norm([xi-x/2, yi-y/2]),0.01)) 10+5sin(2000r/norm([x,y])) ],
//        ];

points = [
for (xi=[0:x]) [xi, 0, 0],  // bottom front
for (xi=[0:x]) [xi, y, 0],  // bottom back
for (yi=[0:y]) [0, yi, 0],  // bottom left
for (yi=[0:y]) [x, yi, 0],  // bottom right
for (xi=[0:x], yi=[0:y]) [xi,yi,image[xi][yi]+base]
];

// Return the point index for the specified data point
function pt(xi,yi) = 2*(x+1) + 2*(y+1) + (y+1)xi + yi;
// Return the point index for the specified bottom-edge point
function ptx1(xi) = xi;                  // Front
function ptx2(xi) = (x+1) + xi;          // Back
function pty1(yi) = 2
(x+1) + yi;        // Left
function pty2(yi) = 2*(x+1) + (y+1) + yi; // Right

faces = [
// Bottom
[
for (xi=[0:x-1]) ptx1(xi),
for (yi=[0:y-1]) pty2(yi),
for (xi=[x:-1:1]) ptx2(xi),
for (yi=[y:-1:1]) pty1(yi)
],

// Front
for (xi = [0:x-1]) [ ptx1(xi), pt(xi,0), ptx1(xi+1) ],
for (xi = [0:x-1]) [ pt(xi,0), pt(xi+1,0), ptx1(xi+1) ],
// Back
for (xi = [0:x-1]) [ ptx2(xi), ptx2(xi+1), pt(xi,y) ],
for (xi = [0:x-1]) [ pt(xi,y), ptx2(xi+1), pt(xi+1,y) ],
// Left
for (yi = [0:y-1]) [ pty1(yi), pty1(yi+1), pt(0,yi) ],
for (yi = [0:y-1]) [ pt(0,yi), pty1(yi+1), pt(0, yi+1) ],
// Right
for (yi = [0:y-1]) [ pty2(yi), pt(x,yi), pty2(yi+1) ],
for (yi = [0:y-1]) [ pt(x,yi), pt(x,yi+1), pty2(yi+1) ],
// Top
for (xi = [0:x-1], yi=[0:y-1]) [ pt(xi,yi), pt(xi,yi+1), pt(xi+1, yi) ],
for (xi = [0:x-1], yi=[0:y-1]) [ pt(xi,yi+1), pt(xi+1,yi+1), pt(xi+1, yi) ]

];

polyhedron(points=points, faces=faces);

//cube(10);

echo(x=x,y=y,x*y);

On 3/2/2021 5:44 PM, MichaelAtOz wrote: > At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy. > It renders in 15.5 hours using 26GB memory. > It took ~90s to export as stl. > The render view panel is laggy, but works. > > At 100x100, 10,000 cubes, it previews promptly, view panel is responsive. > It renders in 17m 40s, using 3GB, render view panel is responsive. I had the same thought as Adrian, that a polyhedron would perform better than a huge union. I did something slightly different (mostly because I didn't think enough about what yours meant, and didn't try yours until I'd already written mine), but the results surprised me. What I did was to take an (x+1) by (y+1) array of points and connect the adjoining points with triangles, plus added a body below it. That's a simpler structure than yours.  It has approximately (x+1)*(y+1) points, where I think yours has four times that, because each of your data items is a cube rather than a point. With a 501x501 array, it previews in ~15s and renders in the same.  Viewing is slightly laggy.  Maybe 12s of that was generating the data, and the remaining 3s was rendering it. But of course that is what we call "cheating".  It's one object.  If I union it with a cube(10), a 101x101 array takes 24s to render.  A 201x201 array takes 1m45s.  That suggests that it's proportional to the number of points, suggesting that 501x501 will take about 11m.  But I'm not that patient right now. We have no calibration factor for your system versus mine.  Mine is a pretty low-end desktop from maybe five years ago.  Render for your program for a 21x21 grid takes 1m33s. Here's what 101x101 looks like: But it's a lot prettier with a trig function supplying the data: I learned a new thing about polyhedra:  it isn't enough to cover the entire shape in faces; the vertices apparently have to connect.  CGAL didn't like it when the bottom was just one square.  I made it happy by making the bottom be a (2x+2y) - gon with very boring vertices. Here's the program, in case anybody is interested: x=100; y=100; base = 1; randmax = 10; image = [ for(xi=[0:x]) [ for(yi=[0:y]) rands(0,randmax,1)[0] ], ]; //image = [ for(xi=[0:x]) // [ for(yi=[0:y]) let(r=max(norm([xi-x/2, yi-y/2]),0.01)) 10+5*sin(2000*r/norm([x,y])) ], // ]; points = [ for (xi=[0:x]) [xi, 0, 0], // bottom front for (xi=[0:x]) [xi, y, 0], // bottom back for (yi=[0:y]) [0, yi, 0], // bottom left for (yi=[0:y]) [x, yi, 0], // bottom right for (xi=[0:x], yi=[0:y]) [xi,yi,image[xi][yi]+base] ]; // Return the point index for the specified data point function pt(xi,yi) = 2*(x+1) + 2*(y+1) + (y+1)*xi + yi; // Return the point index for the specified bottom-edge point function ptx1(xi) = xi; // Front function ptx2(xi) = (x+1) + xi; // Back function pty1(yi) = 2*(x+1) + yi; // Left function pty2(yi) = 2*(x+1) + (y+1) + yi; // Right faces = [ // Bottom [ for (xi=[0:x-1]) ptx1(xi), for (yi=[0:y-1]) pty2(yi), for (xi=[x:-1:1]) ptx2(xi), for (yi=[y:-1:1]) pty1(yi) ], // Front for (xi = [0:x-1]) [ ptx1(xi), pt(xi,0), ptx1(xi+1) ], for (xi = [0:x-1]) [ pt(xi,0), pt(xi+1,0), ptx1(xi+1) ], // Back for (xi = [0:x-1]) [ ptx2(xi), ptx2(xi+1), pt(xi,y) ], for (xi = [0:x-1]) [ pt(xi,y), ptx2(xi+1), pt(xi+1,y) ], // Left for (yi = [0:y-1]) [ pty1(yi), pty1(yi+1), pt(0,yi) ], for (yi = [0:y-1]) [ pt(0,yi), pty1(yi+1), pt(0, yi+1) ], // Right for (yi = [0:y-1]) [ pty2(yi), pt(x,yi), pty2(yi+1) ], for (yi = [0:y-1]) [ pt(x,yi), pt(x,yi+1), pty2(yi+1) ], // Top for (xi = [0:x-1], yi=[0:y-1]) [ pt(xi,yi), pt(xi,yi+1), pt(xi+1, yi) ], for (xi = [0:x-1], yi=[0:y-1]) [ pt(xi,yi+1), pt(xi+1,yi+1), pt(xi+1, yi) ] ]; polyhedron(points=points, faces=faces); //cube(10); echo(x=x,y=y,x*y);
CA
Carsten Arnholm
Wed, Mar 3, 2021 9:50 AM

On 03.03.2021 02:44, MichaelAtOz wrote:

I decided to test this.

m=5;
x=100m;
y=100
m;
eps=1/256;
echo(x=x,y=y,x*y);
image = [ for(xi=[0:x])
[ for(yi=[0:y]) rands(0,10,1)[0], ],
];

//echo(image);  // only for small vectors
for(xi=[0:x])
translate([xi,0,0])
for(yi=[0:y])
translate([0,yi,0])
cube([1+eps,1+eps,image[xi][yi]]);

At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy.
It renders in 15.5 hours using 26GB memory.
It took ~90s to export as stl.
The render view panel is laggy, but works.

Out of curiosity, I ran that code through AngelCAD using a 9 year old
Win10 desktop (upgraded from Win7 last year) having just 4GB RAM and a
new 500GB SSD system disk replacing an old HDD. Peak memory use is
around ~5GB for this model, some disk swapping therefore occurs. From
start to finish, including export to STL took ~2.5 hours elapsed time on
that machine.

My 3 year old Ubuntu 18.04 desktop with 32GB RAM processed the same in
37 minutes elapsed time.

Carsten Arnholm

On 03.03.2021 02:44, MichaelAtOz wrote: > I decided to test this. > > m=5; > x=100*m; > y=100*m; > eps=1/256; > echo(x=x,y=y,x*y); > image = [ for(xi=[0:x]) > [ for(yi=[0:y]) rands(0,10,1)[0], ], > ]; > > //echo(image); // only for small vectors > for(xi=[0:x]) > translate([xi,0,0]) > for(yi=[0:y]) > translate([0,yi,0]) > cube([1+eps,1+eps,image[xi][yi]]); > > > At 500x500, 250,000 cubes, it previews in 30s, view panel is laggy. > It renders in 15.5 hours using 26GB memory. > It took ~90s to export as stl. > The render view panel is laggy, but works. Out of curiosity, I ran that code through AngelCAD using a 9 year old Win10 desktop (upgraded from Win7 last year) having just 4GB RAM and a new 500GB SSD system disk replacing an old HDD. Peak memory use is around ~5GB for this model, some disk swapping therefore occurs. From start to finish, including export to STL took ~2.5 hours elapsed time on that machine. My 3 year old Ubuntu 18.04 desktop with 32GB RAM processed the same in 37 minutes elapsed time. Carsten Arnholm
CA
Carsten Arnholm
Wed, Mar 3, 2021 9:55 AM

On 03.03.2021 06:47, Jordan Brown wrote:

What I did was to take an (x+1) by (y+1) array of points and connect the
adjoining points with triangles, plus added a body below it.

I think that is a good approach if the data is assumed to be an image.
It is also far less computations. Nice.

Carsten Arnholm

On 03.03.2021 06:47, Jordan Brown wrote: > What I did was to take an (x+1) by (y+1) array of points and connect the > adjoining points with triangles, plus added a body below it. I think that is a good approach if the data is assumed to be an image. It is also far less computations. Nice. Carsten Arnholm