Joints: gears, rack and pinion, and screws (#1524)
Motion links can carry a coupling (gear pair, rack and pinion, screw) whose ratio follows radii, picked round faces or pitch. Design format 23. Co-authored-by: SychPL <SychPL@users.noreply.github.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
29 files changed
+1476
-54
No files matched your search
@@ -1,5 +1,5 @@
|
||||
//! Assembly dialogs: New Component, Joint, As-built Joint, Joint Origin, Rigid Group, Drive
|
||||
//! Joints, Motion Link and Interference. Joint origins are picked by hovering geometry: a face
|
||||
//! Joints, Motion Link, Gear, Rack and Pinion, Screw (`dialogs_coupling`) and Interference. Joint origins are picked by hovering geometry: a face
|
||||
//! snaps to its centre (or a round face to the centre of its nearer end), an edge to its middle
|
||||
//! (a round edge to its centre), a vertex to itself; the snap shows as a glyph with its z axis
|
||||
//! before the click. Joints and drives preview on the placed (world) model: the moving
|
||||
@@ -27,8 +27,19 @@ const TYPE_LABELS: [&str; 7] = ["Rigid", "Revolute", "Slider", "Cylindrical", "P
|
||||
/// What a joint origin input accepts (snaps on faces, edges and vertices).
|
||||
const SNAPS: u16 = FACES | EDGES | VERTICES;
|
||||
/// Commands whose effect is where occurrences sit (previewed on the placed model).
|
||||
const MOVES: [&str; 8] =
|
||||
["joint.create", "joint.as_built", "joint.drive", "joint.edit", "joint.limits", "joint.rigid_group", "parts.insert", "parts.fastener"];
|
||||
const MOVES: [&str; 11] = [
|
||||
"joint.create",
|
||||
"joint.as_built",
|
||||
"joint.drive",
|
||||
"joint.edit",
|
||||
"joint.limits",
|
||||
"joint.rigid_group",
|
||||
"joint.gear",
|
||||
"joint.rack_pinion",
|
||||
"joint.screw",
|
||||
"parts.insert",
|
||||
"parts.fastener",
|
||||
];
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Asm {
|
||||
@@ -56,6 +67,7 @@ pub enum Asm {
|
||||
ratio: String,
|
||||
offset: String,
|
||||
},
|
||||
Coupling(Box<crate::dialogs_coupling::CouplingForm>),
|
||||
Interference {
|
||||
result: Option<Value>,
|
||||
overlaps: Vec<Mesh>,
|
||||
@@ -128,12 +140,17 @@ impl Asm {
|
||||
Asm::RigidGroup => "RIGID GROUP",
|
||||
Asm::Drive { .. } => "DRIVE JOINTS",
|
||||
Asm::MotionLink { .. } => "MOTION LINK",
|
||||
Asm::Coupling(f) => match f.command {
|
||||
"joint.gear" => "GEAR",
|
||||
"joint.rack_pinion" => "RACK AND PINION",
|
||||
_ => "SCREW",
|
||||
},
|
||||
Asm::Interference { .. } => "INTERFERENCE",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn previews(&self) -> bool {
|
||||
matches!(self, Asm::Joint(_) | Asm::Drive { .. } | Asm::RigidGroup)
|
||||
matches!(self, Asm::Joint(_) | Asm::Drive { .. } | Asm::RigidGroup | Asm::Coupling(_))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +183,7 @@ pub fn start(app: &SolveApp, id: &str) -> Option<(Kind, Vec<SelInput>)> {
|
||||
let b = usize::from(movable(s).len() > 1);
|
||||
(Asm::MotionLink { a: 0, b, ia: 0, ib: 0, ratio: "1".into(), offset: "0".into() }, vec![])
|
||||
}
|
||||
"joint.gear" | "joint.rack_pinion" | "joint.screw" => crate::dialogs_coupling::start(app, id)?,
|
||||
"inspect.interference" => {
|
||||
(Asm::Interference { result: None, overlaps: Vec::new(), of: Vec::new() }, vec![SelInput::new("Bodies (all if none)", BODIES, true)])
|
||||
}
|
||||
@@ -657,6 +675,7 @@ pub fn rows(app: &mut SolveApp, ui: &mut egui::Ui, k: &mut Asm, inputs: &mut [Se
|
||||
enter |= field(ui, offset);
|
||||
ui.end_row();
|
||||
}
|
||||
Asm::Coupling(f) => enter |= crate::dialogs_coupling::rows(app, ui, f, inputs),
|
||||
Asm::Interference { result, overlaps, of } => {
|
||||
let picked: Vec<Sel> = inputs.first().map(|i| i.items.clone()).unwrap_or_default();
|
||||
row_label(ui, "");
|
||||
@@ -883,6 +902,7 @@ pub fn commands(app: &SolveApp, k: &Asm, inputs: &[SelInput]) -> Result<Vec<(Str
|
||||
let ratio = eval(ratio, ValueKind::Unitless)?;
|
||||
cmd("joint.motion_link", json!({"a": ja.id, "b": jb.id, "ia": ia, "ib": ib, "ratio": ratio, "offset": offset.trim()}))
|
||||
}
|
||||
Asm::Coupling(f) => return crate::dialogs_coupling::commands(app, f, inputs),
|
||||
// The check runs from its Compute button; OK only closes.
|
||||
Asm::Interference { .. } => Vec::new(),
|
||||
})
|
||||
@@ -890,6 +910,9 @@ pub fn commands(app: &SolveApp, k: &Asm, inputs: &[SelInput]) -> Result<Vec<(Str
|
||||
|
||||
/// The preview's commands: OK's, with the joint's values playing its motion while animating.
|
||||
pub fn animate(app: &SolveApp, k: &Asm, cmds: &mut Vec<(String, Value)>) {
|
||||
if let Asm::Coupling(f) = k {
|
||||
crate::dialogs_coupling::animate(&app.session, f, cmds);
|
||||
}
|
||||
let Asm::Joint(f) = k else { return };
|
||||
if !f.animate {
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user