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 evenly spaced points on a plane in 3D space. |
|
Generates an equidistant 3D grid of points within the given bounding box. |
|
Transform mesh coordinates uniformly to [-1, 1] in all axes. |
|
Calculates the minimum distance from one or more query points to one or more line segments defined by endpoints P1 and P2. |
|
Project 3D AABB bounds onto a slice plane and return 2D limits. |
|
D: np.array of shape (num_points, num_geometries) k: smoothness parameter |
|
D: np.array of shape (num_points, num_geometries) k: smoothness parameter |
Classes
|
|
A dictionary type describing boundary conditions ("caps") for each axis direction (x, y, z). |
|
|
Applies planar boundary caps to another SDF. |
|
Subtracts objs2 from obj1 |
|
|
|
|
|
Abstract base class for Signed Distance Functions with optional deformation and parametrization. |
|
|
|
|
|
Create an SDF from a triangle mesh using closest-point queries. |
|
|
|
Generic SDF wrapper that applies a transformation to the input queries. |
|
- 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:
TypedDictA 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.CappedBorderSDF(sdf, cap_border_dict=None, scale=(1, 1, 1))#
Bases:
DeepSDFStruct.SDF.SDFBaseApplies planar boundary caps to another SDF.
- Parameters:
cap_border_dict (DeepSDFStruct.SDF.CapBorderDict)
- cap_border_dict: DeepSDFStruct.SDF.CapBorderDict#
- class DeepSDFStruct.SDF.DifferenceSDF(obj1, obj2)#
Bases:
DeepSDFStruct.SDF.SDFBaseSubtracts objs2 from obj1
- Parameters:
obj1 (DeepSDFStruct.SDF.SDFBase)
obj2 (DeepSDFStruct.SDF.SDFBase)
- class DeepSDFStruct.SDF.NegatedCallable(obj)#
Bases:
DeepSDFStruct.SDF.SDFBase- Parameters:
- class DeepSDFStruct.SDF.SDF2D(obj, axes, offset=0.0)#
Bases:
DeepSDFStruct.SDF.SDFBase- Parameters:
axes (list[int])
- class DeepSDFStruct.SDF.SDFBase(parametrization=None, geometric_dim=3)#
Bases:
torch.nn.modules.module.Module,abc.ABCAbstract 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 geometryExamples
>>> 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:
- 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.SDFBaseCreate 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:
obj1 (DeepSDFStruct.SDF.SDFBase)
obj2 (DeepSDFStruct.SDF.SDFBase)
- class DeepSDFStruct.SDF.TransformedSDF(sdf, rotationMatrix=None, translation=None, scaleFactor=None)#
Bases:
DeepSDFStruct.SDF.SDFBaseGeneric SDF wrapper that applies a transformation to the input queries. Transformation can be rotation, translation, or scaling.
- Parameters:
- class DeepSDFStruct.SDF.UnionSDF(obj1, obj2)#
Bases:
DeepSDFStruct.SDF.SDFBase- Parameters:
obj1 (DeepSDFStruct.SDF.SDFBase)
obj2 (DeepSDFStruct.SDF.SDFBase)
- 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