cuda-accelerated SDF slicing
Find a file
2026-09-25 18:09:19 +03:00
examples new 2026-09-25 18:09:19 +03:00
include new 2026-09-25 18:09:19 +03:00
python/cudaslicer new 2026-09-25 18:09:19 +03:00
src new 2026-09-25 18:09:19 +03:00
.gitignore new 2026-09-25 18:09:19 +03:00
benchy.stl new 2026-09-25 18:09:19 +03:00
CMakeLists.txt new 2026-09-25 18:09:19 +03:00
Makefile new 2026-09-25 18:09:19 +03:00
pyproject.toml new 2026-09-25 18:09:19 +03:00
README.md new 2026-09-25 18:09:19 +03:00
setup.py new 2026-09-25 18:09:19 +03:00

CUDA Slicer: GPU-Accelerated Slicing & Polygon Offsetting Library

Python Version CUDA License: MIT

A high-performance C/C++ and CUDA library with native Python bindings for Linux & Windows providing GPU-accelerated 2D/3D polygon offsetting, Jump Flooding Signed Distance Fields (JFA / SDF), and slicing for 3D printing, CAM, and computational geometry.


🚀 Benchmark Summary (3DBenchy, 239 Layers @ 0.20 mm)

Tested on NVIDIA RTX A4500 Laptop GPU (16 GB VRAM) vs 12th Gen Intel Core i7 CPU:

Pipeline Total Time (Mesh \to Offset Contours) Slicing / Offsetting Rate Speedup vs PrusaSlicer
100% GPU Direct Mesh Slicing (0.10 mm Pitch) 74.4 ms 3,212 layers/sec 57.47x Faster
100% GPU Direct Mesh Slicing (0.05 mm Pitch) 190.9 ms 1,252 layers/sec 22.55x Faster
Hybrid CPU Slicing + GPU JFA (0.05 mm Pitch) 739.4 ms 323 layers/sec 5.82x Faster
PrusaSlicer CLI Headless (CPU Baseline) 4,305.7 ms 55 layers/sec 1.00x (Baseline)

⚡ Key Optimizations Applied:

  • Stage 6 (Marching Squares Vectorization): Reduced from 72.5 ms down to 35.4 ms (2.05x faster / 6,751 layer/s) via zero-allocation discrete edge-table addressing, thread-local buffer reuse, and on-the-fly collinear point decimation (>95% vertex reduction).
  • Stage 5 (D2H Transfer): Reduced from 136.3 ms down to 4.5 ms (30x–48x faster) via GPU 32-bit bit-packing + page-locked pinned host DMA (cudaMallocHost).
  • Stage 3 (GPU JFA Distance Field): Reduced from 118.9 ms down to 52.8 ms (2.25x faster) via perimeter-band limited steps and integer arithmetic.

🐍 Python Package Integration

1. Installation

A. Install from Source (Linux & Windows)

Make sure you have NVIDIA CUDA Toolkit (11.5+ or 12.x) and a C++ compiler (GCC on Linux, MSVC 2019/2022 on Windows) installed:

# Clone the repository
cd cudaslicer

# Install directly with pip
pip install .

B. Build Wheel (.whl)

python -m pip install --upgrade build wheel
python -m build --wheel
# The wheel will be generated in dist/
# e.g., dist/cudaslicer-1.0.0-cp310-cp310-linux_x86_64.whl
# or dist/cudaslicer-1.0.0-cp310-cp310-win_amd64.whl

2. Python API Quickstart

A. Backend Selection & GPU Capability Check

import cudaslicer

# 1. Check if a CUDA GPU is present
if cudaslicer.has_cuda():
    print("CUDA GPU is active!")
else:
    print("Running in multi-threaded CPU compatibility mode.")

# 2. Control compute backend globally ('auto', 'cuda', 'cpu')
cudaslicer.set_backend("auto")  # Auto: use CUDA if available, fallback to CPU

B. Offsetting 2D Polygon Contours (Single Layer or Multi-Layer)

import numpy as np
import cudaslicer

# Define a polygon (e.g. 50x50 mm square)
poly = np.array([
    [10.0, 10.0],
    [60.0, 10.0],
    [60.0, 60.0],
    [10.0, 60.0]
], dtype=np.float32)

# Generate 2 inward perimeters (at -0.5*w and -1.5*w) and infill mask (at -2.0*w)
# pitch_mm defaults to 0.10 mm, backend defaults to 'auto'
layer = cudaslicer.offset_polygons(
    layers=[poly],
    perimeters_count=2,
    layer_width=0.45,
    pitch_mm=0.10,
    backend="auto"  # 'auto', 'cuda', or 'cpu'
)

# Unpack directly
perimeters, infill_mask = layer
print(f"Outer Perimeter 1 (-0.225mm): {len(perimeters[0])} loop(s)")
print(f"Inner Perimeter 2 (-0.675mm): {len(perimeters[1])} loop(s)")
print(f"Infill Region Mask (-0.900mm): shape {infill_mask.shape}, {infill_mask.sum()} px")

C. Offsetting 2D / 3D Occupancy Masks Directly

import numpy as np
import cudaslicer

# Create a 2D binary grid (e.g., 200 x 200 pixels)
mask = np.zeros((200, 200), dtype=np.uint8)
mask[40:160, 40:160] = 1

# Compute Euclidean perimeters and infill mask
perimeters, infill_mask = cudaslicer.offset_masks(
    masks=mask,
    perimeters_count=2,
    layer_width=0.45,
    pitch_mm=0.10,
    backend="auto"
)
print("Perimeters shape:", perimeters.shape) # (2, 200, 200)
print("Infill mask shape:", infill_mask.shape) # (200, 200)

D. End-to-End Mesh Slicing with Custom First Layer Height

import trimesh
import cudaslicer

mesh = trimesh.load("benchy.stl")

# 100% GPU Slicing & Perimeter Offsetting
layers = cudaslicer.slice_mesh(
    mesh_or_triangles=mesh,
    layer_height=0.20,
    first_layer_height=0.25, # custom first layer height
    perimeters_count=2,
    layer_width=0.45,
    pitch_mm=0.10            # default 0.10
)

print(f"Sliced {len(layers)} layers in GPU VRAM!")
layer_0 = layers[0] # First layer at Z = 0.25 mm
perims, infill_mask = layer_0
print(f"Layer 0 (Z = {layer_0.z} mm): {len(perims)} perimeters, infill mask: {infill_mask.shape}")

🛠️ Building Standalone C/C++ Libraries (Windows & Linux)

Linux Build (libcudaslicer_offset.so & .a)

mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(nproc)

Outputs:

  • Shared Library: build/lib/libcudaslicer_offset.so
  • Static Library: build/lib/libcudaslicer_offset.a
  • C Benchmark CLI: build/bin/gpu_slicer_c_bench

Windows Build (cudaslicer_offset.dll & .lib)

Open x64 Native Tools Command Prompt for VS 2022 and run:

mkdir build
cd build
cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release
cmake --build . --config Release

Outputs:

  • DLL: build/lib/Release/cudaslicer_offset.dll
  • Import Lib: build/lib/Release/cudaslicer_offset.lib
  • Benchmark: build/bin/Release/gpu_slicer_c_bench.exe

⚙️ Cross-Platform C API Reference (include/gpu_offset.h)

The public header provides a portable C API with __declspec(dllexport) / __declspec(dllimport) on Windows and default symbol visibility on Linux:

#include "gpu_offset.h"

// 1. Initialize GPU
gpu_offset_init(0);

// 2. Configure slicing & offsetting parameters
GpuOffsetConfig config = {
    .pitch_mm = 0.10f,             // default 0.10 mm
    .pad_mm = 1.5f,
    .perimeters_count = 2,         // 2 perimeter passes
    .layer_width = 0.45f,          // 0.45 mm extrusion width
    .first_layer_height = 0.25f,   // 0.25 mm first layer height
    .export_infill_mask = 1,       // generate 2D binary infill mask
    .use_gpu_rasterizer = 1
};

// 3. 100% Direct GPU Mesh Slicing & Offsetting
GpuLayerResult* results = NULL;
size_t num_layers = 0;
GpuOffsetStats stats = {0};

gpu_offset_slice_mesh_and_offset(
    triangles, num_triangles,
    min_x, min_y, min_z, max_x, max_y, max_z,
    0.20f, 0.25f, &config,
    &results, &num_layers, &stats
);

// Access perimeters and infill mask
for (size_t l = 0; l < num_layers; ++l) {
    float z = results[l].z_height;
    size_t num_perims = results[l].num_perimeters; // 2
    GpuContour* infill_cnts = results[l].infill.contours;
    uint8_t* infill_mask = results[l].infill.mask;
}

// 4. Cleanup
gpu_offset_free_results(results, num_layers);
gpu_offset_cleanup();

🔄 Automated CI/CD (GitHub Actions)

  • Building Linux Python wheels (manylinux_2_35_x86_64) across Python 3.9, 3.10, 3.11, 3.12.
  • Building Windows x64 Python wheels (win_amd64) across Python 3.9, 3.10, 3.11, 3.12.
  • Building standalone Linux .so and Windows .dll binaries as downloadable CI artifacts.

📄 License

MIT License. Free for commercial and research use.