DeepSDFStruct.SDF#

Signed Distance Function (SDF) Base Classes and Operations#

This module provides the foundational classes and utilities for working with Signed Distance Functions (SDFs) in DeepSDFStruct. SDFs are implicit geometric representations that encode the distance from any point in space to the nearest surface, with the sign indicating whether the point is inside (negative) or outside (positive) the geometry.

Key Features#

SDFBase Abstract Class

Base class for all SDF representations with support for: - Spline-based geometric deformations - Spatially-varying parametrization - Boundary conditions and capping - Boolean operations (union, intersection) - Differentiable operations for optimization

SDFfromMesh

Convert triangular surface meshes to SDF representations using fast winding number algorithms for robust inside/outside testing.

SDFfromDeepSDF

Neural network-based SDF using trained DeepSDF models for complex, learned geometric representations.

Union and Intersection

Combine multiple SDFs using smooth boolean operations with configurable smoothing for differentiable geometry.

Utility Functions
  • Grid sampling for SDF evaluation

  • Gradient computation for normal vectors

  • Boundary condition application

The module enables flexible construction and manipulation of complex 3D geometries in a differentiable framework suitable for optimization, simulation, and machine learning applications.

Examples

Create and evaluate an SDF from a mesh:

import trimesh
from DeepSDFStruct.SDF import SDFfromMesh

mesh = trimesh.load('model.stl')
sdf = SDFfromMesh(mesh)

# Query SDF values
points = torch.rand(1000, 3)
distances = sdf(points)

Combine SDFs with boolean operations:

from DeepSDFStruct.sdf_primitives import SphereSDF
from DeepSDFStruct.SDF import Union

sphere1 = SphereSDF([0, 0, 0], radius=1.0)
sphere2 = SphereSDF([1, 0, 0], radius=1.0)
combined = Union([sphere1, sphere2], smoothing=0.1)

Functions

generate_plane_points(origin, normal, res, ...)

Generate evenly spaced points on a plane in 3D space.

get_equidistant_grid_sample(bounds, grid_spacing)

Generates an equidistant 3D grid of points within the given bounding box.

normalize_mesh_to_unit_cube(mesh[, ...])

Transform mesh coordinates uniformly to [-1, 1] in all axes.

point_segment_distance(P1, P2, query_points)

Calculates the minimum distance from one or more query points to one or more line segments defined by endpoints P1 and P2.

project_bounds(origin, normal[, bounds])

Project 3D AABB bounds onto a slice plane and return 2D limits.

union_numpy(D[, k])

D: np.array of shape (num_points, num_geometries) k: smoothness parameter

union_torch(D[, k])

D: np.array of shape (num_points, num_geometries) k: smoothness parameter

Classes

BoxSDF([box_size, center])

CapBorderDict

A dictionary type describing boundary conditions ("caps") for each axis direction (x, y, z).

CapType

CappedBorderSDF(sdf[, cap_border_dict, scale])

Applies planar boundary caps to another SDF.

DifferenceSDF(obj1, obj2)

Subtracts objs2 from obj1

NegatedCallable(obj)

SDF2D(obj, axes[, offset])

SDFBase([parametrization, geometric_dim])

Abstract base class for Signed Distance Functions with optional deformation and parametrization.

SDFfromDeepSDF(model[, max_batch])

SDFfromLineMesh(line_mesh, thickness[, ...])

SDFfromMesh(mesh[, dtype, flip_sign, scale, ...])

Create an SDF from a triangle mesh using closest-point queries.

SummedSDF(obj1, obj2)

TransformedSDF(sdf[, rotationMatrix, ...])

Generic SDF wrapper that applies a transformation to the input queries.

UnionSDF(obj1, obj2)

class DeepSDFStruct.SDF.BoxSDF(box_size=1, center=tensor([0, 0, 0]))#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:
  • box_size (float)

  • center (torch._VariableFunctionsClass.tensor)

class DeepSDFStruct.SDF.CapBorderDict#

Bases: TypedDict

A dictionary type describing boundary conditions (“caps”) for each axis direction (x, y, z).

Each key (x0, x1, y0, y1, z0, z1) corresponds to one boundary face of a 3D domain, and maps to a dictionary with two fields:

  • cap (int): Type of cap applied (e.g., -1 = none, 1 = active).

  • measure (float): Numerical measure associated with the cap (e.g., thickness, scaling factor, tolerance).

Example

>>> caps: CapBorderDict = {
...     "x0": {"cap": 1, "measure": 0.02},
...     "x1": {"cap": 1, "measure": 0.02},
...     "y0": {"cap": 1, "measure": 0.02},
...     "y1": {"cap": 1, "measure": 0.02},
...     "z0": {"cap": 1, "measure": 0.02},
...     "z1": {"cap": 1, "measure": 0.02},
... }
x0: DeepSDFStruct.SDF.CapType = {'cap': -1, 'measure': 0}#
x1: DeepSDFStruct.SDF.CapType = {'cap': -1, 'measure': 0}#
y0: DeepSDFStruct.SDF.CapType = {'cap': -1, 'measure': 0}#
y1: DeepSDFStruct.SDF.CapType = {'cap': -1, 'measure': 0}#
z0: DeepSDFStruct.SDF.CapType = {'cap': -1, 'measure': 0}#
z1: DeepSDFStruct.SDF.CapType = {'cap': -1, 'measure': 0}#
class DeepSDFStruct.SDF.CapType#

Bases: TypedDict

cap: int#
measure: float#
class DeepSDFStruct.SDF.CappedBorderSDF(sdf, cap_border_dict=None, scale=(1, 1, 1))#

Bases: DeepSDFStruct.SDF.SDFBase

Applies planar boundary caps to another SDF.

Parameters:
cap_border_dict: DeepSDFStruct.SDF.CapBorderDict#
class DeepSDFStruct.SDF.DifferenceSDF(obj1, obj2)#

Bases: DeepSDFStruct.SDF.SDFBase

Subtracts objs2 from obj1

Parameters:
class DeepSDFStruct.SDF.NegatedCallable(obj)#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:

obj (DeepSDFStruct.SDF.SDFBase)

class DeepSDFStruct.SDF.SDF2D(obj, axes, offset=0.0)#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:
obj: DeepSDFStruct.SDF.SDFBase#
class DeepSDFStruct.SDF.SDFBase(parametrization=None, geometric_dim=3)#

Bases: torch.nn.modules.module.Module, abc.ABC

Abstract base class for Signed Distance Functions with optional deformation and parametrization.

This class provides the foundation for all SDF representations in DeepSDFStruct. SDFs represent geometry as an implicit function that returns the signed distance from any query point to the nearest surface. Negative values indicate points inside the geometry, positive values indicate points outside, and zero indicates points on the surface.

The class supports: - Optional spline-based deformations for smooth transformations - Parametrization functions for spatially-varying properties - Composition operations (union, intersection) via overloading

Parameters:
  • parametrization (torch.nn.Module, optional) – A function that provides spatially-varying parameters for the SDF (e.g., varying thickness in a lattice).

  • geometric_dim (int, default 3) – Geometric dimension of the SDF (2 or 3).

Notes

Subclasses must implement: - _compute(queries): Calculate SDF values for query points - _get_domain_bounds(): Return the bounding box of geometry

Examples

>>> from DeepSDFStruct.sdf_primitives import SphereSDF
>>> import torch
>>>
>>> # Create a sphere SDF
>>> sphere = SphereSDF(center=[0, 0, 0], radius=1.0)
>>>
>>> # Query SDF values
>>> points = torch.tensor([[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]])
>>> distances = sphere(points)
>>> print(distances)  # [-1.0, 1.0] (inside, outside)
forward(queries)#

Evaluate the SDF at given query points.

This method validates input, computes SDF values using the subclass implementation, and applies optional boundary conditions and capping.

Parameters:

queries (torch.Tensor) – Query points of shape (N, 2) for 2D or (N, 3) for 3D, where N is the number of points to evaluate.

Returns:

Signed distance values of shape (N, 1). Negative values indicate points inside the geometry, positive values outside.

Return type:

torch.Tensor

Raises:
  • ValueError – If queries have invalid shape.

  • RuntimeError – If SDF computation returns invalid output.

geometric_dim: int#
get_device()#

Return the device of the first parameter or buffer in this module.

If the module has no parameters and no buffers, returns cpu.

get_dtype()#

Return the dtype of the first parameter or buffer in this module.

If the module has no parameters and no buffers, returns float32.

plot_slice(origin=(0, 0, 0), normal=(0, 0, 1), res=(100, 100), ax=None, clim=(-1, 1), cmap='seismic', show_zero_level=True, deformation_function=None)#

Plot a 2D slice through an SDF as a contour plot.

This function evaluates an SDF on a planar grid and visualizes the signed distance values using a color map. The zero level set (the actual surface) can be highlighted with a contour line.

Parameters:
  • fun (callable) – The SDF function to visualize. Should accept a torch.Tensor of shape (N, 3) and return distances of shape (N, 1).

  • origin (tuple of float, default (0, 0, 0)) – A point on the slice plane.

  • normal (tuple of float, default (0, 0, 1)) – Normal vector of the slice plane. Currently supports only axis-aligned planes: (1,0,0), (0,1,0), or (0,0,1).

  • res (tuple of int, default (100, 100)) – Resolution of the slice grid (num_points_u, num_points_v).

  • ax (matplotlib.axes.Axes, optional) – Axes to plot on. If None, creates a new figure.

  • xlim (tuple of float, default (-1, 1)) – Range along the first plane axis.

  • ylim (tuple of float, default (-1, 1)) – Range along the second plane axis.

  • clim (tuple of float, default (-1, 1)) – Color map limits for distance values.

  • cmap (str, default 'seismic') – Matplotlib colormap name.

  • show_zero_level (bool, default True) – If True, draws a black contour line at distance=0 (the surface).

  • deformation_function (callable, optional) – Deformation mapping from parametric to physical space. If given, sample points are deformed before SDF evaluation and plotting.

Returns:

fig, ax – Only returned if ax was None (i.e., a new figure was created).

Return type:

matplotlib.figure.Figure, matplotlib.axes.Axes

Examples

>>> from DeepSDFStruct.sdf_primitives import SphereSDF
>>> from DeepSDFStruct.plotting import plot_slice
>>> import matplotlib.pyplot as plt
>>>
>>> # Create a sphere
>>> sphere = SphereSDF(center=[0, 0, 0], radius=0.5)
>>>
>>> # Plot XY slice at z=0
>>> fig, ax = plot_slice(
...     sphere,
...     origin=(0, 0, 0),
...     normal=(0, 0, 1),
...     res=(200, 200)
... )
>>> plt.title("XY Slice of Sphere")
>>> plt.show()

Notes

The ‘seismic’ colormap is well-suited for SDFs as it uses blue for negative (inside) and red for positive (outside), with white near zero.

to2D(axes, offset=0.0)#

Converts SDF to 2D

Parameters:
  • axis – list of axes that will be used for the 2D

  • axes (list[int])

class DeepSDFStruct.SDF.SDFfromDeepSDF(model, max_batch=32768)#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:

model (DeepSDFStruct.deep_sdf.models.DeepSDFModel)

set_latent_vec(latent_vec)#

Set conditioning parameters for the model (e.g., latent code).

Parameters:

latent_vec (torch.Tensor)

class DeepSDFStruct.SDF.SDFfromLineMesh(line_mesh, thickness, smoothness=0)#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:

line_mesh (gustaf.edges.Edges)

line_mesh: gustaf.edges.Edges#
class DeepSDFStruct.SDF.SDFfromMesh(mesh, dtype=<class 'numpy.float32'>, flip_sign=False, scale=True, threshold=1e-05, backend='igl')#

Bases: DeepSDFStruct.SDF.SDFBase

Create an SDF from a triangle mesh using closest-point queries.

This class wraps a triangle mesh and computes signed distances by finding the closest point on the mesh surface to each query point. The sign is determined using winding number or ray casting to determine inside/outside.

The mesh can be optionally normalized to fit within a unit cube centered at the origin, which is useful for consistent scaling across different geometries.

Parameters:
  • mesh (trimesh.Trimesh or gustaf.faces.Faces) – The input triangle mesh. If a gustaf Faces object is provided, it will be converted to a trimesh object.

  • dtype (numpy dtype, default np.float32) – Data type for distance calculations.

  • flip_sign (bool, default False) – If True, flips the sign of the computed distances (inside becomes outside and vice versa).

  • scale (bool, default True) – If True, normalizes the mesh to fit within a unit cube [-1, 1]^3 centered at the origin.

  • threshold (float, default 1e-5) – Small threshold value for numerical stability in distance computations.

mesh#

The (possibly normalized) triangle mesh.

Type:

trimesh.Trimesh

dtype#

Data type used for calculations.

Type:

numpy dtype

flip_sign#

Whether distances are sign-flipped.

Type:

bool

threshold#

Numerical threshold for stability.

Type:

float

Notes

This class uses libigl for efficient closest-point queries and embree for ray intersection tests to determine inside/outside status.

Examples

>>> import trimesh
>>> from DeepSDFStruct.SDF import SDFfromMesh
>>> import torch
>>>
>>> # Load or create a mesh
>>> mesh = trimesh.creation.box(extents=[1, 1, 1])
>>>
>>> # Create SDF from mesh
>>> sdf = SDFfromMesh(mesh, scale=True)
>>>
>>> # Query distances
>>> points = torch.tensor([[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]])
>>> distances = sdf(points)
class DeepSDFStruct.SDF.SummedSDF(obj1, obj2)#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:
class DeepSDFStruct.SDF.TransformedSDF(sdf, rotationMatrix=None, translation=None, scaleFactor=None)#

Bases: DeepSDFStruct.SDF.SDFBase

Generic SDF wrapper that applies a transformation to the input queries. Transformation can be rotation, translation, or scaling.

Parameters:

sdf (DeepSDFStruct.SDF.SDFBase)

class DeepSDFStruct.SDF.UnionSDF(obj1, obj2)#

Bases: DeepSDFStruct.SDF.SDFBase

Parameters:
DeepSDFStruct.SDF.generate_plane_points(origin, normal, res, xlim, ylim)#

Generate evenly spaced points on a plane in 3D space.

Creates a regular grid of points on a plane defined by a point and normal vector. The grid is axis-aligned in the plane’s local coordinate system.

Parameters:
  • origin (array-like of shape (3,)) – A point on the plane (3D vector).

  • normal (array-like of shape (3,)) – Normal vector of the plane (3D vector). Currently supports only axis-aligned normals: [1,0,0], [0,1,0], or [0,0,1].

  • res (tuple of int) – Grid resolution (num_points_u, num_points_v).

  • xlim (tuple of float) – Range along the first plane axis (umin, umax).

  • ylim (tuple of float) – Range along the second plane axis (vmin, vmax).

Returns:

  • points (np.ndarray of shape (num_points_u * num_points_v, 3)) – 3D coordinates of grid points.

  • u (np.ndarray of shape (num_points_u * num_points_v,)) – First plane coordinate for each point.

  • v (np.ndarray of shape (num_points_u * num_points_v,)) – Second plane coordinate for each point.

Raises:

NotImplementedError – If normal is not axis-aligned.

Examples

>>> from DeepSDFStruct.plotting import generate_plane_points
>>> import numpy as np
>>>
>>> # Generate points on XY plane at z=0.5
>>> points, u, v = generate_plane_points(
...     origin=[0, 0, 0.5],
...     normal=[0, 0, 1],
...     res=(10, 10),
...     xlim=(-1, 1),
...     ylim=(-1, 1)
... )
>>> print(points.shape)  # (100, 3)
>>> print(np.allclose(points[:, 2], 0.5))  # True (all on z=0.5 plane)

Notes

The function determines two orthogonal axes (u and v) in the plane based on the normal vector. For axis-aligned planes: - Normal [0,0,1] (XY plane): u=[1,0,0], v=[0,1,0] - Normal [0,1,0] (XZ plane): u=[1,0,0], v=[0,0,1] - Normal [1,0,0] (YZ plane): u=[0,1,0], v=[0,0,1]

DeepSDFStruct.SDF.get_equidistant_grid_sample(bounds, grid_spacing, dtype=torch.float32, device='cpu')#

Generates an equidistant 3D grid of points within the given bounding box.

Parameters:
  • bounds (torch.Tensor) – Tensor of shape (2,3), [[xmin, ymin, zmin], [xmax, ymax, zmax]]

  • grid_spacing (float) – Approximate spacing between points along each axis.

Returns:

points – Tensor of shape (N,3) containing all grid points.

Return type:

torch.Tensor

DeepSDFStruct.SDF.normalize_mesh_to_unit_cube(mesh, shrink_factor=1.0)#

Transform mesh coordinates uniformly to [-1, 1] in all axes. Keeps aspect ratio of original mesh.

shrink_factorfloat

Uniform scaling factor applied after normalization. 1.0 -> exactly fills [-1, 1] 0.95 -> 5% smaller

Returns:

The fitted mesh, the inverse scaling factor applied (can directly be used as input for the TorchScaling), and the translation vector used.

Parameters:
  • mesh (trimesh.base.Trimesh)

  • shrink_factor (float)

DeepSDFStruct.SDF.point_segment_distance(P1, P2, query_points)#

Calculates the minimum distance from one or more query points to one or more line segments defined by endpoints P1 and P2.

Parameters:
  • P1 (np.ndarray) – Array of shape (M, 2) or (2,) representing first endpoints of segments.

  • P2 (np.ndarray) – Array of shape (M, 2) or (2,) representing second endpoints of segments.

  • query_points (np.ndarray) – Array of shape (N, 2) or (2,) representing query point(s).

Returns:

Array of shape (N,) with the minimum distance from

each query point to the closest segment.

Return type:

np.ndarray

DeepSDFStruct.SDF.project_bounds(origin, normal, bounds=None)#

Project 3D AABB bounds onto a slice plane and return 2D limits.

Parameters:
  • origin ((3,)) – Point on plane

  • normal ((3,)) – Plane normal

  • bounds ((2, 3)) – AABB bounds [[xmin,ymin,zmin],[xmax,ymax,zmax]] If None, defaults to unit cube [0,1]^3

Returns:

xlim, ylim – Limits in plane coordinates

Return type:

tuple

DeepSDFStruct.SDF.union_numpy(D, k=0)#

D: np.array of shape (num_points, num_geometries) k: smoothness parameter

DeepSDFStruct.SDF.union_torch(D, k=0)#

D: np.array of shape (num_points, num_geometries) k: smoothness parameter