From 8395993edffcc35a8a835c353c718558ed6cabd2 Mon Sep 17 00:00:00 2001 From: grimsace Date: Wed, 22 Apr 2026 13:50:16 -0500 Subject: [PATCH] added mask export --- src/app.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/app.rs b/src/app.rs index 4d07d1f..37db376 100644 --- a/src/app.rs +++ b/src/app.rs @@ -235,6 +235,68 @@ impl TerrainApp { }); } + fn start_batch_export(&mut self) { + if self.export_in_progress { + self.status_message = String::from("Export already in progress..."); + return; + } + + let Some(generated) = &self.generated else { + self.status_message = String::from("No generated images available to export."); + return; + }; + + let folder = rfd::FileDialog::new() + .set_title("Select Export Folder") + .pick_folder(); + let Some(path) = folder else { + return; + }; + + let generated = generated.clone(); + let (tx, rx) = mpsc::channel(); + self.export_receiver = Some(rx); + self.export_in_progress = true; + self.status_message = format!("Exporting all layers to {}...", path.display()); + + thread::spawn(move || { + let result = (|| -> Result { + let save = |img_rgba: Option<&image::RgbaImage>, + img_gray: Option<&image::GrayImage>, + name: &str| { + let full_path = path.join(format!("{}.png", name)); + if let Some(img) = img_rgba { + img.save(&full_path) + } else if let Some(img) = img_gray { + img.save(&full_path) + } else { + return Err(format!("No image data for {}", name)); + } + .map_err(|e| format!("Failed to save {}: {}", name, e)) + }; + + save( + Some(&generated.terrain_composite_image), + None, + "terrain_composite", + )?; + save(Some(&generated.terrain_color_image), None, "terrain_color")?; + save(None, Some(&generated.heightmap_image), "heightmap")?; + save(None, Some(&generated.bumpmap_image), "bumpmap")?; + save(None, Some(&generated.grass_mask_image), "mask_grass")?; + save(None, Some(&generated.water_mask_image), "mask_water")?; + save(None, Some(&generated.rock_mask_image), "mask_rock")?; + save(None, Some(&generated.snow_mask_image), "mask_snow")?; + + Ok(format!( + "Successfully exported 8 layers to {}.", + path.display() + )) + })(); + let _ = tx.send(result); + }); + } + fn install_textures(&mut self, ctx: &Context, images: &GeneratedImages) { let heightmap = gray_to_color_image(&images.heightmap_image); let bumpmap = gray_to_color_image(&images.bumpmap_image); @@ -428,6 +490,17 @@ impl TerrainApp { self.start_generation(); } + ui.add_space(8.0); + if ui + .add_sized( + [ui.available_width(), 32.0], + egui::Button::new("Export All Layers"), + ) + .clicked() + { + self.start_batch_export(); + } + if self.generation_in_progress { ui.add_space(8.0); ui.spinner();