geop_core_topology/euler/
mer.rs1use crate::{
2 Coedge, CoedgeGeometry, CoedgeId, Edge, EdgeId, FaceId, Model, Sense,
3 argument_validation::{
4 validate_curve_start_and_end, validate_pcurve_start_and_end, validate_same_loop,
5 },
6 boundary::BoundaryType,
7};
8use geop_core_geometry::nurb_curve::{NurbCurve2D, NurbCurve3D};
9use geop_core_math::{
10 geop_error::{GeopError, GeopResult, WithContext},
11 scalars::Scalar,
12 with_context,
13};
14
15impl<S: Scalar> Model<S> {
16 pub fn mer(
32 self: &mut Model<S>,
33 coedge1: CoedgeId,
34 coedge2: CoedgeId,
35 curve: NurbCurve3D<S>,
36 pcurve: NurbCurve2D<S>,
37 pcurve_reversed: NurbCurve2D<S>,
38 existing_face_id: FaceId,
39 ) -> GeopResult<(EdgeId, CoedgeId, CoedgeId)> {
40 let ctx = |e: GeopError| {
41 e.with_context(format!(
42 "Model::mer(
43 coedge1={coedge1}
44 coedge2={coedge2}
45 curve={curve}
46 pcurve={pcurve}
47 pcurve_reversed={pcurve_reversed}
48 existing_face_id={existing_face_id}"
49 ))
50 };
51
52 let ce1 = self.get_coedge(coedge1)?.clone();
53 let ce2 = self.get_coedge(coedge2)?.clone();
54 validate_same_loop(self, coedge1, coedge2)?;
55 let old_face_id = ce1.face;
56 let old_face = self.get_face(old_face_id)?.clone();
57 let existing_face = self.get_face(existing_face_id)?.clone();
58
59 let start = self
60 .get_vertex(self.coedge_end_vertex_id(coedge1)?)?
61 .clone()
62 .point;
63 let end = self
64 .get_vertex(self.coedge_start_vertex_id(coedge2)?)?
65 .clone()
66 .point;
67
68 validate_pcurve_start_and_end(&existing_face.surface, &pcurve, &start, &end)
69 .with_context("initial arg validation")
70 .with_context(&ctx)?;
71 validate_pcurve_start_and_end(&old_face.surface, &pcurve_reversed, &end, &start)
72 .with_context("initial arg validation")
73 .with_context(&ctx)?;
74 validate_curve_start_and_end(&curve, &start, &end)
75 .with_context("initial arg validation")
76 .with_context(&ctx)?;
77
78 let old_boundary_idx = self
82 .find_boundary_containing(old_face_id, coedge1)
83 .with_context(&ctx)?;
84
85 let mut ring_members = vec![coedge2];
88 while *ring_members.last().unwrap() != coedge1 {
89 ring_members.push(self.get_coedge(*ring_members.last().unwrap())?.next);
90 }
91 for &member in &ring_members {
92 let c = self.get_coedge(member)?.clone();
93 let sp = self.coedge_start_vertex(member)?.point;
94 let ep = self.coedge_end_vertex(member)?.point;
95 validate_pcurve_start_and_end(&existing_face.surface, &c.pcurve, &sp, &ep)
96 .with_context(with_context!(
97 "reassigning coedge {member} to existing_face_id"
98 ))
99 .with_context(&ctx)?;
100 }
101
102 let edge_id = self.insert_edge(Edge {
104 curve,
105 start_vertex: self.coedge_end_vertex_id(coedge1)?,
106 end_vertex: self.coedge_start_vertex_id(coedge2)?,
107 });
108 let next1 = ce1.next;
109 let prev2 = ce2.prev;
110
111 let coedge_forward = self.insert_coedge(Coedge {
113 geometry: CoedgeGeometry::Edge(edge_id),
114 sense: Sense::Forward,
115 pcurve: pcurve,
116 next: coedge2,
117 prev: coedge1,
118 face: ce1.face, });
120
121 let coedge_backward = self.insert_coedge(Coedge {
123 geometry: CoedgeGeometry::Edge(edge_id),
124 sense: Sense::Reversed,
125 pcurve: pcurve_reversed,
126 next: next1,
127 prev: prev2,
128 face: ce1.face,
129 });
130
131 self.coedges.get_mut(&coedge1).unwrap().next = coedge_forward;
132 self.coedges.get_mut(&coedge2).unwrap().prev = coedge_forward;
133 self.coedges.get_mut(&prev2).unwrap().next = coedge_backward;
134 self.coedges.get_mut(&next1).unwrap().prev = coedge_backward;
135
136 let existing = self.faces.get_mut(&existing_face_id).unwrap();
145 match existing.outer {
146 BoundaryType::Vertex(_) => existing.outer = BoundaryType::Loop(coedge2),
147 BoundaryType::Loop(_) => existing.holes.push(BoundaryType::Loop(coedge2)),
148 }
149
150 self.coedges.get_mut(&coedge_forward).unwrap().face = existing_face_id;
152 for &member in &ring_members {
153 self.coedges.get_mut(&member).unwrap().face = existing_face_id;
154 }
155
156 self.faces
161 .get_mut(&old_face_id)
162 .unwrap()
163 .set_boundary(old_boundary_idx, BoundaryType::Loop(next1));
164
165 Ok((edge_id, coedge_backward, coedge_forward))
166 }
167}