Skip to main content

geop_ops_inspect/
lib.rs

1//! Inspecting a part: what an engineer asks of a design without changing
2//! it — none of it is an operation, and none of it adds a step. Each is an
3//! [`Inspector`] an editor offers (see [`geop_core_editor::output`]):
4//!
5//! - [`Measure`]: distances, angles, lengths, areas and radii of picked
6//!   entities ([`measure()`]).
7//! - [`MassProperties`]: the mass properties of every solid of a part and
8//!   of the parts placed in it, each of its own part's material, and of
9//!   all of them together ([`mass_report`]).
10//! - [`Interference`]: which solids overlap, by how much, and which only
11//!   touch ([`interference_report`]).
12//! - [`Clearance`]: which solids come nearer each other than a clearance,
13//!   and how near ([`clearance_report`]).
14//!
15//! Every number is computed from the exact geometry and carries how well it
16//! is known ([`Bounded`]): an interval enclosure, widened — for the
17//! integrals — by the quadrature's estimate of its truncation error (see
18//! [`geop_core_math::quadrature`]). Lengths are millimetres, masses
19//! kilograms (see [`geop_ops_model::parameters::Material`]).
20
21pub mod clearance;
22pub mod interference;
23pub mod mass;
24pub mod measure;
25pub mod scope;
26
27pub use clearance::{ClearanceOptions, ClearanceReport, clearance_report};
28pub use interference::{InterferenceReport, interference_report};
29pub use mass::{MassReport, mass_report};
30pub use measure::{Measurement, measure};
31pub use scope::Scope;
32
33use geop_core_editor::editing::Visual;
34use geop_core_editor::output::{Answer, Inspector, InspectorInfo, Output, Picks};
35use geop_core_math::geop_error::GeopResult;
36use geop_core_program::element::PickedElement;
37
38/// Measures picked entities: one alone, or the two last picked together.
39pub struct Measure;
40
41impl Inspector for Measure {
42    const INFO: InspectorInfo = InspectorInfo {
43        kind: "measure",
44        label: "Measure",
45        doc: "Measure picked entities: a point, a length, an area, a radius; the distance and angle between two.",
46        icon: Some(crate::icons::MEASURE),
47        picks: Some(Picks {
48            accepts: measure::PICKS,
49            most: 2,
50        }),
51    };
52    type Options = ();
53    type Report = Measurement;
54
55    fn inspect(
56        output: &mut Output,
57        picked: &[PickedElement],
58        (): (),
59    ) -> GeopResult<(Measurement, Vec<Visual>)> {
60        let measurement = measure(&output.part(), picked);
61        let visuals = measurement.visuals();
62        Ok((measurement, visuals))
63    }
64
65    fn show(measurement: &Measurement) -> Answer {
66        measurement.shown()
67    }
68}
69
70/// Weighs the part: every solid, each of its own part's material.
71pub struct MassProperties;
72
73impl Inspector for MassProperties {
74    const INFO: InspectorInfo = InspectorInfo {
75        kind: "mass_properties",
76        label: "Mass",
77        doc: "The volume, area, mass, centre of mass and inertia of every solid, and of all of them.",
78        icon: Some(crate::icons::MASS),
79        picks: None,
80    };
81    type Options = Scope;
82    type Report = MassReport;
83
84    fn inspect(
85        output: &mut Output,
86        _: &[PickedElement],
87        scope: Scope,
88    ) -> GeopResult<(MassReport, Vec<Visual>)> {
89        Ok((mass_report(&output.part(), &scope)?, Vec::new()))
90    }
91
92    fn show(report: &MassReport) -> Answer {
93        report.shown()
94    }
95}
96
97/// Checks the part's solids for interference.
98pub struct Interference;
99
100impl Inspector for Interference {
101    const INFO: InspectorInfo = InspectorInfo {
102        kind: "interference",
103        label: "Interference",
104        doc: "Which solids overlap, and by how much, and which only touch.",
105        icon: Some(crate::icons::INTERFERENCE),
106        picks: None,
107    };
108    type Options = Scope;
109    type Report = InterferenceReport;
110
111    fn inspect(
112        output: &mut Output,
113        _: &[PickedElement],
114        scope: Scope,
115    ) -> GeopResult<(InterferenceReport, Vec<Visual>)> {
116        Ok((interference_report(&output.part(), &scope)?, Vec::new()))
117    }
118
119    fn show(report: &InterferenceReport) -> Answer {
120        report.shown()
121    }
122}
123
124/// Checks the part's solids keep a clearance from each other.
125pub struct Clearance;
126
127impl Inspector for Clearance {
128    const INFO: InspectorInfo = InspectorInfo {
129        kind: "clearance",
130        label: "Clearance",
131        doc: "Which solids come nearer each other than a clearance, and the least distance between them.",
132        icon: Some(crate::icons::CLEARANCE),
133        picks: None,
134    };
135    type Options = ClearanceOptions;
136    type Report = ClearanceReport;
137
138    fn inspect(
139        output: &mut Output,
140        _: &[PickedElement],
141        options: ClearanceOptions,
142    ) -> GeopResult<(ClearanceReport, Vec<Visual>)> {
143        let report = clearance_report(&output.part(), options)?;
144        let visuals = report.visuals();
145        Ok((report, visuals))
146    }
147
148    fn show(report: &ClearanceReport) -> Answer {
149        report.shown()
150    }
151}
152
153#[cfg(test)]
154mod editor_tests;
155mod icons;
156#[cfg(test)]
157mod regression_tests;
158#[cfg(test)]
159mod tests;
160
161use geop_core_editor::registry::Registry;
162
163/// Adds what this crate offers an editor to `r`: measuring a part, its mass
164/// properties, where its bodies interfere and where they come too near.
165pub fn register(r: Registry) -> GeopResult<Registry> {
166    r.inspector(Measure)?
167        .inspector(MassProperties)?
168        .inspector(Interference)?
169        .inspector(Clearance)
170}