{"id":26052523,"url":"https://github.com/qalle2/isometry","last_synced_at":"2026-07-04T06:05:22.957Z","repository":{"id":202639397,"uuid":"707806019","full_name":"qalle2/isometry","owner":"qalle2","description":"convert a voxel image to PNG/OpenSCAD","archived":false,"fork":false,"pushed_at":"2026-04-28T08:33:27.000Z","size":379,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-28T10:08:45.771Z","etag":null,"topics":["3d-graphics","command-line","isometry","openscad","python","voxel-graphics"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qalle2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-10-20T17:45:09.000Z","updated_at":"2026-04-28T08:33:31.000Z","dependencies_parsed_at":"2026-01-07T20:09:05.198Z","dependency_job_id":null,"html_url":"https://github.com/qalle2/isometry","commit_stats":null,"previous_names":["qalle2/isometry"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/qalle2/isometry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalle2%2Fisometry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalle2%2Fisometry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalle2%2Fisometry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalle2%2Fisometry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qalle2","download_url":"https://codeload.github.com/qalle2/isometry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qalle2%2Fisometry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35111450,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["3d-graphics","command-line","isometry","openscad","python","voxel-graphics"],"created_at":"2025-03-08T06:40:49.939Z","updated_at":"2026-07-04T06:05:22.952Z","avatar_url":"https://github.com/qalle2.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# isometry\n*This project has been moved to [Codeberg](https://codeberg.org/qalle/voxel). This version on GitHub will no longer be updated.*\n\nPrograms 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.\n\nTable of contents:\n* [3D coordinates](#3d-coordinates)\n* [voxel2png.py](#voxel2pngpy)\n* [voxel2scad.py](#voxel2scadpy)\n* [Voxel files](#voxel-files)\n* [Colour numbers](#colour-numbers)\n* [Other files](#other-files)\n\n## 3D coordinates\nAs in OpenSCAD, the Z axis is vertical.\n\nExamples without X rotation and increasing Z rotation from `voxel2png.py`:\n\n![examples without X rotation](example-xrot0.png)\n\nExamples with 45-degree X rotation and increasing Z rotation from `voxel2png.py`:\n\n![examples with 45-degree X rotation](example-xrot45.png)\n\nExamples of mirroring (none, along X axis, along Y axis, along Z axis) from `voxel2png.py`:\n\n![examples of mirroring with the letter P](example-mirroring.png)\n\n## voxel2png.py\nRenders a voxel file as a PNG image file without perspective. Requires the [Pillow](https://pypi.org/project/pillow/) module.\n\nCommand line arguments: *inputFile outputFile xRotation yRotation zRotation axesToMirror*\n* *inputFile*: voxel file to read (see \"voxel files\" below)\n* *outputFile*: image file to write (PNG; RGB or RGBA)\n* *xRotation*, *yRotation*, *zRotation*: how much to rotate the object around each axis:\n  * unit: 22.5 degrees (1/16 of a full turn)\n  * an integer between 0 and 15\n  * for *xRotation*, only even numbers are supported\n  * for *yRotation*, only multiples of 4 are supported\n* *axesToMirror*:\n  * a string consisting of the characters `X`, `Y` and `Z`; zero or one of each\n  * for each character, the object will be mirrored along that axis\n  * the order of the characters does not matter\n  * optional (default is no mirroring)\n  * case insensitive\n\nNote: all arguments except *axesToMirror* are required.\n\n## voxel2scad.py\nConverts a voxel file into an OpenSCAD file (`.scad`). Does not require Pillow.\n\nCommand line arguments: *inputFile combineColours removeHidden combineCubes allowOverlap*\n* *inputFile*: The voxel file to read. Required. See \"voxel files\" below.\n* *combineColours*: Make all opaque cubes the same colour? Optional. 0=no (default), 1=yes.\n* *removeHidden*: Remove hidden cubes? Optional. 0=no (default), 1=yes. Improves efficiency if combineCubes=0 but decreases it otherwise!\n* *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.\n* *allowOverlap*: Are combined cubes allowed to overlap with each other? Optional. 0=no, 1=yes (default). Improves efficiency. Has no effect if combineCubes=0.\n\nPrints the output data to `stdout` (screen).\n\n## Voxel files\n* Describes a 3D object using small cubes.\n* This format was developed by me; it's not used anywhere else as far as I know.\n* Encoding: UTF-8.\n* File extension: `.txt`\n* Case insensitive.\n* On each line, leading and trailing whitespace is ignored.\n* Lines that are ignored:\n  * empty lines\n  * comments (lines that start with `#`)\n* \"Setting\" lines:\n  * Each one on its own line, anywhere in the file.\n  * Object width in blocks: `W` immediately followed by an integer 1\u0026ndash;256. Required.\n  * Object depth in blocks: `D` immediately followed by an integer 1\u0026ndash;256. Required.\n  * Object height in blocks: `H` immediately followed by an integer 1\u0026ndash;256. Required.\n  * Redefine colours: `Cirrggbb` where `i` is the index (1 to 9) and `rrggbb` is 6 hexadecimal digits, `000000`\u0026ndash;`ffffff`.\n    Has no effect in `voxel2png.py`. Optional.\n* \"Block\" lines:\n  * Each line describes a slice of *objectWidth*\u0026times;1\u0026times;1 blocks of the object from left to right.\n  * Syntax of each line: a pipe (`|`) followed by up to *objectWidth* spaces or digits, plus optionally newline.\n  * A space or a `0` denotes \"no block\" (transparent) and `1`\u0026ndash;`9` denotes a block of that colour (see \"colour numbers\" below).\n  * If there are less than *objectWidth* spaces or digits, the rest of the line is implicitly padded with spaces or zeroes.\n  * The number of lines must be *objectHeight*\u0026times;*objectDepth*.\n  * Order of lines: first rear to front, then bottom to top. That is, each group of *objectDepth* lines represents a horizontal layer.\n\nAn example (a single black block):\n```\nW1\nD1\nH1\n|1\n```\n\nThere are more examples under `test-in/`\n\n## Colour numbers\nColour indexes used in voxel files:\n* 0: none (transparent)\n* 1: black\n* 2: red\n* 3: orange\n* 4: yellow\n* 5: green\n* 6: cyan\n* 7: blue\n* 8: magenta\n* 9: white\n\n## Other files\n`blocks.png` contains the building blocks (small cubes); it's read programmatically:\n\n![the building blocks](blocks.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqalle2%2Fisometry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqalle2%2Fisometry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqalle2%2Fisometry/lists"}