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,6 +1,6 @@
|
||||
#![allow(clippy::unwrap_used, clippy::panic)]
|
||||
use super::*;
|
||||
use solidcraft_doc::joints::{Joint, JointKind, MotionLink, NamedOrigin};
|
||||
use solidcraft_doc::joints::{Coupling, Joint, JointKind, MotionLink, NamedOrigin, Size};
|
||||
use solidcraft_doc::motion::{ContactSet, ExplodedView, MotionStudy, StudyKey};
|
||||
use solidcraft_doc::{IDENTITY, Occurrence};
|
||||
use solidcraft_geom::Vec3;
|
||||
@@ -43,8 +43,10 @@ fn documents() -> (Document, Document) {
|
||||
},
|
||||
NamedOrigin { name: "Outside".into(), origin: at(9) },
|
||||
];
|
||||
source.assembly.links =
|
||||
vec![MotionLink { a: 1, ia: 0, b: 2, ib: 0, ratio: -2.0, offset: 0.3 }, MotionLink { a: 1, ia: 0, b: 3, ib: 0, ratio: 1.0, offset: 0.0 }];
|
||||
source.assembly.links = vec![
|
||||
MotionLink { a: 1, ia: 0, b: 2, ib: 0, ratio: -2.0, offset: 0.3, coupling: None },
|
||||
MotionLink { a: 1, ia: 0, b: 3, ib: 0, ratio: 1.0, offset: 0.0, coupling: None },
|
||||
];
|
||||
source.assembly.contact_sets = vec![
|
||||
ContactSet { id: 1, name: "Internal contact".into(), occurrences: vec![1, 2], suppressed: true },
|
||||
ContactSet { id: 2, name: "Cross contact".into(), occurrences: vec![1, 9], suppressed: false },
|
||||
@@ -96,6 +98,29 @@ fn internal_relationships_receive_independent_ids_and_remapped_typed_references(
|
||||
assert_eq!(source.assembly.joints[0].values[0], 0.25);
|
||||
}
|
||||
|
||||
/// A gear's picked round face is on the copy's occurrence and face; one picked on geometry the
|
||||
/// copy doesn't have is reported, not pointed back at the original.
|
||||
#[test]
|
||||
fn copied_gears_take_their_picked_faces_along() {
|
||||
let (mut source, _) = documents();
|
||||
let circle = |face: &str| Size::Circle(JointOrigin { occurrence: 1, snap: Snap::CircleCenter { pick: Vec3::X, face: Some(face.into()) } });
|
||||
let gear = |ra| Coupling::Gear { ra, rb: Size::Length(5.0), internal: false, reverse: false };
|
||||
source.assembly.links = vec![
|
||||
MotionLink { a: 1, ia: 0, b: 2, ib: 0, ratio: -2.0, offset: 0.0, coupling: Some(gear(circle("F1:side"))) },
|
||||
MotionLink { a: 2, ia: 0, b: 1, ib: 0, ratio: -0.5, offset: 0.0, coupling: Some(gear(circle("F99:side"))) },
|
||||
];
|
||||
let mut destination = source.clone();
|
||||
destination.occurrences.extend([101, 102].map(occurrence));
|
||||
let report =
|
||||
clone_assembly(&mut destination, &source, &BTreeMap::from([(1, 101), (2, 102)]), &BTreeMap::from([(1, 11), (10, 110)]), &BTreeMap::new())
|
||||
.unwrap();
|
||||
let copied = destination.assembly.links.get(2).and_then(|l| l.coupling.clone());
|
||||
let Some(Coupling::Gear { ra: Size::Circle(o), .. }) = copied else { panic!("{:?}", destination.assembly.links) };
|
||||
assert!(o.occurrence == 101 && matches!(&o.snap, Snap::CircleCenter { face: Some(f), .. } if f == "F11:side"), "{o:?}");
|
||||
assert_eq!(destination.assembly.links.len(), 3, "the gear on foreign geometry stays behind");
|
||||
assert!(report.iter().any(|m| m.contains("motion link")), "{report:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn naming_remaps_exact_tokens_unicode_and_legacy_body_identity() {
|
||||
let features = BTreeMap::from([(1, 21), (10, 30)]);
|
||||
|
||||
Reference in new issue
Block a user