Skip to main content

DistForge Logo

DistForge

About

DistForge is a Python library for creating 3D models using Signed Distance Functions (SDFs). It provides a real-time, interactive rendering experience in a native desktop window, powered by GLSL raymarching.

Features

  • Simple, Pythonic API: Define complex shapes by combining primitives using standard operators (|, -, &) and chaining transformations.
  • Real-time Rendering with Hot-Reloading: Get instant visual feedback in a lightweight native window powered by moderngl and glfw. Changes to your script are reloaded automatically.
  • Mesh Exporting: Save your creations as .stl, .obj, or .glb files for 3D printing or use in other software.
  • Interactive Parameters: Define parameters that can be controlled by UI sliders in real-time (with a compatible UI renderer).
  • Standalone GLSL Export: Export your entire scene to a single, self-contained GLSL fragment shader for use in game engines or graphics applications.
  • Custom GLSL Primitives: Write custom SDF logic directly in GLSL using the Forge object for maximum flexibility and performance.

Getting Started

Hello Forge

Define a simple shape and open a real-time preview window with just a few lines of code.

from distforge import sphere, box

shape = sphere(1) & box(1.5)
shape.render()

Live Preview & Hot-Reloading

For an interactive workflow, wrap your scene definition in a main() function. When you save any changes to the file, the preview window will automatically update.

from distforge import box, sphere

def main():
    """
    While this script is running, try changing the values below and
    saving the file. The render window will update automatically.
    """
    box_size = 1.6
    sphere_radius = 1.2
    
    scene = box(box_size) | sphere(sphere_radius)
    return scene

if __name__ == "__main__":
    scene = main()
    scene.render()

Saving to a Mesh File

You can save any static model to an .stl, .obj, or .glb file. The .save() method uses the Marching Cubes algorithm to generate a mesh from the SDF.

from distforge import sphere, box

shape = box(1.5) - sphere(1.2)
shape.save('model.obj', samples=2**22)

Core Concepts

Primitives & Operations

Create complex objects by starting with primitives and combining them with Python's bitwise operators: | for union, & for intersection, and - for difference.

from distforge import sphere, box

b = box(1.5)
s = sphere(1.0)
scene = b - s
scene.render()

Transformations & Shaping

Chain methods to transform, shape, and repeat objects.

import numpy as np
from distforge import box, Y

b = box(size=(0.5, 2.5, 0.5))
scene = b.twist(3.0).rotate(Y, np.pi / 4)
scene.render()

Materials

You can assign a unique color to any object or group of objects using the .color() method.

from distforge import sphere, box

red_box = box(1.5).color(1.0, 0.2, 0.2)
blue_sphere = sphere(1.0).color(0.3, 0.5, 1.0)
scene = red_box - blue_sphere
scene.render()

Camera & Lighting

You can override the default interactive camera and lighting to set a static viewpoint or create specific lighting conditions by passing Camera and Light objects to the renderer.

from distforge import box, sphere, Camera, Light

def main():
    scene = box(1.5) | sphere(1.2)    
    cam = Camera(position=(4, 3, 4), target=(0, 0, 0), zoom=1.5)    
    light = Light(position=(4, 5, 3), shadow_softness=16.0)

    return scene, cam, light

if __name__ == '__main__':
    scene, cam, light = main()
    scene.render(camera=cam, light=light)

Advanced Usage

Interactive Parameters

Use Param objects to define interactive, real-time parameters for your model. A compatible UI-enabled renderer would show these as sliders. The default renderer will use their default values.

from distforge import box, Param

p_size = Param("Box Size", 0.8, 0.2, 2.0)
scene = box(size=p_size)
scene.render()

Custom GLSL with Forge

For complex or highly-performant shapes, you can write GLSL code directly. This object integrates perfectly with the rest of the API.

from distforge import sphere, Forge

s = sphere(1.2)
custom_box = Forge("""
    vec3 q = abs(p) - vec3(0.8);
    return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
""")
scene = s - custom_box
scene.render()

Standalone GLSL Export

Generate a complete, self-contained GLSL fragment shader for your scene. This file can be used directly in applications like Godot, TouchDesigner, or Three.js.

from distforge import box, sphere

scene = box(1.5) - sphere(1.2)
scene.export_shader("exported_shader.glsl")

Installation

1. System Dependencies

The live viewer relies on glfw, which may require you to install its system-level libraries first. This is a common first step before installing the Python package.

On Debian/Ubuntu:

sudo apt-get install libglfw3-dev

On macOS (with Homebrew):

brew install glfw

On Windows: glfw is generally bundled with the Python wheels, so no separate installation is typically needed.

2. Python Package

The library and its core dependencies can be installed using pip.

Standard Installation: This will install the core library, including numpy, moderngl, and glfw, enabling all fundamental features like modeling, live preview with hot-reloading, and exporting to .stl and .obj formats.

pip install distforge

Optional Features: For additional functionality, you can install "extras":

  • .glb Export: To enable saving models to the GLB format, a modern and efficient format for web and game engines.

    pip install "distforge[export]"
    
  • Interactive UI: To enable UI widgets like sliders for Param objects.

    pip install "distforge[ui]"
    
  • Full Installation: To install all optional features at once.

    pip install "distforge[full]"
    

Acknowledgements

This project is inspired by the simplicity and elegant API of Michael Fogleman's fogleman/sdf library. DistForge aims to build on that foundation by adding a real-time, interactive GLSL-powered renderer.

Metadata

Release files for distforge 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for distforge 1.0.0
File Size Uploaded
distforge-1.0.0.tar.gz 89.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for distforge 1.0.0
File Interpreter ABI Platform
distforge-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 199.8 kB

Release files / distforge-1.0.0.tar.gz

Download URL distforge-1.0.0.tar.gz
Size 89.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0f39fdf5882bd52e903ee45a907ae261cca3be277293391a3eb6832452718f96
BLAKE2b-256 checksum
How to use checksums
5646fface7ba1be92b35d6bd8ff556a0dcd117eae2f9691f0c7f8ba041779b49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / distforge-1.0.0-py3-none-any.whl

Download URL distforge-1.0.0-py3-none-any.whl
Size 110.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2661a36230db15b3a26b4d34f9995a645d4103177d19b8487064af5821e85356
BLAKE2b-256 checksum
How to use checksums
26994eb01dfdac83750b99f25a0008309906410d204d2e7ca0e4e9dbda777a09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page