forked from 1b-agent/opencadstudio-upstream
feat: raster image render pipeline (IMAGE command + GPU textured quad)
- Add IMAGE / IMAGEATTACH / IM command with async file-picker (rfd) - src/scene/image_model.rs: ImageModel with RGBA pixel data + quad corners - src/scene/pipeline/image_gpu.rs: ImageGpu with wgpu texture, sampler, opacity uniform - src/scene/pipeline/mod.rs: image render pipeline (pass 2, between hatches and meshes) - src/scene/render.rs: include images in Primitive, call upload_images in prepare - src/scene/mod.rs: images HashMap, populate_images_from_document, cache on add_entity - src/modules/home/draw/raster_image.rs: ImageCommand (two-click: origin + width, aspect-correct preview) - src/io/mod.rs: pick_image_file() async helper (file dialog + dimension decode) - app: ImagePick / ImagePickResult messages, populate on file open and undo/redo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
3d1f355a5c
commit
4312b6c3a5
39 files changed
+702
-15
No files matched your search
@@ -49,6 +49,7 @@ impl H7CAD {
|
||||
self.tabs[i].current_path = Some(path);
|
||||
self.tabs[i].scene.document = doc;
|
||||
self.tabs[i].scene.populate_hatches_from_document();
|
||||
self.tabs[i].scene.populate_images_from_document();
|
||||
self.tabs[i].scene.selected = std::collections::HashSet::new();
|
||||
self.tabs[i].scene.preview_wires = vec![];
|
||||
self.tabs[i].scene.current_layout = "Model".to_string();
|
||||
@@ -71,6 +72,35 @@ impl H7CAD {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::ImagePick => {
|
||||
Task::perform(crate::io::pick_image_file(), Message::ImagePickResult)
|
||||
}
|
||||
|
||||
Message::ImagePickResult(Ok((path, pw, ph))) => {
|
||||
use crate::command::CadCommand;
|
||||
use crate::modules::home::draw::raster_image::ImageCommand;
|
||||
let path_str = path.to_string_lossy().into_owned();
|
||||
let short = std::path::Path::new(&path_str)
|
||||
.file_name()
|
||||
.and_then(|n| n.to_str())
|
||||
.unwrap_or(&path_str)
|
||||
.to_string();
|
||||
self.command_line
|
||||
.push_output(&format!("IMAGE \"{short}\": {pw}×{ph} px"));
|
||||
let cmd = ImageCommand::new(path_str, pw, ph);
|
||||
let i = self.active_tab;
|
||||
self.command_line.push_info(&cmd.prompt());
|
||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::ImagePickResult(Err(e)) => {
|
||||
if e != "Cancelled" {
|
||||
self.command_line.push_error(&format!("IMAGE: {e}"));
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::SaveFile => {
|
||||
let i = self.active_tab;
|
||||
if let Some(path) = &self.tabs[i].current_path {
|
||||
|
||||
Reference in new issue
Block a user