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