diff --git a/src/pc_reader_raw.rs b/src/pc_reader_raw.rs index ec82b7a..629a395 100644 --- a/src/pc_reader_raw.rs +++ b/src/pc_reader_raw.rs @@ -1,4 +1,3 @@ -use crate::error::Converter; use crate::paged_reader::PagedReader; use crate::queue_reader::QueueReader; use crate::PointCloud; @@ -26,17 +25,6 @@ impl<'a, T: Read + Seek> PointCloudReaderRaw<'a, T> { read: 0, }) } - - fn pop_point(&mut self) -> Result { - let mut point = RawValues::with_capacity(self.prototype_len); - for i in 0..self.prototype_len { - let value = self.queue_reader.queues[i] - .pop_front() - .internal_err("Failed to pop value for next point")?; - point.push(value); - } - Ok(point) - } } impl<'a, T: Read + Seek> Iterator for PointCloudReaderRaw<'a, T> { @@ -58,8 +46,9 @@ impl<'a, T: Read + Seek> Iterator for PointCloudReaderRaw<'a, T> { } // Extract next point - match self.pop_point() { - Ok(point) => { + let mut point = RawValues::with_capacity(self.prototype_len); + match self.queue_reader.pop_point(&mut point) { + Ok(()) => { self.read += 1; Some(Ok(point)) } diff --git a/src/pc_reader_simple.rs b/src/pc_reader_simple.rs index 5e4e294..a5e0f2e 100644 --- a/src/pc_reader_simple.rs +++ b/src/pc_reader_simple.rs @@ -1,4 +1,3 @@ -use crate::error::Converter; use crate::paged_reader::PagedReader; use crate::queue_reader::QueueReader; use crate::{ @@ -144,13 +143,7 @@ impl<'a, T: Read + Seek> PointCloudReaderSimple<'a, T> { fn pop_point(&mut self) -> Result { // Read raw values of the point from queue - self.values.clear(); - for i in 0..self.pc.prototype.len() { - let value = self.queue_reader.queues[i] - .pop_front() - .internal_err("Failed to pop value for next point")?; - self.values.push(value); - } + self.queue_reader.pop_point(&mut self.values)?; // Some shortcuts for better readability let proto = &self.pc.prototype; diff --git a/src/queue_reader.rs b/src/queue_reader.rs index 98cc99b..51ee183 100644 --- a/src/queue_reader.rs +++ b/src/queue_reader.rs @@ -6,6 +6,7 @@ use crate::packet::PacketHeader; use crate::paged_reader::PagedReader; use crate::Error; use crate::PointCloud; +use crate::RawValues; use crate::RecordDataType; use crate::RecordValue; use crate::Result; @@ -13,14 +14,13 @@ use std::collections::VecDeque; use std::io::{Read, Seek}; /// Read compressed vector sections into queues of raw values. -/// There will be once queue for each record defined by the prototype. pub struct QueueReader<'a, T: Read + Seek> { pc: PointCloud, reader: &'a mut PagedReader, buffer: Vec, buffer_sizes: Vec, byte_streams: Vec, - pub queues: Vec>, + queues: Vec>, } impl<'a, T: Read + Seek> QueueReader<'a, T> { @@ -59,6 +59,19 @@ impl<'a, T: Read + Seek> QueueReader<'a, T> { av } + /// Return values for the next point by popping one value from each queue. + /// Use an existing vector with enough capacity to avoid frequent reallocations! + pub fn pop_point(&mut self, output: &mut RawValues) -> Result<()> { + output.clear(); + for i in 0..self.pc.prototype.len() { + let value = self.queues[i] + .pop_front() + .internal_err("Failed to pop value for next point")?; + output.push(value); + } + Ok(()) + } + /// Reads the next packet from the compressed vector and decodes it into the queues. pub fn advance(&mut self) -> Result<()> { let packet_header = PacketHeader::read(self.reader)?;