utils#
Utility functions for 3D graphics and visualization.
This module contains various utility functions for 3D graphics and visualization, including trilinear interpolation, affine transformations, normal calculations, and grid generation. These functions are designed to work with numpy arrays and are useful for manipulating 3D data structures, such as meshes and point clouds.
|
Evaluate input_array at the given indices using trilinear interpolation. |
|
Apply affine matrix aff to points pts. |
|
Convert string to bytes using latin1 encoding. |
|
Construct a XY-grid based on the cells content shape. |
|
Normalize a numpy array of 3 component vectors in-place. |
|
Calculate vertex normals from vertices and faces. |
Calculate tangents from normals and a direction of anisotropy. |
|
|
Determine the winding order of a given triangle face. |
|
Change the vertices order of a given triangle. |
|
Return triangles with a fixed winding order. |
|
Generate UVs by projecting vertices onto a plane. |
|
Create a SH basis matrix for real spherical harmonics. |
|
Get the maximum degree (l_max) from the number of coefficients. |
|
Get the number of spherical harmonic coefficients from the maximum degree. |
|
Get the min and max ranges of a transformed cube. |
|
Extract boundary voxel coordinates for a label within a volume. |
|
Generate voxel face corners for scalar or vector inputs. |
|
Build a watertight mesh from a 3D volume where objects are volume > 0. |
map_coordinates_3d_4d#
- fury.utils.map_coordinates_3d_4d(input_array, indices)[source]#
Evaluate input_array at the given indices using trilinear interpolation.
Uses trilinear interpolation to sample values from a 3D or 4D array at specified coordinates.
- Parameters:
input_array (ndarray) – 3D or 4D array to be sampled.
indices (ndarray) – Coordinates at which to evaluate input_array. Should have shape (N, D) where N is the number of points and D is the dimensionality of the input array.
- Returns:
1D or 2D array of values evaluated at indices. Shape will be (N,) for 3D input or (N, M) for 4D input, where M is the size of the last dimension of input_array.
- Return type:
ndarray
- Raises:
ValueError – If input_array is not 3D or 4D.
apply_affine#
- fury.utils.apply_affine(aff, pts)[source]#
Apply affine matrix aff to points pts.
Returns result of application of aff to the right of pts. The coordinate dimension of pts should be the last.
- Parameters:
aff (ndarray, shape (N, N)) – Homogeneous affine matrix. For 3D points, will be 4 by 4. The affine will be applied on the left of pts.
pts (ndarray, shape (..., N-1)) – Points to transform, where the last dimension contains the coordinates of each point. For 3D, the last dimension will be length 3.
- Returns:
Transformed points with same shape as input pts.
- Return type:
ndarray, shape (…, N-1)
Notes
Copied from nibabel to remove dependency.
For the 3D case, aff will be shape (4,4) and pts will have final axis length 3. The transformation is computed as:
res = np.dot(aff[:3,:3], pts.T) + aff[:3,3:4] transformed_pts = res.T
Examples
>>> aff = np.array([[0,2,0,10],[3,0,0,11],[0,0,4,12],[0,0,0,1]]) >>> pts = np.array([[1,2,3],[2,3,4],[4,5,6],[6,7,8]]) >>> apply_affine(aff, pts) array([[14, 14, 24], [16, 17, 28], [20, 23, 36], [24, 29, 44]]...) >>> # Just to show that in the simple 3D case, it is equivalent to: >>> (np.dot(aff[:3,:3], pts.T) + aff[:3,3:4]).T array([[14, 14, 24], [16, 17, 28], [20, 23, 36], [24, 29, 44]]...) >>> # But `pts` can be a more complicated shape: >>> pts = pts.reshape((2,2,3)) >>> apply_affine(aff, pts) array([[[14, 14, 24], [16, 17, 28]], [[20, 23, 36], [24, 29, 44]]]...)
asbytes#
get_grid_cells_position#
- fury.utils.get_grid_cells_position(shapes, *, aspect_ratio=1.7777777777777777, dim=None)[source]#
Construct a XY-grid based on the cells content shape.
Generate coordinates for a grid of cells with specified content shapes. The grid follows a row-major order with the top left corner at (0,0,0).
- Parameters:
shapes (list of tuple of int) – The shape (width, height) of every cell content.
aspect_ratio (float, optional) – Aspect ratio of the grid (width/height). Default is 16/9.
dim (tuple of int, optional) – Dimension (nb_rows, nb_cols) of the grid. If None, dimensions are calculated automatically to match the aspect_ratio.
- Returns:
3D coordinates of every grid cell center, where N is the number of cells.
- Return type:
ndarray, shape (N, 3)
- Raises:
ValueError – If the provided dim is too small to contain all elements.
Notes
The grid width and height are determined by the largest width and height among all cell contents. X coordinates increase from left to right while Y coordinates decrease from top to bottom.
normalize_v3#
- fury.utils.normalize_v3(arr)[source]#
Normalize a numpy array of 3 component vectors in-place.
- Parameters:
arr (ndarray, shape (N, 3)) – Array of vectors to normalize.
- Returns:
The input array, normalized in-place.
- Return type:
ndarray, shape (N, 3)
Notes
Vectors are normalized by dividing each component by the vector length. Zero-length vectors will cause division by zero.
normals_from_v_f#
- fury.utils.normals_from_v_f(vertices, faces)[source]#
Calculate vertex normals from vertices and faces.
Compute surface normals for each vertex based on the faces that include it.
- Parameters:
vertices (ndarray, shape (N, 3)) – Array of vertex coordinates.
faces (ndarray, shape (M, 3)) – Array of triangle indices, where each element is an index into vertices.
- Returns:
Array of calculated normals, one per vertex.
- Return type:
ndarray, shape (N, 3)
Notes
The normal for each face is calculated and then accumulated for each vertex. The final normals are normalized to unit length.
tangents_from_direction_of_anisotropy#
- fury.utils.tangents_from_direction_of_anisotropy(normals, direction)[source]#
Calculate tangents from normals and a direction of anisotropy.
- Parameters:
normals (ndarray, shape (N, 3)) – Array of surface normals per vertex.
direction (array_like, shape (3,)) – Vector representing the direction of anisotropy.
- Returns:
Array of calculated tangents, one per vertex.
- Return type:
ndarray, shape (N, 3)
Notes
The tangent vectors are calculated by first finding the binormal (cross product of normal and tangent direction), then taking the cross product of the normal and binormal.
triangle_order#
- fury.utils.triangle_order(vertices, face)[source]#
Determine the winding order of a given triangle face.
- Parameters:
vertices (ndarray, shape (N, 3)) – Array of vertices making up a shape.
face (ndarray, shape (3,)) – Array of 3 indices representing a single triangle face.
- Returns:
True if the order is counter-clockwise (CCW), False otherwise.
- Return type:
Notes
The winding order is determined using the sign of the determinant of a 4x4 matrix containing the triangle vertices.
change_vertices_order#
- fury.utils.change_vertices_order(triangle)[source]#
Change the vertices order of a given triangle.
- Parameters:
triangle (ndarray, shape (3,)) – Array of 3 vertex indices making up a triangle.
- Returns:
New array of vertex indices in the opposite winding order.
- Return type:
ndarray, shape (3,)
Notes
Reverses the winding order by swapping the first and last vertices.
fix_winding_order#
- fury.utils.fix_winding_order(vertices, triangles, *, clockwise=False)[source]#
Return triangles with a fixed winding order.
- Parameters:
vertices (ndarray, shape (N, 3)) – Array of vertices corresponding to a shape.
triangles (ndarray, shape (M, 3)) – Array of triangles corresponding to a shape.
clockwise (bool, optional) – Desired triangle order type: True for clockwise, False for counter-clockwise (default).
- Returns:
The triangles with corrected winding order.
- Return type:
ndarray, shape (M, 3)
Notes
Clockwise means that the three vertices, in order, rotate clockwise around the triangle’s center. This function ensures all triangles have the specified winding order by checking each triangle and correcting as needed.
generate_planar_uvs#
- fury.utils.generate_planar_uvs(vertices, *, axis='xy')[source]#
Generate UVs by projecting vertices onto a plane.
- Parameters:
vertices (ndarray, shape (N, 3)) – Array of vertex coordinates in 3D space.
axis (str, optional) – The plane onto which to project the vertices. Options are ‘xy’, ‘xz’, or ‘yz’.
- Returns:
Array of UV coordinates, shape (N, 2), where N is the number of vertices.
- Return type:
ndarray
create_sh_basis_matrix#
- fury.utils.create_sh_basis_matrix(vertices, l_max)[source]#
Create a SH basis matrix for real spherical harmonics.
- Parameters:
vertices (ndarray, shape (N, 3)) – Array of vertex coordinates in 3D space, where N is the number of vertices.
l_max (int) – Maximum spherical harmonic degree.
- Returns:
Matrix of spherical harmonic basis functions evaluated at the vertices.
- Return type:
ndarray, shape (N, (l_max + 1) ** 2)
get_lmax#
get_n_coeffs#
get_transformed_cube_bounds#
- fury.utils.get_transformed_cube_bounds(affine_matrix, vertex1, vertex2)[source]#
Get the min and max ranges of a transformed cube.
- Parameters:
affine_matrix (ndarray, shape (4, 4)) – The affine transformation matrix to apply to the cube vertices.
vertex1 (ndarray, shape (3,)) – The coordinates of one corner of the cube.
vertex2 (ndarray, shape (3,)) – The coordinates of the opposite corner of the cube.
- Returns:
A list containing the min and max ranges of the transformed cube in the format [[min_x, min_y, min_z], [max_x, max_y, max_z]].
- Return type:
extract_surface_voxels#
- fury.utils.extract_surface_voxels(volume, label_value, *, structuring_element=None)[source]#
Extract boundary voxel coordinates for a label within a volume.
- Parameters:
volume (ndarray) – Labeled volume containing the objects of interest; can be a full volume or a cropped sub-section.
label_value (int) – The label identifying the object whose surface voxels should be returned.
structuring_element (ndarray, optional) – Structuring element defining the desired connectivity. If None, a default 1-connectivity structuring element is used.
- Returns:
Returns (surface_coords, object_mask) when a surface is found, where surface_coords has shape (N, 3) ordered as (x, y, z). Returns None when the label does not have exposed voxels.
- Return type:
tuple or None
face_generation#
- fury.utils.face_generation(coords, axis, sign)[source]#
Generate voxel face corners for scalar or vector inputs.
- Parameters:
coords (array_like) – Voxel origins shaped as (…, 3). Arrays are broadcast with axis and sign to produce multiple quads simultaneously.
axis (array_like) – Axis orthogonal to each face (0=x, 1=y, 2=z).
sign (array_like) – Orientation of each face normal (+1 or -1).
- Returns:
Array of quad vertices with shape (…, 4, 3), where the leading dimensions match the broadcasted inputs.
- Return type:
ndarray
voxel_mesh_by_object#
- fury.utils.voxel_mesh_by_object(volume, *, connectivity=1, spacing=(1.0, 1.0, 1.0), triangulate=False)[source]#
Build a watertight mesh from a 3D volume where objects are volume > 0.
- Parameters:
volume (ndarray) – 3D array where objects are represented by non-zero values.
connectivity (int, optional) – Possible options are {1, 2, 3}. 1 -> 6-neighborhood, 2 -> 18, 3 -> 26.
spacing (tuple, optional) – Voxel spacing along each axis (dx, dy, dz).
triangulate (bool, optional) – Whether to triangulate the resulting mesh faces.
- Returns:
A dictionary where keys are object labels and values are dictionaries with ‘verts’ and ‘faces’ of the generated meshes.
- Return type: