feat(model): align polysolid workflow

This commit is contained in:
ramox81 committed 2026-09-01 22:01:43 +03:00
1 parent 6d6defa0ad
commit 1dd6b115cf
12 files changed
+857 -250

No files matched your search

+14 -1
View File
@@ -1636,11 +1636,24 @@ impl OpenCADStudio {
entity,
solid,
history,
erase_source,
} => {
let label = self.history_label_from_active_cmd(i, "SOLID");
let pending = self.begin_undo(i, label, 1, true);
let erase_source = erase_source.filter(|handle| {
self.tabs[i].scene.document.header.delete_objects
&& !self.tabs[i].scene.is_layer_locked(*handle)
});
let pending = self.begin_undo(
i,
label,
1 + usize::from(erase_source.is_some()),
true,
);
let handle = self.add_solid_model(entity, *solid, history);
if !handle.is_null() {
if let Some(source) = erase_source {
self.tabs[i].scene.erase_entities(&[source]);
}
self.tabs[i].dirty = true;
if let Some(pd) = pending {
self.commit_undo_delta(i, pd);
+18 -22
View File
@@ -1038,32 +1038,28 @@ impl OpenCADStudio {
return Some(self.solid_convtosurface());
}
// POLYSOLID <width> <height> — extrude a selected polyline into a
// wall-like solid.
"POLYSOLID" => {
use crate::command::SelectThenTwoValueCommand;
let has_sel = !self.tabs[i].scene.selected_entities().is_empty();
let c = SelectThenTwoValueCommand::new(
"POLYSOLID",
"POLYSOLID wall width:",
"POLYSOLID wall height:",
has_sel,
);
use crate::modules::model::polysolid_cmd::PolysolidCommand;
let preselected = self.tabs[i]
.scene
.selected_entities()
.into_iter()
.find(|(_, entity)| {
matches!(
entity,
acadrust::EntityType::Line(_)
| acadrust::EntityType::Arc(_)
| acadrust::EntityType::Circle(_)
| acadrust::EntityType::Ellipse(_)
| acadrust::EntityType::LwPolyline(_)
| acadrust::EntityType::Spline(_)
)
})
.map(|(handle, entity)| (handle, entity.clone()));
let c = PolysolidCommand::new(preselected);
self.command_line.push_info(&c.prompt());
self.tabs[i].active_cmd = Some(Box::new(c));
}
cmd if cmd.starts_with("POLYSOLID ") => {
let nums: Vec<f64> = cmd
.split_whitespace()
.skip(1)
.filter_map(|s| s.parse::<f64>().ok())
.collect();
if nums.len() >= 2 && nums[0] > 0.0 && nums[1] > 0.0 {
return Some(self.solid_polysolid(nums[0], nums[1]));
}
self.command_line
.push_info(crate::t!("Usage: POLYSOLID <width> <height> (select a polyline first)").as_ref());
}
// SPLINEFIT — fit a smooth spline through the selected polyline's points.
"SPLINEFIT" | "FITSPLINE" => {
-49
View File
@@ -468,55 +468,6 @@ impl super::OpenCADStudio {
Task::none()
}
/// POLYSOLID — build a wall solid around an exact polyline offset.
pub(super) fn solid_polysolid(&mut self, width: f64, height: f64) -> Task<Message> {
let i = self.active_tab;
let found: Option<(Handle, EntityType)> = self.tabs[i]
.scene
.selected_entities()
.iter()
.filter(|(h, _)| !self.tabs[i].scene.is_layer_locked(*h))
.find_map(|(h, e)| match e {
EntityType::LwPolyline(_) => Some((*h, (*e).clone())),
_ => None,
});
let Some((handle, entity)) = found else {
self.command_line
.push_error(crate::t!("POLYSOLID: select a polyline first.").as_ref());
return Task::none();
};
let Some(result) = crate::scene::model::sweep_model::polysolid(&entity, width, height)
else {
self.command_line
.push_error(crate::t!("POLYSOLID: the kernel could not offset the polyline.").as_ref());
return Task::none();
};
if crate::scene::convert::acis_export::solid_to_sat(&result).is_none() {
self.command_line
.push_error(crate::t!("POLYSOLID: the result could not be encoded as ACIS.").as_ref());
return Task::none();
}
self.push_undo_snapshot(i, "POLYSOLID");
self.tabs[i].scene.erase_entities(&[handle]);
let mut s3d = Solid3D::new();
s3d.wires = solid_model::edge_wires(&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);
}
if !h.is_null() {
self.tabs[i].dirty = true;
self.refresh_properties();
self.command_line.push_output(
crate::tf!("POLYSOLID: created a wall solid (width {width}, height {height}).")
.as_ref(),
);
}
Task::none()
}
/// 3DMIRROR — add a mirrored copy of the one selected solid across the plane
/// perpendicular to the X/Y/Z axis (0/1/2) through its centre, keeping the
/// original. A reflection loses handedness, so the kernel reverses every