mlx3d.ops¶
mlx3d.ops
¶
decimate_mesh(meshes, voxel_size)
¶
Simplify a mesh by vertex clustering on a regular voxel grid.
Vertices in the same voxel_size cell collapse to their centroid; faces
are remapped and degenerate ones (with a repeated vertex) dropped. Fast and
robust — coarser than quadric-error decimation, but topology-agnostic.
Returns a new single-mesh :class:~mlx3d.structures.Meshes.
Source code in src/mlx3d/ops/geometry.py
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | |
estimate_point_normals(points, k=16, orient_towards=None)
¶
Estimate per-point normals by PCA over each point's k nearest neighbors.
The normal is the eigenvector of the local covariance with the smallest
eigenvalue. Normal orientation is inherently ambiguous; pass
orient_towards (e.g. the camera position) to flip normals consistently
toward that point.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
array
|
|
required |
k
|
int
|
neighborhood size. |
16
|
orient_towards
|
tuple[float, float, float] | array | None
|
optional |
None
|
Returns:
| Type | Description |
|---|---|
array
|
|
Source code in src/mlx3d/ops/geometry.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
icp(source, target, iters=20, tol=1e-06)
¶
Rigidly align source to target with Iterative Closest Point.
Each iteration matches every source point to its nearest target point and
solves for the best rigid transform (Kabsch/SVD), accumulating the total
R/t such that aligned = source @ R.T + t.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
array
|
|
required |
target
|
array
|
|
required |
iters
|
int
|
maximum iterations. |
20
|
tol
|
float
|
stop when the mean matched-distance improves by less than this. |
1e-06
|
Returns:
| Type | Description |
|---|---|
dict[str, array]
|
dict with |
dict[str, array]
|
|
Source code in src/mlx3d/ops/geometry.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
poisson_reconstruction(points, normals, resolution=64, padding=0.1)
¶
Reconstruct a watertight surface mesh from oriented points (Poisson).
Solves the Poisson equation on a regular grid: the oriented points define a
vector field whose divergence drives an indicator function chi (via an
FFT Poisson solve), then the surface is extracted with marching cubes at the
iso-level passing through the input points. This is the regular-grid form of
Screened Poisson Surface Reconstruction (Kazhdan et al.) -- the same physics
without an octree.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
points
|
array
|
|
required |
normals
|
array
|
|
required |
resolution
|
int
|
grid cells per axis. |
64
|
padding
|
float
|
fractional padding added around the point bounding box. |
0.1
|
Returns:
| Type | Description |
|---|---|
Meshes
|
A single-mesh :class: |
Source code in src/mlx3d/ops/geometry.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
knn_gather(x, idx)
¶
Gather neighbor features: x (N, P2, C), idx (N, P1, K) -> (N, P1, K, C).
Source code in src/mlx3d/ops/knn.py
180 181 182 183 184 185 186 | |
knn_points(p1, p2, K=1, chunk_size=4096)
¶
For each point in p1 find its K nearest neighbors in p2.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
p1
|
array
|
(N, P1, D) or (P1, D) query points. |
required |
p2
|
array
|
(N, P2, D) or (P2, D) reference points. |
required |
K
|
int
|
number of neighbors. |
1
|
chunk_size
|
int
|
queries processed per tile to bound the (P1, P2) distance matrix memory. |
4096
|
Returns:
| Type | Description |
|---|---|
array
|
|
array
|
into |
Source code in src/mlx3d/ops/knn.py
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
ray_mesh_intersect(meshes, origins, directions, face_chunk_size=4096, eps=1e-08, aabb_cull=True, spatial_sort=False, return_stats=False)
¶
Nearest ray-triangle hit per ray (Möller-Trumbore).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
meshes
|
Meshes
|
a single-mesh :class: |
required |
origins
|
array
|
|
required |
directions
|
array
|
|
required |
face_chunk_size
|
int
|
faces per chunk, bounding the |
4096
|
eps
|
float
|
parallel / degenerate-triangle tolerance. |
1e-08
|
aabb_cull
|
bool
|
if |
True
|
spatial_sort
|
bool
|
sort faces by Morton code before chunking. This one-time
CPU preprocessing step is useful for arbitrary face orderings and
maps returned |
False
|
return_stats
|
bool
|
include simple broad-phase counters useful for tests and profiling. |
False
|
Returns:
| Type | Description |
|---|---|
dict[str, object]
|
dict with |
dict[str, object]
|
miss), |
dict[str, object]
|
barycentric coords, and |
dict[str, object]
|
hit position is differentiable w.r.t. the mesh vertices. |
Source code in src/mlx3d/ops/ray_mesh.py
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | |
spatially_sort_faces(meshes)
¶
Return a copy with faces sorted by Morton code of their centroids.
Spatial ordering makes adjacent face chunks geometrically coherent, which
improves the effectiveness of chunk-level AABB culling in
:func:ray_mesh_intersect. The second return value maps sorted face rows
back to original packed face indices.
Source code in src/mlx3d/ops/ray_mesh.py
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | |
sample_points_from_meshes(meshes, num_samples=10000, return_normals=False)
¶
Uniformly sample points from mesh surfaces (area-weighted).
Sampling locations are differentiable with respect to vertex positions (the face choice and barycentric coordinates are treated as constants, as in PyTorch3D).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
meshes
|
Meshes
|
a :class: |
required |
num_samples
|
int
|
points per mesh. |
10000
|
return_normals
|
bool
|
also return the face normal at each sample. |
False
|
Returns:
| Type | Description |
|---|---|
array | tuple[array, array]
|
An (N, num_samples, 3) array of samples, plus an (N, num_samples, 3) |
array | tuple[array, array]
|
array of normals if |
Source code in src/mlx3d/ops/sample_points.py
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | |
subdivide_meshes(meshes)
¶
Subdivide each triangle into four by inserting edge midpoints.
Each face (v0, v1, v2) becomes four faces using the midpoints of its
three edges; midpoints are shared between adjacent faces (so the result is
watertight where the input was). New vertex positions are the differentiable
averages of their two endpoints, so gradients flow back to the originals.
Operates on a single mesh and returns a new :class:~mlx3d.structures.Meshes.
Source code in src/mlx3d/ops/subdivide.py
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | |