fj_operations/
difference_2d.rs1use std::ops::Deref;
2
3use fj_interop::{debug::DebugInfo, ext::ArrayExt, mesh::Color};
4use fj_kernel::{
5 algorithms::reverse::Reverse,
6 objects::{Face, Sketch},
7 operations::Insert,
8 services::Services,
9};
10use fj_math::Aabb;
11
12use super::Shape;
13
14impl Shape for fj::Difference2d {
15 type Brep = Sketch;
16
17 fn compute_brep(
18 &self,
19 services: &mut Services,
20 debug_info: &mut DebugInfo,
21 ) -> Self::Brep {
22 let mut faces = Vec::new();
26
27 let mut exteriors = Vec::new();
28 let mut interiors = Vec::new();
29
30 let [a, b] = self
31 .shapes()
32 .each_ref_ext()
33 .map(|shape| shape.compute_brep(services, debug_info));
34
35 if let Some(face) = a.faces().into_iter().next() {
36 let surface = face.surface();
39
40 for face in a.faces() {
41 assert_eq!(
42 surface,
43 face.surface(),
44 "Trying to subtract faces with different surfaces.",
45 );
46
47 exteriors.push(face.exterior().clone());
48 for cycle in face.interiors() {
49 interiors.push(cycle.clone().reverse(services));
50 }
51 }
52
53 for face in b.faces() {
54 assert_eq!(
55 surface,
56 face.surface(),
57 "Trying to subtract faces with different surfaces.",
58 );
59
60 interiors.push(face.exterior().clone().reverse(services));
61 }
62
63 let exterior = exteriors
73 .pop()
74 .expect("Can't construct face without an exterior");
75 assert!(
76 exteriors.is_empty(),
77 "Can't construct face with multiple exteriors"
78 );
79
80 let face = Face::new(
81 surface.clone(),
82 exterior,
83 interiors,
84 Some(Color(self.color())),
85 );
86 faces.push(face.insert(services));
87 }
88
89 let difference = Sketch::new(faces).insert(services);
90 difference.deref().clone()
91 }
92
93 fn bounding_volume(&self) -> Aabb<3> {
94 self.shapes()[0].bounding_volume()
98 }
99}