{"id":15761765,"url":"https://github.com/johanmodin/spacecubes","last_synced_at":"2025-04-01T14:32:08.460Z","repository":{"id":65495595,"uuid":"581996788","full_name":"johanmodin/spacecubes","owner":"johanmodin","description":"A simple voxel renderer for 3D NumPy arrays","archived":false,"fork":false,"pushed_at":"2024-09-07T18:01:57.000Z","size":110,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-11T11:21:17.800Z","etag":null,"topics":["3d","easy","numpy","render","voxel"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johanmodin.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}},"created_at":"2022-12-25T08:17:11.000Z","updated_at":"2024-09-07T17:59:05.000Z","dependencies_parsed_at":"2024-10-25T10:14:50.371Z","dependency_job_id":"7cbae0a0-3a34-4dfe-b14c-6126a7cd796d","html_url":"https://github.com/johanmodin/spacecubes","commit_stats":{"total_commits":43,"total_committers":2,"mean_commits":21.5,"dds":0.2558139534883721,"last_synced_commit":"fe2dbac840444d61c394a0d730dc053740200430"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanmodin%2Fspacecubes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanmodin%2Fspacecubes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanmodin%2Fspacecubes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johanmodin%2Fspacecubes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johanmodin","download_url":"https://codeload.github.com/johanmodin/spacecubes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246604613,"owners_count":20804100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","easy","numpy","render","voxel"],"created_at":"2024-10-04T11:04:12.789Z","updated_at":"2025-04-01T14:32:08.110Z","avatar_url":"https://github.com/johanmodin.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# spacecubes\n## Overview\n*spacecubes* is a simple voxel renderer for three-dimensional NumPy arrays. It is made to be easy to use and allowing fast visualization. It is not made to produce good looking images or be feature rich.\n\n### Installation\n`pip install 'spacecubes[all]'`\n\n## Demo\n![Alt Text](https://media.giphy.com/media/1XADnkAnPnnw2YyCAg/giphy.gif)\n\nBelow is how the Windows 95 screensaver-esque demo was created using spacecubes ([examples/screensaver_opencv](examples/screensaver_opencv.py)).\n```python\nimport numpy as np\nfrom spacecubes import Camera\nfrom spacecubes.io_devices import OpenCV\n\nworld = np.zeros((50, 50, 100))\ncolor_mask = np.random.randint(0, 1000, size=world.shape)\nrandom_mask = np.random.random(size=world.shape)\nworld[random_mask \u003c 0.001] = color_mask[random_mask \u003c 0.001]\ncolors = {i: np.random.random(3) * 255 for i in range(1, 1000)}\ndevice = OpenCV(colors, resolution=(1080, 1920))\ncamera = Camera(x=25, y=25, z=0)\ncamera.look_at(x=25, y=25, z=100)\nwhile True:\n    if camera.position[-1] \u003e 1:\n        camera.move_xyz(z=-1)\n        world = np.roll(world, -1, axis=-1)\n    camera.move(forward=0.1)\n    device.render(world, camera)\n```\n\nYou can also render directly to the terminal. In this case, colored spaces are used as pixels. This is the ([examples/screensaver_terminal](examples/screensaver_terminal.py)) script, which runs the same demo as above but rendered directly in the terminal using curses. The resolution is changed by setting the font size (e.g., CTRL +, CTRL -) in the terminal, which is what happens when the window flickers. After closing the script, you may have to run `reset` to reset the terminal state.\n\n![Alt Text](https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExcDhwN2FpODExMzVxaGgzZTc1aHVxdHNyeTczcW1zN3R5eHpienY2YyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/XW4vLbJC6gggCeY8l7/giphy.gif)\n\n\n## Examples\nRendering a single voxel (cube) in OpenCV and flying the camera around it can be done by running:\n```python\nimport numpy as np\nfrom spacecubes import Camera\nfrom spacecubes.io_devices import OpenCV\n\nworld = np.ones((1, 1, 1))\ncamera = Camera(x=-1, y=-1, z=-1)\ncolors = {1: (0, 255, 0)}\ndevice = OpenCV(colors, resolution=(1080, 1920))\nwhile True:\n    camera.move(up=0.01, right=0.01)\n    camera.look_at(x=0, y=0, z=0)\n    device.render(world, camera)\n```\n\nOther examples with more a fleshed out description can be found in the [examples](examples) directory.\n\n## Features\nAny NumPy array with 3 dimensions can be rendered. All non-zero values in the array are considered voxels, while elements with value 0 will be treated as empty space.\n\n### IO Devices\nAn IO Device in spacecubes is what (optionally) [handles user input](examples/interactive_camera.py) and definitely handles image frame output. The output can be done e.g., through visualization or raw dump. The IO Device needs to know what colors to map each value in the numpy array with, which is what the `colors` argument does. The available io_devices are specified below along with how they are used:\n```python\nfrom spacecubes.io_devices import OpenCV, Raw, Terminal\nfrom spacecubes import Camera\nimport numpy as np\nworld = np.ones((1,1,1))\ncamera = Camera()\n\n# Output the frame using OpenCV imshow\nopencv_device = OpenCV(colors={i: (0, 255, 0) for i in range(1, 100)}, resolution=(1080, 1920))\nopencv_device.render(world, camera)\n\n# Returns the frame as an numpy array\nraw_device = Raw(colors={i: (0, 255, 0) for i in range(1, 100)}, resolution=(1080, 1920))\nframe = raw_device.render(world, camera)\n\n# Outputs the frame directly in the terminal using ncurses\nterminal_device = Terminal(colors={i: 5 for i in range(1, 100)})\nterminal_device.render(world, camera)\n```\n\nTo render the output on the IO device, `device.render(world, camera)` is used, where world is a 3D NumPy array and Camera is..\n\n### Camera\nCamera is the object that handles the virtual camera which specifies the perspective through which the image is rendered. It supports some functions\nrelated to moving, rotating and looking at world locations:\n```python\nfrom spacecubes import Camera\n\n# Initialize a camera along with some world position\ncamera = Camera(x=1, y=2, z=3)\n\n# Move the camera 1 unit back from the camera's perspective\ncamera.move(up=0, forward=-1, right=0)\n\n# Move the camera -1 unit along the world y-axis\ncamera.move_xyz(x=0, y=-1, z=0)\n\n# Move the camera to a specified world position (0, 5, 0)\ncamera.move_to_xyz(x=0, y=5, z=0)\n\n# The camera can be rotated manually through yaw, pitch and roll given in radians\ncamera.rotate(yaw=-3.14/2, pitch=0, roll=0)\n\n# Make the camera look at a specified world location (3, 5, 2)\ncamera.look_at(x=3, y=5, z=2)\n\n# If camera.look_at is too snappy, the same can be done but interpolated.\n# This is done by supplying an amount, which is a fraction between\n# 0 and 1 that specifies where in the interpolation between the current camera\n# pose and the target camera pose that the camera should look\nfor interp_amount in range(100):\n    camera.look_at_interpolated(x=3, y=5, z=2, amount=interp_amount / 100)\n    device.render(world, camera)\n```\n\n## Installation tags\nspacecubes can be installed using tags that specify which visualization packages to include. `all` will include all visualization packages, e.g., OpenCV. If no tag is specified, only `Raw` and `Terminal` IO devices can be used.\n\nPyPI tags (with apostrophes added for the packages with brackets to be installable in e.g., zsh shells): \n- `spacecubes`\n- `'spacecubes[opencv]'`\n- `'spacecubes[all]'`\n\n\n### Dependencies:\n- numpy\n- pyquaternion\n- opencv-python (optional)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohanmodin%2Fspacecubes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohanmodin%2Fspacecubes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohanmodin%2Fspacecubes/lists"}