pub struct SelectionBuffer(/* private fields */);Expand description
The selection storage buffer.
This buffer holds the selection bitmask for Gaussians, where each bit represents whether a Gaussian is selected (1) or not (0).
Implementations§
Source§impl SelectionBuffer
impl SelectionBuffer
Sourcepub fn new(device: &Device, gaussian_count: u32) -> Self
pub fn new(device: &Device, gaussian_count: u32) -> Self
Create a new selection buffer.
Examples found in repository?
examples/filter_selection.rs (line 195)
98async fn main() {
99 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
100
101 let args = Args::parse();
102 let model_path = &args.model;
103 let pos = Vec3::from_slice(&args.pos);
104 let rot = Quat::from_slice(&args.rot);
105 let scale = Vec3::from_slice(&args.scale);
106 let shape = match args.shape {
107 Shape::Sphere => gs::SelectionBundle::<GaussianPod>::create_sphere_bundle,
108 Shape::Box => gs::SelectionBundle::<GaussianPod>::create_box_bundle,
109 };
110 let repeat = args.repeat;
111 let offset = Vec3::from_slice(&args.offset);
112
113 log::debug!("Creating wgpu instance");
114 let instance =
115 wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle_from_env());
116
117 log::debug!("Requesting adapter");
118 let adapter = instance
119 .request_adapter(&wgpu::RequestAdapterOptions::default())
120 .await
121 .expect("adapter");
122
123 log::debug!("Requesting device");
124 let (device, queue) = adapter
125 .request_device(&wgpu::DeviceDescriptor {
126 label: Some("Device"),
127 required_limits: adapter.limits(),
128 ..Default::default()
129 })
130 .await
131 .expect("device");
132
133 log::debug!("Creating gaussians");
134 let gaussians = [
135 gs::core::GaussiansSource::Ply,
136 gs::core::GaussiansSource::Spz,
137 ]
138 .into_iter()
139 .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
140 .expect("gaussians");
141
142 log::debug!("Creating gaussians buffer");
143 let gaussians_buffer = gs::core::GaussiansBuffer::<GaussianPod>::new(&device, &gaussians);
144
145 log::debug!("Creating model transform buffer");
146 let model_transform = gs::core::ModelTransformBuffer::new(&device);
147
148 log::debug!("Creating Gaussian transform buffer");
149 let gaussian_transform = gs::core::GaussianTransformBuffer::new(&device);
150
151 log::debug!("Creating shape selection compute bundle");
152 let shape_selection = shape(&device);
153
154 log::debug!("Creating selection bundle");
155 let selection_bundle = gs::SelectionBundle::<GaussianPod>::new(&device, vec![shape_selection]);
156
157 log::debug!("Creating shape selection buffers");
158 let shape_selection_buffers = (0..repeat)
159 .map(|i| {
160 let offset_pos = pos + offset * i as f32;
161 let buffer = gs::InvTransformBuffer::new(&device);
162 buffer.update_with_scale_rot_pos(&queue, scale, rot, offset_pos);
163 buffer
164 })
165 .collect::<Vec<_>>();
166
167 log::debug!("Creating shape selection bind groups");
168 let shape_selection_bind_groups = shape_selection_buffers
169 .iter()
170 .map(|buffer| {
171 selection_bundle.bundles[0]
172 .create_bind_group(
173 &device,
174 // index 0 is the Gaussians buffer, so we use 1,
175 // see docs of create_sphere_bundle or create_box_bundle
176 1,
177 [buffer.buffer().as_entire_binding()],
178 )
179 .expect("bind group")
180 })
181 .collect::<Vec<_>>();
182
183 log::debug!("Creating selection expression");
184 let selection_expr = shape_selection_bind_groups.into_iter().fold(
185 gs::SelectionExpr::Identity,
186 |acc, bind_group| {
187 acc.union(gs::SelectionExpr::selection(
188 0, // the 0 here is the bundle index in the selection bundle
189 vec![bind_group],
190 ))
191 },
192 );
193
194 log::debug!("Creating destination buffer");
195 let dest = gs::SelectionBuffer::new(&device, gaussians_buffer.len() as u32);
196
197 log::info!("Starting selection process");
198 let time = std::time::Instant::now();
199
200 log::debug!("Selecting Gaussians");
201 let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
202 label: Some("Selection Encoder"),
203 });
204
205 selection_bundle.evaluate(
206 &device,
207 &mut encoder,
208 &selection_expr,
209 &dest,
210 &model_transform,
211 &gaussian_transform,
212 &gaussians_buffer,
213 );
214
215 queue.submit(Some(encoder.finish()));
216
217 device
218 .poll(wgpu::PollType::wait_indefinitely())
219 .expect("poll");
220
221 log::info!("Editing process completed in {:?}", time.elapsed());
222
223 log::debug!("Filtering Gaussians");
224 let selected_gaussians = dest
225 .download::<u32>(&device, &queue)
226 .await
227 .expect("selected download")
228 .iter()
229 .flat_map(|group| {
230 std::iter::repeat_n(group, 32)
231 .enumerate()
232 .map(|(i, g)| g & (1 << i) != 0)
233 })
234 .zip(gaussians.iter_gaussian())
235 .filter(|(selected, _)| *selected)
236 .map(|(_, g)| g)
237 .collect::<Vec<_>>();
238
239 let selected_gaussians = match &args.output[args.output.len().saturating_sub(4)..] {
240 ".ply" => gs::core::Gaussians::Ply(gs::core::PlyGaussians::from_iter(
241 selected_gaussians.into_iter(),
242 )),
243 ".spz" => {
244 gs::core::Gaussians::Spz(
245 gs::core::SpzGaussians::from_gaussians_with_options(
246 selected_gaussians,
247 &gs::core::SpzGaussiansFromGaussianSliceOptions {
248 version: 2, // Version 2 is more widely supported as of now
249 ..Default::default()
250 },
251 )
252 .expect("SpzGaussians from gaussians"),
253 )
254 }
255 _ => panic!("Unsupported output file extension, expected .ply or .spz"),
256 };
257
258 log::debug!("Writing modified Gaussians to output file");
259 selected_gaussians
260 .write_to_file(&args.output)
261 .expect("write modified Gaussians to output file");
262
263 log::info!("Filtered Gaussians written to {}", args.output);
264}Sourcepub fn new_with_label(device: &Device, label: &str, gaussian_count: u32) -> Self
pub fn new_with_label(device: &Device, label: &str, gaussian_count: u32) -> Self
Create a new selection buffer with additional label.
Trait Implementations§
Source§impl BufferWrapper for SelectionBuffer
impl BufferWrapper for SelectionBuffer
Source§const DEFAULT_USAGES: BufferUsages
const DEFAULT_USAGES: BufferUsages
The default usages.
Source§fn download<'life0, 'life1, 'life2, 'async_trait, T>(
&'life0 self,
device: &'life1 Device,
queue: &'life2 Queue,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Send + Sync + 'async_trait,
T: 'async_trait + NoUninit + AnyBitPattern,
fn download<'life0, 'life1, 'life2, 'async_trait, T>(
&'life0 self,
device: &'life1 Device,
queue: &'life2 Queue,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: Send + Sync + 'async_trait,
T: 'async_trait + NoUninit + AnyBitPattern,
Download the buffer data into a
Vec.Source§fn prepare_download(
&self,
device: &Device,
encoder: &mut CommandEncoder,
) -> Buffer
fn prepare_download( &self, device: &Device, encoder: &mut CommandEncoder, ) -> Buffer
Prepare for downloading the buffer data. Read more
Source§fn map_download<'life0, 'life1, 'async_trait, T>(
download: &'life0 Buffer,
device: &'life1 Device,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
T: 'async_trait + NoUninit + AnyBitPattern,
Self: Send + 'async_trait,
fn map_download<'life0, 'life1, 'async_trait, T>(
download: &'life0 Buffer,
device: &'life1 Device,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
T: 'async_trait + NoUninit + AnyBitPattern,
Self: Send + 'async_trait,
Map the download buffer to read the buffer data. Read more
Source§fn map_download_with_poll_type<'life0, 'life1, 'async_trait, T>(
download: &'life0 Buffer,
device: &'life1 Device,
poll_type: PollType<SubmissionIndex>,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
T: 'async_trait + NoUninit + AnyBitPattern,
fn map_download_with_poll_type<'life0, 'life1, 'async_trait, T>(
download: &'life0 Buffer,
device: &'life1 Device,
poll_type: PollType<SubmissionIndex>,
) -> Pin<Box<dyn Future<Output = Result<Vec<T>, DownloadBufferError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
T: 'async_trait + NoUninit + AnyBitPattern,
Map the download buffer to read the buffer data with custom
wgpu::PollType. Read moreSource§impl Clone for SelectionBuffer
impl Clone for SelectionBuffer
Source§fn clone(&self) -> SelectionBuffer
fn clone(&self) -> SelectionBuffer
Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for SelectionBuffer
impl Debug for SelectionBuffer
Source§impl From<Buffer> for SelectionBuffer
impl From<Buffer> for SelectionBuffer
Source§impl From<SelectionBuffer> for Buffer
impl From<SelectionBuffer> for Buffer
Source§fn from(wrapper: SelectionBuffer) -> Self
fn from(wrapper: SelectionBuffer) -> Self
Converts to this type from the input type.
Auto Trait Implementations§
impl Freeze for SelectionBuffer
impl !RefUnwindSafe for SelectionBuffer
impl Send for SelectionBuffer
impl Sync for SelectionBuffer
impl Unpin for SelectionBuffer
impl UnsafeUnpin for SelectionBuffer
impl !UnwindSafe for SelectionBuffer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more