geop_core_topology/euler/
mve.rs1use crate::{
2 Coedge, CoedgeGeometry, CoedgeId, Edge, EdgeId, FaceId, Model, Sense, Vertex, VertexId,
3 argument_validation::{validate_curve_start_and_end, validate_pcurve_start_and_end},
4 boundary::BoundaryType,
5};
6use geop_core_geometry::nurb_curve::{NurbCurve2D, NurbCurve3D};
7use geop_core_math::{
8 geop_error::{GeopError, GeopResult, WithContext},
9 scalars::Scalar,
10 vector::Vector3,
11};
12
13impl<S: Scalar> Model<S> {
14 pub fn mve(
19 self: &mut Model<S>,
20 coedge: CoedgeId,
21 curve: NurbCurve3D<S>,
22 pcurve: NurbCurve2D<S>,
23 pcurve_reversed: NurbCurve2D<S>,
24 p: Vector3<S>,
25 ) -> GeopResult<(VertexId, CoedgeId, CoedgeId, EdgeId)> {
26 let ctx = |e: GeopError| {
27 e.with_context(format!(
28 "Model::mve(
29 coedge={coedge}
30 curve={curve}
31 pcurve={pcurve}
32 pcurve_reversed={pcurve_reversed}
33 p={p}
34)"
35 ))
36 };
37 let ce = self.get_coedge(coedge)?.clone();
38 let face = self.get_face(ce.face)?.clone();
39
40 let ce_end_id = self.coedge_end_vertex_id(coedge)?;
41 let ce_end = self.get_vertex(ce_end_id)?.clone();
42
43 validate_pcurve_start_and_end(&face.surface, &pcurve, &ce_end.point, &p)
44 .with_context(&ctx)?;
45 validate_pcurve_start_and_end(&face.surface, &pcurve_reversed, &p, &ce_end.point)
46 .with_context(&ctx)?;
47 validate_curve_start_and_end(&curve, &ce_end.point, &p).with_context(&ctx)?;
48
49 let v = self.insert_vertex(Vertex { point: p });
50 let edge_id = self.insert_edge(Edge {
51 curve: curve,
52 start_vertex: ce_end_id,
53 end_vertex: v,
54 });
55
56 let coedge_forward = self.insert_coedge(Coedge {
57 geometry: CoedgeGeometry::Edge(edge_id),
58 sense: Sense::Forward,
59 pcurve: pcurve,
60 next: CoedgeId(0), prev: coedge,
62 face: ce.face,
63 });
64
65 let coedge_reversed = self.insert_coedge(Coedge {
66 geometry: CoedgeGeometry::Edge(edge_id),
67 sense: Sense::Reversed,
68 pcurve: pcurve_reversed,
69 next: ce.next, prev: CoedgeId(0), face: ce.face,
72 });
73
74 self.coedges.get_mut(&coedge_forward).unwrap().next = coedge_reversed;
75 self.coedges.get_mut(&coedge_reversed).unwrap().prev = coedge_forward;
76 self.coedges.get_mut(&coedge).unwrap().next = coedge_forward;
77 self.coedges.get_mut(&ce.next).unwrap().prev = coedge_reversed;
78
79 Ok((v, coedge_forward, coedge_reversed, edge_id))
80 }
81
82 pub fn mve_from_vertex(
87 self: &mut Model<S>,
88 face_id: FaceId,
89 vertex: VertexId,
90 curve: NurbCurve3D<S>,
91 pcurve: NurbCurve2D<S>,
92 pcurve_reversed: NurbCurve2D<S>,
93 p: Vector3<S>,
94 ) -> GeopResult<(VertexId, CoedgeId, CoedgeId, EdgeId)> {
95 let face = self.get_face(face_id)?.clone();
96 let ce_end = self.get_vertex(vertex)?.clone();
97 validate_pcurve_start_and_end(&face.surface, &pcurve, &ce_end.point, &p)?;
98 validate_pcurve_start_and_end(&face.surface, &pcurve_reversed, &p, &ce_end.point)?;
99 validate_curve_start_and_end(&curve, &ce_end.point, &p)?;
100
101 let v = self.insert_vertex(Vertex { point: p });
102 let edge_id = self.insert_edge(Edge {
103 curve: curve,
104 start_vertex: vertex,
105 end_vertex: v,
106 });
107
108 let coedge_forward = self.insert_coedge(Coedge {
109 geometry: CoedgeGeometry::Edge(edge_id),
110 sense: Sense::Forward,
111 pcurve: pcurve,
112 next: CoedgeId(0), prev: CoedgeId(0), face: face_id,
115 });
116
117 let coedge_reversed = self.insert_coedge(Coedge {
118 geometry: CoedgeGeometry::Edge(edge_id),
119 sense: Sense::Reversed,
120 pcurve: pcurve_reversed,
121 next: CoedgeId(0), prev: CoedgeId(0), face: face_id,
124 });
125
126 self.coedges.get_mut(&coedge_forward).unwrap().next = coedge_reversed;
127 self.coedges.get_mut(&coedge_reversed).unwrap().prev = coedge_forward;
128 self.coedges.get_mut(&coedge_forward).unwrap().prev = coedge_reversed;
129 self.coedges.get_mut(&coedge_reversed).unwrap().next = coedge_forward;
130
131 let face = self.get_face_mut(face_id)?;
133 let is_this_vertex =
134 |b: &BoundaryType| matches!(b, BoundaryType::Vertex(v_id) if *v_id == vertex);
135 if is_this_vertex(&face.outer) {
136 face.outer = BoundaryType::Loop(coedge_reversed);
137 } else if let Some(hole) = face.holes.iter_mut().find(|b| is_this_vertex(b)) {
138 *hole = BoundaryType::Loop(coedge_reversed);
139 }
140
141 Ok((v, coedge_forward, coedge_reversed, edge_id))
142 }
143}