Merge pull request #1070 from ramox81/codex/filletedge-parity

# Conflicts:
#	Cargo.lock
This commit is contained in:
Hakan Seven committed 2026-09-08 18:30:34 +03:00
commit 7ec07f3222
21 files changed
+1544 -138

No files matched your search

+92 -12
View File
@@ -1,6 +1,6 @@
use super::*;
fn selected_solid(app: &OpenCADStudio, tab: usize) -> Option<acadrust::Handle> {
fn selected_edge_body(app: &OpenCADStudio, tab: usize) -> Option<acadrust::Handle> {
let scene = &app.tabs.get(tab)?.scene;
let selected = scene.selected_handles_in_order();
let [handle] = selected.as_slice() else {
@@ -9,7 +9,7 @@ fn selected_solid(app: &OpenCADStudio, tab: usize) -> Option<acadrust::Handle> {
if matches!(
scene.document.get_entity(*handle),
Some(acadrust::EntityType::Solid3D(_))
Some(acadrust::EntityType::Solid3D(_) | acadrust::EntityType::Surface(_))
) {
Some(*handle)
} else {
@@ -17,6 +17,36 @@ fn selected_solid(app: &OpenCADStudio, tab: usize) -> Option<acadrust::Handle> {
}
}
fn solid_edge_sources(
app: &mut OpenCADStudio,
tab: usize,
) -> Vec<(acadrust::Handle, cadkernel::brep::Body)> {
let handles = app.tabs[tab]
.scene
.document
.entities()
.filter_map(|entity| {
matches!(
entity,
acadrust::EntityType::Solid3D(_) | acadrust::EntityType::Surface(_)
)
.then_some(entity.common().handle)
})
.collect::<Vec<_>>();
app.tabs[tab].scene.restore_solid_models(&handles);
handles
.into_iter()
.filter_map(|handle| {
app.tabs[tab]
.scene
.solid_models
.get(&handle)
.cloned()
.map(|body| (handle, body))
})
.collect()
}
impl OpenCADStudio {
pub(super) fn dispatch_dim(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
match cmd {
@@ -960,16 +990,30 @@ impl OpenCADStudio {
self.tabs[i].active_cmd = Some(Box::new(new_cmd));
}
"SOLIDFILLET" => {
"FILLETEDGE" | "SOLIDFILLET" => {
use crate::modules::model::edge_cmd::{EdgeOperation, SolidEdgeCommand};
let command = SolidEdgeCommand::new(EdgeOperation::Fillet, selected_solid(self, i));
let target = selected_edge_body(self, i);
let bodies = solid_edge_sources(self, i);
let command = SolidEdgeCommand::new(
EdgeOperation::Fillet,
target,
bodies,
crate::scene::WireModel::SELECTED,
);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
"FILLET" if selected_solid(self, i).is_some() => {
"FILLET" if selected_edge_body(self, i).is_some() => {
use crate::modules::model::edge_cmd::{EdgeOperation, SolidEdgeCommand};
let command = SolidEdgeCommand::new(EdgeOperation::Fillet, selected_solid(self, i));
let target = selected_edge_body(self, i);
let bodies = solid_edge_sources(self, i);
let command = SolidEdgeCommand::new(
EdgeOperation::Fillet,
target,
bodies,
crate::scene::WireModel::SELECTED,
);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
@@ -1107,16 +1151,52 @@ impl OpenCADStudio {
}
}
"SOLIDCHAMFER" => {
use crate::modules::model::edge_cmd::{EdgeOperation, SolidEdgeCommand};
let command = SolidEdgeCommand::new(EdgeOperation::Chamfer, selected_solid(self, i));
"CHAMFEREDGE" | "SOLIDCHAMFER" => {
use crate::modules::model::edge_cmd::SolidEdgeCommand;
let target = selected_edge_body(self, i);
let header = &self.tabs[i].scene.document.header;
let distances = (header.chamfer_distance_a, header.chamfer_distance_b);
let bodies = solid_edge_sources(self, i);
let command = SolidEdgeCommand::new_chamfer(
target,
bodies,
crate::scene::WireModel::SELECTED,
distances,
);
let distances = command.chamfer_distances();
self.command_line.push_output(
crate::tf!(
"Distance1 = {:.4}, Distance2 = {:.4}",
distances.0,
distances.1
)
.as_ref(),
);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
"CHAMFER" if selected_solid(self, i).is_some() => {
use crate::modules::model::edge_cmd::{EdgeOperation, SolidEdgeCommand};
let command = SolidEdgeCommand::new(EdgeOperation::Chamfer, selected_solid(self, i));
"CHAMFER" if selected_edge_body(self, i).is_some() => {
use crate::modules::model::edge_cmd::SolidEdgeCommand;
let target = selected_edge_body(self, i);
let header = &self.tabs[i].scene.document.header;
let distances = (header.chamfer_distance_a, header.chamfer_distance_b);
let bodies = solid_edge_sources(self, i);
let command = SolidEdgeCommand::new_chamfer(
target,
bodies,
crate::scene::WireModel::SELECTED,
distances,
);
let distances = command.chamfer_distances();
self.command_line.push_output(
crate::tf!(
"Distance1 = {:.4}, Distance2 = {:.4}",
distances.0,
distances.1
)
.as_ref(),
);
self.command_line.push_info(&command.prompt());
self.tabs[i].active_cmd = Some(Box::new(command));
}
+4 -6
View File
@@ -335,9 +335,9 @@ impl OpenCADStudio {
"PERSP" => return Some(Task::done(Message::SetProjection(false))),
"LAYERS" => return Some(Task::done(Message::ToggleLayers)),
// SCRIPT <path> — run a command script: each non-blank, non-comment
// SCRIPT <path> — run a command script: each non-comment
// line is fed through the same command path the `--script` startup
// flag uses, so the behaviour matches headless automation exactly.
// flag uses. Blank rows submit Enter to the active command.
"SCRIPT" | "SCR" => {
use crate::command::ValuePromptCommand;
let c = ValuePromptCommand::new("SCRIPT", "SCRIPT path to the .scr file:");
@@ -352,10 +352,8 @@ impl OpenCADStudio {
let cmds: Vec<Task<Message>> = text
.lines()
.map(str::trim)
.filter(|l| {
!l.is_empty() && !l.starts_with('#') && !l.starts_with(';')
})
.map(|l| Task::done(Message::Command(l.to_string())))
.filter(|l| !l.starts_with('#') && !l.starts_with(';'))
.map(|l| Task::done(Message::ScriptLine(l.to_string())))
.collect();
self.command_line.push_output(crate::tf!(
"SCRIPT: running {} command(s) from {p}.",