Skip to main content

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

Project description

SDForge Logo

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 (|, -, &).
  • Real-time Rendering with Hot-Reloading: Get instant visual feedback in a lightweight native window powered by moderngl and glfw.
  • Mesh Exporting: Save your creations as .stl files for 3D printing or use in other software.
  • Flexible Scene Construction: Write custom SDF logic directly in GLSL, easily assign different materials to individual objects, etc.

Quick Start

from sdforge import *

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

# Subtract three cylinders along each axis
c = cylinder(0.5)
f -= c.orient(X) | c.orient(Y) | c.orient(Z)

# Render a live preview in a native window.
# With watch=True, the view will update when you save the file.
f.render(watch=True)

Advanced

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 *

# A standard library primitive
s = sphere(1.2)

# A custom shape defined with GLSL
# 'p' is the vec3 point in space
custom_twist = Forge("""
    float k = 10.0;
    float c = cos(k*p.y);
    float s = sin(k*p.y);
    mat2  m = mat2(c,-s,s,c);
    vec3  q = vec3(m*p.xz,p.y);
    return length(q) - 0.5;
""")

f = s - custom_twist

# Rendering and saving works out of the box
f.render()
f.save('example_forge.stl')

Camera Controls

You can override the default mouse-orbit camera to create cinematic animations or set a static viewpoint. The Camera object accepts GLSL expressions for its position and target, which will be updated every frame.

To use a custom camera, have your main function return a tuple containing your SDFObject and your Camera object.

from sdforge import *

def main():
    # A simple shape to look at
    shape = sphere(1) & box(1.5)

    # An animated camera that orbits around the origin
    cam = Camera(
        position=(
            "5.0 * sin(u_time * 0.5)",
            "3.0",
            "5.0 * cos(u_time * 0.5)"
        ),
        target=(0, 0, 0) # Look at the center
    )

    # For hot-reloading to work, the main function must return the shape and camera
    return shape, cam

if __name__ == '__main__':
    sdf_object, camera_object = main()
    sdf_object.render(camera=camera_object, watch=True)

Light Controls

You can customize the scene's lighting, including light position, ambient light, and shadow softness. The Light object accepts GLSL expressions for its properties, which will be updated every frame.

To use custom lighting, your main function can return a tuple containing your SDFObject, your Camera object, and your Light object.

from sdforge import *

# A simple shape to look at
shape = sphere(1) - cylinder(0.5)

# A standard orbiting camera
cam = Camera(position=("5.0 * sin(u_time * 0.5)", "3.0", "5.0 * cos(u_time * 0.5)"))

# An animated light source with soft shadows
lighting = Light(
    position=(
        "8.0 * sin(u_time * 0.3)",
        "5.0",
        "8.0 * cos(u_time * 0.3)"
    ),
    ambient_strength=0.05,
    shadow_softness="8.0 + 7.0 * sin(u_time * 0.7)"
)

# For hot-reloading, return all scene objects from main
def main():
    return shape, cam, lighting

if __name__ == '__main__':
    sdf_obj, cam_obj, light_obj = main()
    sdf_obj.render(camera=cam_obj, lighting=light_obj, watch=True)

Material Assignment

You can assign a unique color to any object or group of objects using the .color() method. The renderer will automatically handle combining the shapes and their materials correctly.

from sdforge import *

# Define shapes with different colors
red_sphere = sphere(0.8).color(1, 0, 0)
blue_box = box(1.2).color(0, 0, 1)

# Combine colored objects
# The union operation will correctly preserve the material of the closest surface
model = red_sphere | blue_box.translate(X * 0.5)

# You can also set a custom background color
model.render(bg_color=(0.1, 0.2, 0.3))

Render to File

You can save any static (non-animated) SDF model to an .stl file for 3D printing or use in other software. The .save() method uses the Marching Cubes algorithm to generate a mesh from the SDF.

from sdforge import *

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

# Subtract three cylinders along each axis
c = cylinder(0.5)
f -= c.orient(X) | c.orient(Y) | c.orient(Z)

# Save the model to a file
f.save('model.stl', samples=2**24) # Higher samples = more detail

Record Render

You can record the interactive session to an MP4 video file by passing the record argument to the .render() method. This requires the optional [record] dependencies.

from sdforge import *

# Animate a box size using the u_time uniform
f = box(size="0.5 + 0.3 * sin(u_time)")

# Render and record the output to a video file.
# Close the window to stop the recording.
f.render(record="animated_box.mp4")

Installation

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

pip install sdforge

To enable optional video recording features, install the [record] extra:

pip install sdforge[record]

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.1.0.tar.gz (21.1 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.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for sdforge-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1c4a9f849a57a1e8dd4307afc4d89820436fdbb8e3f20c87b4eeeb568eb9bd35
MD5 f28c37de4ac53076b9e3e87fe47ec5c3
BLAKE2b-256 1b1db9e35c9cbb13cb6c669f2635a6ea32a91f9f3e79a80d105743e75317f24e

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for sdforge-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dbe395a4c3e4a4d5fa1f5a9dd4657e26fa6db101b6567bfbaf3eb21949b1462f
MD5 e6164662ce80ba0b55c2c3bb7dfceb9a
BLAKE2b-256 85e66b63d53f234bd101d14d9deeda3497b756a11d6ff0efc9e4861f0bae3447

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