microcad_lang/builtin/
operation.rs1use microcad_core::{BooleanOp, Geometry2D};
7
8use crate::{builtin::*, model::*, render::*, src_ref::SrcRef, value::Tuple};
9
10impl Operation for BooleanOp {
11 fn process_2d(&self, context: &mut RenderContext) -> RenderResult<Geometry2DOutput> {
12 context.update_2d(|context, model| {
13 let model = model.into_group().unwrap_or(model);
14 let model_ = model.borrow();
15 let geometries: Geometries2D = model_.children.render_with_context(context)?;
16
17 Ok(Geometry2D::MultiPolygon(geometries.boolean_op(self)))
18 })
19 }
20
21 fn process_3d(&self, context: &mut RenderContext) -> RenderResult<Geometry3DOutput> {
22 context.update_3d(|context, model| {
23 let model = model.into_group().unwrap_or(model);
24 let model_ = model.borrow();
25 let geometries: Geometries3D = model_.children.render_with_context(context)?;
26
27 Ok(Geometry3D::Manifold(geometries.boolean_op(self)))
28 })
29 }
30}
31
32pub struct Union;
34
35impl BuiltinWorkbenchDefinition for Union {
36 fn id() -> &'static str {
37 "union"
38 }
39
40 fn kind() -> BuiltinWorkbenchKind {
41 BuiltinWorkbenchKind::Operation
42 }
43
44 fn workpiece_function() -> &'static BuiltinWorkpieceFn {
45 &|_| {
46 Ok(BuiltinWorkpieceOutput::Operation(Box::new(
47 BooleanOp::Union,
48 )))
49 }
50 }
51}
52
53pub struct Subtract;
55
56impl BuiltinWorkbenchDefinition for Subtract {
57 fn id() -> &'static str {
58 "subtract"
59 }
60
61 fn kind() -> BuiltinWorkbenchKind {
62 BuiltinWorkbenchKind::Operation
63 }
64
65 fn workpiece_function() -> &'static BuiltinWorkpieceFn {
66 &|_| {
67 Ok(BuiltinWorkpieceOutput::Operation(Box::new(
68 BooleanOp::Subtract,
69 )))
70 }
71 }
72}
73
74pub struct Intersect;
76
77impl BuiltinWorkbenchDefinition for Intersect {
78 fn id() -> &'static str {
79 "intersect"
80 }
81
82 fn kind() -> BuiltinWorkbenchKind {
83 BuiltinWorkbenchKind::Operation
84 }
85
86 fn workpiece_function() -> &'static BuiltinWorkpieceFn {
87 &|_| {
88 Ok(BuiltinWorkpieceOutput::Operation(Box::new(
89 BooleanOp::Intersect,
90 )))
91 }
92 }
93}
94
95pub struct Multiply;
97
98impl Operation for Multiply {
99 fn process_2d(&self, context: &mut RenderContext) -> RenderResult<Geometry2DOutput> {
100 context.update_2d(|context, model| {
101 Ok(Geometry2D::Collection(
102 model.borrow().children.render_with_context(context)?,
103 ))
104 })
105 }
106
107 fn process_3d(&self, context: &mut RenderContext) -> RenderResult<Geometry3DOutput> {
108 context.update_3d(|context, model| {
109 Ok(Geometry3D::Collection(
110 model.borrow().children.render_with_context(context)?,
111 ))
112 })
113 }
114}
115
116impl BuiltinWorkbenchDefinition for Multiply {
117 fn id() -> &'static str {
118 "multiply"
119 }
120
121 fn kind() -> BuiltinWorkbenchKind {
122 BuiltinWorkbenchKind::Operation
123 }
124
125 fn workpiece_function() -> &'static BuiltinWorkpieceFn {
126 &|_| Ok(BuiltinWorkpieceOutput::Operation(Box::new(Multiply)))
127 }
128
129 fn model(creator: Creator) -> Model {
130 let n: Integer = creator.arguments.get("n");
131 let model = ModelBuilder::new(Element::Multiplicity, SrcRef(None)).build();
132
133 model.append_children(
134 ModelBuilder::new(Element::InputPlaceholder, SrcRef(None))
135 .build()
136 .multiply(n)
137 .into(),
138 );
139
140 model
141 }
142
143 fn parameters() -> ParameterValueList {
144 [parameter!(n: Integer)].into_iter().collect()
145 }
146}
147
148impl From<BooleanOp> for BuiltinWorkpiece {
149 fn from(value: BooleanOp) -> Self {
150 match value {
151 BooleanOp::Union => Union::workpiece(Creator::new(Union::symbol(), Tuple::default())),
152 BooleanOp::Subtract => {
153 Subtract::workpiece(Creator::new(Subtract::symbol(), Tuple::default()))
154 }
155 BooleanOp::Intersect => {
156 Intersect::workpiece(Creator::new(Intersect::symbol(), Tuple::default()))
157 }
158 BooleanOp::Complement => unimplemented!(),
159 }
160 }
161}