use crate::error::Error;
use crate::filter::Filter;
use crate::pipeline::{Frame, Frameset};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PointFormat {
Xyz,
XyzRgb,
}
impl PointFormat {
pub fn as_raw(&self) -> i32 {
match self {
PointFormat::Xyz => orbbec_sys::OBFormat_OB_FORMAT_POINT,
PointFormat::XyzRgb => orbbec_sys::OBFormat_OB_FORMAT_RGB_POINT,
}
}
}
pub struct PointCloudFilter {
inner: Filter,
}unsafe impl Send for PointCloudFilter {}
impl PointCloudFilter {
pub fn new() -> Result<Self, Error> {
Ok(Self {
inner: Filter::new("PointCloudFilter")?,
})
}
pub fn as_raw(&self) -> *mut orbbec_sys::ob_filter {
self.inner.as_raw()
}
pub fn set_point_format(&self, format: PointFormat) -> Result<(), Error> {
self.inner
.set_config_value("pointFormat", format.as_raw() as f64)
}
pub fn set_decimate(&self, factor: u32) -> Result<(), Error> {
self.inner.set_config_value("decimate", factor.clamp(1, 8) as f64)
}
pub fn set_coordinate_scale(&self, scale: f32) -> Result<(), Error> {
self.inner.set_config_value("coordinateDataScale", scale as f64)
}
pub fn generate(&self, frameset: &Frameset) -> Result<Option<Frame>, Error> {
self.inner.process_frameset(frameset)
}
pub fn generate_frame(&self, frame: &Frame) -> Result<Option<Frame>, Error> {
self.inner.process(frame)
}
pub fn set_callback<F>(&self, callback: F) -> Result<(), Error>
where
F: FnMut(Frame) + Send + 'static,
{
self.inner.set_callback(callback)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ColorPoint {
pub x: f32,
pub y: f32,
pub z: f32,
pub r: f32,
pub g: f32,
pub b: f32,
}
pub struct ThresholdFilter {
inner: Filter,
}
impl ThresholdFilter {
pub fn new() -> Result<Self, Error> {
Ok(Self {
inner: Filter::new("ThresholdFilter")?,
})
}
pub fn set_min_mm(&self, value: u16) -> Result<(), Error> {
self.inner.set_config_value("min", value as f64)
}
pub fn set_max_mm(&self, value: u16) -> Result<(), Error> {
self.inner.set_config_value("max", value as f64)
}
pub fn process(&self, frame: &Frame) -> Result<Option<Frame>, Error> {
self.inner.process(frame)
}
}
pub struct DecimationFilter {
inner: Filter,
}
impl DecimationFilter {
pub fn new() -> Result<Self, Error> {
Ok(Self {
inner: Filter::new("DecimationFilter")?,
})
}
pub fn set_decimate(&self, factor: u32) -> Result<(), Error> {
self.inner.set_config_value("decimate", factor.clamp(1, 8) as f64)
}
pub fn process(&self, frame: &Frame) -> Result<Option<Frame>, Error> {
self.inner.process(frame)
}
}
pub struct PointCloud {
frame: Frame,
format: PointFormat,
}
impl PointCloud {
pub fn from_frame(frame: Frame, format: PointFormat) -> Self {
Self { frame, format }
}
pub fn len(&self) -> usize {
let stride = match self.format {
PointFormat::Xyz => 12,
PointFormat::XyzRgb => 24,
};
self.frame.data_size() as usize / stride
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn data(&self) -> &[u8] {
self.frame.data()
}
pub fn points(&self) -> Vec<[f32; 3]> {
match self.format {
PointFormat::Xyz => self
.data()
.chunks_exact(12)
.map(|c| {
let x = f32::from_le_bytes([c[0], c[1], c[2], c[3]]);
let y = f32::from_le_bytes([c[4], c[5], c[6], c[7]]);
let z = f32::from_le_bytes([c[8], c[9], c[10], c[11]]);
[x, y, z]
})
.collect(),
PointFormat::XyzRgb => self
.data()
.chunks_exact(24)
.map(|c| {
let x = f32::from_le_bytes([c[0], c[1], c[2], c[3]]);
let y = f32::from_le_bytes([c[4], c[5], c[6], c[7]]);
let z = f32::from_le_bytes([c[8], c[9], c[10], c[11]]);
[x, y, z]
})
.collect(),
}
}
pub fn points_in_range(&self, min_m: f32, max_m: f32) -> Vec<[f32; 3]> {
self.points()
.into_iter()
.filter(|p| p[2] >= min_m && p[2] <= max_m)
.collect()
}
pub fn colored_points(&self) -> Vec<ColorPoint> {
match self.format {
PointFormat::Xyz => Vec::new(),
PointFormat::XyzRgb => self
.data()
.chunks_exact(24)
.map(|c| {
let x = f32::from_le_bytes([c[0], c[1], c[2], c[3]]);
let y = f32::from_le_bytes([c[4], c[5], c[6], c[7]]);
let z = f32::from_le_bytes([c[8], c[9], c[10], c[11]]);
let r = f32::from_le_bytes([c[12], c[13], c[14], c[15]]);
let g = f32::from_le_bytes([c[16], c[17], c[18], c[19]]);
let b = f32::from_le_bytes([c[20], c[21], c[22], c[23]]);
ColorPoint { x, y, z, r, g, b }
})
.collect(),
}
}
}