fast_gicp_sys/
lib.rs

1//! Low-level FFI bindings for the fast_gicp C++ library.
2//!
3//! This crate provides unsafe bindings to the fast_gicp C++ library through the cxx crate.
4//! For a safe, high-level API, use the `fast-gicp` crate instead.
5
6// Configuration based on features:
7// - Default: Use cxx::bridge directly with C++ compilation
8// - docs-only: Use pre-generated stub (no C++ compilation)
9// - bindgen: Regenerate stubs (for maintainers)
10
11// Normal builds: use actual cxx::bridge directly
12#[cfg(not(feature = "docs-only"))]
13#[cxx::bridge]
14pub mod ffi {
15    // FFI-safe structs
16    #[derive(Debug, Clone, Copy)]
17    pub struct Transform4f {
18        pub data: [f32; 16],
19    }
20
21    #[derive(Debug, Clone, Copy)]
22    pub struct Point3f {
23        pub x: f32,
24        pub y: f32,
25        pub z: f32,
26    }
27
28    #[derive(Debug, Clone, Copy)]
29    pub struct Point4f {
30        pub x: f32,
31        pub y: f32,
32        pub z: f32,
33        pub intensity: f32,
34    }
35
36    unsafe extern "C++" {
37        include!("wrapper.h");
38
39        // === Core Types ===
40        type PointCloudXYZ;
41        type PointCloudXYZI;
42
43        // Registration types
44        type FastGICP;
45        type FastVGICP;
46        type FastGICPI;
47        type FastVGICPI;
48
49        // CUDA types (always declared for CXX compatibility, dummy types when CUDA disabled)
50        type FastVGICPCuda;
51        type NDTCuda;
52
53        // === Point Cloud Factory Functions ===
54        fn create_point_cloud_xyz() -> UniquePtr<PointCloudXYZ>;
55        fn create_point_cloud_xyzi() -> UniquePtr<PointCloudXYZI>;
56
57        // === Point Cloud Operations ===
58        fn point_cloud_xyz_size(cloud: &PointCloudXYZ) -> usize;
59        fn point_cloud_xyz_empty(cloud: &PointCloudXYZ) -> bool;
60        fn point_cloud_xyz_clear(cloud: Pin<&mut PointCloudXYZ>);
61        fn point_cloud_xyz_reserve(cloud: Pin<&mut PointCloudXYZ>, capacity: usize);
62        fn point_cloud_xyz_push_point(cloud: Pin<&mut PointCloudXYZ>, x: f32, y: f32, z: f32);
63        fn point_cloud_xyz_get_point(cloud: &PointCloudXYZ, index: usize) -> Point3f;
64        fn point_cloud_xyz_set_point(
65            cloud: Pin<&mut PointCloudXYZ>,
66            index: usize,
67            x: f32,
68            y: f32,
69            z: f32,
70        );
71
72        fn point_cloud_xyzi_size(cloud: &PointCloudXYZI) -> usize;
73        fn point_cloud_xyzi_empty(cloud: &PointCloudXYZI) -> bool;
74        fn point_cloud_xyzi_clear(cloud: Pin<&mut PointCloudXYZI>);
75        fn point_cloud_xyzi_reserve(cloud: Pin<&mut PointCloudXYZI>, capacity: usize);
76        fn point_cloud_xyzi_push_point(
77            cloud: Pin<&mut PointCloudXYZI>,
78            x: f32,
79            y: f32,
80            z: f32,
81            intensity: f32,
82        );
83        fn point_cloud_xyzi_get_point(cloud: &PointCloudXYZI, index: usize) -> Point4f;
84        fn point_cloud_xyzi_set_point(
85            cloud: Pin<&mut PointCloudXYZI>,
86            index: usize,
87            x: f32,
88            y: f32,
89            z: f32,
90            intensity: f32,
91        );
92
93        // === GICP Factory Functions ===
94        fn create_fast_gicp() -> UniquePtr<FastGICP>;
95        fn create_fast_vgicp() -> UniquePtr<FastVGICP>;
96        fn create_fast_gicp_i() -> UniquePtr<FastGICPI>;
97        fn create_fast_vgicp_i() -> UniquePtr<FastVGICPI>;
98
99        // CUDA factory functions (conditionally compiled)
100        #[cfg(feature = "cuda")]
101        fn create_fast_vgicp_cuda() -> UniquePtr<FastVGICPCuda>;
102        #[cfg(feature = "cuda")]
103        fn create_ndt_cuda() -> UniquePtr<NDTCuda>;
104
105        // === Registration Configuration ===
106        fn fast_gicp_set_input_source(gicp: Pin<&mut FastGICP>, cloud: &PointCloudXYZ);
107        fn fast_gicp_set_input_target(gicp: Pin<&mut FastGICP>, cloud: &PointCloudXYZ);
108        fn fast_gicp_set_max_iterations(gicp: Pin<&mut FastGICP>, max_iterations: i32);
109        fn fast_gicp_set_transformation_epsilon(gicp: Pin<&mut FastGICP>, eps: f64);
110        fn fast_gicp_set_euclidean_fitness_epsilon(gicp: Pin<&mut FastGICP>, eps: f64);
111        fn fast_gicp_set_max_correspondence_distance(gicp: Pin<&mut FastGICP>, distance: f64);
112        fn fast_gicp_set_num_threads(gicp: Pin<&mut FastGICP>, num_threads: i32);
113        fn fast_gicp_set_correspondence_randomness(gicp: Pin<&mut FastGICP>, k: i32);
114        fn fast_gicp_set_regularization_method(gicp: Pin<&mut FastGICP>, method: i32);
115        fn fast_gicp_set_rotation_epsilon(gicp: Pin<&mut FastGICP>, eps: f64);
116
117        fn fast_vgicp_set_input_source(vgicp: Pin<&mut FastVGICP>, cloud: &PointCloudXYZ);
118        fn fast_vgicp_set_input_target(vgicp: Pin<&mut FastVGICP>, cloud: &PointCloudXYZ);
119        fn fast_vgicp_set_max_iterations(vgicp: Pin<&mut FastVGICP>, max_iterations: i32);
120        fn fast_vgicp_set_transformation_epsilon(vgicp: Pin<&mut FastVGICP>, eps: f64);
121        fn fast_vgicp_set_euclidean_fitness_epsilon(vgicp: Pin<&mut FastVGICP>, eps: f64);
122        fn fast_vgicp_set_max_correspondence_distance(vgicp: Pin<&mut FastVGICP>, distance: f64);
123        fn fast_vgicp_set_resolution(vgicp: Pin<&mut FastVGICP>, resolution: f64);
124        fn fast_vgicp_set_num_threads(vgicp: Pin<&mut FastVGICP>, num_threads: i32);
125        fn fast_vgicp_set_regularization_method(vgicp: Pin<&mut FastVGICP>, method: i32);
126        fn fast_vgicp_set_voxel_accumulation_mode(vgicp: Pin<&mut FastVGICP>, mode: i32);
127        fn fast_vgicp_set_neighbor_search_method(vgicp: Pin<&mut FastVGICP>, method: i32);
128
129        // CUDA configuration functions (conditionally compiled)
130        #[cfg(feature = "cuda")]
131        fn fast_vgicp_cuda_set_input_source(
132            cuda_vgicp: Pin<&mut FastVGICPCuda>,
133            cloud: &PointCloudXYZ,
134        );
135        #[cfg(feature = "cuda")]
136        fn fast_vgicp_cuda_set_input_target(
137            cuda_vgicp: Pin<&mut FastVGICPCuda>,
138            cloud: &PointCloudXYZ,
139        );
140        #[cfg(feature = "cuda")]
141        fn fast_vgicp_cuda_set_max_iterations(
142            cuda_vgicp: Pin<&mut FastVGICPCuda>,
143            max_iterations: i32,
144        );
145        #[cfg(feature = "cuda")]
146        fn fast_vgicp_cuda_set_transformation_epsilon(
147            cuda_vgicp: Pin<&mut FastVGICPCuda>,
148            eps: f64,
149        );
150        #[cfg(feature = "cuda")]
151        fn fast_vgicp_cuda_set_euclidean_fitness_epsilon(
152            cuda_vgicp: Pin<&mut FastVGICPCuda>,
153            eps: f64,
154        );
155        #[cfg(feature = "cuda")]
156        fn fast_vgicp_cuda_set_max_correspondence_distance(
157            cuda_vgicp: Pin<&mut FastVGICPCuda>,
158            distance: f64,
159        );
160        #[cfg(feature = "cuda")]
161        fn fast_vgicp_cuda_set_resolution(cuda_vgicp: Pin<&mut FastVGICPCuda>, resolution: f64);
162        #[cfg(feature = "cuda")]
163        fn fast_vgicp_cuda_set_neighbor_search_method(
164            cuda_vgicp: Pin<&mut FastVGICPCuda>,
165            method: i32,
166        );
167
168        // === Registration Execution ===
169        fn fast_gicp_align(gicp: Pin<&mut FastGICP>) -> Transform4f;
170        fn fast_gicp_align_with_guess(gicp: Pin<&mut FastGICP>, guess: &Transform4f)
171            -> Transform4f;
172
173        fn fast_vgicp_align(vgicp: Pin<&mut FastVGICP>) -> Transform4f;
174        fn fast_vgicp_align_with_guess(
175            vgicp: Pin<&mut FastVGICP>,
176            guess: &Transform4f,
177        ) -> Transform4f;
178
179        // CUDA execution functions (conditionally compiled)
180        #[cfg(feature = "cuda")]
181        fn fast_vgicp_cuda_align(cuda_vgicp: Pin<&mut FastVGICPCuda>) -> Transform4f;
182        #[cfg(feature = "cuda")]
183        fn fast_vgicp_cuda_align_with_guess(
184            cuda_vgicp: Pin<&mut FastVGICPCuda>,
185            guess: &Transform4f,
186        ) -> Transform4f;
187
188        // === Registration Status ===
189        fn fast_gicp_has_converged(gicp: &FastGICP) -> bool;
190        fn fast_gicp_get_fitness_score(gicp: &FastGICP) -> f64;
191        fn fast_gicp_get_final_num_iterations(gicp: &FastGICP) -> i32;
192
193        fn fast_vgicp_has_converged(vgicp: &FastVGICP) -> bool;
194        fn fast_vgicp_get_fitness_score(vgicp: &FastVGICP) -> f64;
195        fn fast_vgicp_get_final_num_iterations(vgicp: &FastVGICP) -> i32;
196
197        // CUDA status functions (conditionally compiled)
198        #[cfg(feature = "cuda")]
199        fn fast_vgicp_cuda_has_converged(cuda_vgicp: &FastVGICPCuda) -> bool;
200        #[cfg(feature = "cuda")]
201        fn fast_vgicp_cuda_get_fitness_score(cuda_vgicp: &FastVGICPCuda) -> f64;
202        #[cfg(feature = "cuda")]
203        fn fast_vgicp_cuda_get_final_num_iterations(cuda_vgicp: &FastVGICPCuda) -> i32;
204
205        // === NDTCuda Operations ===
206        // NDTCuda type and factory function are already declared above for CXX compatibility
207
208        // NDTCuda configuration
209        #[cfg(feature = "cuda")]
210        fn ndt_cuda_set_input_source(ndt_cuda: Pin<&mut NDTCuda>, cloud: &PointCloudXYZ);
211        #[cfg(feature = "cuda")]
212        fn ndt_cuda_set_input_target(ndt_cuda: Pin<&mut NDTCuda>, cloud: &PointCloudXYZ);
213        #[cfg(feature = "cuda")]
214        fn ndt_cuda_set_max_iterations(ndt_cuda: Pin<&mut NDTCuda>, max_iterations: i32);
215        #[cfg(feature = "cuda")]
216        fn ndt_cuda_set_transformation_epsilon(ndt_cuda: Pin<&mut NDTCuda>, eps: f64);
217        #[cfg(feature = "cuda")]
218        fn ndt_cuda_set_euclidean_fitness_epsilon(ndt_cuda: Pin<&mut NDTCuda>, eps: f64);
219        #[cfg(feature = "cuda")]
220        fn ndt_cuda_set_max_correspondence_distance(ndt_cuda: Pin<&mut NDTCuda>, distance: f64);
221        #[cfg(feature = "cuda")]
222        fn ndt_cuda_set_resolution(ndt_cuda: Pin<&mut NDTCuda>, resolution: f64);
223        #[cfg(feature = "cuda")]
224        fn ndt_cuda_set_distance_mode(ndt_cuda: Pin<&mut NDTCuda>, mode: i32);
225        #[cfg(feature = "cuda")]
226        fn ndt_cuda_set_neighbor_search_method(
227            ndt_cuda: Pin<&mut NDTCuda>,
228            method: i32,
229            radius: f64,
230        );
231
232        // NDTCuda execution
233        #[cfg(feature = "cuda")]
234        fn ndt_cuda_align(ndt_cuda: Pin<&mut NDTCuda>) -> Transform4f;
235        #[cfg(feature = "cuda")]
236        fn ndt_cuda_align_with_guess(
237            ndt_cuda: Pin<&mut NDTCuda>,
238            guess: &Transform4f,
239        ) -> Transform4f;
240
241        // NDTCuda status
242        #[cfg(feature = "cuda")]
243        fn ndt_cuda_has_converged(ndt_cuda: &NDTCuda) -> bool;
244        #[cfg(feature = "cuda")]
245        fn ndt_cuda_get_fitness_score(ndt_cuda: &NDTCuda) -> f64;
246        #[cfg(feature = "cuda")]
247        fn ndt_cuda_get_final_num_iterations(ndt_cuda: &NDTCuda) -> i32;
248
249        // === Transform Utilities ===
250        fn transform_identity() -> Transform4f;
251        fn transform_from_translation(x: f32, y: f32, z: f32) -> Transform4f;
252        fn transform_multiply(a: &Transform4f, b: &Transform4f) -> Transform4f;
253        fn transform_inverse(t: &Transform4f) -> Transform4f;
254    }
255}
256
257// Docs-only builds: use appropriate stub based on CUDA feature
258#[cfg(all(feature = "docs-only", not(feature = "cuda")))]
259include!("generated/stub.rs");
260
261#[cfg(all(feature = "docs-only", feature = "cuda"))]
262include!("generated/stub_cuda.rs");
263
264// Re-export the types for convenience
265pub use ffi::{Point3f, Point4f, Transform4f};
266
267#[cfg(test)]
268mod test;
269
270#[cfg(feature = "docs-only")]
271#[cfg(test)]
272mod docs_only_tests {
273    use super::ffi::{Point3f, Point4f, Transform4f};
274
275    #[test]
276    fn test_types_exist() {
277        // Test that basic types can be created
278        let _point3f = Point3f {
279            x: 1.0,
280            y: 2.0,
281            z: 3.0,
282        };
283        let _point4f = Point4f {
284            x: 1.0,
285            y: 2.0,
286            z: 3.0,
287            intensity: 4.0,
288        };
289        let _transform = Transform4f { data: [0.0; 16] };
290    }
291}