3个不稳定版本
0.2.1 | 2024年2月18日 |
---|---|
0.2.0 | 2024年2月16日 |
0.1.0 | 2024年2月5日 |
#145 in 数据格式
每月下载量53
用于 mesh_to_sdf_client
87KB
1.5K SLoC
mesh_to_sdf
⚠️ 此crate处于早期阶段。预计API将发生变化。
此crate提供两个入口点
generate_sdf
:计算由vertices
和indices
定义的网格在query_points
点上的有符号距离场。generate_grid_sdf
:计算由vertices
和indices
定义的网格上的有符号距离场。
use mesh_to_sdf::{generate_sdf, generate_grid_sdf, SignMethod, Topology, Grid};
// vertices are [f32; 3], but can be cgmath::Vector3<f32>, glam::Vec3, etc.
let vertices: Vec<[f32; 3]> = vec![[0.5, 1.5, 0.5], [1., 2., 3.], [1., 3., 7.]];
let indices: Vec<u32> = vec![0, 1, 2];
// query points must be of the same type as vertices
let query_points: Vec<[f32; 3]> = vec![[0.5, 0.5, 0.5]];
// Query points are expected to be in the same space as the mesh.
let sdf: Vec<f32> = generate_sdf(
&vertices,
Topology::TriangleList(Some(&indices)), // TriangleList as opposed to TriangleStrip
&query_points,
SignMethod::Raycast, // How the sign is computed.
); // Raycast is robust but requires the mesh to be watertight.
for point in query_points.iter().zip(sdf.iter()) {
// distance is positive outside the mesh and negative inside.
println!("Distance to {:?}: {}", point.0, point.1);
}
// if you can, use generate_grid_sdf instead of generate_sdf as it's optimized and much faster.
let bounding_box_min = [0., 0., 0.];
let bounding_box_max = [10., 10., 10.];
let cell_count = [10, 10, 10];
let grid = Grid::from_bounding_box(&bounding_box_min, &bounding_box_max, cell_count);
let sdf: Vec<f32> = generate_grid_sdf(
&vertices,
Topology::TriangleList(Some(&indices)),
&grid,
SignMethod::Raycast, // How the sign is computed.
); // Raycast is robust but requires the mesh to be watertight.
for x in 0..cell_count[0] {
for y in 0..cell_count[1] {
for z in 0..cell_count[2] {
let index = grid.get_cell_idx(&[x, y, z]);
log::info!("Distance to cell [{}, {}, {}]: {}", x, y, z, sdf[index as usize]);
}
}
}
网格拓扑
索引可以是实现 Into<u32>
的任何类型,例如 u16
和 u32
。拓扑可以是列表或条带。如果没有提供索引,则假定它们是 0..vertices.len()
。
对于顶点,此库旨在尽可能通用,通过提供可以针对任何类型实现的 Point
特性。大多数常见数学库的实现受功能标志控制。默认情况下,只提供 [f32; 3]
。如果您找不到您喜欢的库,请随意为其实现特性并提交PR或打开问题。
计算符号
此库提供了两种计算距离符号的方法
SignMethod::Raycast
(默认):一种计算距离符号的稳健方法。它计算从查询点发出的射线与网格三角形的交点数。它只适用于封闭网格,但保证符号正确。SignMethod::Normal
:它使用三角形的法线通过计算查询点方向的点积来估计符号。它适用于非封闭网格,但可能会在网格外部泄漏负距离。
对于网格生成,Raycast
慢约1%。对于查询点,Raycast
慢约10%。请注意,它取决于查询点/网格大小与三角形比例,但这只是一个大致的概念。
使用您最喜欢的库
要使用您最喜欢的数学库与 mesh_to_sdf
,需要将其添加到 mesh_to_sdf
依赖项中。例如,要使用 glam
[dependencies]
mesh_to_sdf = { version = "0.2.1", features = ["glam"] }
目前支持以下库
cgmath
(cgmath::Vector3<f32>
)glam
(glam::Vec3
)mint
(mint::Vector3<f32>
和mint::Point3<f32>
)nalgebra
(nalgebra::Vector3<f32>
和nalgebra::Point3<f32>
)[f32; 3]
基准测试
generate_grid_sdf
比比 generate_sdf
快得多,应尽可能使用。 generate_sdf
不分配内存(除了结果数组),但速度较慢。计划在未来实现更快的版本。 SignMethod::Raycast
比比 SignMethod::Normal
稍慢,但更稳健,应尽可能使用(在 generate_grid_sdf
中约1%,在 generate_sdf
中约10%)。
许可证:MIT OR Apache-2.0
依赖项
~1.8–3.5MB
~76K SLoC