Complete revolve workflow and properties

This commit is contained in:
ramox81 committed 2026-09-03 13:40:23 +03:00
1 parent e6429d5712
commit 2e112f9aeb
9 files changed
+913 -94

No files matched your search

+104 -37
View File
@@ -3822,66 +3822,133 @@ impl OpenCADStudio {
}
// ── REVOLVE ────────────────────────────────────────────────────
CmdResult::RevolveEntity {
handle,
CmdResult::RevolveEntities {
handles,
axis_start,
axis_end,
angle_deg,
angle,
start_angle,
mode,
color: _,
} => {
if self.reject_locked_edit(i, handle) {
if handles.is_empty()
|| handles
.iter()
.any(|handle| self.reject_locked_edit(i, *handle))
{
self.tabs[i].active_cmd = None;
return Task::none();
}
use crate::modules::insert::solid3d_cmds::empty_solid3d;
let delete_sources = self.tabs[i].scene.document.header.delete_objects;
use crate::command::ExtrudeMode;
use crate::modules::insert::solid3d_cmds::{
empty_revolved_surface, empty_solid3d,
};
use crate::scene::model::sweep_model;
let entity_opt = self.tabs[i].scene.document.get_entity(handle).cloned();
if let Some(entity) = entity_opt {
let from = [
axis_start.x as f64,
axis_start.y as f64,
axis_start.z as f64,
];
let to = [axis_end.x as f64, axis_end.y as f64, axis_end.z as f64];
let angle = (angle_deg as f64).to_radians();
let result = sweep_model::revolve_history(&entity, from, to, angle)
let from = axis_start.to_array();
let to = axis_end.to_array();
let pending = self.begin_undo(i, "REVOLVE", handles.len(), true);
let mut created_handles = Vec::new();
let mut consumed = Vec::new();
let mut failed = 0usize;
for handle in &handles {
let Some(entity) = self.tabs[i].scene.document.get_entity(*handle).cloned()
else {
failed += 1;
continue;
};
let Some((_, closed)) = sweep_model::extrusion_profile_of(&entity) else {
failed += 1;
continue;
};
let creates_surface = mode == ExtrudeMode::Surface || !closed;
let created = if creates_surface {
let Some(body) =
sweep_model::revolved_surface(&entity, from, to, angle, start_angle)
else {
failed += 1;
continue;
};
self.add_surface_model(
empty_revolved_surface(
&entity,
axis_start,
axis_end,
angle,
start_angle,
),
body,
)
} else {
let result = sweep_model::revolve_history(
&entity,
from,
to,
angle,
start_angle,
)
.and_then(|history| {
cadkernel::acis::rebuild_body(&history)
.ok()
.map(|solid| (solid, history))
})
.or_else(|| {
sweep_model::revolved(&entity, from, to, angle).map(|solid| {
let history =
crate::scene::model::solid_history::brep_op(&solid);
(solid, history)
})
sweep_model::revolved(&entity, from, to, angle, start_angle).map(
|solid| {
let history =
crate::scene::model::solid_history::brep_op(&solid);
(solid, history)
},
)
});
if let Some((solid, history)) = result {
let pending = self.begin_undo(i, "REVOLVE", 1, true);
let created = self.add_solid_model(empty_solid3d(), solid, history);
if !created.is_null() {
self.tabs[i].dirty = true;
self.command_line.push_output(
crate::tf!("REVOLVE: solid created ({:.0}°).", angle_deg).as_ref(),
);
if let Some(pd) = pending {
self.commit_undo_delta(i, pd);
}
}
let Some((solid, history)) = result else {
failed += 1;
continue;
};
self.add_solid_model(empty_solid3d(), solid, history)
};
if created.is_null() {
failed += 1;
} else {
self.command_line
.push_error(crate::t!("REVOLVE: could not revolve profile.").as_ref());
created_handles.push(created);
if delete_sources {
consumed.push(*handle);
}
}
}
if delete_sources && !created_handles.is_empty() {
consumed.sort_unstable_by_key(|handle| handle.value());
consumed.dedup();
self.tabs[i].scene.erase_entities(&consumed);
}
if !created_handles.is_empty() {
self.tabs[i].scene.deselect_all();
for handle in &created_handles {
self.tabs[i].scene.select_entity(*handle, true);
}
self.tabs[i].dirty = true;
self.command_line.push_output(
crate::tf!(
"REVOLVE: created %{created} object(s); %{failed} source(s) could not be revolved.",
created = created_handles.len(),
failed = failed
)
.as_ref(),
);
} else {
self.command_line
.push_error(crate::t!("REVOLVE: entity not found.").as_ref());
self.command_line.push_error(
crate::t!("REVOLVE: no selected object could be revolved with the requested options.")
.as_ref(),
);
}
if let Some(pending) = pending {
self.commit_undo_delta(i, pending);
}
self.tabs[i].active_cmd = None;
self.tabs[i].snap_result = None;
self.tabs[i].scene.clear_preview_wire();
self.restore_pre_cmd_tangent();
self.refresh_properties();
}
// ── SWEEP ─────────────────────────────────────────────────────
CmdResult::SweepEntity {
+10 -1
View File
@@ -794,8 +794,17 @@ impl OpenCADStudio {
// ── REVOLVE ────────────────────────────────────────────────────
"REVOLVE" => {
use crate::modules::insert::solid3d_cmds::RevolveCommand;
let selected: Vec<_> = self.tabs[i].scene.selected_entities().into_iter().collect();
let color = self.tabs[i].scene.layer_color(&self.tabs[i].active_layer);
let cmd = RevolveCommand::new(color);
let mut cmd = RevolveCommand::new(color);
if !selected.is_empty() {
cmd.set_preselection(
selected
.iter()
.map(|(handle, entity)| (*handle, (*entity).clone()))
.collect(),
);
}
self.command_line.push_info(&cmd.prompt());
self.tabs[i].active_cmd = Some(Box::new(cmd));
}
+10 -1
View File
@@ -660,7 +660,16 @@ impl OpenCADStudio {
// the sign of the cursor's side relative to the reference, so the
// committed direction matches the drag (the box shows magnitude
// only). Commands receive an already-signed string.
let text = self.dyn_sign_angle_text(i, text);
let auto_sign = self.tabs[i]
.active_cmd
.as_ref()
.map(|command| command.dyn_auto_sign_angle())
.unwrap_or(true);
let text = if auto_sign {
self.dyn_sign_angle_text(i, text)
} else {
text
};
let result = self.tabs[i]
.active_cmd
.as_mut()