forked from 1b-agent/opencadstudio-upstream
feat(model): persist solid creation history
This commit is contained in:
1 parent
dc6dc2256d
commit
e37b77e426
10 files changed
+331
-21
No files matched your search
@@ -1046,10 +1046,14 @@ impl OpenCADStudio {
|
||||
self.commit_undo_delta(i, pd);
|
||||
}
|
||||
}
|
||||
CmdResult::CommitSolid { entity, solid } => {
|
||||
CmdResult::CommitSolid {
|
||||
entity,
|
||||
solid,
|
||||
history,
|
||||
} => {
|
||||
let label = self.history_label_from_active_cmd(i, "SOLID");
|
||||
let pending = self.begin_undo(i, label, 1, true);
|
||||
self.add_solid_model(entity, *solid);
|
||||
self.add_solid_model(entity, *solid, history);
|
||||
self.tabs[i].dirty = true;
|
||||
self.tabs[i].scene.clear_preview_wire();
|
||||
self.tabs[i].active_cmd = None;
|
||||
@@ -2673,12 +2677,20 @@ impl OpenCADStudio {
|
||||
let result = sweep_model::extruded(&entity, height as f64)
|
||||
.and_then(|body| Some((solid_model::mesh_from_solid(&body, color)?, body)));
|
||||
if let Some((mesh, solid)) = result {
|
||||
let history = crate::scene::model::solid_history::extrusion_op(
|
||||
&entity,
|
||||
height as f64,
|
||||
);
|
||||
let pending = self.begin_undo(i, "EXTRUDE", 1, true);
|
||||
let mut s3d = empty_solid3d();
|
||||
if let acadrust::EntityType::Solid3D(inner) = &mut s3d {
|
||||
inner.wires = solid_model::edge_wires(&solid);
|
||||
}
|
||||
let new_handle = self.tabs[i].scene.add_entity(s3d);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.create_solid_history(new_handle, history);
|
||||
self.tabs[i].scene.register_solid_model(new_handle, solid);
|
||||
let _ = mesh;
|
||||
self.tabs[i].dirty = true;
|
||||
@@ -2726,12 +2738,22 @@ impl OpenCADStudio {
|
||||
)
|
||||
.and_then(|body| Some((solid_model::mesh_from_solid(&body, color)?, body)));
|
||||
if let Some((mesh, solid)) = result {
|
||||
let history = crate::scene::model::solid_history::revolve_op(
|
||||
&entity,
|
||||
axis_start.to_array(),
|
||||
axis_end.to_array(),
|
||||
(angle_deg as f64).to_radians(),
|
||||
);
|
||||
let pending = self.begin_undo(i, "REVOLVE", 1, true);
|
||||
let mut s3d = empty_solid3d();
|
||||
if let acadrust::EntityType::Solid3D(inner) = &mut s3d {
|
||||
inner.wires = solid_model::edge_wires(&solid);
|
||||
}
|
||||
let new_handle = self.tabs[i].scene.add_entity(s3d);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.create_solid_history(new_handle, history);
|
||||
self.tabs[i].scene.register_solid_model(new_handle, solid);
|
||||
let _ = mesh;
|
||||
self.tabs[i].dirty = true;
|
||||
@@ -2768,6 +2790,12 @@ impl OpenCADStudio {
|
||||
.get_entity(profile_handle)
|
||||
.cloned();
|
||||
let path_ent = self.tabs[i].scene.document.get_entity(path_handle).cloned();
|
||||
let history = profile_ent
|
||||
.as_ref()
|
||||
.zip(path_ent.as_ref())
|
||||
.map(|(profile, path)| {
|
||||
crate::scene::model::solid_history::sweep_op(profile, path)
|
||||
});
|
||||
let result = profile_ent
|
||||
.zip(path_ent)
|
||||
.and_then(|(profile, path)| sweep_model::swept(&profile, &path, color));
|
||||
@@ -2782,6 +2810,12 @@ impl OpenCADStudio {
|
||||
);
|
||||
}
|
||||
let new_handle = self.tabs[i].scene.add_entity(entity);
|
||||
if let Some(history) = history {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.create_solid_history(new_handle, history);
|
||||
}
|
||||
for mesh in &mut set.lods {
|
||||
mesh.name = format!("{}", new_handle.value());
|
||||
}
|
||||
@@ -2810,6 +2844,7 @@ impl OpenCADStudio {
|
||||
.filter_map(|handle| self.tabs[i].scene.document.get_entity(*handle).cloned())
|
||||
.collect();
|
||||
if let Some(mut set) = sweep_model::lofted(&profiles, color) {
|
||||
let history = crate::scene::model::solid_history::loft_op(&profiles);
|
||||
let pending = self.begin_undo(i, "LOFT", 1, true);
|
||||
let mut entity = empty_solid3d();
|
||||
if let acadrust::EntityType::Solid3D(solid) = &mut entity {
|
||||
@@ -2819,6 +2854,10 @@ impl OpenCADStudio {
|
||||
);
|
||||
}
|
||||
let new_handle = self.tabs[i].scene.add_entity(entity);
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.create_solid_history(new_handle, history);
|
||||
for mesh in &mut set.lods {
|
||||
mesh.name = format!("{}", new_handle.value());
|
||||
}
|
||||
|
||||
+33
-9
@@ -7,23 +7,34 @@
|
||||
// cylinder afterwards, and saves as one.
|
||||
|
||||
use acadrust::entities::Solid3D;
|
||||
use acadrust::objects::SolidHistoryOperation;
|
||||
use cadkernel::brep::Body;
|
||||
use acadrust::{EntityType, Handle};
|
||||
use iced::Task;
|
||||
|
||||
use super::Message;
|
||||
use crate::modules::model::boolean_cmd::BoolOp;
|
||||
use crate::scene::model::solid_history;
|
||||
use crate::scene::model::solid_model::{self, Bool};
|
||||
|
||||
impl super::OpenCADStudio {
|
||||
/// Commit a Model-tab solid: add its acadrust entity to the document, then
|
||||
/// register the B-rep (caches it for booleans + tessellates it into the
|
||||
/// shaded mesh pipeline). Returns the new entity handle.
|
||||
pub(super) fn add_solid_model(&mut self, entity: EntityType, solid: Body) -> Handle {
|
||||
pub(super) fn add_solid_model(
|
||||
&mut self,
|
||||
entity: EntityType,
|
||||
solid: Body,
|
||||
history: SolidHistoryOperation,
|
||||
) -> Handle {
|
||||
let i = self.active_tab;
|
||||
let Some(handle) = self.commit_entity_handle(entity) else {
|
||||
return Handle::NULL;
|
||||
};
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.document
|
||||
.create_solid_history(handle, history);
|
||||
self.tabs[i].scene.register_solid_model(handle, solid);
|
||||
handle
|
||||
}
|
||||
@@ -66,7 +77,8 @@ impl super::OpenCADStudio {
|
||||
// mesh + cached B-rep; its edge wires make it pickable.
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&result);
|
||||
let handle = self.add_solid_model(EntityType::Solid3D(s3d), result);
|
||||
let history = solid_history::brep_op(&result);
|
||||
let handle = self.add_solid_model(EntityType::Solid3D(s3d), result, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !handle.is_null() {
|
||||
self.tabs[i].scene.select_entity(handle, false);
|
||||
@@ -137,7 +149,8 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.erase_entities(&handles);
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&result);
|
||||
let handle = self.add_solid_model(EntityType::Solid3D(s3d), result);
|
||||
let history = solid_history::brep_op(&result);
|
||||
let handle = self.add_solid_model(EntityType::Solid3D(s3d), result, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !handle.is_null() {
|
||||
self.tabs[i].scene.select_entity(handle, false);
|
||||
@@ -176,7 +189,8 @@ impl super::OpenCADStudio {
|
||||
// Keep both originals; add the interference solid.
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&result);
|
||||
self.add_solid_model(EntityType::Solid3D(s3d), result);
|
||||
let history = solid_history::brep_op(&result);
|
||||
self.add_solid_model(EntityType::Solid3D(s3d), result, history);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
@@ -223,7 +237,8 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.erase_entities(&handles);
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&rotated);
|
||||
let handle = self.add_solid_model(EntityType::Solid3D(s3d), rotated);
|
||||
let history = solid_history::brep_op(&rotated);
|
||||
let handle = self.add_solid_model(EntityType::Solid3D(s3d), rotated, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !handle.is_null() {
|
||||
self.tabs[i].scene.select_entity(handle, false);
|
||||
@@ -306,7 +321,8 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.erase_entities(&[handle]);
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&result);
|
||||
let h = self.add_solid_model(EntityType::Solid3D(s3d), result);
|
||||
let history = solid_history::brep_op(&result);
|
||||
let h = self.add_solid_model(EntityType::Solid3D(s3d), result, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !h.is_null() {
|
||||
self.tabs[i].scene.select_entity(h, false);
|
||||
@@ -351,7 +367,8 @@ impl super::OpenCADStudio {
|
||||
self.push_undo_snapshot(i, "3DMIRROR");
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&reflected);
|
||||
let h = self.add_solid_model(EntityType::Solid3D(s3d), reflected);
|
||||
let history = solid_history::brep_op(&reflected);
|
||||
let h = self.add_solid_model(EntityType::Solid3D(s3d), reflected, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !h.is_null() {
|
||||
self.tabs[i].scene.select_entity(h, false);
|
||||
@@ -421,7 +438,8 @@ impl super::OpenCADStudio {
|
||||
self.tabs[i].scene.erase_entities(&handles);
|
||||
let mut s3d = Solid3D::new();
|
||||
s3d.wires = solid_model::edge_wires(&aligned);
|
||||
let h = self.add_solid_model(EntityType::Solid3D(s3d), aligned);
|
||||
let history = solid_history::brep_op(&aligned);
|
||||
let h = self.add_solid_model(EntityType::Solid3D(s3d), aligned, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !h.is_null() {
|
||||
self.tabs[i].scene.select_entity(h, false);
|
||||
@@ -514,7 +532,13 @@ impl super::OpenCADStudio {
|
||||
if let EntityType::Solid3D(inner) = &mut entity {
|
||||
inner.wires = solid_model::edge_wires(&solid);
|
||||
}
|
||||
let handle = self.add_solid_model(entity, solid);
|
||||
let history = solid_history::pyramid_op(
|
||||
glam::DMat4::IDENTITY.to_cols_array(),
|
||||
radius,
|
||||
height,
|
||||
n,
|
||||
);
|
||||
let handle = self.add_solid_model(entity, solid, history);
|
||||
self.tabs[i].scene.deselect_all();
|
||||
if !handle.is_null() {
|
||||
self.tabs[i].scene.select_entity(handle, false);
|
||||
|
||||
Reference in new issue
Block a user