API Reference¶
Functions¶
- isoext.marching_cubes(grid: isoext.isoext_ext.Grid, level: float = 0.0, method: str = 'vega') tuple¶
Extract an iso-surface from a grid using the Marching Cubes algorithm.
- Parameters:
grid – The input grid (UniformGrid or SparseGrid) containing scalar values.
level – The iso-value at which to extract the surface. Default is 0.0.
method – The marching cubes variant to use. Options are ‘vega’ (default), ‘lewiner’, ‘nagae’, or ‘lorensen’. The default resolves the topological ambiguities of standard marching cubes with the corrected interior test of Vega et al.
- Returns:
A tuple (vertices, faces) where vertices is an (N, 3) float32 tensor of vertex positions and faces is an (M, 3) int32 tensor of triangle indices.
- isoext.marching_tetrahedra(grid: isoext.isoext_ext.Grid, level: float = 0.0) tuple¶
Extract an iso-surface using the marching tetrahedra algorithm.
Each cell is split into 6 tetrahedra, which have no ambiguous sign configurations, so the mesh is closed and consistent by construction. Produces roughly 2-3x more triangles than marching cubes on the same grid.
- Parameters:
grid – The input grid containing scalar values.
level – The iso-value. Default is 0.0.
- Returns:
A tuple (vertices, faces) where vertices is an (N, 3) float32 tensor and faces is an (M, 3) int32 tensor of triangle indices.
- isoext.dual_contouring(grid, level=0.0, intersection=None, method='ju', **options)¶
Extract an iso-surface with dual contouring.
Every cell the surface crosses gets one vertex and every crossed grid edge one quad connecting the four cells around it. The vertex placement depends on the variant:
"ju"(default) is dual contouring of Hermite data (Ju et al. 2002): each vertex minimizes the QEF of the tangent planes at the cell’s edge crossings. It needs normals; estimated from the grid values they are smeared at sharp features, exact SDF normals attached to the intersection reproduce them. One linear solve per cell."carrera"is dual contouring of signed distance data (Carrera et al. 2026). The vertices are optimized so that the mesh is tangent to the spheres around the grid samples near the surface, of radius equal to the absolute sample value, which recovers sharp features from the samples alone, without normals. The grid must hold a signed distance field. Iterative, and orders of magnitude slower than"ju".- Parameters:
grid – The input grid containing scalar values.
level – The iso-value. Default is 0.0.
intersection – Optional Intersection from get_intersection(). Both variants use its points as the edge crossings; normals attached to it are used by “ju” directly and by “carrera” as the initial Hermite normals. Computed automatically when omitted.
method – “ju” (default) or “carrera”.
reg – (ju) Regularization weight of the QEF. Default 0.01.
svd_tol – (ju) Relative eigenvalue cutoff of the QEF solve. Default 1e-6.
clamp – (ju) Keep each vertex inside its cell. Default True.
outer_iters – (carrera) Global iterations. Default 100.
inner_iters – (carrera) Per-cell iterations per outer iteration. Default 100.
mu – (carrera) Regularization toward the previous iterate. Default 0.1.
hermite_weight – (carrera) Weight of the Hermite plane terms. Default 0.02.
update_weight – (carrera) Blend weight of the per-iteration Hermite and face point updates. Default 0.2.
hermite_update – (carrera) Refine the Hermite data from the mesh each iteration. Default True.
qef_assignment – (carrera) Assign the samples of the first iteration on the mesh of QEF vertices instead of the centroid mesh, as the reference code does. Default True.
band – (carrera) Only samples within this many cell diagonals of the surface are used. Default 3.0.
tol – (carrera) Inner-loop stopping step, in cell diagonals. Default 1e-5.
- Returns:
A tuple (vertices, faces) where vertices is an (N, 3) float32 tensor and faces is an (M, 3) int32 tensor of triangle indices.
- isoext.surface_nets(grid: isoext.isoext_ext.Grid, level: float = 0.0, intersection: isoext.isoext_ext.Intersection | None = None) tuple¶
Extract an iso-surface using the surface nets algorithm.
Each cell crossed by the surface gets one vertex, placed at the centroid of the cell’s edge intersections. Compared to dual contouring this needs no normals and no linear solves, at the cost of less accurate vertex placement.
- Parameters:
grid – The input grid containing scalar values.
level – The iso-value. Default is 0.0.
intersection – Optional Intersection data from get_intersection(). If not provided, intersections are computed automatically.
- Returns:
A tuple (vertices, faces) where vertices is an (N, 3) float32 tensor and faces is an (M, 3) int32 tensor of triangle indices.
- isoext.dual_marching_cubes(grid: isoext.isoext_ext.Grid, level: float = 0.0, method: str = 'vega', intersection: isoext.isoext_ext.Intersection | None = None) tuple¶
Extract an iso-surface using dual marching cubes.
The dual of the marching cubes mesh: the chosen variant’s tables triangulate each cell, every connected patch of that triangulation becomes one vertex, and every crossed grid edge yields a quad connecting the four adjacent cells’ patch vertices. When the intersection carries normals, patch vertices are placed by the same QEF as dual contouring, which reproduces sharp features; without normals the centroid of the patch’s crossings is used. Cells crossed by several surface sheets get one vertex per sheet, which avoids the connectivity defects of dual contouring. The mesh ends half a cell short of the grid boundary.
- Parameters:
grid – The input grid containing scalar values.
level – The iso-value. Default is 0.0.
method – The marching cubes variant used on the dual grid. Options are ‘vega’ (default), ‘lewiner’, ‘nagae’, or ‘lorensen’.
intersection – Optional Intersection data from get_intersection(). Attach normals to it (e.g. from the SDF gradient) to get sharp features. If not provided, intersections are computed automatically and vertices are placed at centroids.
- Returns:
A tuple (vertices, faces) where vertices is an (N, 3) float32 tensor and faces is an (M, 3) int32 tensor of triangle indices.
- isoext.get_intersection(grid: isoext.isoext_ext.Grid, level: float = 0.0, compute_normals: bool = False) isoext.isoext_ext.Intersection¶
Compute edge-surface intersections for dual contouring.
Finds where grid edges cross the iso-surface and computes intersection points using linear interpolation.
- Parameters:
grid – The input grid containing scalar values.
level – The iso-value. Default is 0.0.
compute_normals – If True, compute normals from grid values. Default is False.
- Returns:
An Intersection object containing points (and normals if compute_normals=True).
- isoext.gaussian_smooth(field, sigma=1.0, kernel_size=None)¶
Smooth a 3D scalar field using a Gaussian filter.
- Parameters:
field (Tensor) – Input scalar field with shape (X, Y, Z)
sigma (float) – Standard deviation of the Gaussian kernel (default: 1.0)
kernel_size (int | None) – Size of the kernel. If None, uses int(6 * sigma) | 1 to ensure odd size.
- Returns:
Smoothed scalar field with the same shape as input
- Return type:
Tensor
- isoext.write_obj(obj_path, vertices, faces)¶
Write vertices and faces to an OBJ file.
- Parameters:
obj_path (str) – Path to the output OBJ file
vertices (Tensor) – Tensor of vertices with shape (N, 3)
faces (Tensor) – Tensor of face indices with shape (M, 3)
- Return type:
None
SDF Toolbox¶
Signed distance functions and helpers for building test fields; the SDF Utilities page shows them in use.
- class isoext.sdf.SDF¶
Abstract base class for Signed Distance Functions.
- class isoext.sdf.SDFProtocol(*args, **kwargs)¶
Protocol for SDF callable objects.
- class isoext.sdf.SphereSDF(radius)¶
SDF for a sphere centered at the origin.
- Parameters:
radius (float)
- class isoext.sdf.TorusSDF(R, r)¶
SDF for a torus in the xy-plane.
- Parameters:
R (float) – Major radius (distance from center to tube center)
r (float) – Minor radius (tube radius)
- class isoext.sdf.CuboidSDF(size)¶
SDF for an axis-aligned cuboid centered at the origin.
- Parameters:
size (list[float]) – Full lengths in x, y, z directions
- class isoext.sdf.MandelbulbSDF(power=8.0, iterations=10)¶
Distance estimator for the Mandelbulb fractal.
The values estimate the distance to the fractal surface; they are not an exact SDF. Fewer iterations give a smoother, blobbier shape. The bulb fits inside a sphere of radius about 1.2.
- Parameters:
power (float) – Exponent of the iteration; 8 is the classic Mandelbulb.
iterations (int) – Number of fractal iterations.
- class isoext.sdf.TriangleMeshSDF(vertices, faces, signed=True, sign='winding')¶
Signed distance to a triangle mesh.
The mesh is held on the GPU behind a bounding volume hierarchy, so the field can be evaluated at many points at once: sampling a mesh into a grid to extract it again, or building a field around scanned geometry. The gradient is the exact gradient of a distance field, so get_sdf_normal and project_to_surface work as for the analytic SDFs.
- Parameters:
vertices (Tensor) – (V, 3) tensor of vertex positions on the CUDA device.
faces (Tensor) – (F, 3) tensor of vertex indices.
signed (bool) – Give points inside the mesh a negative distance. Pass False for the unsigned distance.
sign (str) – How the inside is decided. “winding” (default) uses the generalized winding number, which tolerates holes, self-intersections and disconnected pieces and does not depend on the mesh orientation. “parity” counts ray crossings, which is cheaper but needs a closed mesh.
- winding_number(p)¶
Generalized winding number at the given points.
1 inside a closed mesh and 0 outside; fractional near holes and for triangle soups. Negative for an inward-oriented mesh.
- Parameters:
p (Tensor) – Points tensor with shape (…, 3)
- Returns:
Tensor with shape (…)
- Return type:
Tensor
- closest_points(p)¶
Project points onto the mesh.
- Parameters:
p (Tensor) – Points tensor with shape (…, 3)
- Returns:
the closest points on the mesh with shape (…, 3) and the index of the triangle holding each one with shape (…).
- Return type:
A tuple (points, face_ids)
- class isoext.sdf.UnionOp(sdf_list)¶
Union operation combining multiple SDFs (minimum distance).
- Parameters:
sdf_list (list[SDF])
- class isoext.sdf.IntersectionOp(sdf_list)¶
Intersection operation combining multiple SDFs (maximum distance).
- Parameters:
sdf_list (list[SDF])
- class isoext.sdf.NegationOp(sdf)¶
Negation operation (inverts SDF, creating inverse shape).
- Parameters:
sdf (SDF)
- class isoext.sdf.SmoothUnionOp(sdf_list, k)¶
Smooth union operation combining multiple SDFs with blending.
- Parameters:
sdf_list (list[SDF]) – List of SDFs to combine
k (float) – Blending parameter (smaller values = sharper transition)
- class isoext.sdf.TranslationOp(sdf, offset)¶
Translation operation (moves SDF by an offset).
- Parameters:
sdf (SDF)
offset (list[float])
- class isoext.sdf.RotationOp(sdf, axis, angle, use_degree=True)¶
Rotation operation (rotates SDF around an axis).
- Parameters:
sdf (SDF) – SDF to rotate
axis (list[float]) – Rotation axis as [x, y, z]
angle (float) – Rotation angle
use_degree (bool) – If True, angle is in degrees; if False, in radians
- isoext.sdf.get_sdf_grad(sdf, p)¶
Compute the gradient of an SDF at given points.
- Parameters:
sdf (SDFProtocol) – SDF function to evaluate
p (Tensor) – Points tensor with shape (…, 3)
- Returns:
Gradient tensor with shape (…, 3)
- Return type:
Tensor
- isoext.sdf.get_sdf_normal(sdf, p)¶
Compute normalized gradient (surface normal) of an SDF at given points.
- Parameters:
sdf (SDFProtocol) – SDF function to evaluate
p (Tensor) – Points tensor with shape (…, 3)
- Returns:
Normalized gradient tensor with shape (…, 3)
- Return type:
Tensor
- isoext.sdf.project_to_surface(sdf, p, iters=2)¶
Project points onto the zero level set of an SDF with Newton steps.
Useful for refining the linearly interpolated intersection points from get_intersection before running dual contouring; more accurate points give sharper features.
- Parameters:
sdf (SDFProtocol) – SDF function to evaluate
p (Tensor) – Points tensor with shape (…, 3)
iters (int) – Number of Newton steps
- Returns:
Projected points tensor with shape (…, 3)
- Return type:
Tensor
Test Meshes¶
Well-known meshes for trying things out, downloaded on first use; the SDF Utilities shows one turned into a field.
Well-known test meshes, downloaded on first use.
The meshes are not shipped with the package. The Stanford models may be used and redistributed for research but not commercially, so they are fetched from the Stanford Computer Graphics Laboratory when first requested and cached locally; Spot is public domain.
- isoext.assets.load_mesh(name, size=1.6, device='cuda')¶
Load one of the test meshes as (vertices, faces) tensors.
The mesh is downloaded and cached on first use, then centered at the origin, scaled so that its longest side has length
size(so it fits the default grid domain [-1, 1] with a margin) and turned z-up.- Parameters:
name (str) – One of the keys of ASSETS: “bunny”, “armadillo”, “dragon” or “spot”. “armadillo” and “spot” are closed; “bunny” and “dragon” have holes at the bottom.
size (float) – Length of the longest side of the bounding box after scaling.
device – Device of the returned tensors.
- Returns:
an (N, 3) float32 tensor and an (M, 3) int32 tensor of triangles.
- Return type:
A tuple (vertices, faces)
- isoext.assets.cache_dir()¶
Directory holding the downloaded meshes.
$ISOEXT_CACHEif set, else$XDG_CACHE_HOME/isoextor~/.cache/isoext.- Return type:
Path
Viewer¶
Interactive visualization built on viser.
Interactive mesh viewing and scene export built on viser.
Typical use:
import isoext
from isoext import viewer
v, f = isoext.marching_cubes(grid)
server = viewer.show(v, f) # open an interactive viewer in the browser
viewer.embed(v, f) # inline scene for (statically hosted) notebooks
- isoext.viewer.add_mesh(server, vertices, faces, *, name='/mesh', color=(0.71, 0.8, 1.0), flat_shading=False, wireframe=False, side='front')¶
Add a mesh from isoext output tensors to a viser scene.
- Parameters:
server – A viser.ViserServer instance.
vertices (Tensor) – (N, 3) tensor of vertex positions.
faces (Tensor) – (M, 3) tensor of triangle indices.
name (str) – Scene tree name of the mesh.
color – RGB tuple with components in [0, 1], or a color name.
flat_shading (bool) – Shade each triangle with a constant normal.
wireframe (bool) – Render the mesh as a wireframe.
side (str) – Which triangle sides to render: “front”, “back” or “double”. Use “double” for open surfaces, which disappear from behind with the default backface culling.
- Returns:
The viser mesh handle.
- isoext.viewer.add_grid(server, grid, *, level=0.0, name='/grid', point_size=None, line_width=2.0)¶
Draw a grid’s cell edges and its corner values as colored dots.
Corners with a value below the level are drawn red (inside the surface), the rest blue. For sparse grids only the active cells are drawn. Meant for small demonstration grids, like the single-cell examples on the marching cubes variants page.
- Parameters:
server – A viser.ViserServer instance.
grid – A UniformGrid or SparseGrid whose values are set.
level (float) – The iso-value that separates inside from outside.
name (str) – Scene tree name prefix for the lines and dots.
point_size (float | None) – Dot diameter in world units. Defaults to a fraction of the cell edge length.
line_width (float) – Width of the cell edges in pixels.
- isoext.viewer.add_points(server, points, *, color=(0.93, 0.79, 0.24), point_size=0.06, name=None)¶
Draw raw points, for annotating a scene on top of the mesh and grid.
- Parameters:
server – A viser.ViserServer instance.
points (Tensor) – (N, 3) tensor of positions.
color – RGB tuple with components in [0, 1], or a color name.
point_size (float) – Dot diameter in world units.
name (str | None) – Scene tree name of the point cloud. Defaults to a unique name, so repeated calls add to the scene instead of replacing the previous points.
- isoext.viewer.add_lines(server, segments, *, color=(0.55, 0.55, 0.55), line_width=2.0, name=None)¶
Draw raw line segments, for annotating a scene.
- Parameters:
server – A viser.ViserServer instance.
segments (Tensor) – (N, 2, 3) tensor: N segments with start and end points.
color – RGB tuple with components in [0, 1], or a color name.
line_width (float) – Width of the segments in pixels.
name (str | None) – Scene tree name of the segments. Defaults to a unique name, so repeated calls add to the scene instead of replacing the previous segments.
- isoext.viewer.add_label(server, text, position, *, name=None)¶
Draw a text label, e.g. to caption the meshes of a composed scene.
- Parameters:
server – A viser.ViserServer instance.
text (str) – The label text.
position – The label position as a (3,) tensor, list or tuple.
name (str | None) – Scene tree name. Defaults to a unique name.
- isoext.viewer.add_arrows(server, origins, directions, *, color=(0.45, 0.45, 0.45), line_width=2.0, name=None)¶
Draw arrows as line shafts with cone heads, e.g. for normals.
- Parameters:
server – A viser.ViserServer instance.
origins (Tensor) – (N, 3) tensor of arrow start points.
directions (Tensor) – (N, 3) tensor of arrow vectors; length sets the size.
color – RGB tuple with components in [0, 1], or a color name.
line_width (float) – Width of the shafts in pixels.
name (str | None) – Scene tree name prefix. Defaults to a unique name.
- isoext.viewer.add_planes(server, centers, normals, *, size=0.5, color=(0.6, 0.7, 0.9), opacity=0.4, name=None)¶
Draw translucent square patches perpendicular to the given normals, e.g. tangent planes.
- Parameters:
server – A viser.ViserServer instance.
centers (Tensor) – (N, 3) tensor of patch centers.
normals (Tensor) – (N, 3) tensor of patch normals.
size (float) – Half of the patch side length, in world units.
color – RGB tuple with components in [0, 1], or a color name.
opacity (float) – Patch opacity in [0, 1].
name (str | None) – Scene tree name. Defaults to a unique name.
- isoext.viewer.add_spheres(server, centers, radii, *, color=(0.6, 0.7, 0.9), opacity=0.3, name=None)¶
Draw translucent spheres, e.g. the distance spheres of SDF samples.
- Parameters:
server – A viser.ViserServer instance.
centers (Tensor) – (N, 3) tensor of sphere centers.
radii (Tensor) – (N,) tensor of radii.
color – RGB tuple with components in [0, 1], or a color name.
opacity (float) – Sphere opacity in [0, 1].
name (str | None) – Scene tree name. Defaults to a unique name.
- isoext.viewer.show(vertices, faces, *, port=8080, grid=None, grid_level=0.0, draw=None, **mesh_kwargs)¶
Open an interactive viewer serving the given mesh.
The server keeps running until it is stopped or the process exits; the printed URL can be opened in any browser.
- Parameters:
vertices (Tensor) – (N, 3) tensor of vertex positions.
faces (Tensor) – (M, 3) tensor of triangle indices.
port (int) – Port to serve on (the next free port is used if taken).
grid – Optional grid to overlay with add_grid.
grid_level (float) – Iso-value for the grid overlay’s corner colors.
draw – Callable that receives the server to add extra elements, e.g. with add_points and add_lines.
**mesh_kwargs – Forwarded to add_mesh.
- Returns:
The running viser.ViserServer; call .stop() to shut it down.
- isoext.viewer.serialize_scene(vertices=None, faces=None, *, grid=None, grid_level=0.0, draw=None, **mesh_kwargs)¶
Serialize a scene containing the given mesh to .viser bytes.
The bytes can be written to a
.viserfile and played back offline by viser’s static client, e.g. embedded in a web page. See save_scene and embed for convenience wrappers. The mesh is optional: pass None to build a scene of only a grid overlay and drawn annotations.- Parameters:
vertices (Tensor | None)
faces (Tensor | None)
grid_level (float)
- Return type:
bytes
- isoext.viewer.save_scene(path, vertices, faces, **mesh_kwargs)¶
Serialize a scene with the given mesh and write it to a .viser file.
- Parameters:
vertices (Tensor)
faces (Tensor)
- Return type:
None
- isoext.viewer.copy_client(directory)¶
Copy viser’s single-file static web client into a directory.
The client is a self-contained index.html that plays back .viser scene files passed via its
?playbackPath=URL parameter. The copy is refreshed whenever the installed viser ships a different build.- Returns:
The path of the copied index.html.
- Return type:
Path
- isoext.viewer.embed(vertices=None, faces=None, *, root='_static', height=420, frame=None, **mesh_kwargs)¶
Display a mesh as a self-contained interactive scene in a notebook.
Unlike show, which starts a live server, this writes static assets – the viser client to root/viser/ and the serialized scene to root/scenes/ – and returns an IFrame referencing them with relative URLs. Rendered notebooks therefore stay interactive when hosted statically, for example on documentation pages.
- Parameters:
vertices (Tensor | None) – (N, 3) tensor of vertex positions, or None for a scene without a mesh.
faces (Tensor | None) – (M, 3) tensor of triangle indices.
root – Directory for the static assets, relative to the notebook.
height (int) – Height of the embedded viewer in pixels.
frame – Optional (N, 3) tensor of points that define the initial camera framing, for scenes composed with draw= whose extent the mesh alone does not describe.
**mesh_kwargs – Forwarded to add_mesh; pass grid= (and optionally grid_level=) to overlay the grid’s edges and corner signs, and draw= to add extra elements with add_points and add_lines.
- Returns:
An IPython IFrame displaying the scene.
Classes¶
UniformGrid¶
- class isoext.UniformGrid(shape, aabb_min=[-1, -1, -1], aabb_max=[1, 1, 1], default_value=float_max)¶
A dense uniform grid for storing scalar values.
The grid divides a 3D axis-aligned bounding box into a regular lattice of cells. Each cell has 8 corner points where scalar values are stored.
- Parameters:
shape (Sequence[int]) – The number of sample points in each dimension (x, y, z); the grid has one fewer cell than points along each axis.
aabb_min (Sequence[float]) – The minimum corner of the bounding box.
aabb_max (Sequence[float]) – The maximum corner of the bounding box.
default_value (float) – Initial scalar value for all points.
- UniformGrid.get_points(self) torch.Tensor[dtype=float32, order='C', device='cuda']¶
Return the 3D coordinates of all grid points as a (X, Y, Z, 3) float32 tensor.
- UniformGrid.get_values(self) torch.Tensor[dtype=float32, order='C', device='cuda']¶
Return the scalar values as a (X, Y, Z) float32 tensor.
- UniformGrid.set_values(self, new_values: torch.Tensor[dtype=float32, shape=(*, *, *), order='C', device='cuda']) None¶
Set the scalar values from a (X, Y, Z) float32 tensor.
SparseGrid¶
- class isoext.SparseGrid(shape, aabb_min=[-1, -1, -1], aabb_max=[1, 1, 1], default_value=float_max)¶
A sparse adaptive grid for storing scalar values.
Unlike UniformGrid, SparseGrid only allocates memory for cells that are explicitly added. This is useful for large domains where only a small region contains the iso-surface.
- Parameters:
shape (Sequence[int]) – The number of sample points in each dimension (x, y, z); cells may be added anywhere in the implied lattice.
aabb_min (Sequence[float]) – The minimum corner of the bounding box.
aabb_max (Sequence[float]) – The maximum corner of the bounding box.
default_value (float) – Default scalar value for unset points.
- SparseGrid.get_num_cells(self) int¶
Return the number of active cells in the grid.
- SparseGrid.get_num_points(self) int¶
Return the number of points in active cells (num_cells * 8).
- SparseGrid.get_points(self) torch.Tensor[dtype=float32, order='C', device='cuda']¶
Return the 3D coordinates of points in active cells as an (N, 8, 3) float32 tensor.
- SparseGrid.get_values(self) torch.Tensor[dtype=float32, order='C', device='cuda']¶
Return the scalar values at active cell corners as an (N, 8) float32 tensor.
- SparseGrid.set_values(self, new_values: torch.Tensor[dtype=float32, shape=(*, 8), order='C', device='cuda']) None¶
Set the scalar values from an (N, 8) float32 tensor.
- SparseGrid.get_cells(self) torch.Tensor[dtype=uint32, order='C', device='cuda']¶
Return the cell connectivity as point indices.
- SparseGrid.add_cells(self, new_cell_indices: torch.Tensor[dtype=int32, shape=(*), order='C', device='cuda']) None¶
Add cells to the grid by their linear indices.
- Parameters:
new_cell_indices – 1D int32 tensor of cell indices to add.
- SparseGrid.remove_cells(self, new_cell_indices: torch.Tensor[dtype=int32, shape=(*), order='C', device='cuda']) None¶
Remove cells from the grid by their linear indices.
- Parameters:
new_cell_indices – 1D int32 tensor of cell indices to remove.
- SparseGrid.get_cell_indices(self) torch.Tensor[dtype=int32, order='C', device='cuda']¶
Return the linear indices of all active cells as a 1D int32 tensor.
- SparseGrid.get_potential_cell_indices(self, arg: int, /) list[torch.Tensor[dtype=int32, order='C', device='cuda']]¶
Get potential cell indices in chunks for memory-efficient processing.
- Parameters:
chunk_size – Maximum number of cells per chunk.
- Returns:
A list of 1D int32 tensors, each containing cell indices for a chunk.
- SparseGrid.get_points_by_cell_indices(self, cell_indices: torch.Tensor[dtype=int32, shape=(*), order='C', device='cuda']) torch.Tensor[dtype=float32, order='C', device='cuda']¶
Get the corner points of specified cells.
- Parameters:
cell_indices – 1D int32 tensor of cell indices.
- Returns:
An (N, 8, 3) float32 tensor of corner coordinates.
- SparseGrid.filter_cell_indices(self, cell_indices: torch.Tensor[dtype=int32, shape=(*), order='C', device='cuda'], values: torch.Tensor[dtype=float32, shape=(*, 8), order='C', device='cuda'], level: float = 0.0) torch.Tensor[dtype=int32, order='C', device='cuda']¶
Filter cells to keep only those that cross the iso-surface.
- Parameters:
cell_indices – 1D int32 tensor of cell indices to filter.
values – (N, 8) float32 tensor of scalar values at cell corners.
level – The iso-value to check against. Default is 0.0.
- Returns:
A 1D int32 tensor of cell indices that cross the iso-surface.
Intersection¶
- class isoext.Intersection¶
Stores edge-surface intersection points and normals for dual contouring.
Created by get_intersection() and used as input to dual_contouring(). You can modify the normals to control the surface reconstruction.
- get_normals¶
Return the surface normals at intersection points as an (N, 3) float32 tensor.
- get_points¶
Return the intersection points as an (N, 3) float32 tensor.
- has_normals¶
Return True if normals have been set or computed.
- set_normals¶
Set custom normals for the intersection points.
- Parameters:
new_normals – (N, 3) float32 tensor of normal vectors.
- set_points¶
Set custom intersection points, e.g. after refining them against the exact SDF.
- Parameters:
new_points – (N, 3) float32 tensor of point positions.