BasicSelectionModifier

Type Alias BasicSelectionModifier 

Source
pub type BasicSelectionModifier<G> = SelectionModifier<G, BasicModifier<G, WithSelection>>;
Expand description

A type alias of SelectionModifier with BasicModifier.

Aliased Type§

pub struct BasicSelectionModifier<G> {
    pub selection_expr: SelectionExpr,
    pub selection_buffer: SelectionBuffer,
    pub selection: SelectionBundle<G>,
    pub modifier: BasicModifier<G, WithSelection>,
}

Fields§

§selection_expr: SelectionExpr§selection_buffer: SelectionBuffer§selection: SelectionBundle<G>§modifier: BasicModifier<G, WithSelection>

Implementations§

Source§

impl<G: GaussianPod> BasicSelectionModifier<G>

Source

pub fn new_with_basic_modifier( device: &Device, gaussians_buffer: &GaussiansBuffer<G>, model_transform: &ModelTransformBuffer, gaussian_transform: &GaussianTransformBuffer, selection_bundles: Vec<ComputeBundle<()>>, ) -> Self

Create a new selection modifier with BasicModifier.

bundles are used for SelectionExpr::Unary, SelectionExpr::Binary, or SelectionExpr::Selection, they must have the same bind group 0 as the SelectionBundle::GAUSSIANS_BIND_GROUP_LAYOUT_DESCRIPTOR, see documentation of SelectionBundle for more details.

Examples found in repository?
examples/modify_selection.rs (lines 187-193)
137async fn main() {
138    env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
139
140    let args = Args::parse();
141    let model_path = &args.model;
142    let pos = Vec3::from_slice(&args.pos);
143    let rot = Quat::from_slice(&args.rot);
144    let scale = Vec3::from_slice(&args.scale);
145    let shape = match args.shape {
146        Shape::Sphere => gs::SelectionBundle::<GaussianPod>::create_sphere_bundle,
147        Shape::Box => gs::SelectionBundle::<GaussianPod>::create_box_bundle,
148    };
149    let repeat = args.repeat;
150    let offset = Vec3::from_slice(&args.offset);
151
152    log::debug!("Creating wgpu instance");
153    let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
154
155    log::debug!("Requesting adapter");
156    let adapter = instance
157        .request_adapter(&wgpu::RequestAdapterOptions::default())
158        .await
159        .expect("adapter");
160
161    log::debug!("Requesting device");
162    let (device, queue) = adapter
163        .request_device(&wgpu::DeviceDescriptor {
164            label: Some("Device"),
165            required_limits: adapter.limits(),
166            ..Default::default()
167        })
168        .await
169        .expect("device");
170
171    log::debug!("Creating gaussians");
172    let gaussians = [
173        gs::core::GaussiansSource::Ply,
174        gs::core::GaussiansSource::Spz,
175    ]
176    .into_iter()
177    .find_map(|source| gs::core::Gaussians::read_from_file(model_path, source).ok())
178    .expect("gaussians");
179
180    log::debug!("Creating editor");
181    let editor = gs::Editor::<GaussianPod>::new(&device, &gaussians);
182
183    log::debug!("Creating shape selection compute bundle");
184    let shape_selection = shape(&device);
185
186    log::debug!("Creating basic selection modifier");
187    let mut basic_selection_modifier = gs::SelectionModifier::new_with_basic_modifier(
188        &device,
189        &editor.gaussians_buffer,
190        &editor.model_transform_buffer,
191        &editor.gaussian_transform_buffer,
192        vec![shape_selection],
193    );
194
195    log::debug!("Configuring modifiers");
196    basic_selection_modifier
197        .modifier
198        .basic_color_modifiers_buffer
199        .update(
200            &queue,
201            match args.override_rgb {
202                true => gs::BasicColorRgbOverrideOrHsvModifiersPod::new_rgb_override,
203                false => gs::BasicColorRgbOverrideOrHsvModifiersPod::new_hsv_modifiers,
204            }(Vec3::from_slice(&args.rgb_or_hsv)),
205            args.alpha,
206            args.contrast,
207            args.exposure,
208            args.gamma,
209        );
210
211    log::debug!("Creating shape selection buffers");
212    let shape_selection_buffers = (0..repeat)
213        .map(|i| {
214            let offset_pos = pos + offset * i as f32;
215            let buffer = gs::InvTransformBuffer::new(&device);
216            buffer.update_with_scale_rot_pos(&queue, scale, rot, offset_pos);
217            buffer
218        })
219        .collect::<Vec<_>>();
220
221    log::debug!("Creating shape selection bind groups");
222    let shape_selection_bind_groups = shape_selection_buffers
223        .iter()
224        .map(|buffer| {
225            basic_selection_modifier.selection.bundles[0]
226                .create_bind_group(
227                    &device,
228                    // index 0 is the Gaussians buffer, so we use 1,
229                    // see docs of create_sphere_bundle or create_box_bundle
230                    1,
231                    [buffer.buffer().as_entire_binding()],
232                )
233                .expect("bind group")
234        })
235        .collect::<Vec<_>>();
236
237    log::debug!("Creating selection expression");
238    basic_selection_modifier.selection_expr = shape_selection_bind_groups.into_iter().fold(
239        gs::SelectionExpr::Identity,
240        |acc, bind_group| {
241            acc.union(gs::SelectionExpr::selection(
242                0, // the 0 here is the bundle index in the selection bundle
243                vec![bind_group],
244            ))
245        },
246    );
247
248    log::info!("Starting editing process");
249    let time = std::time::Instant::now();
250
251    log::debug!("Editing Gaussians");
252    let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
253        label: Some("Edit Encoder"),
254    });
255
256    editor.apply(
257        &device,
258        &mut encoder,
259        [&basic_selection_modifier as &dyn gs::Modifier<GaussianPod>],
260    );
261
262    queue.submit(Some(encoder.finish()));
263
264    device
265        .poll(wgpu::PollType::wait_indefinitely())
266        .expect("poll");
267
268    log::info!("Editing process completed in {:?}", time.elapsed());
269
270    log::debug!("Downloading Gaussians");
271    let modified_gaussians = editor
272        .gaussians_buffer
273        .download_gaussians(&device, &queue)
274        .await
275        .map(|gs| {
276            match &args.output[args.output.len().saturating_sub(4)..] {
277                ".ply" => {
278                    gs::core::Gaussians::Ply(gs::core::PlyGaussians::from_iter(gs.into_iter()))
279                }
280                ".spz" => {
281                    gs::core::Gaussians::Spz(
282                        gs::core::SpzGaussians::from_gaussians_with_options(
283                            gs,
284                            &gs::core::SpzGaussiansFromGaussianSliceOptions {
285                                version: 2, // Version 2 is more widely supported as of now
286                                ..Default::default()
287                            },
288                        )
289                        .expect("SpzGaussians from gaussians"),
290                    )
291                }
292                _ => panic!("Unsupported output file extension, expected .ply or .spz"),
293            }
294        })
295        .expect("gaussians download");
296
297    log::debug!("Writing modified Gaussians to output file");
298    modified_gaussians
299        .write_to_file(&args.output)
300        .expect("write modified Gaussians to output file");
301
302    log::info!("Modified Gaussians written to {}", args.output);
303}