#![allow(unused_macros)]
#![allow(unused_unsafe)]
#![allow(non_camel_case_types)]
use std::collections::HashMap;
use std::fmt;
use std::marker::PhantomData;
use paste::paste;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
use nalgebra::{DMatrix, DVector, Point3, Quaternion, Vector4};
#[path = "./pcl_header.rs"]
mod pcl_header;
use pcl_header::PclHeader;
struct FieldMapping {
serialized_offset: usize,
struct_offset: usize,
size: usize,
}
type MsgFieldMap = Vec<FieldMapping>;
struct NdCopyEigenPointFunctor<PointOutputType> {
p1: DVector<f32>,
p2: *mut PointOutputType,
f_idx: usize,
}
impl<PointOutputType> NdCopyEigenPointFunctor<PointOutputType> {
fn new(p1: DVector<f32>, p2: &mut PointOutputType) -> Self {
Self {
p1,
p2: p2 as *mut PointOutputType,
f_idx: 0,
}
}
}
struct NdCopyPointEigenFunctor<PointInT> {
p1: *const PointInT,
p2: DVector<f32>,
f_idx: usize,
}
impl<PointInT> NdCopyPointEigenFunctor<PointInT> {
fn new(p1: &PointInT, p2: DVector<f32>) -> Self {
Self {
p1: p1 as *const PointInT,
p2,
f_idx: 0,
}
}
}
#[derive(Clone, Debug)]
pub struct PointCloud<PointType> {
pub header: PclHeader,
pub points: Vec<PointType>,
pub size: u32,
pub width: u32,
pub height: u32,
pub is_dense: bool,
pub sensor_origin: Vector4<f32>,
pub sensor_orientation: Quaternion<f32>,
_m: PhantomData<PointType>,
}
impl<PointType: Clone> PointCloud<PointType> {
pub fn new() -> Self {
PointCloud {
header: PclHeader::new_auto(),
points: Vec::<PointType>::new(),
size: 0,
width: 0,
height: 0,
is_dense: true,
sensor_origin: Vector4::zeros(),
sensor_orientation: Quaternion::identity(),
_m: PhantomData::<PointType>,
}
}
pub fn from_points_vec(input_points_vec: Vec<PointType>) -> Self {
let len = input_points_vec.len() as u32;
Self {
header: PclHeader::new_auto(),
points: input_points_vec,
size: len,
width: len,
height: 1,
is_dense: true,
sensor_origin: Vector4::zeros(),
sensor_orientation: Quaternion::identity(),
_m: PhantomData::<PointType>,
}
}
pub fn from_subset(pc: &PointCloud<PointType>, indices: &[usize]) -> Self {
let mut points = Vec::with_capacity(indices.len());
for &i in indices {
points.push(pc.points[i].clone());
}
let len = indices.len() as u32;
PointCloud {
header: pc.header.clone(),
points,
size: len,
width: len,
height: 1,
is_dense: pc.is_dense,
sensor_origin: pc.sensor_origin,
sensor_orientation: pc.sensor_orientation,
_m: PhantomData::<PointType>,
}
}
pub fn size(&self) -> usize {
self.points.len()
}
pub fn is_organized(&self) -> bool {
self.height > 1
}
pub fn clear(&mut self) {
self.points.clear();
self.width = 0;
self.height = 0;
}
}
impl<PointType> fmt::Display for PointCloud<PointType> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "header: {}", self.header)?;
writeln!(f, "points[]: {}", self.size)?;
writeln!(f, "width: {}", self.width)?;
writeln!(f, "height: {}", self.height)?;
writeln!(f, "is_dense: {}", self.is_dense)?;
writeln!(
f,
"sensor origin (xyz): [{}, {}, {}] / orientation (xyzw): [{}, {}, {}, {}]",
self.sensor_origin.x,
self.sensor_origin.y,
self.sensor_origin.z,
self.sensor_orientation.i,
self.sensor_orientation.j,
self.sensor_orientation.k,
self.sensor_orientation.w
)
}
}