use super::guard::ffi_guard;
use super::registry::{get_mesh, get_node, register_mesh, remove_mesh};
use super::types::*;
use crate::prelude::*;
use std::ffi::c_char;
#[no_mangle]
pub extern "C" fn alice_sdf_generate_mesh(
node: SdfHandle,
resolution: u32,
bounds: f32,
) -> MeshHandle {
ffi_guard(MESH_HANDLE_NULL, || {
let sdf_node = match get_node(node) {
Some(n) => n,
None => return MESH_HANDLE_NULL,
};
let config = MarchingCubesConfig {
resolution: resolution as usize,
iso_level: 0.0,
compute_normals: true,
..Default::default()
};
let min = glam::Vec3::splat(-bounds);
let max = glam::Vec3::splat(bounds);
let mesh = sdf_to_mesh(&sdf_node, min, max, &config);
register_mesh(mesh)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_mesh_vertex_count(mesh: MeshHandle) -> u32 {
ffi_guard(0, || get_mesh(mesh).map_or(0, |m| m.vertex_count() as u32))
}
#[no_mangle]
pub extern "C" fn alice_sdf_mesh_triangle_count(mesh: MeshHandle) -> u32 {
ffi_guard(0, || {
get_mesh(mesh).map_or(0, |m| m.triangle_count() as u32)
})
}
#[no_mangle]
pub extern "C" fn alice_sdf_free_mesh(mesh: MeshHandle) {
ffi_guard((), || {
if !mesh.is_null() {
remove_mesh(mesh);
}
});
}
pub(super) unsafe fn path_from_c(path: *const c_char) -> Result<&'static str, SdfResult> {
if path.is_null() {
return Err(SdfResult::NullPointer);
}
std::ffi::CStr::from_ptr(path)
.to_str()
.map_err(|_| SdfResult::InvalidParameter)
}
pub(super) unsafe fn resolve_mesh(
mesh_handle: MeshHandle,
sdf_handle: SdfHandle,
resolution: u32,
bounds: f32,
) -> Result<std::sync::Arc<crate::mesh::Mesh>, SdfResult> {
if !mesh_handle.is_null() {
return get_mesh(mesh_handle).ok_or(SdfResult::InvalidHandle);
}
let sdf_node = get_node(sdf_handle).ok_or(SdfResult::InvalidHandle)?;
let config = MarchingCubesConfig {
resolution: resolution as usize,
iso_level: 0.0,
compute_normals: true,
..Default::default()
};
let min = glam::Vec3::splat(-bounds);
let max = glam::Vec3::splat(bounds);
Ok(std::sync::Arc::new(sdf_to_mesh(
&sdf_node, min, max, &config,
)))
}
#[no_mangle]
pub unsafe extern "C" fn alice_sdf_export_obj(
mesh_handle: MeshHandle,
sdf_handle: SdfHandle,
path: *const c_char,
resolution: u32,
bounds: f32,
) -> SdfResult {
ffi_guard(SdfResult::Unknown, || {
let path_str = match path_from_c(path) {
Ok(s) => s,
Err(e) => return e,
};
let mesh = match resolve_mesh(mesh_handle, sdf_handle, resolution, bounds) {
Ok(m) => m,
Err(e) => return e,
};
match crate::io::export_obj(&mesh, path_str, &ObjConfig::default(), None) {
Ok(()) => SdfResult::Ok,
Err(_) => SdfResult::IoError,
}
})
}
#[no_mangle]
pub unsafe extern "C" fn alice_sdf_export_glb(
mesh_handle: MeshHandle,
sdf_handle: SdfHandle,
path: *const c_char,
resolution: u32,
bounds: f32,
) -> SdfResult {
ffi_guard(SdfResult::Unknown, || {
let path_str = match path_from_c(path) {
Ok(s) => s,
Err(e) => return e,
};
let mesh = match resolve_mesh(mesh_handle, sdf_handle, resolution, bounds) {
Ok(m) => m,
Err(e) => return e,
};
match crate::io::export_glb(&mesh, path_str, &GltfConfig::default(), None) {
Ok(()) => SdfResult::Ok,
Err(_) => SdfResult::IoError,
}
})
}
#[no_mangle]
pub unsafe extern "C" fn alice_sdf_export_usda(
mesh_handle: MeshHandle,
sdf_handle: SdfHandle,
path: *const c_char,
resolution: u32,
bounds: f32,
) -> SdfResult {
ffi_guard(SdfResult::Unknown, || {
let path_str = match path_from_c(path) {
Ok(s) => s,
Err(e) => return e,
};
let mesh = match resolve_mesh(mesh_handle, sdf_handle, resolution, bounds) {
Ok(m) => m,
Err(e) => return e,
};
match crate::io::export_usda(&mesh, path_str, &UsdConfig::default(), None) {
Ok(()) => SdfResult::Ok,
Err(_) => SdfResult::IoError,
}
})
}
#[no_mangle]
pub unsafe extern "C" fn alice_sdf_export_alembic(
mesh_handle: MeshHandle,
sdf_handle: SdfHandle,
path: *const c_char,
resolution: u32,
bounds: f32,
) -> SdfResult {
ffi_guard(SdfResult::Unknown, || {
let path_str = match path_from_c(path) {
Ok(s) => s,
Err(e) => return e,
};
let mesh = match resolve_mesh(mesh_handle, sdf_handle, resolution, bounds) {
Ok(m) => m,
Err(e) => return e,
};
match crate::io::export_alembic(&mesh, path_str, &AlembicConfig::default()) {
Ok(()) => SdfResult::Ok,
Err(_) => SdfResult::IoError,
}
})
}
#[no_mangle]
pub unsafe extern "C" fn alice_sdf_export_fbx(
mesh_handle: MeshHandle,
sdf_handle: SdfHandle,
path: *const c_char,
resolution: u32,
bounds: f32,
) -> SdfResult {
ffi_guard(SdfResult::Unknown, || {
let path_str = match path_from_c(path) {
Ok(s) => s,
Err(e) => return e,
};
let mesh = match resolve_mesh(mesh_handle, sdf_handle, resolution, bounds) {
Ok(m) => m,
Err(e) => return e,
};
match crate::io::export_fbx(&mesh, path_str, &FbxConfig::default(), None) {
Ok(()) => SdfResult::Ok,
Err(_) => SdfResult::IoError,
}
})
}