Commit dc61bc0e authored by Egor Larionov's avatar Egor Larionov

Apply rustfmt to c api code

parent d171108a
extern crate libc;
extern crate hrbf;
extern crate libc;
extern crate nalgebra as na;
use libc::{size_t, c_int, c_double};
use na::{
Point3,
DimName,
VectorN,
Point,
U3,
DefaultAllocator
};
use hrbf::{Csrbf31HRBF, Csrbf42HRBF, GaussHRBF, HRBFTrait, Pow3HRBF, Pow5HRBF};
use libc::{c_double, c_int, size_t};
use na::allocator::Allocator;
use hrbf::{
Pow3HRBF,
Pow5HRBF,
GaussHRBF,
Csrbf31HRBF,
Csrbf42HRBF,
HRBFTrait,
};
use na::{DefaultAllocator, DimName, Point, Point3, U3, VectorN};
/// Create an HRBF field object. At this stage, the field is zero. You need to fit it to some data
/// using `HRBF_fit` to produce a useful field.
/// using `HRBF_fit` to produce a useful field.
///
/// * `num_sites` is the number of sites needed to represent this HRBF.
/// * `sites_ptr` is the pointer to a contiguous array of 3 dimensional vectors of `double`s. the
......@@ -34,20 +20,20 @@ use hrbf::{
/// `3` for CSRBF31 kernel: `(1-x)^4 (4x + 1)` and
/// `4` for CSRBF42 kernel: `(1-x)^6 (35x^2 + 18x + 3)`.
#[no_mangle]
pub unsafe extern "C" fn HRBF_create(num_sites: size_t,
sites_ptr: *const c_double,
kern_type: c_int) -> *mut HRBFTrait<f64>
{
pub unsafe extern "C" fn HRBF_create(
num_sites: size_t,
sites_ptr: *const c_double,
kern_type: c_int,
) -> *mut HRBFTrait<f64> {
let sites = ptr_to_vec_of_points::<f64, U3>(num_sites, sites_ptr);
let hrbf: Box<HRBFTrait<f64>> =
match kern_type {
1 => Box::new(Pow5HRBF::new(sites)),
2 => Box::new(GaussHRBF::new(sites)),
3 => Box::new(Csrbf31HRBF::new(sites)),
4 => Box::new(Csrbf42HRBF::new(sites)),
_ => Box::new(Pow3HRBF::new(sites)),
};
let hrbf: Box<HRBFTrait<f64>> = match kern_type {
1 => Box::new(Pow5HRBF::new(sites)),
2 => Box::new(GaussHRBF::new(sites)),
3 => Box::new(Csrbf31HRBF::new(sites)),
4 => Box::new(Csrbf42HRBF::new(sites)),
_ => Box::new(Pow3HRBF::new(sites)),
};
Box::into_raw(hrbf)
}
......@@ -60,10 +46,12 @@ pub unsafe extern "C" fn HRBF_free(hrbf: *mut HRBFTrait<f64>) {
/// Given an HRBF object, fit it to the given set of points and normals.
/// NOTE: Currently this function only works for the same number of points as there are sites.
#[no_mangle]
pub unsafe extern "C" fn HRBF_fit(hrbf: *mut HRBFTrait<f64>,
num_pts: size_t,
pts_ptr: *const c_double,
nmls_ptr: *const c_double) -> bool {
pub unsafe extern "C" fn HRBF_fit(
hrbf: *mut HRBFTrait<f64>,
num_pts: size_t,
pts_ptr: *const c_double,
nmls_ptr: *const c_double,
) -> bool {
let pts = ptr_to_vec_of_points::<f64, U3>(num_pts, pts_ptr);
let nmls = ptr_to_vec_of_vectors::<f64, U3>(num_pts, nmls_ptr);
(*hrbf).fit(&pts, &nmls)
......@@ -71,24 +59,26 @@ pub unsafe extern "C" fn HRBF_fit(hrbf: *mut HRBFTrait<f64>,
/// Evaluate the given HRBF field at a particular point.
#[no_mangle]
pub unsafe extern "C" fn HRBF_eval(hrbf: *const HRBFTrait<f64>,
x: c_double,
y: c_double,
z: c_double) -> c_double
{
(*hrbf).eval(Point3::new(x,y,z))
pub unsafe extern "C" fn HRBF_eval(
hrbf: *const HRBFTrait<f64>,
x: c_double,
y: c_double,
z: c_double,
) -> c_double {
(*hrbf).eval(Point3::new(x, y, z))
}
/// Evaluate the gradient of the given HRBF field at a particular point.
/// `out` is expected to be an array of 3 doubles representing a 3D vector.
#[no_mangle]
pub unsafe extern "C" fn HRBF_grad(hrbf: *const HRBFTrait<f64>,
x: c_double,
y: c_double,
z: c_double,
out: *mut c_double)
{
let g = (*hrbf).grad(Point3::new(x,y,z));
pub unsafe extern "C" fn HRBF_grad(
hrbf: *const HRBFTrait<f64>,
x: c_double,
y: c_double,
z: c_double,
out: *mut c_double,
) {
let g = (*hrbf).grad(Point3::new(x, y, z));
*out.offset(0) = g[0];
*out.offset(1) = g[1];
*out.offset(2) = g[2];
......@@ -97,16 +87,17 @@ pub unsafe extern "C" fn HRBF_grad(hrbf: *const HRBFTrait<f64>,
/// Evaluate the hessian of the given HRBF field at a particular point.
/// `out` is expected to be an array of 9 doubles representing a 3x3 matrix.
#[no_mangle]
pub unsafe extern "C" fn HRBF_hess(hrbf: *const HRBFTrait<f64>,
x: c_double,
y: c_double,
z: c_double,
out: *mut c_double)
{
let h = (*hrbf).hess(Point3::new(x,y,z));
pub unsafe extern "C" fn HRBF_hess(
hrbf: *const HRBFTrait<f64>,
x: c_double,
y: c_double,
z: c_double,
out: *mut c_double,
) {
let h = (*hrbf).hess(Point3::new(x, y, z));
for i in 0..3 {
for j in 0..3 {
*out.offset(3*i + j) = h[(i as usize,j as usize)];
*out.offset(3 * i + j) = h[(i as usize, j as usize)];
}
}
}
......@@ -135,38 +126,38 @@ pub unsafe extern "C" fn HRBF_hess(hrbf: *const HRBFTrait<f64>,
/// * `b` output vector expected to be a contiguous array of `4*num_pts` doubles.
#[no_mangle]
#[allow(non_snake_case)]
pub unsafe extern "C" fn HRBF_fit_system(num_sites: size_t,
sites_ptr: *const c_double,
num_pts: size_t,
pts_ptr: *const c_double,
nmls_ptr: *const c_double,
kern_type: c_int,
A: *mut c_double,
b: *mut c_double)
{
pub unsafe extern "C" fn HRBF_fit_system(
num_sites: size_t,
sites_ptr: *const c_double,
num_pts: size_t,
pts_ptr: *const c_double,
nmls_ptr: *const c_double,
kern_type: c_int,
A: *mut c_double,
b: *mut c_double,
) {
let sites = ptr_to_vec_of_points::<f64, U3>(num_sites, sites_ptr);
let pts = ptr_to_vec_of_points::<f64, U3>(num_pts, pts_ptr);
let nmls = ptr_to_vec_of_vectors::<f64, U3>(num_pts, nmls_ptr);
let hrbf: Box<HRBFTrait<f64>> =
match kern_type {
1 => Box::new(Pow5HRBF::new(sites)),
2 => Box::new(GaussHRBF::new(sites)),
3 => Box::new(Csrbf31HRBF::new(sites)),
4 => Box::new(Csrbf42HRBF::new(sites)),
_ => Box::new(Pow3HRBF::new(sites)),
};
let hrbf: Box<HRBFTrait<f64>> = match kern_type {
1 => Box::new(Pow5HRBF::new(sites)),
2 => Box::new(GaussHRBF::new(sites)),
3 => Box::new(Csrbf31HRBF::new(sites)),
4 => Box::new(Csrbf42HRBF::new(sites)),
_ => Box::new(Pow3HRBF::new(sites)),
};
let mut offsets = Vec::new();
offsets.resize(num_pts, 0.0);
let (A_na, b_na) = (*hrbf).fit_system(&pts, &offsets, &nmls);
for col in 0..4*num_sites {
for row in 0..4*num_pts {
*A.offset((num_sites*col + row) as isize) = A_na[(row,col)];
for col in 0..4 * num_sites {
for row in 0..4 * num_pts {
*A.offset((num_sites * col + row) as isize) = A_na[(row, col)];
}
}
for i in 0..4*num_pts {
for i in 0..4 * num_pts {
*b.offset(i as isize) = b_na[i];
}
}
......@@ -174,18 +165,31 @@ pub unsafe extern "C" fn HRBF_fit_system(num_sites: size_t,
/// Helper routines for converting C-style data to Rust-style data.
/// `n` is the number of vectors to output, which means that `data_ptr` must point to an array of
/// `n*D::dim()` doubles.
unsafe fn ptr_to_vec_of_vectors<T: na::Real, D: DimName>(n: size_t, data_ptr: *const T) -> Vec<VectorN<T, D>>
where DefaultAllocator: Allocator<T, D>
unsafe fn ptr_to_vec_of_vectors<T: na::Real, D: DimName>(
n: size_t,
data_ptr: *const T,
) -> Vec<VectorN<T, D>>
where
DefaultAllocator: Allocator<T, D>,
{
let mut data = Vec::with_capacity(n);
for i in 0..n as isize {
data.push(VectorN::from_fn(|r,_| *data_ptr.offset(3*i + r as isize)));
}
for i in 0..n as isize {
data.push(VectorN::from_fn(|r, _| {
*data_ptr.offset(3 * i + r as isize)
}));
}
data
}
unsafe fn ptr_to_vec_of_points<T: na::Real, D: DimName>(n: size_t, data_ptr: *const T) -> Vec<Point<T, D>>
where DefaultAllocator: Allocator<T, D>
unsafe fn ptr_to_vec_of_points<T: na::Real, D: DimName>(
n: size_t,
data_ptr: *const T,
) -> Vec<Point<T, D>>
where
DefaultAllocator: Allocator<T, D>,
{
ptr_to_vec_of_vectors(n, data_ptr).into_iter().map(|v| Point::from_coordinates(v)).collect()
ptr_to_vec_of_vectors(n, data_ptr)
.into_iter()
.map(|v| Point::from_coordinates(v))
.collect()
}
extern crate nalgebra as na;
extern crate libc;
extern crate itertools;
#[macro_use] extern crate approx;
extern crate libc;
extern crate nalgebra as na;
#[macro_use]
extern crate approx;
extern crate chrbf;
use na::{Point3, Vector3};
use itertools::Itertools;
use libc::{size_t, c_double};
use chrbf::*;
use itertools::Itertools;
use libc::{c_double, size_t};
use na::{Point3, Vector3};
#[test]
fn test_hrbf_fit() {
// Fit an hrbf surface to a unit box
let pts: &[c_double] = &[
// Corners of the box
0.0, 0.0, 0.0,
0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
0.0, 1.0, 1.0,
1.0, 0.0, 0.0,
1.0, 0.0, 1.0,
1.0, 1.0, 0.0,
1.0, 1.0, 1.0,
0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0,
// Extra vertices on box faces
0.5, 0.5, 0.0,
0.5, 0.5, 1.0,
0.5, 0.0, 0.5,
0.5, 1.0, 0.5,
0.0, 0.5, 0.5,
1.0, 0.5, 0.5,
0.5, 0.5, 0.0, 0.5, 0.5, 1.0, 0.5, 0.0, 0.5, 0.5, 1.0,
0.5, 0.0, 0.5, 0.5, 1.0, 0.5, 0.5,
];
let a: c_double = 1.0/c_double::sqrt(3.0);
let a: c_double = 1.0 / c_double::sqrt(3.0);
let nmls: &[c_double] = &[
// Corner normals
-a, -a, -a,
-a, -a, a,
-a, a, -a,
-a, a, a,
a, -a, -a,
a, -a, a,
a, a, -a,
a, a, a,
// Side normals
0.0, 0.0, -1.0,
0.0, 0.0, 1.0,
0.0, -1.0, 0.0,
0.0, 1.0, 0.0,
-1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
-a, -a, -a, -a, -a, a, -a, a, -a, -a, a, a, a, -a, -a, a, -a, a, a,
a, -a, a, a, a, // Side normals
0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0,
1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
];
unsafe {
......@@ -60,18 +38,23 @@ fn test_hrbf_fit() {
for ((&p0, &p1, &p2), (&n0, &n1, &n2)) in pts.iter().tuples().zip(nmls.iter().tuples()) {
let p = Point3::new(p0, p1, p2);
let n = Vector3::new(n0, n1, n2);
let p_u = p + n*0.001;
let p_l = p - n*0.001;
assert_relative_eq!(HRBF_eval(hrbf, p[0], p[1], p[2]), 0.0, max_relative=1e-6, epsilon=1e-11);
let p_u = p + n * 0.001;
let p_l = p - n * 0.001;
assert_relative_eq!(
HRBF_eval(hrbf, p[0], p[1], p[2]),
0.0,
max_relative = 1e-6,
epsilon = 1e-11
);
assert!(HRBF_eval(hrbf, p_l[0], p_l[1], p_l[2]) < 0.0);
assert!(HRBF_eval(hrbf, p_u[0], p_u[1], p_u[2]) > 0.0);
let mut g = [0.0f64; 3];
HRBF_grad(hrbf, p[0], p[1], p[2], g.as_mut_ptr());
assert_relative_eq!(g[0], n[0], max_relative=1e-6, epsilon=1e-11);
assert_relative_eq!(g[1], n[1], max_relative=1e-6, epsilon=1e-11);
assert_relative_eq!(g[2], n[2], max_relative=1e-6, epsilon=1e-11);
assert_relative_eq!(g[0], n[0], max_relative = 1e-6, epsilon = 1e-11);
assert_relative_eq!(g[1], n[1], max_relative = 1e-6, epsilon = 1e-11);
assert_relative_eq!(g[2], n[2], max_relative = 1e-6, epsilon = 1e-11);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment