https://github.com/qalle2/isometry
convert a voxel image to PNG/OpenSCAD
https://github.com/qalle2/isometry
3d-graphics command-line isometry openscad python voxel-graphics
Last synced: 23 days ago
JSON representation
convert a voxel image to PNG/OpenSCAD
- Host: GitHub
- URL: https://github.com/qalle2/isometry
- Owner: qalle2
- License: gpl-3.0
- Created: 2023-10-20T17:45:09.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2026-04-28T08:33:27.000Z (3 months ago)
- Last Synced: 2026-04-28T10:08:45.771Z (3 months ago)
- Topics: 3d-graphics, command-line, isometry, openscad, python, voxel-graphics
- Language: Python
- Homepage:
- Size: 370 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# isometry
*This project has been moved to [Codeberg](https://codeberg.org/qalle/voxel). This version on GitHub will no longer be updated.*
Programs that read a 3D image consisting of small cubes from a "voxel file" (see "voxel files" below) and output a rendered PNG image or an OpenSCAD file.
Table of contents:
* [3D coordinates](#3d-coordinates)
* [voxel2png.py](#voxel2pngpy)
* [voxel2scad.py](#voxel2scadpy)
* [Voxel files](#voxel-files)
* [Colour numbers](#colour-numbers)
* [Other files](#other-files)
## 3D coordinates
As in OpenSCAD, the Z axis is vertical.
Examples without X rotation and increasing Z rotation from `voxel2png.py`:

Examples with 45-degree X rotation and increasing Z rotation from `voxel2png.py`:

Examples of mirroring (none, along X axis, along Y axis, along Z axis) from `voxel2png.py`:

## voxel2png.py
Renders a voxel file as a PNG image file without perspective. Requires the [Pillow](https://pypi.org/project/pillow/) module.
Command line arguments: *inputFile outputFile xRotation yRotation zRotation axesToMirror*
* *inputFile*: voxel file to read (see "voxel files" below)
* *outputFile*: image file to write (PNG; RGB or RGBA)
* *xRotation*, *yRotation*, *zRotation*: how much to rotate the object around each axis:
* unit: 22.5 degrees (1/16 of a full turn)
* an integer between 0 and 15
* for *xRotation*, only even numbers are supported
* for *yRotation*, only multiples of 4 are supported
* *axesToMirror*:
* a string consisting of the characters `X`, `Y` and `Z`; zero or one of each
* for each character, the object will be mirrored along that axis
* the order of the characters does not matter
* optional (default is no mirroring)
* case insensitive
Note: all arguments except *axesToMirror* are required.
## voxel2scad.py
Converts a voxel file into an OpenSCAD file (`.scad`). Does not require Pillow.
Command line arguments: *inputFile combineColours removeHidden combineCubes allowOverlap*
* *inputFile*: The voxel file to read. Required. See "voxel files" below.
* *combineColours*: Make all opaque cubes the same colour? Optional. 0=no (default), 1=yes.
* *removeHidden*: Remove hidden cubes? Optional. 0=no (default), 1=yes. Improves efficiency if combineCubes=0 but decreases it otherwise!
* *combineCubes*: Combine cubes into larger cuboids? Optional. 0=no, 1=yes (default). Improves efficiency. If removeHidden=0, uses hidden cubes as "don't care" colours to improve efficiency even more.
* *allowOverlap*: Are combined cubes allowed to overlap with each other? Optional. 0=no, 1=yes (default). Improves efficiency. Has no effect if combineCubes=0.
Prints the output data to `stdout` (screen).
## Voxel files
* Describes a 3D object using small cubes.
* This format was developed by me; it's not used anywhere else as far as I know.
* Encoding: UTF-8.
* File extension: `.txt`
* Case insensitive.
* On each line, leading and trailing whitespace is ignored.
* Lines that are ignored:
* empty lines
* comments (lines that start with `#`)
* "Setting" lines:
* Each one on its own line, anywhere in the file.
* Object width in blocks: `W` immediately followed by an integer 1–256. Required.
* Object depth in blocks: `D` immediately followed by an integer 1–256. Required.
* Object height in blocks: `H` immediately followed by an integer 1–256. Required.
* Redefine colours: `Cirrggbb` where `i` is the index (1 to 9) and `rrggbb` is 6 hexadecimal digits, `000000`–`ffffff`.
Has no effect in `voxel2png.py`. Optional.
* "Block" lines:
* Each line describes a slice of *objectWidth*×1×1 blocks of the object from left to right.
* Syntax of each line: a pipe (`|`) followed by up to *objectWidth* spaces or digits, plus optionally newline.
* A space or a `0` denotes "no block" (transparent) and `1`–`9` denotes a block of that colour (see "colour numbers" below).
* If there are less than *objectWidth* spaces or digits, the rest of the line is implicitly padded with spaces or zeroes.
* The number of lines must be *objectHeight*×*objectDepth*.
* Order of lines: first rear to front, then bottom to top. That is, each group of *objectDepth* lines represents a horizontal layer.
An example (a single black block):
```
W1
D1
H1
|1
```
There are more examples under `test-in/`
## Colour numbers
Colour indexes used in voxel files:
* 0: none (transparent)
* 1: black
* 2: red
* 3: orange
* 4: yellow
* 5: green
* 6: cyan
* 7: blue
* 8: magenta
* 9: white
## Other files
`blocks.png` contains the building blocks (small cubes); it's read programmatically:
