geop_ops_assembly/
placed.rs1use geop_core_program::{
14 element::ElementReference,
15 part::StepContext,
16 placed::{PlacedArgs, place},
17 reader::Reader,
18};
19use std::{
20 hash::{Hash, Hasher},
21 rc::Rc,
22};
23
24use geop_core_editor::view::{PartView, annotations_of};
25use geop_core_math::geop_error::{GeopError, GeopResult};
26use geop_core_rasterize::Rasterizer;
27use geop_lib_constraints::{solve::Mobility, unknown::Unknowns};
28use geop_ops_model::{
29 datums::read_datums,
30 parameters::{Instance, Placement, define_instance, read_properties},
31 placed::{
32 Drawn, drawn, drawn_target,
33 explode::{exploded, explosions},
34 placed_parts,
35 },
36 read_model,
37 sketch::PlacedSketch,
38};
39
40pub(crate) fn draw(reader: &Reader) -> GeopResult<PartView> {
47 let mut view = PartView::new();
48 read_model(reader)?.draw("model", &mut Rasterizer::default(), &mut view)?;
49 read_datums(reader)?.draw(&mut view)?;
50 for target in reader.targets_of::<PlacedSketch>() {
51 let name = target.name().to_string();
52 let reference = ElementReference::<_, PlacedSketch>::whole(target);
53 reader
54 .retrieve_element(&reference)?
55 .draw(&name, &mut view)?;
56 }
57 view.annotations = annotations_of(reader);
58 read_properties(reader)?.draw(&mut view);
59 Ok(view.finish())
60}
61
62pub fn define_placed(
69 ctx: &mut StepContext,
70 name: &str,
71 placed: &PlacedArgs,
72 placement: Placement,
73) -> GeopResult<()> {
74 let instance = Instance {
77 placement,
78 file: placed.file.clone(),
79 inputs: placed.inputs.clone(),
80 then: placed.then.clone(),
81 };
82 define_instance(ctx, name, &instance)?;
83 let loaded = place(ctx, name, placed);
84 let drawn = ctx.produce(&drawn_target(name), &name.to_string(), |reader, name| {
85 let inside = reader.placed_part(name)?;
87 let drawn = inside.shared("drawn", |inside| {
88 let mut view = draw(inside)?;
89 view.sketches.clear();
90 let shown = serde_json::to_vec(&view)
91 .map_err(|e| GeopError::new(format!("the drawing of `{name}`: {e}")))?;
92 let mut key = std::hash::DefaultHasher::new();
93 shown.hash(&mut key);
94 Ok(Drawn {
95 key: format!("{:016x}", key.finish()),
96 view: Rc::new(view),
97 })
98 })?;
99 Ok((*drawn).clone())
100 });
101 loaded.and(drawn)
104}
105
106pub(crate) fn draw_instances(reader: &Reader, view: &mut PartView) -> GeopResult<()> {
114 let unknowns = Unknowns::of(reader)?;
115 let explosions = explosions(reader);
116 for placed in placed_parts(reader)? {
117 let located = placed.located;
118 let pose = exploded(&explosions, &placed.name, &located.world);
119 let origin = geop_core_math::primitives::CoordinateSystem::world_at(
120 geop_core_math::vector::Vector3::zero(),
121 );
122 let drawn = drawn(reader, &placed.name)?;
123 view.instances.push(geop_core_editor::view::ViewInstance {
124 frame: pose.motion().apply_frame(&origin)?,
125 name: placed.name,
126 component: drawn.key.clone(),
127 pose,
128 view: drawn.view.clone(),
129 fixed: (located.state.as_ref())
130 .and_then(|state| unknowns.get(state))
131 .is_none_or(|unknown| unknown.mobility == Mobility::Fixed),
132 state: located.state,
133 color: None,
134 });
135 }
136 Ok(())
137}