Skip to main content

A Python library for SDF modeling with real-time GLSL rendering and mesh export.

Project description

SDForge Logo

About

SDF Forge 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 sdforge import sphere, box

# A sphere intersected with a box
shape = sphere(1) & box(1.5)

# Render a preview in a native window.
# An interactive orbit camera is used by default.
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 sdforge 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.5
    sphere_radius = 1.2
    
    scene = box(box_size, radius=0.1) | sphere(sphere_radius)
    return scene

if __name__ == "__main__":
    # The render() function automatically enables hot-reloading by default
    # and looks for a `main` function in this file to call upon reload.
    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 sdforge import sphere, box

# A box with a sphere carved out of it
shape = box(1.5) - sphere(1.2)

# Save the model. Higher samples = more detail.
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 sdforge import sphere, box

# A box with a sphere carved out of it.
b = box(size=1.5)
s = sphere(r=1.0)
scene = b - s

scene.render()

Transformations & Shaping

Chain methods to transform, shape, and repeat objects.

import numpy as np
from sdforge import box, Y

# A tall box
b = box(size=(0.5, 2.5, 0.5))

# Twist it around the Y-axis
# The 'k' parameter controls the amount of twist.
scene = b.twist(k=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 sdforge import sphere, box

# A blue sphere is subtracted from a red box.
red_box = box(1.5, radius=0.1).color(1.0, 0.2, 0.2)
blue_sphere = sphere(1.2).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 sdforge import box, sphere, Camera, Light

def main():
    scene = box(1.5, radius=0.1) | sphere(1.2)
    
    # A camera positioned at (4, 3, 4), looking at the origin.
    cam = Camera(position=(4, 3, 4), target=(0, 0, 0), zoom=1.5)
    
    # A light source with soft shadows
    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 sdforge import box, Param

# Create Param objects to control different aspects of the scene.
# Param(name, default_value, min_value, max_value)
p_size = Param("Box Size", 0.8, 0.2, 2.0)
p_radius = Param("Corner Radius", 0.1, 0.0, 0.5)

# Use the Param objects just like regular numbers.
scene = box(size=p_size, radius=p_radius)

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 sdforge import sphere, Forge

# A standard library primitive
s = sphere(1.2)

# A custom shape defined with GLSL
# 'p' is the vec3 point in space
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);
""")

# The Forge object can be combined like any other shape
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 sdforge import box, sphere

scene = box(1.5, radius=0.1) - sphere(1.2)

# This single call generates the entire shader file.
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 sdforge

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 "sdforge[export]"
    
  • Interactive UI: To enable UI widgets like sliders for Param objects.

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

    pip install "sdforge[full]"
    

Acknowledgements

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sdforge-0.2.1.tar.gz (89.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sdforge-0.2.1-py3-none-any.whl (112.2 kB view details)

Uploaded Python 3

File details

Details for the file sdforge-0.2.1.tar.gz.

File metadata

  • Download URL: sdforge-0.2.1.tar.gz
  • Upload date:
  • Size: 89.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for sdforge-0.2.1.tar.gz
Algorithm Hash digest
SHA256 f25bb042330c5ac9198c5f4ec5c2530bb26841e4f66b5f6c5ff3eeba01dae230
MD5 761425e7a225cfd9d8d3cfbd63e8e65a
BLAKE2b-256 bb28c5733f77e177157c30b7d4a99688775dcd196df1b77b97fe2bf41c9a6dff

See more details on using hashes here.

File details

Details for the file sdforge-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: sdforge-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 112.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for sdforge-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d4c2dbfca1900603c86b38b240624bf2bb5e060c1bcc5127bb327b636df93cab
MD5 983219b30ac93c06cb68d4dd559a9eb2
BLAKE2b-256 22f6b9b1f0229a3fa06cacd3d66cec97c80fb4467bddbd9cf99b42e1e7df883d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page