Skip to main content

geop_ops_boolean/
examples.rs

1//! The examples of combining and splitting solids, which an editor offers
2//! to load ([`set`]).
3
4use geop_core_editor::registry::ExampleSet;
5use geop_core_math::primitives::FrameAxis;
6use geop_core_program::program::Program;
7use geop_ops_extrude_revolve::{Extent, Extents, ExtrudeArgs, Output};
8use geop_ops_model::datums::origin_plane;
9use geop_ops_model::sketch::{
10    Constraint, Sketch, SketchPlane,
11    figures::{circle, n, rectangle, solved},
12    whole_sketch,
13};
14use geop_ops_model::{Combine, element, solid};
15use geop_ops_sketch::AddSketchArgs;
16
17use crate::{Along, SplitArgs, SplitFaceArgs};
18
19/// The examples of this crate, as an editor offers them.
20pub fn set() -> ExampleSet {
21    ExampleSet {
22        programs: vec![("split_plate", split_plate), ("badge", badge)],
23        workspaces: Vec::new(),
24    }
25}
26
27/// The plane of the origin normal to `normal`, as a plane to sketch on.
28fn on_origin(normal: FrameAxis) -> SketchPlane {
29    SketchPlane::Datum(origin_plane(normal))
30}
31
32/// A plate with a round hole, cut in two: the plate (`plate`) extruded both
33/// ways from its sketch, a line across it sketched on the plane through its
34/// middle and extruded into a face standing on its own (`cut`), and the
35/// plate split along that face (`halves`) into `split(halves,0)` and
36/// `split(halves,1)`, one of them with the hole.
37pub fn split_plate() -> Program {
38    let mut program = Program::new();
39    let mut plate = Sketch::new();
40    rectangle(&mut plate, [0.0, 0.0], 3.0, 1.0);
41    circle(&mut plate, [0.75, 0.5], 0.3);
42    program.push(
43        "plate_sketch",
44        AddSketchArgs::on(on_origin(FrameAxis::Z), solved(plate)),
45    );
46    program.push(
47        "plate",
48        ExtrudeArgs {
49            sketch: whole_sketch("plate_sketch"),
50            extent: Extents {
51                side1: Extent::blind(0.5),
52                symmetric: true,
53                side2: None,
54                reversed: false,
55            },
56            output: Output::Solid(Combine::NewBody),
57            draft: 0.0,
58        },
59    );
60
61    // Sketch x runs along world x, sketch y along world -z: a line across
62    // the plate's thickness at x = 2.
63    let mut cut = Sketch::new();
64    let (a, b) = (
65        cut.add_point(n(2.0), n(-1.0)),
66        cut.add_point(n(2.0), n(1.0)),
67    );
68    let line = cut.add_line(a, b);
69    for (point, y) in [(a, -1.0), (b, 1.0)] {
70        cut.constrain(Constraint::Fix {
71            point,
72            x: n(2.0),
73            y: n(y),
74        });
75    }
76    program.push(
77        "cut_sketch",
78        AddSketchArgs::on(on_origin(FrameAxis::Y), solved(cut)),
79    );
80    program.push(
81        "cut",
82        ExtrudeArgs {
83            sketch: whole_sketch("cut_sketch"),
84            extent: Extents {
85                side1: Extent::blind(3.0),
86                symmetric: true,
87                side2: None,
88                reversed: false,
89            },
90            output: Output::Faces { up_to: None },
91            draft: 0.0,
92        },
93    );
94    program.push(
95        "halves",
96        SplitArgs {
97            solid: solid("extrude(plate)"),
98            face: element(format!("extrude(cut,cut_sketch,{line})")),
99        },
100    );
101    program
102}
103
104/// A plate with a disc on its top, ready to colour or to pick on its own: the
105/// plate extruded from its sketch (`plate`), a circle sketched on the plane
106/// under it (`mark`), and the top divided along it (`disc`) into the disc,
107/// `split_face(disc,extrude(plate,end),...)`, and the rest of the top, which
108/// keeps its name. The solid is as it was.
109pub fn badge() -> Program {
110    let mut program = Program::new();
111    let mut plate = Sketch::new();
112    rectangle(&mut plate, [0.0, 0.0], 4.0, 2.0);
113    program.push(
114        "plate_sketch",
115        AddSketchArgs::on(on_origin(FrameAxis::Z), solved(plate)),
116    );
117    program.push(
118        "plate",
119        ExtrudeArgs {
120            sketch: whole_sketch("plate_sketch"),
121            extent: Extents {
122                side1: Extent::blind(0.5),
123                symmetric: false,
124                side2: None,
125                reversed: false,
126            },
127            output: Output::Solid(Combine::NewBody),
128            draft: 0.0,
129        },
130    );
131    let mut mark = Sketch::new();
132    circle(&mut mark, [2.0, 1.0], 0.6);
133    program.push(
134        "mark",
135        AddSketchArgs::on(on_origin(FrameAxis::Z), solved(mark)),
136    );
137    program.push(
138        "disc",
139        SplitFaceArgs {
140            face: Some(element("extrude(plate,end)")),
141            sketch: whole_sketch("mark"),
142            along: Along::SketchNormal,
143        },
144    );
145    program
146}