POV‑Ray img2mesh
Converting greyscale PNG and PNM into POV, OBJ, DXF and STL 3D mesh
Img2mesh is a pretty simple (well, it was initially) program that reads regular bitmap image, and writes 3D triangle mesh, using pixel X and Y coordinates for «east» and «south» position of 3D triangle mesh nodes, and, most important, pixel brightness as Z, that is, height of the node, thus converting image into sort of 3D landscape. Program is available at GitHub for download.


Source image (actual size) and resulting 3D object rendering (default texture). Due to unusual mesh building algorithm img2mesh provides smooth fine surface from just 64x64 px image.
Currently img2mesh support a variety of common input and output formats, briefly summarized below:
Input format | Output format |
---|---|
8 bpc and 16 bpc PNG, binary PGM, ascii PGM, binary PPM, ascii PPM |
POV-Ray, Wavefront OBJ, stereolithography ascii STL, ascii Autodesk DXF |
There is a substantial difference between POV, OBJ, DXF and STL output:
- POV‑Ray file is a scene file, containing triangle mesh, CSG difference of it with box (yes, mesh generated with img2mesh doesn't have gaps and is tight enough to correctly produce CSG), example textures (currently two overlaid textures with color gradient and equal height contour lines to simplify visual perception), light and camera;
- STL contains a single object, consisting of height field triangle mesh plus sides and bottom meshes to close the object as required by 3D printer;
- OBJ and DXF files contain just an object of height field triangle mesh with no extras, since these formats are intended to be imported into other software where all the bells and whistles are supposed to be added.

Screenshot of Windows Explorer window with test source PNG map and resulting output files preview side by side.
POV-Ray export provides most flexibility. One of the features of POV export is mapping. Maps are transfer functions z value is passed through. Result is similar to Photoshop or GIMP "Curves" applied to source heightfield image, except for that with img2mesh map is nondestructively applied to mesh within POV‑Ray, so you can change map and affect mesh rendering without changing the mesh itself.
Currently maps are represented by generalized linear spline curve. Descriptive part in the beginning of POV file generated look like this:
#declare Curve = function { spline { linear_spline 0.0, <0.0, 0> 0.25, <0.25, 0> 0.5, <0.5, 0> 0.75, <0.75, 0> 1.0, <1.0, 0>} } #declare map = function(c) {Curve(c).u}
First column contain input values, second column contain corresponding output values (third column currently is not used for anything good, just leave it alone). By default, input=output, that is, map does not change anything. However, you can edit it.



Left to right: source image, rendered result (default map), rendered result (map changed from 0.25, <0.25, 0> 0.75, <0.75, 0> to 0.75, <0.25, 0> 0.75, <0.25, 0>, i.e. the area between 1/4 and 3/4 of range was inverted (negative)).
Note that POV‑Ray does not pay attention to the order of control points appearance, so you can add midpoints after endpoints in no particular order. Just remember to have endpoints 0 and 1 defined, since POV‑Ray cannot use undefined functions; everything between 0 and 1 is up to you to edit. Beside that, you can change linear spline to other splines supported by POV‑Ray. Finally, nothing can stop you from writing your own non-spline maps. For example, #declare map = function(c) {int(4*c)/4} will give you function similar to Photoshop "Posterize" with 4 colors, while #declare map = function(c) {4*c-int(4*c)} is 4-teeth saw function.
Img2mesh may be used both for visualizing some actual elevation map and for rendering 3D appearance variant of a logo or other drawing.
Example image below was started as simple black and white drawing, converted to PNG, then some Gaussian Blur was applied in GIMP, resulting PNG fed to img2mesh, then exported POV file rendered with POV‑Ray.

Surely POV‑Ray can import PNG and use them as «heightfields» directly, but img2mesh uses rather unusual «pyramid» conversion algorithm, providing extra quality for small elevation maps (you can see it by smooth shiny surface without defect reflections in example above).
Default export to POV file suggests camera autofocus on object, object scaling to fit 1, 1, 1 cube, and suitable scene structuring for easy editing later.
Exported .POV file may be included intact as .INC into another scene, by setting a flag in the main scene file:
#declare Main = 1; #include "generated.pov" object {thething}
«Main» variable in master file turns off camera, light and texture in "generated.pov" file, allowing master file to take over.

For Windows users, compiled Windows 64‑bit exe file is available for download in Release section of GitHub. For other platforms, use Python sources - program is rather self-contained, all non-standard modules enclosed to download; in case downloaded program does not work right out of the box, you will be provided with replacement copy at no extra charge.
For developers: img2mesh currently restructured as image import modules and 3D export module list2mesh; the latter may be freely used by other software developers.
Step forward to img2mesh at GitHub for downloads.
or Move back to main page.