How to work with images?

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

How to work with images?

Seidensticker

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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

RevarBat
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 <[hidden email]> 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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

Seidensticker
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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

RevarBat
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. 


-Revar



On Mar 1, 2021, at 6:13 PM, Seidensticker <[hidden email]> 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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

Troberg
In reply to this post by RevarBat
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 the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

MichaelAtOz
Administrator
In reply to this post by Seidensticker
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.

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.

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 the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
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.
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

adrianv
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
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

JordanBrown
In reply to this post by MichaelAtOz
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);


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

cacb
In reply to this post by MichaelAtOz
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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

cacb
In reply to this post by JordanBrown
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



_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

caggius
In reply to this post by JordanBrown
Can’t help myself but compare system performances on my M1 Mac mini - still deciding if it was VFM - not too bad for running OpenSCAD in an emulator - but the viewing is unusably laggy
Compiling design (CSG Tree generation)...

ECHO: x = 501, y = 501, 251001

Compiling design (CSG Products generation)...

….

Total rendering time: 0:00:06.326


Compiling design (CSG Tree generation)...

ECHO: x = 501, y = 501, 251001

Rendering Polygon Mesh using CGAL...

...

Total rendering time: 0:00:05.831




On 3 Mar 2021, at 05:47, Jordan Brown <[hidden email]> wrote:

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:

<albkacimhfakpddl.png>


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

<lidflaeganlkkidn.png>


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);

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

Ronaldo
In reply to this post by JordanBrown
Problems and solutions come and go. See for instance this 8 month old thread: http://forum.openscad.org/surface-without-import-tp26710.html

Em qua., 3 de mar. de 2021 às 05:48, Jordan Brown <[hidden email]> escreveu:
I had the same thought as Adrian, that a polyhedron would perform better than a huge union.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: How to work with images?

RevarBat
Of course, you could always just have your external script process your pixel manipulations, then write out a new image to import with `surface()`. 

-Revar


On Mar 3, 2021, at 3:54 AM, Ronaldo Persiano <[hidden email]> wrote:


Problems and solutions come and go. See for instance this 8 month old thread: http://forum.openscad.org/surface-without-import-tp26710.html

Em qua., 3 de mar. de 2021 às 05:48, Jordan Brown <[hidden email]> escreveu:
I had the same thought as Adrian, that a polyhedron would perform better than a huge union.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org