feat(model): add section plane workflow

This commit is contained in:
ramox81 committed 2026-09-09 18:29:35 +03:00
1 parent 56e09cd3f5
commit c9c768cd9f
11 files changed
+1122 -51

No files matched your search

+26 -1
View File
@@ -353,7 +353,32 @@ impl OpenCADStudio {
self.reset_tracking_after_point();
self.push_ucs_to_cmd(i);
}
if let StepInput::EntityPick(handle, _) = &input {
if let StepInput::EntityPick(handle, point) = &input {
let solid_pick = matches!(
self.tabs[i].scene.document.get_entity(*handle),
Some(
acadrust::EntityType::Solid3D(_)
| acadrust::EntityType::Surface(_)
| acadrust::EntityType::Region(_)
| acadrust::EntityType::Body(_)
)
);
let direction = if solid_pick {
self.tabs[i]
.scene
.solid_planar_face_normal_at(*handle, *point)
} else {
self.tabs[i]
.scene
.document
.get_entity(*handle)
.and_then(crate::entities::curve::entity_curve)
.and_then(|curve| curve.plane.normal())
.map(glam::DVec3::from_array)
};
if let Some(command) = self.tabs[i].active_cmd.as_mut() {
command.set_entity_pick_direction(direction);
}
if self.tabs[i].active_cmd.as_ref()
.is_some_and(|command| command.inject_before_entity_pick())
{
+58
View File
@@ -1212,6 +1212,64 @@ impl OpenCADStudio {
}
}
"SECTIONPLANE" => {
use crate::modules::model::sectionplane_cmd::SectionPlaneCommand;
let (bounds, next_name) = {
let scene = &mut self.tabs[i].scene;
let solid_handles = scene
.document
.entities()
.filter_map(|entity| {
matches!(
entity,
acadrust::EntityType::Solid3D(_)
| acadrust::EntityType::Surface(_)
| acadrust::EntityType::Region(_)
| acadrust::EntityType::Body(_)
)
.then_some(entity.common().handle)
})
.collect::<Vec<_>>();
scene.restore_solid_models(&solid_handles);
let bounds = solid_handles
.iter()
.filter_map(|handle| scene.solid_models.get(handle))
.filter_map(crate::scene::model::solid_model::extent)
.fold(None::<(glam::DVec3, glam::DVec3)>, |bounds, (low, high)| {
let low = glam::DVec3::from_array(low);
let high = glam::DVec3::from_array(high);
Some(match bounds {
None => (low, high),
Some((min, max)) => (min.min(low), max.max(high)),
})
});
let next_name = scene
.document
.entities()
.filter_map(|entity| {
let acadrust::EntityType::Extended(extended) = entity else {
return None;
};
let acadrust::entities::ExtendedEntityData::SectionObject(data) =
&extended.data
else {
return None;
};
data.name
.strip_prefix("Section Plane (")
.and_then(|name| name.strip_suffix(')'))
.and_then(|name| name.parse::<usize>().ok())
})
.max()
.unwrap_or(0)
+ 1;
(bounds, next_name)
};
let command = SectionPlaneCommand::new(bounds, next_name);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
// 3DALIGN <18 numbers> — align the selected solid by 3 source→3 dest points.
cmd if cmd == "3DALIGN"
|| cmd == "ALIGN3D"
+1
View File
@@ -462,6 +462,7 @@ inventory::submit!(crate::command::CommandRegistration {
"3DALIGN",
"ALIGN3D",
"SECTION",
"SECTIONPLANE",
"PYRAMID",
"PYR",
"SPLINEFIT",
+1
View File
@@ -171,6 +171,7 @@ impl OpenCADStudio {
| "text_color"
| "block_content_color"
| "background_fill_color"
| "indicator_fill_color"
) {
self.update(Message::PropColorFieldChanged {
field: p.field.into(),
+15
View File
@@ -5226,6 +5226,21 @@ impl OpenCADStudio {
Message::PropColorFieldChanged { field, color } => {
let i = self.active_tab;
let handles = self.property_target_handles(i);
if field == "indicator_fill_color" {
self.apply_property_op(i, "CHPROP", &handles, |app, handle| {
if let Some(acadrust::EntityType::Extended(extended)) =
app.tabs[i].scene.document.get_entity_mut(handle)
{
if let acadrust::entities::ExtendedEntityData::SectionObject(data) =
&mut extended.data
{
data.indicator_color = color;
}
}
});
self.tabs[i].properties.open_color_field = None;
return Task::none();
}
// Dim-line colour override (Leader / Dimension): write it as an
// ACAD_DSTYLE code-176 override (an ACI index) so it round-trips
// through DWG and DXF. RGB picks collapse to the nearest ACI, in