Insert Part dialog (SOLID > INSERT > Insert Fastener)

The standard parts library by type (with its ISO standard), size and length, the size's table
values and a picture of the part; picking a hole's wall or rim seats it there with a rigid joint
(the live preview shows it seated), without a pick it goes at the origin. Opens on
FusionFastenersCommand (and parts.insert); OK runs FusionFastenersCommand. Its own icon.
Insert's world picks (`at`, `point`, `direction`) go through the component frames like other
picks. Tests for the library parsing and the insert parameters; checked in the app: an M3 socket
head cap screw seated in a drilled hole with its joint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-08 18:28:08 +00:00
1 parent 4eff2146d2
commit 0a6f6c4422
6 files changed
+280 -2

No files matched your search

+8 -1
View File
@@ -215,6 +215,8 @@ pub enum Kind {
Appearance(crate::dialogs_appearance::Ap),
/// Contact sets, motion studies, exploded views, configurations (`dialogs_motion`).
Motion(crate::dialogs_motion::Mo),
/// Insert Part from the standard parts library (`dialogs_parts`).
Part(crate::dialogs_parts::Pt),
}
/// The rest of the Hole dialog: placement, extents, tap type and drill point.
@@ -413,7 +415,8 @@ impl Dialog {
.or_else(|| crate::dialogs_sheet::start(app, id))
.or_else(|| crate::dialogs_plastic::start(app, id))
.or_else(|| crate::dialogs_appearance::start(app, id))
.or_else(|| crate::dialogs_motion::start(app, id))?;
.or_else(|| crate::dialogs_motion::start(app, id))
.or_else(|| crate::dialogs_parts::start(app, id))?;
Dialog::new(kind, inputs)
}
};
@@ -514,6 +517,7 @@ impl Dialog {
Kind::Assembly(k) => return k.previews(),
Kind::Sheet(k) => return k.previews(),
Kind::Plastic(k) => return k.previews(),
Kind::Part(_) => return true,
_ => {}
}
matches!(
@@ -773,6 +777,7 @@ fn title(k: &Kind) -> &'static str {
Kind::Plastic(k) => k.title(),
Kind::Appearance(_) => "APPEARANCE",
Kind::Motion(k) => k.title(),
Kind::Part(_) => "INSERT PART",
}
}
@@ -1493,6 +1498,7 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
Kind::Plastic(k) => enter |= crate::dialogs_plastic::rows(app, ui, k, &d.inputs),
Kind::Appearance(k) => enter |= crate::dialogs_appearance::rows(app, ui, k, &mut d.inputs),
Kind::Motion(k) => enter |= crate::dialogs_motion::rows(app, ui, k, &mut d.inputs),
Kind::Part(k) => enter |= crate::dialogs_parts::rows(app, ui, k, &d.inputs),
Kind::ConfirmDelete { with, fail, .. } => {
if !with.is_empty() {
row_label(ui, "Also deletes");
@@ -2127,6 +2133,7 @@ fn dialog_commands(app: &SolveApp, d: &Dialog) -> Result<Vec<(String, Value)>, S
Kind::Plastic(k) => return crate::dialogs_plastic::commands(app, k, &d.inputs, &d.extra),
Kind::Appearance(k) => return Ok(crate::dialogs_appearance::commands(k, &d.inputs)),
Kind::Motion(k) => return crate::dialogs_motion::commands(app, k, &d.inputs),
Kind::Part(k) => return crate::dialogs_parts::commands(app, k, &d.inputs),
};
let mut params = params;
if let Value::Object(m) = &mut params {