discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

surface()

RD
Revar Desmera
Wed, May 11, 2022 1:22 AM

That should be pip install --upgrade Pillow with two dashes, not an em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera revarbat@gmail.com wrote:

You need to install the Pillow library.  Usually this can be done simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
Yes, save the script to the file img2scad.py.  I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows.  A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which may be helpful.

This script would probably better fit in a separate BOSL2-helpers repository.

A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated.  But what do I need on my desktop to run python apps?  I've never done a thing with Python that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
I wrote up a simple Python image-to-scadfile converter.  It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:
#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height), file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0]
         opts.varname = non_alnum.sub("", opts.varname)
     else:
         opts.varname = "image_data"
 size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$')
 if opts.resize:
     m = size_pat.match(opts.resize)
     if not m:
         print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr)
         sys.exit(-1)
     opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname), file=sys.stderr)
     sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there.  Heck, openSCAD is used for parameter customizing on many within Thingiverse alone.  Currently I use converter https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else.

I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps.  Maybe they will work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com mailto:nop.head@gmail.com> wrote:
Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:
Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().  Works great.  I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
BOSL2 has a function/module called heightfield() that you can feed an array of heights, or a function literal that can calculate the heights dynamically.  However, there is currently no way for an OpenSCAD script to read height values from an image file.  You can only generate 3D geometry using surface().

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

Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Cannot run surface() as a function to return a vnf array of the data to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org

That should be `pip install --upgrade Pillow` with two dashes, not an em-dash. Thank you auto-correct who thinks it know best. - Revar > On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com> wrote: > > You need to install the Pillow library. Usually this can be done simplest from the command-line with the command: > > pip install —upgrade Pillow > > More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html <https://pillow.readthedocs.io/en/latest/installation.html> > > - Revar > > > >> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >> >> I am receiving this error msg when I run the script: >> >> Line 10: ModuleNotFoundError: No module named 'PIL' >> >> Any ideas? >> >> >> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >> Yes, save the script to the file `img2scad.py`. I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows. A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ <https://www.geeksforgeeks.org/how-to-install-python-on-windows/> which may be helpful. >> >> This script would probably better fit in a separate BOSL2-helpers repository. >> >> A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform. >> >> - Revar >> >> >>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>> >>> Holy sh..! How the heck do you write something THAT fast? >>> >>> You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed! >>> >>> I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated. But what do I need on my desktop to run python apps? I've never done a thing with Python that I am aware of. >>> >>> >>> >>> >>> >>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>> I wrote up a simple Python image-to-scadfile converter. It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file. >>> >>> - Revar >>> >>> >>> Usage: >>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>> >>> Script: >>> #!env python3 >>> >>> import re >>> import os >>> import sys >>> import os.path >>> import argparse >>> >>> from PIL import Image >>> >>> >>> def img2scad(filename, varname, resize, outf): >>> indent = " " * 4 >>> im = Image.open(filename).convert('L') >>> if resize: >>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>> im = im.resize(resize) >>> pix = im.load() >>> width, height = im.size >>> print("// Image {} ({}x{})".format(filename, width, height), file=outf) >>> print("{} = [".format(varname), file=outf) >>> line = indent >>> for x in range(width): >>> line += "[ " >>> for y in range(height): >>> line += "{:d}, ".format(pix[x,y]) >>> if len(line) > 60: >>> print(line, file=outf) >>> line = indent * 2 >>> line += " ]," >>> if line != indent: >>> print(line, file=outf) >>> line = indent >>> print("];", file=outf) >>> print("", file=outf) >>> >>> >>> def main(): >>> parser = argparse.ArgumentParser(prog='img2scad') >>> parser.add_argument('-o', '--outfile', >>> help='Output .scad file.') >>> parser.add_argument('-v', '--varname', >>> help='Variable to use in .scad file.') >>> parser.add_argument('-r', '--resize', >>> help='Resample image to WIDTHxHEIGHT.') >>> parser.add_argument('infile', help='Input image file.') >>> opts = parser.parse_args() >>> >>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>> if not opts.varname: >>> if opts.outfile: >>> opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0] >>> opts.varname = non_alnum.sub("", opts.varname) >>> else: >>> opts.varname = "image_data" >>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>> if opts.resize: >>> m = size_pat.match(opts.resize) >>> if not m: >>> print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr) >>> sys.exit(-1) >>> opts.resize = (int(m.group(1)), int(m.group(2))) >>> >>> if not opts.varname or non_alnum.search(opts.varname): >>> print("Bad variable name: {}".format(opts.varname), file=sys.stderr) >>> sys.exit(-1) >>> >>> if opts.outfile: >>> with open(opts.outfile, "w") as outf: >>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>> else: >>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>> >>> sys.exit(0) >>> >>> >>> if __name__ == "__main__": >>> main() >>> >>> >>> >>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>> >>>> No doubt ... but I never used Python. >>>> >>>> I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there. Heck, openSCAD is used for parameter customizing on many within Thingiverse alone. Currently I use converter <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else. >>>> >>>> I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps. Maybe they will work with the BOSL heightfield() function ... you never know. >>>> >>>> >>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com <mailto:nop.head@gmail.com>> wrote: >>>> Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure. >>>> >>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>> Using surface( file = "Flourish_01b.png" ) on this png file: >>>> >>>> <Flourish_01b.png> >>>> >>>> results in this: >>>> >>>> <result.png> >>>> >>>> Except for the square base, I was surprised it even worked. >>>> >>>> Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead. >>>> >>>> When using BOSL, I can create a nice vnf array from a sweep(). Works great. I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever. >>>> >>>> This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure. >>>> >>>> >>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>> BOSL2 has a function/module called `heightfield()` that you can feed an array of heights, or a function literal that can calculate the heights dynamically. However, there is currently no way for an OpenSCAD script to read height values from an image file. You can only generate 3D geometry using `surface()`. >>>> >>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield <https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield> >>>> >>>> Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data. >>>> >>>> - Revar >>>> >>>> >>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>> >>>>> Cannot run surface() as a function to return a vnf array of the data to manipulate. >>>>> >>>>> Is there a BOSL function that can do what surface() does? >>>>> >>>>> If not, is there another library out there that will do it? >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >
JW
Joe Weinpert
Wed, May 11, 2022 1:49 AM

FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10 which
I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ... I
only typed "pip install pillow" ... which it successfully did but with a
warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean
instantly.  Created the scad height file.  Hopefully, BOSL2 heightfield()
function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is
the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is
902 pixels wide by 1024 pixels.  Is that what I am looking for?  The
numbers do match the result columns and rows in the created scad file.
Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

[image: installPip.png]

On Tue, May 10, 2022 at 9:22 PM Revar Desmera revarbat@gmail.com wrote:

That should be pip install --upgrade Pillow with two dashes, not an
em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera revarbat@gmail.com wrote:

You need to install the Pillow library.  Usually this can be done simplest
from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow:
https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera revarbat@gmail.com wrote:

Yes, save the script to the file img2scad.py.  I’m afraid that this is
just a command-line tool, and while it’s easy enough to use on Linux or a
Mac, I’m not truly sure about how to set up a command-line on Windows.  A
quick googling results in
https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which
may be helpful.

This script would probably better fit in a separate BOSL2-helpers
repository.

A GUI version is perfectly possible to do, but that may take me a couple
weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as
some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ... and
your usage example is "run command line" orientated.  But what do I need on
my desktop to run python apps?  I've never done a thing with Python that I
am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera revarbat@gmail.com wrote:

I wrote up a simple Python image-to-scadfile converter.  It’ll read most
common image types, convert them to Luminosity grayscale, with optional
re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:

#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height),
file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname =

os.path.splitext(os.path.basename(opts.outfile))[0]
opts.varname = non_alnum.sub("", opts.varname)
else:
opts.varname = "image_data"
size_pat = re.compile(r'^([0-9][0-9])x([0-9][0-9])$')
if opts.resize:
m = size_pat.match(opts.resize)
if not m:
print("Expected WIDTHxHEIGHT resize format.",
file=sys.stderr)
sys.exit(-1)
opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname),

file=sys.stderr)
sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by
handling them as data arrays would open up many doors. There are thousands
upon thousands of STL files out there.  Heck, openSCAD is used
for parameter customizing on many within Thingiverse alone.  Currently I
use converter
https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html to
convert an STL to a PNG. Super super super basic ... but it does work until
I can find something else.

I will continue searching for a converter to take files like the
grayscale png picture I posted and make height data maps.  Maybe they will
work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head nop.head@gmail.com wrote:

Python has libraries for everything so you should be able to read a PNG
as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert joe.weinpert@gmail.com
wrote:

Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause a
problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().  Works
great.  I can then use *vnf_polyhedron() *to draw it or draw copies
and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as
you say it can be ... I've never touched python in my life and never dealt
with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera revarbat@gmail.com
wrote:

BOSL2 has a function/module called heightfield() that you can feed
an array of heights, or a function literal that can calculate the heights
dynamically.  However, there is currently no way for an OpenSCAD script to
read height values from an image file.  You can only generate 3D geometry
using surface().

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

Having said that, it should not be too difficult to write a Python
script to read in an image file, and have it write out a .scad source file
containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Cannot run surface() as a function to return a vnf array of the data
to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

FYI I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem. Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic). And ... I ran your *mg2scad.py* script and it ran instantly ... and I mean instantly. Created the scad height file. Hopefully, BOSL2 *heightfield()* function can use it. Haven't tried that yet. My question, however, is the optional command -r WIDTHxHEIGHT. How is the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is 902 pixels wide by 1024 pixels. Is that what I am looking for? The numbers do match the result columns and rows in the created scad file. Columns being the WIDTH and rows (indices) being the height. So far .. so good! [image: installPip.png] On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com> wrote: > That should be `pip install --upgrade Pillow` with two dashes, not an > em-dash. Thank you auto-correct who thinks it know best. > > - Revar > > > On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com> wrote: > > You need to install the Pillow library. Usually this can be done simplest > from the command-line with the command: > > pip install —upgrade Pillow > > More info on installing Pillow: > https://pillow.readthedocs.io/en/latest/installation.html > > - Revar > > > > On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > > I am receiving this error msg when I run the script: > > Line 10: ModuleNotFoundError: No module named 'PIL' > > > Any ideas? > > > On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com> wrote: > >> Yes, save the script to the file `img2scad.py`. I’m afraid that this is >> just a command-line tool, and while it’s easy enough to use on Linux or a >> Mac, I’m not truly sure about how to set up a command-line on Windows. A >> quick googling results in >> https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which >> may be helpful. >> >> This script would probably better fit in a separate BOSL2-helpers >> repository. >> >> A GUI version is perfectly possible to do, but that may take me a couple >> weeks to refresh my memory on how to do cross-platform. >> >> - Revar >> >> >> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >> >> Holy sh..! How the heck do you write something THAT fast? >> >> You have my thanks ... and in any way that this can be added to BOSL as >> some sort of function would be something indeed! >> >> I assume "mg2scad.py" is the file name to save the Python code as ... and >> your usage example is "run command line" orientated. But what do I need on >> my desktop to run python apps? I've never done a thing with Python that I >> am aware of. >> >> >> >> >> >> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com> wrote: >> >>> I wrote up a simple Python image-to-scadfile converter. It’ll read most >>> common image types, convert them to Luminosity grayscale, with optional >>> re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file. >>> >>> - Revar >>> >>> >>> Usage: >>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>> >>> Script: >>> >>> #!env python3 >>> >>> import re >>> import os >>> import sys >>> import os.path >>> import argparse >>> >>> from PIL import Image >>> >>> >>> def img2scad(filename, varname, resize, outf): >>> indent = " " * 4 >>> im = Image.open(filename).convert('L') >>> if resize: >>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>> im = im.resize(resize) >>> pix = im.load() >>> width, height = im.size >>> print("// Image {} ({}x{})".format(filename, width, height), >>> file=outf) >>> print("{} = [".format(varname), file=outf) >>> line = indent >>> for x in range(width): >>> line += "[ " >>> for y in range(height): >>> line += "{:d}, ".format(pix[x,y]) >>> if len(line) > 60: >>> print(line, file=outf) >>> line = indent * 2 >>> line += " ]," >>> if line != indent: >>> print(line, file=outf) >>> line = indent >>> print("];", file=outf) >>> print("", file=outf) >>> >>> >>> def main(): >>> parser = argparse.ArgumentParser(prog='img2scad') >>> parser.add_argument('-o', '--outfile', >>> help='Output .scad file.') >>> parser.add_argument('-v', '--varname', >>> help='Variable to use in .scad file.') >>> parser.add_argument('-r', '--resize', >>> help='Resample image to WIDTHxHEIGHT.') >>> parser.add_argument('infile', help='Input image file.') >>> opts = parser.parse_args() >>> >>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>> if not opts.varname: >>> if opts.outfile: >>> opts.varname = >>> os.path.splitext(os.path.basename(opts.outfile))[0] >>> opts.varname = non_alnum.sub("", opts.varname) >>> else: >>> opts.varname = "image_data" >>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>> if opts.resize: >>> m = size_pat.match(opts.resize) >>> if not m: >>> print("Expected WIDTHxHEIGHT resize format.", >>> file=sys.stderr) >>> sys.exit(-1) >>> opts.resize = (int(m.group(1)), int(m.group(2))) >>> >>> if not opts.varname or non_alnum.search(opts.varname): >>> print("Bad variable name: {}".format(opts.varname), >>> file=sys.stderr) >>> sys.exit(-1) >>> >>> if opts.outfile: >>> with open(opts.outfile, "w") as outf: >>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>> else: >>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>> >>> sys.exit(0) >>> >>> >>> if __name__ == "__main__": >>> main() >>> >>> >>> >>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com> >>> wrote: >>> >>> No doubt ... but I never used Python. >>> >>> I think that openSCAD having a way to import and use external STLs by >>> handling them as data arrays would open up many doors. There are thousands >>> upon thousands of STL files out there. Heck, openSCAD is used >>> for parameter customizing on many within Thingiverse alone. Currently I >>> use converter >>> <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> to >>> convert an STL to a PNG. Super super super basic ... but it does work until >>> I can find something else. >>> >>> I will continue searching for a converter to take files like the >>> grayscale png picture I posted and make height data maps. Maybe they will >>> work with the BOSL heightfield() function ... you never know. >>> >>> >>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com> wrote: >>> >>>> Python has libraries for everything so you should be able to read a PNG >>>> as an image and not need to know the file structure. >>>> >>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com> >>>> wrote: >>>> >>>>> Using *surface( file = "Flourish_01b.png" )* on this png file: >>>>> >>>>> <Flourish_01b.png> >>>>> >>>>> results in this: >>>>> >>>>> <result.png> >>>>> >>>>> Except for the square base, I was surprised it even worked. >>>>> >>>>> Attempting to use pre-built STL files in SCAD always seems to cause a >>>>> problem, so I wanted to try using grayscale images instead. >>>>> >>>>> When using BOSL, I can create a nice vnf array from a sweep(). Works >>>>> great. I can then use *vnf_polyhedron() *to draw it or draw copies >>>>> and mirrors of it ... whatever. >>>>> >>>>> This is why I was hoping for a function ... however ... as simple as >>>>> you say it can be ... I've never touched python in my life and never dealt >>>>> with the PNG file structure. >>>>> >>>>> >>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com> >>>>> wrote: >>>>> >>>>>> BOSL2 has a function/module called `heightfield()` that you can feed >>>>>> an array of heights, or a function literal that can calculate the heights >>>>>> dynamically. However, there is currently no way for an OpenSCAD script to >>>>>> read height values from an image file. You can only generate 3D geometry >>>>>> using `surface()`. >>>>>> >>>>>> >>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield >>>>>> >>>>>> Having said that, it should not be too difficult to write a Python >>>>>> script to read in an image file, and have it write out a .scad source file >>>>>> containing the array of height data. >>>>>> >>>>>> - Revar >>>>>> >>>>>> >>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>>> wrote: >>>>>> >>>>>> Cannot run surface() as a function to return a vnf array of the data >>>>>> to manipulate. >>>>>> >>>>>> Is there a BOSL function that can do what surface() does? >>>>>> >>>>>> If not, is there another library out there that will do it? >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
RD
Revar Desmera
Wed, May 11, 2022 3:00 AM

I tested using heightfield() with a 512x512 image, so I can verify it works, though there is a possible bug in heightfield() that you can work around by adding the argument `anchor=BOT’. I’ll fix that soon.

Yes -r uses pixel counts. If you do not give -r the data it outputs will be for the original image size.

You can fix the pip warning with:

pip install --upgrade pip

-Revar

On May 10, 2022, at 6:50 PM, Joe Weinpert joe.weinpert@gmail.com wrote:


FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean instantly.  Created the scad height file.  Hopefully, BOSL2 heightfield() function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is 902 pixels wide by 1024 pixels.  Is that what I am looking for?  The numbers do match the result columns and rows in the created scad file.  Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

On Tue, May 10, 2022 at 9:22 PM Revar Desmera revarbat@gmail.com wrote:
That should be pip install --upgrade Pillow with two dashes, not an em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera revarbat@gmail.com wrote:

You need to install the Pillow library.  Usually this can be done simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera revarbat@gmail.com wrote:
Yes, save the script to the file img2scad.py.  I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows.  A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which may be helpful.

This script would probably better fit in a separate BOSL2-helpers repository.

A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated.  But what do I need on my desktop to run python apps?  I've never done a thing with Python that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera revarbat@gmail.com wrote:
I wrote up a simple Python image-to-scadfile converter.  It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:
#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height), file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0]
         opts.varname = non_alnum.sub("", opts.varname)
     else:
         opts.varname = "image_data"
 size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$')
 if opts.resize:
     m = size_pat.match(opts.resize)
     if not m:
         print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr)
         sys.exit(-1)
     opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname), file=sys.stderr)
     sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there.  Heck, openSCAD is used for parameter customizing on many within Thingiverse alone.  Currently I use converter to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else.

I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps.  Maybe they will work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head nop.head@gmail.com wrote:
Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert joe.weinpert@gmail.com wrote:
Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().  Works great.  I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera revarbat@gmail.com wrote:
BOSL2 has a function/module called heightfield() that you can feed an array of heights, or a function literal that can calculate the heights dynamically.  However, there is currently no way for an OpenSCAD script to read height values from an image file.  You can only generate 3D geometry using surface().

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

Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

Cannot run surface() as a function to return a vnf array of the data to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

I tested using `heightfield()` with a 512x512 image, so I can verify it works, though there is a possible bug in `heightfield()` that you can work around by adding the argument `anchor=BOT’. I’ll fix that soon. Yes -r uses pixel counts. If you do not give -r the data it outputs will be for the original image size. You can fix the pip warning with: pip install --upgrade pip -Revar > On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > >  > FYI > > I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem. > > Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic). > > And ... > > I ran your mg2scad.py script and it ran instantly ... and I mean instantly. Created the scad height file. Hopefully, BOSL2 heightfield() function can use it. Haven't tried that yet. > > My question, however, is the optional command -r WIDTHxHEIGHT. How is the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is 902 pixels wide by 1024 pixels. Is that what I am looking for? The numbers do match the result columns and rows in the created scad file. Columns being the WIDTH and rows (indices) being the height. > > So far .. so good! > > > > >> On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com> wrote: >> That should be `pip install --upgrade Pillow` with two dashes, not an em-dash. Thank you auto-correct who thinks it know best. >> >> - Revar >> >> >>> On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com> wrote: >>> >>> You need to install the Pillow library. Usually this can be done simplest from the command-line with the command: >>> >>> pip install —upgrade Pillow >>> >>> More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html >>> >>> - Revar >>> >>> >>> >>>> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >>>> >>>> I am receiving this error msg when I run the script: >>>> >>>> Line 10: ModuleNotFoundError: No module named 'PIL' >>>> >>>> Any ideas? >>>> >>>> >>>>> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com> wrote: >>>>> Yes, save the script to the file `img2scad.py`. I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows. A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which may be helpful. >>>>> >>>>> This script would probably better fit in a separate BOSL2-helpers repository. >>>>> >>>>> A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform. >>>>> >>>>> - Revar >>>>> >>>>> >>>>>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >>>>>> >>>>>> Holy sh..! How the heck do you write something THAT fast? >>>>>> >>>>>> You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed! >>>>>> >>>>>> I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated. But what do I need on my desktop to run python apps? I've never done a thing with Python that I am aware of. >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com> wrote: >>>>>>> I wrote up a simple Python image-to-scadfile converter. It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file. >>>>>>> >>>>>>> - Revar >>>>>>> >>>>>>> >>>>>>> Usage: >>>>>>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>>>>>> >>>>>>> Script: >>>>>>> #!env python3 >>>>>>> >>>>>>> import re >>>>>>> import os >>>>>>> import sys >>>>>>> import os.path >>>>>>> import argparse >>>>>>> >>>>>>> from PIL import Image >>>>>>> >>>>>>> >>>>>>> def img2scad(filename, varname, resize, outf): >>>>>>> indent = " " * 4 >>>>>>> im = Image.open(filename).convert('L') >>>>>>> if resize: >>>>>>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>>>>>> im = im.resize(resize) >>>>>>> pix = im.load() >>>>>>> width, height = im.size >>>>>>> print("// Image {} ({}x{})".format(filename, width, height), file=outf) >>>>>>> print("{} = [".format(varname), file=outf) >>>>>>> line = indent >>>>>>> for x in range(width): >>>>>>> line += "[ " >>>>>>> for y in range(height): >>>>>>> line += "{:d}, ".format(pix[x,y]) >>>>>>> if len(line) > 60: >>>>>>> print(line, file=outf) >>>>>>> line = indent * 2 >>>>>>> line += " ]," >>>>>>> if line != indent: >>>>>>> print(line, file=outf) >>>>>>> line = indent >>>>>>> print("];", file=outf) >>>>>>> print("", file=outf) >>>>>>> >>>>>>> >>>>>>> def main(): >>>>>>> parser = argparse.ArgumentParser(prog='img2scad') >>>>>>> parser.add_argument('-o', '--outfile', >>>>>>> help='Output .scad file.') >>>>>>> parser.add_argument('-v', '--varname', >>>>>>> help='Variable to use in .scad file.') >>>>>>> parser.add_argument('-r', '--resize', >>>>>>> help='Resample image to WIDTHxHEIGHT.') >>>>>>> parser.add_argument('infile', help='Input image file.') >>>>>>> opts = parser.parse_args() >>>>>>> >>>>>>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>>>>>> if not opts.varname: >>>>>>> if opts.outfile: >>>>>>> opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0] >>>>>>> opts.varname = non_alnum.sub("", opts.varname) >>>>>>> else: >>>>>>> opts.varname = "image_data" >>>>>>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>>>>>> if opts.resize: >>>>>>> m = size_pat.match(opts.resize) >>>>>>> if not m: >>>>>>> print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr) >>>>>>> sys.exit(-1) >>>>>>> opts.resize = (int(m.group(1)), int(m.group(2))) >>>>>>> >>>>>>> if not opts.varname or non_alnum.search(opts.varname): >>>>>>> print("Bad variable name: {}".format(opts.varname), file=sys.stderr) >>>>>>> sys.exit(-1) >>>>>>> >>>>>>> if opts.outfile: >>>>>>> with open(opts.outfile, "w") as outf: >>>>>>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>>>>>> else: >>>>>>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>>>>>> >>>>>>> sys.exit(0) >>>>>>> >>>>>>> >>>>>>> if __name__ == "__main__": >>>>>>> main() >>>>>>> >>>>>>> >>>>>>> >>>>>>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >>>>>>>> >>>>>>>> No doubt ... but I never used Python. >>>>>>>> >>>>>>>> I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there. Heck, openSCAD is used for parameter customizing on many within Thingiverse alone. Currently I use converter to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else. >>>>>>>> >>>>>>>> I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps. Maybe they will work with the BOSL heightfield() function ... you never know. >>>>>>>> >>>>>>>> >>>>>>>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com> wrote: >>>>>>>>> Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure. >>>>>>>>> >>>>>>>>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com> wrote: >>>>>>>>>> Using surface( file = "Flourish_01b.png" ) on this png file: >>>>>>>>>> >>>>>>>>>> <Flourish_01b.png> >>>>>>>>>> >>>>>>>>>> results in this: >>>>>>>>>> >>>>>>>>>> <result.png> >>>>>>>>>> >>>>>>>>>> Except for the square base, I was surprised it even worked. >>>>>>>>>> >>>>>>>>>> Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead. >>>>>>>>>> >>>>>>>>>> When using BOSL, I can create a nice vnf array from a sweep(). Works great. I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever. >>>>>>>>>> >>>>>>>>>> This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com> wrote: >>>>>>>>>>> BOSL2 has a function/module called `heightfield()` that you can feed an array of heights, or a function literal that can calculate the heights dynamically. However, there is currently no way for an OpenSCAD script to read height values from an image file. You can only generate 3D geometry using `surface()`. >>>>>>>>>>> >>>>>>>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield >>>>>>>>>>> >>>>>>>>>>> Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data. >>>>>>>>>>> >>>>>>>>>>> - Revar >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >>>>>>>>>>>> >>>>>>>>>>>> Cannot run surface() as a function to return a vnf array of the data to manipulate. >>>>>>>>>>>> >>>>>>>>>>>> Is there a BOSL function that can do what surface() does? >>>>>>>>>>>> >>>>>>>>>>>> If not, is there another library out there that will do it? >>>>>>>>>>>> >>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>> OpenSCAD mailing list >>>>>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>>>>> >>>>>>>>>>> _______________________________________________ >>>>>>>>>>> OpenSCAD mailing list >>>>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>>>> _______________________________________________ >>>>>>>>>> OpenSCAD mailing list >>>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JW
Joe Weinpert
Wed, May 11, 2022 3:21 AM

Will use the anchor=BOT for now.

I am getting this warning whenever I run it:using that pic I've been
testing:

WARNING: GeometryEvaluator: Node didn't fit into cache.

Does that affect the program?

Also, when I set the maxz to something like 8 it gets wacky.  Z ends up at
256 which obviously means it is using 256 (0-255) grays. One level for each.

On Tue, May 10, 2022 at 11:00 PM Revar Desmera revarbat@gmail.com wrote:

I tested using heightfield() with a 512x512 image, so I can verify it
works, though there is a possible bug in heightfield() that you can work
around by adding the argument `anchor=BOT’. I’ll fix that soon.

Yes -r uses pixel counts. If you do not give -r the data it outputs will
be for the original image size.

You can fix the pip warning with:

pip install --upgrade pip

-Revar

On May 10, 2022, at 6:50 PM, Joe Weinpert joe.weinpert@gmail.com wrote:


FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10
which I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ... I
only typed "pip install pillow" ... which it successfully did but with a
warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean
instantly.  Created the scad height file.  Hopefully, BOSL2
heightfield() function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is
the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is
902 pixels wide by 1024 pixels.  Is that what I am looking for?  The
numbers do match the result columns and rows in the created scad file.
Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

[image: installPip.png]

On Tue, May 10, 2022 at 9:22 PM Revar Desmera revarbat@gmail.com wrote:

That should be pip install --upgrade Pillow with two dashes, not an
em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera revarbat@gmail.com wrote:

You need to install the Pillow library.  Usually this can be done
simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow:
https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera revarbat@gmail.com wrote:

Yes, save the script to the file img2scad.py.  I’m afraid that this is
just a command-line tool, and while it’s easy enough to use on Linux or a
Mac, I’m not truly sure about how to set up a command-line on Windows.  A
quick googling results in
https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which
may be helpful.

This script would probably better fit in a separate BOSL2-helpers
repository.

A GUI version is perfectly possible to do, but that may take me a couple
weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as
some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ...
and your usage example is "run command line" orientated.  But what do I
need on my desktop to run python apps?  I've never done a thing with Python
that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera revarbat@gmail.com
wrote:

I wrote up a simple Python image-to-scadfile converter.  It’ll read
most common image types, convert them to Luminosity grayscale, with
optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD
source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:

#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height),
file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname =

os.path.splitext(os.path.basename(opts.outfile))[0]
opts.varname = non_alnum.sub("", opts.varname)
else:
opts.varname = "image_data"
size_pat = re.compile(r'^([0-9][0-9])x([0-9][0-9])$')
if opts.resize:
m = size_pat.match(opts.resize)
if not m:
print("Expected WIDTHxHEIGHT resize format.",
file=sys.stderr)
sys.exit(-1)
opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname),

file=sys.stderr)
sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by
handling them as data arrays would open up many doors. There are thousands
upon thousands of STL files out there.  Heck, openSCAD is used
for parameter customizing on many within Thingiverse alone.  Currently I
use converter
https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html to
convert an STL to a PNG. Super super super basic ... but it does work until
I can find something else.

I will continue searching for a converter to take files like the
grayscale png picture I posted and make height data maps.  Maybe they will
work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head nop.head@gmail.com wrote:

Python has libraries for everything so you should be able to read a
PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert joe.weinpert@gmail.com
wrote:

Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause a
problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().  Works
great.  I can then use *vnf_polyhedron() *to draw it or draw copies
and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as
you say it can be ... I've never touched python in my life and never dealt
with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera revarbat@gmail.com
wrote:

BOSL2 has a function/module called heightfield() that you can feed
an array of heights, or a function literal that can calculate the heights
dynamically.  However, there is currently no way for an OpenSCAD script to
read height values from an image file.  You can only generate 3D geometry
using surface().

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

Having said that, it should not be too difficult to write a Python
script to read in an image file, and have it write out a .scad source file
containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Cannot run surface() as a function to return a vnf array of the data
to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Will use the anchor=BOT for now. I am getting this warning whenever I run it:using that pic I've been testing: WARNING: GeometryEvaluator: Node didn't fit into cache. Does that affect the program? Also, when I set the maxz to something like 8 it gets wacky. Z ends up at 256 which obviously means it is using 256 (0-255) grays. One level for each. On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com> wrote: > I tested using `heightfield()` with a 512x512 image, so I can verify it > works, though there is a possible bug in `heightfield()` that you can work > around by adding the argument `anchor=BOT’. I’ll fix that soon. > > Yes -r uses pixel counts. If you do not give -r the data it outputs will > be for the original image size. > > You can fix the pip warning with: > > pip install --upgrade pip > > > -Revar > > > On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > >  > FYI > > I only have Windows 7 and the latest python that runs on it is 3.8.10 > which I downloaded and installed without a problem. > > Did some hunting on Google and found what you are saying ... except ... I > only typed "pip install pillow" ... which it successfully did but with a > warning msg (shown in the attached pic). > > And ... > > I ran your *mg2scad.py* script and it ran instantly ... and I mean > instantly. Created the scad height file. Hopefully, BOSL2 > *heightfield()* function can use it. Haven't tried that yet. > > My question, however, is the optional command -r WIDTHxHEIGHT. How is > the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is > 902 pixels wide by 1024 pixels. Is that what I am looking for? The > numbers do match the result columns and rows in the created scad file. > Columns being the WIDTH and rows (indices) being the height. > > So far .. so good! > > [image: installPip.png] > > > On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com> wrote: > >> That should be `pip install --upgrade Pillow` with two dashes, not an >> em-dash. Thank you auto-correct who thinks it know best. >> >> - Revar >> >> >> On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com> wrote: >> >> You need to install the Pillow library. Usually this can be done >> simplest from the command-line with the command: >> >> pip install —upgrade Pillow >> >> More info on installing Pillow: >> https://pillow.readthedocs.io/en/latest/installation.html >> >> - Revar >> >> >> >> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >> >> I am receiving this error msg when I run the script: >> >> Line 10: ModuleNotFoundError: No module named 'PIL' >> >> >> Any ideas? >> >> >> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com> wrote: >> >>> Yes, save the script to the file `img2scad.py`. I’m afraid that this is >>> just a command-line tool, and while it’s easy enough to use on Linux or a >>> Mac, I’m not truly sure about how to set up a command-line on Windows. A >>> quick googling results in >>> https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which >>> may be helpful. >>> >>> This script would probably better fit in a separate BOSL2-helpers >>> repository. >>> >>> A GUI version is perfectly possible to do, but that may take me a couple >>> weeks to refresh my memory on how to do cross-platform. >>> >>> - Revar >>> >>> >>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com> >>> wrote: >>> >>> Holy sh..! How the heck do you write something THAT fast? >>> >>> You have my thanks ... and in any way that this can be added to BOSL as >>> some sort of function would be something indeed! >>> >>> I assume "mg2scad.py" is the file name to save the Python code as ... >>> and your usage example is "run command line" orientated. But what do I >>> need on my desktop to run python apps? I've never done a thing with Python >>> that I am aware of. >>> >>> >>> >>> >>> >>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com> >>> wrote: >>> >>>> I wrote up a simple Python image-to-scadfile converter. It’ll read >>>> most common image types, convert them to Luminosity grayscale, with >>>> optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD >>>> source file. >>>> >>>> - Revar >>>> >>>> >>>> Usage: >>>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>>> >>>> Script: >>>> >>>> #!env python3 >>>> >>>> import re >>>> import os >>>> import sys >>>> import os.path >>>> import argparse >>>> >>>> from PIL import Image >>>> >>>> >>>> def img2scad(filename, varname, resize, outf): >>>> indent = " " * 4 >>>> im = Image.open(filename).convert('L') >>>> if resize: >>>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>>> im = im.resize(resize) >>>> pix = im.load() >>>> width, height = im.size >>>> print("// Image {} ({}x{})".format(filename, width, height), >>>> file=outf) >>>> print("{} = [".format(varname), file=outf) >>>> line = indent >>>> for x in range(width): >>>> line += "[ " >>>> for y in range(height): >>>> line += "{:d}, ".format(pix[x,y]) >>>> if len(line) > 60: >>>> print(line, file=outf) >>>> line = indent * 2 >>>> line += " ]," >>>> if line != indent: >>>> print(line, file=outf) >>>> line = indent >>>> print("];", file=outf) >>>> print("", file=outf) >>>> >>>> >>>> def main(): >>>> parser = argparse.ArgumentParser(prog='img2scad') >>>> parser.add_argument('-o', '--outfile', >>>> help='Output .scad file.') >>>> parser.add_argument('-v', '--varname', >>>> help='Variable to use in .scad file.') >>>> parser.add_argument('-r', '--resize', >>>> help='Resample image to WIDTHxHEIGHT.') >>>> parser.add_argument('infile', help='Input image file.') >>>> opts = parser.parse_args() >>>> >>>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>>> if not opts.varname: >>>> if opts.outfile: >>>> opts.varname = >>>> os.path.splitext(os.path.basename(opts.outfile))[0] >>>> opts.varname = non_alnum.sub("", opts.varname) >>>> else: >>>> opts.varname = "image_data" >>>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>>> if opts.resize: >>>> m = size_pat.match(opts.resize) >>>> if not m: >>>> print("Expected WIDTHxHEIGHT resize format.", >>>> file=sys.stderr) >>>> sys.exit(-1) >>>> opts.resize = (int(m.group(1)), int(m.group(2))) >>>> >>>> if not opts.varname or non_alnum.search(opts.varname): >>>> print("Bad variable name: {}".format(opts.varname), >>>> file=sys.stderr) >>>> sys.exit(-1) >>>> >>>> if opts.outfile: >>>> with open(opts.outfile, "w") as outf: >>>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>>> else: >>>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>>> >>>> sys.exit(0) >>>> >>>> >>>> if __name__ == "__main__": >>>> main() >>>> >>>> >>>> >>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>> wrote: >>>> >>>> No doubt ... but I never used Python. >>>> >>>> I think that openSCAD having a way to import and use external STLs by >>>> handling them as data arrays would open up many doors. There are thousands >>>> upon thousands of STL files out there. Heck, openSCAD is used >>>> for parameter customizing on many within Thingiverse alone. Currently I >>>> use converter >>>> <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> to >>>> convert an STL to a PNG. Super super super basic ... but it does work until >>>> I can find something else. >>>> >>>> I will continue searching for a converter to take files like the >>>> grayscale png picture I posted and make height data maps. Maybe they will >>>> work with the BOSL heightfield() function ... you never know. >>>> >>>> >>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com> wrote: >>>> >>>>> Python has libraries for everything so you should be able to read a >>>>> PNG as an image and not need to know the file structure. >>>>> >>>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com> >>>>> wrote: >>>>> >>>>>> Using *surface( file = "Flourish_01b.png" )* on this png file: >>>>>> >>>>>> <Flourish_01b.png> >>>>>> >>>>>> results in this: >>>>>> >>>>>> <result.png> >>>>>> >>>>>> Except for the square base, I was surprised it even worked. >>>>>> >>>>>> Attempting to use pre-built STL files in SCAD always seems to cause a >>>>>> problem, so I wanted to try using grayscale images instead. >>>>>> >>>>>> When using BOSL, I can create a nice vnf array from a sweep(). Works >>>>>> great. I can then use *vnf_polyhedron() *to draw it or draw copies >>>>>> and mirrors of it ... whatever. >>>>>> >>>>>> This is why I was hoping for a function ... however ... as simple as >>>>>> you say it can be ... I've never touched python in my life and never dealt >>>>>> with the PNG file structure. >>>>>> >>>>>> >>>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com> >>>>>> wrote: >>>>>> >>>>>>> BOSL2 has a function/module called `heightfield()` that you can feed >>>>>>> an array of heights, or a function literal that can calculate the heights >>>>>>> dynamically. However, there is currently no way for an OpenSCAD script to >>>>>>> read height values from an image file. You can only generate 3D geometry >>>>>>> using `surface()`. >>>>>>> >>>>>>> >>>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield >>>>>>> >>>>>>> Having said that, it should not be too difficult to write a Python >>>>>>> script to read in an image file, and have it write out a .scad source file >>>>>>> containing the array of height data. >>>>>>> >>>>>>> - Revar >>>>>>> >>>>>>> >>>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>>>> wrote: >>>>>>> >>>>>>> Cannot run surface() as a function to return a vnf array of the data >>>>>>> to manipulate. >>>>>>> >>>>>>> Is there a BOSL function that can do what surface() does? >>>>>>> >>>>>>> If not, is there another library out there that will do it? >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
RD
Revar Desmera
Wed, May 11, 2022 3:30 AM

That warning just means it won’t cache the geometry for speed.  It’ll still work.  It just may be slow.  You can increase the cache size in the preferences dialog.

The image data will be from 0 to 255, but if you just divide the image data array by the scalar 255, it will be scaled to the range 0.0 to 1.0.  ie:

include <BOSL2/std.scad>
include <image_data.scad>
heightfield(image_data/255, anchor=BOT);

  • Revar

On May 10, 2022, at 8:21 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

Will use the anchor=BOT for now.

I am getting this warning whenever I run it:using that pic I've been testing:
WARNING: GeometryEvaluator: Node didn't fit into cache.

Does that affect the program?

Also, when I set the maxz to something like 8 it gets wacky.  Z ends up at 256 which obviously means it is using 256 (0-255) grays. One level for each.

On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
I tested using heightfield() with a 512x512 image, so I can verify it works, though there is a possible bug in heightfield() that you can work around by adding the argument `anchor=BOT’. I’ll fix that soon.

Yes -r uses pixel counts. If you do not give -r the data it outputs will be for the original image size.

You can fix the pip warning with:

pip install --upgrade pip

-Revar

On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:


FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean instantly.  Created the scad height file.  Hopefully, BOSL2 heightfield() function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is 902 pixels wide by 1024 pixels.  Is that what I am looking for?  The numbers do match the result columns and rows in the created scad file.  Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

<installPip.png>

On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
That should be pip install --upgrade Pillow with two dashes, not an em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:

You need to install the Pillow library.  Usually this can be done simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
Yes, save the script to the file img2scad.py.  I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows.  A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which may be helpful.

This script would probably better fit in a separate BOSL2-helpers repository.

A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated.  But what do I need on my desktop to run python apps?  I've never done a thing with Python that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
I wrote up a simple Python image-to-scadfile converter.  It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:
#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height), file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0]
         opts.varname = non_alnum.sub("", opts.varname)
     else:
         opts.varname = "image_data"
 size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$')
 if opts.resize:
     m = size_pat.match(opts.resize)
     if not m:
         print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr)
         sys.exit(-1)
     opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname), file=sys.stderr)
     sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there.  Heck, openSCAD is used for parameter customizing on many within Thingiverse alone.  Currently I use converter https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else.

I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps.  Maybe they will work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com mailto:nop.head@gmail.com> wrote:
Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:
Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().  Works great.  I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
BOSL2 has a function/module called heightfield() that you can feed an array of heights, or a function literal that can calculate the heights dynamically.  However, there is currently no way for an OpenSCAD script to read height values from an image file.  You can only generate 3D geometry using surface().

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

Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Cannot run surface() as a function to return a vnf array of the data to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

That warning just means it won’t cache the geometry for speed. It’ll still work. It just may be slow. You can increase the cache size in the preferences dialog. The image data will be from 0 to 255, but if you just divide the image data array by the scalar 255, it will be scaled to the range 0.0 to 1.0. ie: include <BOSL2/std.scad> include <image_data.scad> heightfield(image_data/255, anchor=BOT); - Revar > On May 10, 2022, at 8:21 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > > > Will use the anchor=BOT for now. > > I am getting this warning whenever I run it:using that pic I've been testing: > WARNING: GeometryEvaluator: Node didn't fit into cache. > > Does that affect the program? > > Also, when I set the maxz to something like 8 it gets wacky. Z ends up at 256 which obviously means it is using 256 (0-255) grays. One level for each. > > > > On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: > I tested using `heightfield()` with a 512x512 image, so I can verify it works, though there is a possible bug in `heightfield()` that you can work around by adding the argument `anchor=BOT’. I’ll fix that soon. > > Yes -r uses pixel counts. If you do not give -r the data it outputs will be for the original image size. > > You can fix the pip warning with: > > pip install --upgrade pip > > -Revar > > >> On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >> >>  >> FYI >> >> I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem. >> >> Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic). >> >> And ... >> >> I ran your mg2scad.py script and it ran instantly ... and I mean instantly. Created the scad height file. Hopefully, BOSL2 heightfield() function can use it. Haven't tried that yet. >> >> My question, however, is the optional command -r WIDTHxHEIGHT. How is the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is 902 pixels wide by 1024 pixels. Is that what I am looking for? The numbers do match the result columns and rows in the created scad file. Columns being the WIDTH and rows (indices) being the height. >> >> So far .. so good! >> >> <installPip.png> >> >> >> On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >> That should be `pip install --upgrade Pillow` with two dashes, not an em-dash. Thank you auto-correct who thinks it know best. >> >> - Revar >> >> >>> On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>> >>> You need to install the Pillow library. Usually this can be done simplest from the command-line with the command: >>> >>> pip install —upgrade Pillow >>> >>> More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html <https://pillow.readthedocs.io/en/latest/installation.html> >>> >>> - Revar >>> >>> >>> >>>> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>> >>>> I am receiving this error msg when I run the script: >>>> >>>> Line 10: ModuleNotFoundError: No module named 'PIL' >>>> >>>> Any ideas? >>>> >>>> >>>> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>> Yes, save the script to the file `img2scad.py`. I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows. A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ <https://www.geeksforgeeks.org/how-to-install-python-on-windows/> which may be helpful. >>>> >>>> This script would probably better fit in a separate BOSL2-helpers repository. >>>> >>>> A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform. >>>> >>>> - Revar >>>> >>>> >>>>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>> >>>>> Holy sh..! How the heck do you write something THAT fast? >>>>> >>>>> You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed! >>>>> >>>>> I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated. But what do I need on my desktop to run python apps? I've never done a thing with Python that I am aware of. >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>>> I wrote up a simple Python image-to-scadfile converter. It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file. >>>>> >>>>> - Revar >>>>> >>>>> >>>>> Usage: >>>>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>>>> >>>>> Script: >>>>> #!env python3 >>>>> >>>>> import re >>>>> import os >>>>> import sys >>>>> import os.path >>>>> import argparse >>>>> >>>>> from PIL import Image >>>>> >>>>> >>>>> def img2scad(filename, varname, resize, outf): >>>>> indent = " " * 4 >>>>> im = Image.open(filename).convert('L') >>>>> if resize: >>>>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>>>> im = im.resize(resize) >>>>> pix = im.load() >>>>> width, height = im.size >>>>> print("// Image {} ({}x{})".format(filename, width, height), file=outf) >>>>> print("{} = [".format(varname), file=outf) >>>>> line = indent >>>>> for x in range(width): >>>>> line += "[ " >>>>> for y in range(height): >>>>> line += "{:d}, ".format(pix[x,y]) >>>>> if len(line) > 60: >>>>> print(line, file=outf) >>>>> line = indent * 2 >>>>> line += " ]," >>>>> if line != indent: >>>>> print(line, file=outf) >>>>> line = indent >>>>> print("];", file=outf) >>>>> print("", file=outf) >>>>> >>>>> >>>>> def main(): >>>>> parser = argparse.ArgumentParser(prog='img2scad') >>>>> parser.add_argument('-o', '--outfile', >>>>> help='Output .scad file.') >>>>> parser.add_argument('-v', '--varname', >>>>> help='Variable to use in .scad file.') >>>>> parser.add_argument('-r', '--resize', >>>>> help='Resample image to WIDTHxHEIGHT.') >>>>> parser.add_argument('infile', help='Input image file.') >>>>> opts = parser.parse_args() >>>>> >>>>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>>>> if not opts.varname: >>>>> if opts.outfile: >>>>> opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0] >>>>> opts.varname = non_alnum.sub("", opts.varname) >>>>> else: >>>>> opts.varname = "image_data" >>>>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>>>> if opts.resize: >>>>> m = size_pat.match(opts.resize) >>>>> if not m: >>>>> print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr) >>>>> sys.exit(-1) >>>>> opts.resize = (int(m.group(1)), int(m.group(2))) >>>>> >>>>> if not opts.varname or non_alnum.search(opts.varname): >>>>> print("Bad variable name: {}".format(opts.varname), file=sys.stderr) >>>>> sys.exit(-1) >>>>> >>>>> if opts.outfile: >>>>> with open(opts.outfile, "w") as outf: >>>>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>>>> else: >>>>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>>>> >>>>> sys.exit(0) >>>>> >>>>> >>>>> if __name__ == "__main__": >>>>> main() >>>>> >>>>> >>>>> >>>>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>> >>>>>> No doubt ... but I never used Python. >>>>>> >>>>>> I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there. Heck, openSCAD is used for parameter customizing on many within Thingiverse alone. Currently I use converter <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else. >>>>>> >>>>>> I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps. Maybe they will work with the BOSL heightfield() function ... you never know. >>>>>> >>>>>> >>>>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com <mailto:nop.head@gmail.com>> wrote: >>>>>> Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure. >>>>>> >>>>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>> Using surface( file = "Flourish_01b.png" ) on this png file: >>>>>> >>>>>> <Flourish_01b.png> >>>>>> >>>>>> results in this: >>>>>> >>>>>> <result.png> >>>>>> >>>>>> Except for the square base, I was surprised it even worked. >>>>>> >>>>>> Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead. >>>>>> >>>>>> When using BOSL, I can create a nice vnf array from a sweep(). Works great. I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever. >>>>>> >>>>>> This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure. >>>>>> >>>>>> >>>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>>>> BOSL2 has a function/module called `heightfield()` that you can feed an array of heights, or a function literal that can calculate the heights dynamically. However, there is currently no way for an OpenSCAD script to read height values from an image file. You can only generate 3D geometry using `surface()`. >>>>>> >>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield <https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield> >>>>>> >>>>>> Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data. >>>>>> >>>>>> - Revar >>>>>> >>>>>> >>>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>>> >>>>>>> Cannot run surface() as a function to return a vnf array of the data to manipulate. >>>>>>> >>>>>>> Is there a BOSL function that can do what surface() does? >>>>>>> >>>>>>> If not, is there another library out there that will do it? >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JW
Joe Weinpert
Wed, May 11, 2022 3:59 AM

What you suggested works perfectly!

Now I need to find a way to remove the first bottom row for these pics
where a zero (0) colored base is.  Square/rectangular pics obviously do not
have that problem.  Odd shapes like what I've been testing do.

Maybe it isn't a matter of removing ... maybe a way to ignore values of
zero, or something ... or maybe there is another BOSL2 command to simply
slice the bottom off.  I will look.

Thanks again.

On Tue, May 10, 2022 at 11:30 PM Revar Desmera revarbat@gmail.com wrote:

That warning just means it won’t cache the geometry for speed.  It’ll
still work.  It just may be slow.  You can increase the cache size in the
preferences dialog.

The image data will be from 0 to 255, but if you just divide the image
data array by the scalar 255, it will be scaled to the range 0.0 to 1.0.
ie:

include <BOSL2/std.scad>
include <image_data.scad>
heightfield(image_data/255, anchor=BOT);

  • Revar

On May 10, 2022, at 8:21 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

Will use the anchor=BOT for now.

I am getting this warning whenever I run it:using that pic I've been
testing:

WARNING: GeometryEvaluator: Node didn't fit into cache.

Does that affect the program?

Also, when I set the maxz to something like 8 it gets wacky.  Z ends up at
256 which obviously means it is using 256 (0-255) grays. One level for each.

On Tue, May 10, 2022 at 11:00 PM Revar Desmera revarbat@gmail.com wrote:

I tested using heightfield() with a 512x512 image, so I can verify it
works, though there is a possible bug in heightfield() that you can work
around by adding the argument `anchor=BOT’. I’ll fix that soon.

Yes -r uses pixel counts. If you do not give -r the data it outputs will
be for the original image size.

You can fix the pip warning with:

pip install --upgrade pip

-Revar

On May 10, 2022, at 6:50 PM, Joe Weinpert joe.weinpert@gmail.com wrote:


FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10
which I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ... I
only typed "pip install pillow" ... which it successfully did but with a
warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean
instantly.  Created the scad height file.  Hopefully, BOSL2
heightfield() function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is
the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is
902 pixels wide by 1024 pixels.  Is that what I am looking for?  The
numbers do match the result columns and rows in the created scad file.
Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

<installPip.png>

On Tue, May 10, 2022 at 9:22 PM Revar Desmera revarbat@gmail.com wrote:

That should be pip install --upgrade Pillow with two dashes, not an
em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera revarbat@gmail.com wrote:

You need to install the Pillow library.  Usually this can be done
simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow:
https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera revarbat@gmail.com
wrote:

Yes, save the script to the file img2scad.py.  I’m afraid that this
is just a command-line tool, and while it’s easy enough to use on Linux or
a Mac, I’m not truly sure about how to set up a command-line on Windows.  A
quick googling results in
https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which
may be helpful.

This script would probably better fit in a separate BOSL2-helpers
repository.

A GUI version is perfectly possible to do, but that may take me a
couple weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as
some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ...
and your usage example is "run command line" orientated.  But what do I
need on my desktop to run python apps?  I've never done a thing with Python
that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera revarbat@gmail.com
wrote:

I wrote up a simple Python image-to-scadfile converter.  It’ll read
most common image types, convert them to Luminosity grayscale, with
optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD
source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:

#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height),
file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname =

os.path.splitext(os.path.basename(opts.outfile))[0]
opts.varname = non_alnum.sub("", opts.varname)
else:
opts.varname = "image_data"
size_pat = re.compile(r'^([0-9][0-9])x([0-9][0-9])$')
if opts.resize:
m = size_pat.match(opts.resize)
if not m:
print("Expected WIDTHxHEIGHT resize format.",
file=sys.stderr)
sys.exit(-1)
opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname),

file=sys.stderr)
sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by
handling them as data arrays would open up many doors. There are thousands
upon thousands of STL files out there.  Heck, openSCAD is used
for parameter customizing on many within Thingiverse alone.  Currently I
use converter
https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html
to convert an STL to a PNG. Super super super basic ... but it does work
until I can find something else.

I will continue searching for a converter to take files like the
grayscale png picture I posted and make height data maps.  Maybe they will
work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head nop.head@gmail.com wrote:

Python has libraries for everything so you should be able to read a
PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert joe.weinpert@gmail.com
wrote:

Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause
a problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().
Works great.  I can then use *vnf_polyhedron() *to draw it or draw
copies and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as
you say it can be ... I've never touched python in my life and never dealt
with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera revarbat@gmail.com
wrote:

BOSL2 has a function/module called heightfield() that you can
feed an array of heights, or a function literal that can calculate the
heights dynamically.  However, there is currently no way for an OpenSCAD
script to read height values from an image file.  You can only generate 3D
geometry using surface().

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

Having said that, it should not be too difficult to write a Python
script to read in an image file, and have it write out a .scad source file
containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Cannot run surface() as a function to return a vnf array of the
data to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

What you suggested works perfectly! Now I need to find a way to remove the first bottom row for these pics where a zero (0) colored base is. Square/rectangular pics obviously do not have that problem. Odd shapes like what I've been testing do. Maybe it isn't a matter of removing ... maybe a way to ignore values of zero, or something ... or maybe there is another BOSL2 command to simply slice the bottom off. I will look. Thanks again. On Tue, May 10, 2022 at 11:30 PM Revar Desmera <revarbat@gmail.com> wrote: > That warning just means it won’t cache the geometry for speed. It’ll > still work. It just may be slow. You can increase the cache size in the > preferences dialog. > > The image data will be from 0 to 255, but if you just divide the image > data array by the scalar 255, it will be scaled to the range 0.0 to 1.0. > ie: > > include <BOSL2/std.scad> > include <image_data.scad> > heightfield(image_data/255, anchor=BOT); > > > - Revar > > > On May 10, 2022, at 8:21 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > > > Will use the anchor=BOT for now. > > I am getting this warning whenever I run it:using that pic I've been > testing: > > WARNING: GeometryEvaluator: Node didn't fit into cache. > > > Does that affect the program? > > Also, when I set the maxz to something like 8 it gets wacky. Z ends up at > 256 which obviously means it is using 256 (0-255) grays. One level for each. > > > > On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com> wrote: > >> I tested using `heightfield()` with a 512x512 image, so I can verify it >> works, though there is a possible bug in `heightfield()` that you can work >> around by adding the argument `anchor=BOT’. I’ll fix that soon. >> >> Yes -r uses pixel counts. If you do not give -r the data it outputs will >> be for the original image size. >> >> You can fix the pip warning with: >> >> pip install --upgrade pip >> >> >> -Revar >> >> >> On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >> >>  >> FYI >> >> I only have Windows 7 and the latest python that runs on it is 3.8.10 >> which I downloaded and installed without a problem. >> >> Did some hunting on Google and found what you are saying ... except ... I >> only typed "pip install pillow" ... which it successfully did but with a >> warning msg (shown in the attached pic). >> >> And ... >> >> I ran your *mg2scad.py* script and it ran instantly ... and I mean >> instantly. Created the scad height file. Hopefully, BOSL2 >> *heightfield()* function can use it. Haven't tried that yet. >> >> My question, however, is the optional command -r WIDTHxHEIGHT. How is >> the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is >> 902 pixels wide by 1024 pixels. Is that what I am looking for? The >> numbers do match the result columns and rows in the created scad file. >> Columns being the WIDTH and rows (indices) being the height. >> >> So far .. so good! >> >> <installPip.png> >> >> >> On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com> wrote: >> >>> That should be `pip install --upgrade Pillow` with two dashes, not an >>> em-dash. Thank you auto-correct who thinks it know best. >>> >>> - Revar >>> >>> >>> On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com> wrote: >>> >>> You need to install the Pillow library. Usually this can be done >>> simplest from the command-line with the command: >>> >>> pip install —upgrade Pillow >>> >>> More info on installing Pillow: >>> https://pillow.readthedocs.io/en/latest/installation.html >>> >>> - Revar >>> >>> >>> >>> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com> >>> wrote: >>> >>> I am receiving this error msg when I run the script: >>> >>> Line 10: ModuleNotFoundError: No module named 'PIL' >>> >>> >>> Any ideas? >>> >>> >>> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com> >>> wrote: >>> >>>> Yes, save the script to the file `img2scad.py`. I’m afraid that this >>>> is just a command-line tool, and while it’s easy enough to use on Linux or >>>> a Mac, I’m not truly sure about how to set up a command-line on Windows. A >>>> quick googling results in >>>> https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which >>>> may be helpful. >>>> >>>> This script would probably better fit in a separate BOSL2-helpers >>>> repository. >>>> >>>> A GUI version is perfectly possible to do, but that may take me a >>>> couple weeks to refresh my memory on how to do cross-platform. >>>> >>>> - Revar >>>> >>>> >>>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>> wrote: >>>> >>>> Holy sh..! How the heck do you write something THAT fast? >>>> >>>> You have my thanks ... and in any way that this can be added to BOSL as >>>> some sort of function would be something indeed! >>>> >>>> I assume "mg2scad.py" is the file name to save the Python code as ... >>>> and your usage example is "run command line" orientated. But what do I >>>> need on my desktop to run python apps? I've never done a thing with Python >>>> that I am aware of. >>>> >>>> >>>> >>>> >>>> >>>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com> >>>> wrote: >>>> >>>>> I wrote up a simple Python image-to-scadfile converter. It’ll read >>>>> most common image types, convert them to Luminosity grayscale, with >>>>> optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD >>>>> source file. >>>>> >>>>> - Revar >>>>> >>>>> >>>>> Usage: >>>>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>>>> >>>>> Script: >>>>> >>>>> #!env python3 >>>>> >>>>> import re >>>>> import os >>>>> import sys >>>>> import os.path >>>>> import argparse >>>>> >>>>> from PIL import Image >>>>> >>>>> >>>>> def img2scad(filename, varname, resize, outf): >>>>> indent = " " * 4 >>>>> im = Image.open(filename).convert('L') >>>>> if resize: >>>>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>>>> im = im.resize(resize) >>>>> pix = im.load() >>>>> width, height = im.size >>>>> print("// Image {} ({}x{})".format(filename, width, height), >>>>> file=outf) >>>>> print("{} = [".format(varname), file=outf) >>>>> line = indent >>>>> for x in range(width): >>>>> line += "[ " >>>>> for y in range(height): >>>>> line += "{:d}, ".format(pix[x,y]) >>>>> if len(line) > 60: >>>>> print(line, file=outf) >>>>> line = indent * 2 >>>>> line += " ]," >>>>> if line != indent: >>>>> print(line, file=outf) >>>>> line = indent >>>>> print("];", file=outf) >>>>> print("", file=outf) >>>>> >>>>> >>>>> def main(): >>>>> parser = argparse.ArgumentParser(prog='img2scad') >>>>> parser.add_argument('-o', '--outfile', >>>>> help='Output .scad file.') >>>>> parser.add_argument('-v', '--varname', >>>>> help='Variable to use in .scad file.') >>>>> parser.add_argument('-r', '--resize', >>>>> help='Resample image to WIDTHxHEIGHT.') >>>>> parser.add_argument('infile', help='Input image file.') >>>>> opts = parser.parse_args() >>>>> >>>>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>>>> if not opts.varname: >>>>> if opts.outfile: >>>>> opts.varname = >>>>> os.path.splitext(os.path.basename(opts.outfile))[0] >>>>> opts.varname = non_alnum.sub("", opts.varname) >>>>> else: >>>>> opts.varname = "image_data" >>>>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>>>> if opts.resize: >>>>> m = size_pat.match(opts.resize) >>>>> if not m: >>>>> print("Expected WIDTHxHEIGHT resize format.", >>>>> file=sys.stderr) >>>>> sys.exit(-1) >>>>> opts.resize = (int(m.group(1)), int(m.group(2))) >>>>> >>>>> if not opts.varname or non_alnum.search(opts.varname): >>>>> print("Bad variable name: {}".format(opts.varname), >>>>> file=sys.stderr) >>>>> sys.exit(-1) >>>>> >>>>> if opts.outfile: >>>>> with open(opts.outfile, "w") as outf: >>>>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>>>> else: >>>>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>>>> >>>>> sys.exit(0) >>>>> >>>>> >>>>> if __name__ == "__main__": >>>>> main() >>>>> >>>>> >>>>> >>>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>> wrote: >>>>> >>>>> No doubt ... but I never used Python. >>>>> >>>>> I think that openSCAD having a way to import and use external STLs by >>>>> handling them as data arrays would open up many doors. There are thousands >>>>> upon thousands of STL files out there. Heck, openSCAD is used >>>>> for parameter customizing on many within Thingiverse alone. Currently I >>>>> use converter >>>>> <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> >>>>> to convert an STL to a PNG. Super super super basic ... but it does work >>>>> until I can find something else. >>>>> >>>>> I will continue searching for a converter to take files like the >>>>> grayscale png picture I posted and make height data maps. Maybe they will >>>>> work with the BOSL heightfield() function ... you never know. >>>>> >>>>> >>>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com> wrote: >>>>> >>>>>> Python has libraries for everything so you should be able to read a >>>>>> PNG as an image and not need to know the file structure. >>>>>> >>>>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com> >>>>>> wrote: >>>>>> >>>>>>> Using *surface( file = "Flourish_01b.png" )* on this png file: >>>>>>> >>>>>>> <Flourish_01b.png> >>>>>>> >>>>>>> results in this: >>>>>>> >>>>>>> <result.png> >>>>>>> >>>>>>> Except for the square base, I was surprised it even worked. >>>>>>> >>>>>>> Attempting to use pre-built STL files in SCAD always seems to cause >>>>>>> a problem, so I wanted to try using grayscale images instead. >>>>>>> >>>>>>> When using BOSL, I can create a nice vnf array from a sweep(). >>>>>>> Works great. I can then use *vnf_polyhedron() *to draw it or draw >>>>>>> copies and mirrors of it ... whatever. >>>>>>> >>>>>>> This is why I was hoping for a function ... however ... as simple as >>>>>>> you say it can be ... I've never touched python in my life and never dealt >>>>>>> with the PNG file structure. >>>>>>> >>>>>>> >>>>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com> >>>>>>> wrote: >>>>>>> >>>>>>>> BOSL2 has a function/module called `heightfield()` that you can >>>>>>>> feed an array of heights, or a function literal that can calculate the >>>>>>>> heights dynamically. However, there is currently no way for an OpenSCAD >>>>>>>> script to read height values from an image file. You can only generate 3D >>>>>>>> geometry using `surface()`. >>>>>>>> >>>>>>>> >>>>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield >>>>>>>> >>>>>>>> Having said that, it should not be too difficult to write a Python >>>>>>>> script to read in an image file, and have it write out a .scad source file >>>>>>>> containing the array of height data. >>>>>>>> >>>>>>>> - Revar >>>>>>>> >>>>>>>> >>>>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>>>>> wrote: >>>>>>>> >>>>>>>> Cannot run surface() as a function to return a vnf array of the >>>>>>>> data to manipulate. >>>>>>>> >>>>>>>> Is there a BOSL function that can do what surface() does? >>>>>>>> >>>>>>>> If not, is there another library out there that will do it? >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>> >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Wed, May 11, 2022 4:48 AM

On 5/10/2022 4:02 PM, Joe Weinpert wrote:

I think that openSCAD having a way to import and use external STLs by
handling them as data arrays would open up many doors.

The render() function-like mechanism will do that and more, when it's ready.

https://github.com/openscad/openscad/pull/3956

On 5/10/2022 4:02 PM, Joe Weinpert wrote: > I think that openSCAD having a way to import and use external STLs by > handling them as data arrays would open up many doors. The render() function-like mechanism will do that and more, when it's ready. https://github.com/openscad/openscad/pull/3956
RD
Revar Desmera
Wed, May 11, 2022 10:39 PM

Well, you can do something like top_half() down(5) heightfield(…)

  • Revar

On May 10, 2022, at 8:59 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

What you suggested works perfectly!

Now I need to find a way to remove the first bottom row for these pics where a zero (0) colored base is.  Square/rectangular pics obviously do not have that problem.  Odd shapes like what I've been testing do.

Maybe it isn't a matter of removing ... maybe a way to ignore values of zero, or something ... or maybe there is another BOSL2 command to simply slice the bottom off.  I will look.

Thanks again.

On Tue, May 10, 2022 at 11:30 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
That warning just means it won’t cache the geometry for speed.  It’ll still work.  It just may be slow.  You can increase the cache size in the preferences dialog.

The image data will be from 0 to 255, but if you just divide the image data array by the scalar 255, it will be scaled to the range 0.0 to 1.0.  ie:

include <BOSL2/std.scad>
include <image_data.scad>
heightfield(image_data/255, anchor=BOT);

  • Revar

On May 10, 2022, at 8:21 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Will use the anchor=BOT for now.

I am getting this warning whenever I run it:using that pic I've been testing:
WARNING: GeometryEvaluator: Node didn't fit into cache.

Does that affect the program?

Also, when I set the maxz to something like 8 it gets wacky.  Z ends up at 256 which obviously means it is using 256 (0-255) grays. One level for each.

On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
I tested using heightfield() with a 512x512 image, so I can verify it works, though there is a possible bug in heightfield() that you can work around by adding the argument `anchor=BOT’. I’ll fix that soon.

Yes -r uses pixel counts. If you do not give -r the data it outputs will be for the original image size.

You can fix the pip warning with:

pip install --upgrade pip

-Revar

On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:


FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean instantly.  Created the scad height file.  Hopefully, BOSL2 heightfield() function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is 902 pixels wide by 1024 pixels.  Is that what I am looking for?  The numbers do match the result columns and rows in the created scad file.  Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

<installPip.png>

On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
That should be pip install --upgrade Pillow with two dashes, not an em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:

You need to install the Pillow library.  Usually this can be done simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
Yes, save the script to the file img2scad.py.  I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows.  A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which may be helpful.

This script would probably better fit in a separate BOSL2-helpers repository.

A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated.  But what do I need on my desktop to run python apps?  I've never done a thing with Python that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
I wrote up a simple Python image-to-scadfile converter.  It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:
#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height), file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0]
         opts.varname = non_alnum.sub("", opts.varname)
     else:
         opts.varname = "image_data"
 size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$')
 if opts.resize:
     m = size_pat.match(opts.resize)
     if not m:
         print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr)
         sys.exit(-1)
     opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname), file=sys.stderr)
     sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there.  Heck, openSCAD is used for parameter customizing on many within Thingiverse alone.  Currently I use converter https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else.

I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps.  Maybe they will work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com mailto:nop.head@gmail.com> wrote:
Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:
Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().  Works great.  I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com mailto:revarbat@gmail.com> wrote:
BOSL2 has a function/module called heightfield() that you can feed an array of heights, or a function literal that can calculate the heights dynamically.  However, there is currently no way for an OpenSCAD script to read height values from an image file.  You can only generate 3D geometry using surface().

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

Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com mailto:joe.weinpert@gmail.com> wrote:

Cannot run surface() as a function to return a vnf array of the data to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Well, you can do something like `top_half() down(5) heightfield(…)` - Revar > On May 10, 2022, at 8:59 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > > What you suggested works perfectly! > > Now I need to find a way to remove the first bottom row for these pics where a zero (0) colored base is. Square/rectangular pics obviously do not have that problem. Odd shapes like what I've been testing do. > > Maybe it isn't a matter of removing ... maybe a way to ignore values of zero, or something ... or maybe there is another BOSL2 command to simply slice the bottom off. I will look. > > Thanks again. > > > > > > > On Tue, May 10, 2022 at 11:30 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: > That warning just means it won’t cache the geometry for speed. It’ll still work. It just may be slow. You can increase the cache size in the preferences dialog. > > The image data will be from 0 to 255, but if you just divide the image data array by the scalar 255, it will be scaled to the range 0.0 to 1.0. ie: > > include <BOSL2/std.scad> > include <image_data.scad> > heightfield(image_data/255, anchor=BOT); > > - Revar > > >> On May 10, 2022, at 8:21 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >> >> >> Will use the anchor=BOT for now. >> >> I am getting this warning whenever I run it:using that pic I've been testing: >> WARNING: GeometryEvaluator: Node didn't fit into cache. >> >> Does that affect the program? >> >> Also, when I set the maxz to something like 8 it gets wacky. Z ends up at 256 which obviously means it is using 256 (0-255) grays. One level for each. >> >> >> >> On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >> I tested using `heightfield()` with a 512x512 image, so I can verify it works, though there is a possible bug in `heightfield()` that you can work around by adding the argument `anchor=BOT’. I’ll fix that soon. >> >> Yes -r uses pixel counts. If you do not give -r the data it outputs will be for the original image size. >> >> You can fix the pip warning with: >> >> pip install --upgrade pip >> >> -Revar >> >> >>> On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>> >>>  >>> FYI >>> >>> I only have Windows 7 and the latest python that runs on it is 3.8.10 which I downloaded and installed without a problem. >>> >>> Did some hunting on Google and found what you are saying ... except ... I only typed "pip install pillow" ... which it successfully did but with a warning msg (shown in the attached pic). >>> >>> And ... >>> >>> I ran your mg2scad.py script and it ran instantly ... and I mean instantly. Created the scad height file. Hopefully, BOSL2 heightfield() function can use it. Haven't tried that yet. >>> >>> My question, however, is the optional command -r WIDTHxHEIGHT. How is the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is 902 pixels wide by 1024 pixels. Is that what I am looking for? The numbers do match the result columns and rows in the created scad file. Columns being the WIDTH and rows (indices) being the height. >>> >>> So far .. so good! >>> >>> <installPip.png> >>> >>> >>> On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>> That should be `pip install --upgrade Pillow` with two dashes, not an em-dash. Thank you auto-correct who thinks it know best. >>> >>> - Revar >>> >>> >>>> On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>> >>>> You need to install the Pillow library. Usually this can be done simplest from the command-line with the command: >>>> >>>> pip install —upgrade Pillow >>>> >>>> More info on installing Pillow: https://pillow.readthedocs.io/en/latest/installation.html <https://pillow.readthedocs.io/en/latest/installation.html> >>>> >>>> - Revar >>>> >>>> >>>> >>>>> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>> >>>>> I am receiving this error msg when I run the script: >>>>> >>>>> Line 10: ModuleNotFoundError: No module named 'PIL' >>>>> >>>>> Any ideas? >>>>> >>>>> >>>>> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>>> Yes, save the script to the file `img2scad.py`. I’m afraid that this is just a command-line tool, and while it’s easy enough to use on Linux or a Mac, I’m not truly sure about how to set up a command-line on Windows. A quick googling results in https://www.geeksforgeeks.org/how-to-install-python-on-windows/ <https://www.geeksforgeeks.org/how-to-install-python-on-windows/> which may be helpful. >>>>> >>>>> This script would probably better fit in a separate BOSL2-helpers repository. >>>>> >>>>> A GUI version is perfectly possible to do, but that may take me a couple weeks to refresh my memory on how to do cross-platform. >>>>> >>>>> - Revar >>>>> >>>>> >>>>>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>> >>>>>> Holy sh..! How the heck do you write something THAT fast? >>>>>> >>>>>> You have my thanks ... and in any way that this can be added to BOSL as some sort of function would be something indeed! >>>>>> >>>>>> I assume "mg2scad.py" is the file name to save the Python code as ... and your usage example is "run command line" orientated. But what do I need on my desktop to run python apps? I've never done a thing with Python that I am aware of. >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>>>> I wrote up a simple Python image-to-scadfile converter. It’ll read most common image types, convert them to Luminosity grayscale, with optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD source file. >>>>>> >>>>>> - Revar >>>>>> >>>>>> >>>>>> Usage: >>>>>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>>>>> >>>>>> Script: >>>>>> #!env python3 >>>>>> >>>>>> import re >>>>>> import os >>>>>> import sys >>>>>> import os.path >>>>>> import argparse >>>>>> >>>>>> from PIL import Image >>>>>> >>>>>> >>>>>> def img2scad(filename, varname, resize, outf): >>>>>> indent = " " * 4 >>>>>> im = Image.open(filename).convert('L') >>>>>> if resize: >>>>>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>>>>> im = im.resize(resize) >>>>>> pix = im.load() >>>>>> width, height = im.size >>>>>> print("// Image {} ({}x{})".format(filename, width, height), file=outf) >>>>>> print("{} = [".format(varname), file=outf) >>>>>> line = indent >>>>>> for x in range(width): >>>>>> line += "[ " >>>>>> for y in range(height): >>>>>> line += "{:d}, ".format(pix[x,y]) >>>>>> if len(line) > 60: >>>>>> print(line, file=outf) >>>>>> line = indent * 2 >>>>>> line += " ]," >>>>>> if line != indent: >>>>>> print(line, file=outf) >>>>>> line = indent >>>>>> print("];", file=outf) >>>>>> print("", file=outf) >>>>>> >>>>>> >>>>>> def main(): >>>>>> parser = argparse.ArgumentParser(prog='img2scad') >>>>>> parser.add_argument('-o', '--outfile', >>>>>> help='Output .scad file.') >>>>>> parser.add_argument('-v', '--varname', >>>>>> help='Variable to use in .scad file.') >>>>>> parser.add_argument('-r', '--resize', >>>>>> help='Resample image to WIDTHxHEIGHT.') >>>>>> parser.add_argument('infile', help='Input image file.') >>>>>> opts = parser.parse_args() >>>>>> >>>>>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>>>>> if not opts.varname: >>>>>> if opts.outfile: >>>>>> opts.varname = os.path.splitext(os.path.basename(opts.outfile))[0] >>>>>> opts.varname = non_alnum.sub("", opts.varname) >>>>>> else: >>>>>> opts.varname = "image_data" >>>>>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>>>>> if opts.resize: >>>>>> m = size_pat.match(opts.resize) >>>>>> if not m: >>>>>> print("Expected WIDTHxHEIGHT resize format.", file=sys.stderr) >>>>>> sys.exit(-1) >>>>>> opts.resize = (int(m.group(1)), int(m.group(2))) >>>>>> >>>>>> if not opts.varname or non_alnum.search(opts.varname): >>>>>> print("Bad variable name: {}".format(opts.varname), file=sys.stderr) >>>>>> sys.exit(-1) >>>>>> >>>>>> if opts.outfile: >>>>>> with open(opts.outfile, "w") as outf: >>>>>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>>>>> else: >>>>>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>>>>> >>>>>> sys.exit(0) >>>>>> >>>>>> >>>>>> if __name__ == "__main__": >>>>>> main() >>>>>> >>>>>> >>>>>> >>>>>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>>> >>>>>>> No doubt ... but I never used Python. >>>>>>> >>>>>>> I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. There are thousands upon thousands of STL files out there. Heck, openSCAD is used for parameter customizing on many within Thingiverse alone. Currently I use converter <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> to convert an STL to a PNG. Super super super basic ... but it does work until I can find something else. >>>>>>> >>>>>>> I will continue searching for a converter to take files like the grayscale png picture I posted and make height data maps. Maybe they will work with the BOSL heightfield() function ... you never know. >>>>>>> >>>>>>> >>>>>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com <mailto:nop.head@gmail.com>> wrote: >>>>>>> Python has libraries for everything so you should be able to read a PNG as an image and not need to know the file structure. >>>>>>> >>>>>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>>> Using surface( file = "Flourish_01b.png" ) on this png file: >>>>>>> >>>>>>> <Flourish_01b.png> >>>>>>> >>>>>>> results in this: >>>>>>> >>>>>>> <result.png> >>>>>>> >>>>>>> Except for the square base, I was surprised it even worked. >>>>>>> >>>>>>> Attempting to use pre-built STL files in SCAD always seems to cause a problem, so I wanted to try using grayscale images instead. >>>>>>> >>>>>>> When using BOSL, I can create a nice vnf array from a sweep(). Works great. I can then use vnf_polyhedron() to draw it or draw copies and mirrors of it ... whatever. >>>>>>> >>>>>>> This is why I was hoping for a function ... however ... as simple as you say it can be ... I've never touched python in my life and never dealt with the PNG file structure. >>>>>>> >>>>>>> >>>>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com <mailto:revarbat@gmail.com>> wrote: >>>>>>> BOSL2 has a function/module called `heightfield()` that you can feed an array of heights, or a function literal that can calculate the heights dynamically. However, there is currently no way for an OpenSCAD script to read height values from an image file. You can only generate 3D geometry using `surface()`. >>>>>>> >>>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield <https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield> >>>>>>> >>>>>>> Having said that, it should not be too difficult to write a Python script to read in an image file, and have it write out a .scad source file containing the array of height data. >>>>>>> >>>>>>> - Revar >>>>>>> >>>>>>> >>>>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com <mailto:joe.weinpert@gmail.com>> wrote: >>>>>>>> >>>>>>>> Cannot run surface() as a function to return a vnf array of the data to manipulate. >>>>>>>> >>>>>>>> Is there a BOSL function that can do what surface() does? >>>>>>>> >>>>>>>> If not, is there another library out there that will do it? >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
RD
Revar Desmera
Wed, May 11, 2022 10:41 PM

Sooooooo wanting this feature to finalize.

  • Revar

On May 10, 2022, at 9:48 PM, Jordan Brown openscad@jordan.maileater.net wrote:

On 5/10/2022 4:02 PM, Joe Weinpert wrote:

I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors.

The render() function-like mechanism will do that and more, when it's ready.

https://github.com/openscad/openscad/pull/3956 https://github.com/openscad/openscad/pull/3956


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Sooooooo wanting this feature to finalize. - Revar > On May 10, 2022, at 9:48 PM, Jordan Brown <openscad@jordan.maileater.net> wrote: > > On 5/10/2022 4:02 PM, Joe Weinpert wrote: >> I think that openSCAD having a way to import and use external STLs by handling them as data arrays would open up many doors. > > The render() function-like mechanism will do that and more, when it's ready. > > https://github.com/openscad/openscad/pull/3956 <https://github.com/openscad/openscad/pull/3956> > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org
JW
Joe Weinpert
Wed, May 11, 2022 11:01 PM

Yes.  Did that as top_half( z=.1 ) heightfield(...)

Worked great except for afterwards when you have to wait a few seconds each
time you click on something.  Once I comment out the top_half(), and rerun
it all works fine again.

On Wed, May 11, 2022 at 6:40 PM Revar Desmera revarbat@gmail.com wrote:

Well, you can do something like top_half() down(5) heightfield(…)

  • Revar

On May 10, 2022, at 8:59 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

What you suggested works perfectly!

Now I need to find a way to remove the first bottom row for these pics
where a zero (0) colored base is.  Square/rectangular pics obviously do not
have that problem.  Odd shapes like what I've been testing do.

Maybe it isn't a matter of removing ... maybe a way to ignore values of
zero, or something ... or maybe there is another BOSL2 command to simply
slice the bottom off.  I will look.

Thanks again.

On Tue, May 10, 2022 at 11:30 PM Revar Desmera revarbat@gmail.com wrote:

That warning just means it won’t cache the geometry for speed.  It’ll
still work.  It just may be slow.  You can increase the cache size in the
preferences dialog.

The image data will be from 0 to 255, but if you just divide the image
data array by the scalar 255, it will be scaled to the range 0.0 to 1.0.
ie:

include <BOSL2/std.scad>
include <image_data.scad>
heightfield(image_data/255, anchor=BOT);

  • Revar

On May 10, 2022, at 8:21 PM, Joe Weinpert joe.weinpert@gmail.com wrote:

Will use the anchor=BOT for now.

I am getting this warning whenever I run it:using that pic I've been
testing:

WARNING: GeometryEvaluator: Node didn't fit into cache.

Does that affect the program?

Also, when I set the maxz to something like 8 it gets wacky.  Z ends up
at 256 which obviously means it is using 256 (0-255) grays. One level for
each.

On Tue, May 10, 2022 at 11:00 PM Revar Desmera revarbat@gmail.com
wrote:

I tested using heightfield() with a 512x512 image, so I can verify it
works, though there is a possible bug in heightfield() that you can work
around by adding the argument `anchor=BOT’. I’ll fix that soon.

Yes -r uses pixel counts. If you do not give -r the data it outputs will
be for the original image size.

You can fix the pip warning with:

pip install --upgrade pip

-Revar

On May 10, 2022, at 6:50 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:


FYI

I only have Windows 7 and the latest python that runs on it is 3.8.10
which I downloaded and installed without a problem.

Did some hunting on Google and found what you are saying ... except ...
I only typed "pip install pillow" ... which it successfully did but with a
warning msg (shown in the attached pic).

And ...

I ran your mg2scad.py script and it ran instantly ... and I mean
instantly.  Created the scad height file.  Hopefully, BOSL2
heightfield() function can use it.  Haven't tried that yet.

My question, however, is the optional command -r WIDTHxHEIGHT.  How is
the WIDTHxHEIGHT determined?  Is it pixels?  The one I have been testing is
902 pixels wide by 1024 pixels.  Is that what I am looking for?  The
numbers do match the result columns and rows in the created scad file.
Columns being the WIDTH and rows (indices) being the height.

So far .. so good!

<installPip.png>

On Tue, May 10, 2022 at 9:22 PM Revar Desmera revarbat@gmail.com
wrote:

That should be pip install --upgrade Pillow with two dashes, not an
em-dash.  Thank you auto-correct who thinks it know best.

  • Revar

On May 10, 2022, at 6:19 PM, Revar Desmera revarbat@gmail.com wrote:

You need to install the Pillow library.  Usually this can be done
simplest from the command-line with the command:

pip install —upgrade Pillow

More info on installing Pillow:
https://pillow.readthedocs.io/en/latest/installation.html

  • Revar

On May 10, 2022, at 6:15 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

I am receiving this error msg when I run the script:

Line 10: ModuleNotFoundError: No module named 'PIL'

Any ideas?

On Tue, May 10, 2022 at 8:23 PM Revar Desmera revarbat@gmail.com
wrote:

Yes, save the script to the file img2scad.py.  I’m afraid that this
is just a command-line tool, and while it’s easy enough to use on Linux or
a Mac, I’m not truly sure about how to set up a command-line on Windows.  A
quick googling results in
https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which
may be helpful.

This script would probably better fit in a separate BOSL2-helpers
repository.

A GUI version is perfectly possible to do, but that may take me a
couple weeks to refresh my memory on how to do cross-platform.

  • Revar

On May 10, 2022, at 5:08 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Holy sh..!  How the heck do you write something THAT fast?

You have my thanks ... and in any way that this can be added to BOSL
as some sort of function would be something indeed!

I assume "mg2scad.py" is the file name to save the Python code as ...
and your usage example is "run command line" orientated.  But what do I
need on my desktop to run python apps?  I've never done a thing with Python
that I am aware of.

On Tue, May 10, 2022 at 7:51 PM Revar Desmera revarbat@gmail.com
wrote:

I wrote up a simple Python image-to-scadfile converter.  It’ll read
most common image types, convert them to Luminosity grayscale, with
optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD
source file.

  • Revar

Usage:
img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT

Script:

#!env python3

import re
import os
import sys
import os.path
import argparse

from PIL import Image

def img2scad(filename, varname, resize, outf):
indent = " " * 4
im = Image.open(filename).convert('L')
if resize:
print("Resizing to {}x{}".format(resize[0],resize[1]))
im = im.resize(resize)
pix = im.load()
width, height = im.size
print("// Image {} ({}x{})".format(filename, width, height),
file=outf)
print("{} = [".format(varname), file=outf)
line = indent
for x in range(width):
line += "[ "
for y in range(height):
line += "{:d}, ".format(pix[x,y])
if len(line) > 60:
print(line, file=outf)
line = indent * 2
line += " ],"
if line != indent:
print(line, file=outf)
line = indent
print("];", file=outf)
print("", file=outf)

def main():
parser = argparse.ArgumentParser(prog='img2scad')
parser.add_argument('-o', '--outfile',
help='Output .scad file.')
parser.add_argument('-v', '--varname',
help='Variable to use in .scad file.')
parser.add_argument('-r', '--resize',
help='Resample image to WIDTHxHEIGHT.')
parser.add_argument('infile', help='Input image file.')
opts = parser.parse_args()

 non_alnum = re.compile(r'[^a-zA-Z0-9_]')
 if not opts.varname:
     if opts.outfile:
         opts.varname =

os.path.splitext(os.path.basename(opts.outfile))[0]
opts.varname = non_alnum.sub("", opts.varname)
else:
opts.varname = "image_data"
size_pat = re.compile(r'^([0-9][0-9])x([0-9][0-9])$')
if opts.resize:
m = size_pat.match(opts.resize)
if not m:
print("Expected WIDTHxHEIGHT resize format.",
file=sys.stderr)
sys.exit(-1)
opts.resize = (int(m.group(1)), int(m.group(2)))

 if not opts.varname or non_alnum.search(opts.varname):
     print("Bad variable name: {}".format(opts.varname),

file=sys.stderr)
sys.exit(-1)

 if opts.outfile:
     with open(opts.outfile, "w") as outf:
         img2scad(opts.infile, opts.varname, opts.resize, outf)
 else:
     img2scad(opts.infile, opts.varname, opts.resize, sys.stdout)

 sys.exit(0)

if name == "main":
main()

On May 10, 2022, at 4:02 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

No doubt ... but  I never used Python.

I think that openSCAD having a way to import and use external STLs by
handling them as data arrays would open up many doors. There are thousands
upon thousands of STL files out there.  Heck, openSCAD is used
for parameter customizing on many within Thingiverse alone.  Currently I
use converter
https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html
to convert an STL to a PNG. Super super super basic ... but it does work
until I can find something else.

I will continue searching for a converter to take files like the
grayscale png picture I posted and make height data maps.  Maybe they will
work with the BOSL heightfield() function ... you never know.

On Tue, May 10, 2022 at 5:03 PM nop head nop.head@gmail.com wrote:

Python has libraries for everything so you should be able to read a
PNG as an image and not need to know the file structure.

On Tue, 10 May 2022 at 21:48, Joe Weinpert joe.weinpert@gmail.com
wrote:

Using surface( file = "Flourish_01b.png" ) on this png file:

<Flourish_01b.png>

results in this:

<result.png>

Except for the square base, I was surprised it even worked.

Attempting to use pre-built STL files in SCAD always seems to cause
a problem, so I wanted to try using grayscale images instead.

When using BOSL, I can create a nice vnf array from a sweep().
Works great.  I can then use *vnf_polyhedron() *to draw it or draw
copies and mirrors of it ... whatever.

This is why I was hoping for a function ... however ... as simple
as you say it can be ... I've never touched python in my life and never
dealt with the PNG file structure.

On Tue, May 10, 2022 at 4:23 PM Revar Desmera revarbat@gmail.com
wrote:

BOSL2 has a function/module called heightfield() that you can
feed an array of heights, or a function literal that can calculate the
heights dynamically.  However, there is currently no way for an OpenSCAD
script to read height values from an image file.  You can only generate 3D
geometry using surface().

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

Having said that, it should not be too difficult to write a Python
script to read in an image file, and have it write out a .scad source file
containing the array of height data.

  • Revar

On May 10, 2022, at 1:12 PM, Joe Weinpert joe.weinpert@gmail.com
wrote:

Cannot run surface() as a function to return a vnf array of the
data to manipulate.

Is there a BOSL function that can do what surface() does?

If not, is there another library out there that will do it?


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Yes. Did that as top_half( z=.1 ) heightfield(...) Worked great except for afterwards when you have to wait a few seconds each time you click on something. Once I comment out the top_half(), and rerun it all works fine again. On Wed, May 11, 2022 at 6:40 PM Revar Desmera <revarbat@gmail.com> wrote: > Well, you can do something like `top_half() down(5) heightfield(…)` > > - Revar > > > On May 10, 2022, at 8:59 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: > > What you suggested works perfectly! > > Now I need to find a way to remove the first bottom row for these pics > where a zero (0) colored base is. Square/rectangular pics obviously do not > have that problem. Odd shapes like what I've been testing do. > > Maybe it isn't a matter of removing ... maybe a way to ignore values of > zero, or something ... or maybe there is another BOSL2 command to simply > slice the bottom off. I will look. > > Thanks again. > > > > > > > On Tue, May 10, 2022 at 11:30 PM Revar Desmera <revarbat@gmail.com> wrote: > >> That warning just means it won’t cache the geometry for speed. It’ll >> still work. It just may be slow. You can increase the cache size in the >> preferences dialog. >> >> The image data will be from 0 to 255, but if you just divide the image >> data array by the scalar 255, it will be scaled to the range 0.0 to 1.0. >> ie: >> >> include <BOSL2/std.scad> >> include <image_data.scad> >> heightfield(image_data/255, anchor=BOT); >> >> >> - Revar >> >> >> On May 10, 2022, at 8:21 PM, Joe Weinpert <joe.weinpert@gmail.com> wrote: >> >> >> Will use the anchor=BOT for now. >> >> I am getting this warning whenever I run it:using that pic I've been >> testing: >> >> WARNING: GeometryEvaluator: Node didn't fit into cache. >> >> >> Does that affect the program? >> >> Also, when I set the maxz to something like 8 it gets wacky. Z ends up >> at 256 which obviously means it is using 256 (0-255) grays. One level for >> each. >> >> >> >> On Tue, May 10, 2022 at 11:00 PM Revar Desmera <revarbat@gmail.com> >> wrote: >> >>> I tested using `heightfield()` with a 512x512 image, so I can verify it >>> works, though there is a possible bug in `heightfield()` that you can work >>> around by adding the argument `anchor=BOT’. I’ll fix that soon. >>> >>> Yes -r uses pixel counts. If you do not give -r the data it outputs will >>> be for the original image size. >>> >>> You can fix the pip warning with: >>> >>> pip install --upgrade pip >>> >>> >>> -Revar >>> >>> >>> On May 10, 2022, at 6:50 PM, Joe Weinpert <joe.weinpert@gmail.com> >>> wrote: >>> >>>  >>> FYI >>> >>> I only have Windows 7 and the latest python that runs on it is 3.8.10 >>> which I downloaded and installed without a problem. >>> >>> Did some hunting on Google and found what you are saying ... except ... >>> I only typed "pip install pillow" ... which it successfully did but with a >>> warning msg (shown in the attached pic). >>> >>> And ... >>> >>> I ran your *mg2scad.py* script and it ran instantly ... and I mean >>> instantly. Created the scad height file. Hopefully, BOSL2 >>> *heightfield()* function can use it. Haven't tried that yet. >>> >>> My question, however, is the optional command -r WIDTHxHEIGHT. How is >>> the WIDTHxHEIGHT determined? Is it pixels? The one I have been testing is >>> 902 pixels wide by 1024 pixels. Is that what I am looking for? The >>> numbers do match the result columns and rows in the created scad file. >>> Columns being the WIDTH and rows (indices) being the height. >>> >>> So far .. so good! >>> >>> <installPip.png> >>> >>> >>> On Tue, May 10, 2022 at 9:22 PM Revar Desmera <revarbat@gmail.com> >>> wrote: >>> >>>> That should be `pip install --upgrade Pillow` with two dashes, not an >>>> em-dash. Thank you auto-correct who thinks it know best. >>>> >>>> - Revar >>>> >>>> >>>> On May 10, 2022, at 6:19 PM, Revar Desmera <revarbat@gmail.com> wrote: >>>> >>>> You need to install the Pillow library. Usually this can be done >>>> simplest from the command-line with the command: >>>> >>>> pip install —upgrade Pillow >>>> >>>> More info on installing Pillow: >>>> https://pillow.readthedocs.io/en/latest/installation.html >>>> >>>> - Revar >>>> >>>> >>>> >>>> On May 10, 2022, at 6:15 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>> wrote: >>>> >>>> I am receiving this error msg when I run the script: >>>> >>>> Line 10: ModuleNotFoundError: No module named 'PIL' >>>> >>>> >>>> Any ideas? >>>> >>>> >>>> On Tue, May 10, 2022 at 8:23 PM Revar Desmera <revarbat@gmail.com> >>>> wrote: >>>> >>>>> Yes, save the script to the file `img2scad.py`. I’m afraid that this >>>>> is just a command-line tool, and while it’s easy enough to use on Linux or >>>>> a Mac, I’m not truly sure about how to set up a command-line on Windows. A >>>>> quick googling results in >>>>> https://www.geeksforgeeks.org/how-to-install-python-on-windows/ which >>>>> may be helpful. >>>>> >>>>> This script would probably better fit in a separate BOSL2-helpers >>>>> repository. >>>>> >>>>> A GUI version is perfectly possible to do, but that may take me a >>>>> couple weeks to refresh my memory on how to do cross-platform. >>>>> >>>>> - Revar >>>>> >>>>> >>>>> On May 10, 2022, at 5:08 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>> wrote: >>>>> >>>>> Holy sh..! How the heck do you write something THAT fast? >>>>> >>>>> You have my thanks ... and in any way that this can be added to BOSL >>>>> as some sort of function would be something indeed! >>>>> >>>>> I assume "mg2scad.py" is the file name to save the Python code as ... >>>>> and your usage example is "run command line" orientated. But what do I >>>>> need on my desktop to run python apps? I've never done a thing with Python >>>>> that I am aware of. >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Tue, May 10, 2022 at 7:51 PM Revar Desmera <revarbat@gmail.com> >>>>> wrote: >>>>> >>>>>> I wrote up a simple Python image-to-scadfile converter. It’ll read >>>>>> most common image types, convert them to Luminosity grayscale, with >>>>>> optional re-sizing, and output it to a 2-dimensional array in a OpenSCAD >>>>>> source file. >>>>>> >>>>>> - Revar >>>>>> >>>>>> >>>>>> Usage: >>>>>> img2scad.py INFILE -o OUTSCADFILE -v VARNAME -r WIDTHxHEIGHT >>>>>> >>>>>> Script: >>>>>> >>>>>> #!env python3 >>>>>> >>>>>> import re >>>>>> import os >>>>>> import sys >>>>>> import os.path >>>>>> import argparse >>>>>> >>>>>> from PIL import Image >>>>>> >>>>>> >>>>>> def img2scad(filename, varname, resize, outf): >>>>>> indent = " " * 4 >>>>>> im = Image.open(filename).convert('L') >>>>>> if resize: >>>>>> print("Resizing to {}x{}".format(resize[0],resize[1])) >>>>>> im = im.resize(resize) >>>>>> pix = im.load() >>>>>> width, height = im.size >>>>>> print("// Image {} ({}x{})".format(filename, width, height), >>>>>> file=outf) >>>>>> print("{} = [".format(varname), file=outf) >>>>>> line = indent >>>>>> for x in range(width): >>>>>> line += "[ " >>>>>> for y in range(height): >>>>>> line += "{:d}, ".format(pix[x,y]) >>>>>> if len(line) > 60: >>>>>> print(line, file=outf) >>>>>> line = indent * 2 >>>>>> line += " ]," >>>>>> if line != indent: >>>>>> print(line, file=outf) >>>>>> line = indent >>>>>> print("];", file=outf) >>>>>> print("", file=outf) >>>>>> >>>>>> >>>>>> def main(): >>>>>> parser = argparse.ArgumentParser(prog='img2scad') >>>>>> parser.add_argument('-o', '--outfile', >>>>>> help='Output .scad file.') >>>>>> parser.add_argument('-v', '--varname', >>>>>> help='Variable to use in .scad file.') >>>>>> parser.add_argument('-r', '--resize', >>>>>> help='Resample image to WIDTHxHEIGHT.') >>>>>> parser.add_argument('infile', help='Input image file.') >>>>>> opts = parser.parse_args() >>>>>> >>>>>> non_alnum = re.compile(r'[^a-zA-Z0-9_]') >>>>>> if not opts.varname: >>>>>> if opts.outfile: >>>>>> opts.varname = >>>>>> os.path.splitext(os.path.basename(opts.outfile))[0] >>>>>> opts.varname = non_alnum.sub("", opts.varname) >>>>>> else: >>>>>> opts.varname = "image_data" >>>>>> size_pat = re.compile(r'^([0-9][0-9]*)x([0-9][0-9]*)$') >>>>>> if opts.resize: >>>>>> m = size_pat.match(opts.resize) >>>>>> if not m: >>>>>> print("Expected WIDTHxHEIGHT resize format.", >>>>>> file=sys.stderr) >>>>>> sys.exit(-1) >>>>>> opts.resize = (int(m.group(1)), int(m.group(2))) >>>>>> >>>>>> if not opts.varname or non_alnum.search(opts.varname): >>>>>> print("Bad variable name: {}".format(opts.varname), >>>>>> file=sys.stderr) >>>>>> sys.exit(-1) >>>>>> >>>>>> if opts.outfile: >>>>>> with open(opts.outfile, "w") as outf: >>>>>> img2scad(opts.infile, opts.varname, opts.resize, outf) >>>>>> else: >>>>>> img2scad(opts.infile, opts.varname, opts.resize, sys.stdout) >>>>>> >>>>>> sys.exit(0) >>>>>> >>>>>> >>>>>> if __name__ == "__main__": >>>>>> main() >>>>>> >>>>>> >>>>>> >>>>>> On May 10, 2022, at 4:02 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>>> wrote: >>>>>> >>>>>> No doubt ... but I never used Python. >>>>>> >>>>>> I think that openSCAD having a way to import and use external STLs by >>>>>> handling them as data arrays would open up many doors. There are thousands >>>>>> upon thousands of STL files out there. Heck, openSCAD is used >>>>>> for parameter customizing on many within Thingiverse alone. Currently I >>>>>> use converter >>>>>> <https://fenrus75.github.io/FenrusCNCtools/javascript/stl2png.html> >>>>>> to convert an STL to a PNG. Super super super basic ... but it does work >>>>>> until I can find something else. >>>>>> >>>>>> I will continue searching for a converter to take files like the >>>>>> grayscale png picture I posted and make height data maps. Maybe they will >>>>>> work with the BOSL heightfield() function ... you never know. >>>>>> >>>>>> >>>>>> On Tue, May 10, 2022 at 5:03 PM nop head <nop.head@gmail.com> wrote: >>>>>> >>>>>>> Python has libraries for everything so you should be able to read a >>>>>>> PNG as an image and not need to know the file structure. >>>>>>> >>>>>>> On Tue, 10 May 2022 at 21:48, Joe Weinpert <joe.weinpert@gmail.com> >>>>>>> wrote: >>>>>>> >>>>>>>> Using *surface( file = "Flourish_01b.png" )* on this png file: >>>>>>>> >>>>>>>> <Flourish_01b.png> >>>>>>>> >>>>>>>> results in this: >>>>>>>> >>>>>>>> <result.png> >>>>>>>> >>>>>>>> Except for the square base, I was surprised it even worked. >>>>>>>> >>>>>>>> Attempting to use pre-built STL files in SCAD always seems to cause >>>>>>>> a problem, so I wanted to try using grayscale images instead. >>>>>>>> >>>>>>>> When using BOSL, I can create a nice vnf array from a sweep(). >>>>>>>> Works great. I can then use *vnf_polyhedron() *to draw it or draw >>>>>>>> copies and mirrors of it ... whatever. >>>>>>>> >>>>>>>> This is why I was hoping for a function ... however ... as simple >>>>>>>> as you say it can be ... I've never touched python in my life and never >>>>>>>> dealt with the PNG file structure. >>>>>>>> >>>>>>>> >>>>>>>> On Tue, May 10, 2022 at 4:23 PM Revar Desmera <revarbat@gmail.com> >>>>>>>> wrote: >>>>>>>> >>>>>>>>> BOSL2 has a function/module called `heightfield()` that you can >>>>>>>>> feed an array of heights, or a function literal that can calculate the >>>>>>>>> heights dynamically. However, there is currently no way for an OpenSCAD >>>>>>>>> script to read height values from an image file. You can only generate 3D >>>>>>>>> geometry using `surface()`. >>>>>>>>> >>>>>>>>> >>>>>>>>> https://github.com/revarbat/BOSL2/wiki/shapes3d.scad#functionmodule-heightfield >>>>>>>>> >>>>>>>>> Having said that, it should not be too difficult to write a Python >>>>>>>>> script to read in an image file, and have it write out a .scad source file >>>>>>>>> containing the array of height data. >>>>>>>>> >>>>>>>>> - Revar >>>>>>>>> >>>>>>>>> >>>>>>>>> On May 10, 2022, at 1:12 PM, Joe Weinpert <joe.weinpert@gmail.com> >>>>>>>>> wrote: >>>>>>>>> >>>>>>>>> Cannot run surface() as a function to return a vnf array of the >>>>>>>>> data to manipulate. >>>>>>>>> >>>>>>>>> Is there a BOSL function that can do what surface() does? >>>>>>>>> >>>>>>>>> If not, is there another library out there that will do it? >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>>> >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> OpenSCAD mailing list >>>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> OpenSCAD mailing list >>>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>>> >>>>>>> _______________________________________________ >>>>>>> OpenSCAD mailing list >>>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> OpenSCAD mailing list >>>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>>> >>>>> _______________________________________________ >>>>> OpenSCAD mailing list >>>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >