1use crate::*;
26
27#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
30pub struct HalfEdge<IC>
32where
33 IC: IsIndexContainer,
34{
35 tails: IC,
36 twins: Vec<Option<EId>>,
37 vertices_start_edges: Vec<IC>,
38}
39
40impl<IC> HalfEdge<IC>
41where
42 IC: IsIndexContainer,
43{
44 pub fn new<T, M>(mesh: &M) -> Self
48 where
49 M: IsMesh<T, Face3>,
50 {
51 let n_vertices = mesh.num_vertices();
52 let n_faces = mesh.num_faces();
53 let n_edges = 3 * n_faces;
54
55 let mut tails = IC::with_capacity_and_support_for(n_edges, n_vertices);
56
57 let twins = vec![None; 3 * n_faces];
58 let mut vertices_start_edges = Vec::with_capacity(n_vertices);
59 let estimated_edges_per_vertex = 6; for i in 0..n_faces {
62 match mesh.face_vertex_ids(FId { val: i }) {
63 Err(_) => {}
64 Ok(face) => {
65 tails.push(face.a.val);
66 tails.push(face.b.val);
67 tails.push(face.c.val);
68
69 safe_append_at(
70 &mut vertices_start_edges,
71 estimated_edges_per_vertex,
72 n_edges,
73 face.a.val,
74 i * 3 + 0,
75 );
76 safe_append_at(
77 &mut vertices_start_edges,
78 estimated_edges_per_vertex,
79 n_edges,
80 face.b.val,
81 i * 3 + 1,
82 );
83 safe_append_at(
84 &mut vertices_start_edges,
85 estimated_edges_per_vertex,
86 n_edges,
87 face.c.val,
88 i * 3 + 2,
89 );
90 }
91 }
92 }
93
94 let mut result = HalfEdge {
95 tails,
96 twins,
97 vertices_start_edges,
98 };
99
100 let mut cache = Vec::new();
105 for i in 0..result.tails.len() {
106 cache.clear();
107 let _ = result.next(EId { val: i }).and_then(&mut |next_id: EId| {
108 result.edges_originating(
109 VId {
110 val: result.tails.get(next_id.val),
111 },
112 &mut cache,
113 )
114 });
115 for originating_id in cache.iter() {
116 let _ = result.next(*originating_id).map(|candidate_id| {
117 if result.tails.get(candidate_id.val) == result.tails.get(i) {
118 result.twins[i] = Some(candidate_id)
119 }
120 });
121 }
122 }
123 result
124 }
125 pub fn tail(&self, id: EId) -> Result<VId> {
127 self.ensure_edge_id(id)?;
128 Ok(VId {
129 val: self.tails.get(id.val),
130 })
131 }
132 pub fn face(&self, id: EId) -> Result<FId> {
134 self.ensure_edge_id(id)?;
135 Ok(FId { val: id.val / 3 })
136 }
137 pub fn twin(&self, id: EId) -> Result<Option<EId>> {
139 self.ensure_edge_id(id)?;
140 Ok(self.twins[id.val])
141 }
142 pub fn next(&self, id: EId) -> Result<EId> {
144 self.ensure_edge_id(id)?;
145 if Self::last_in_face(id) {
146 return Ok(EId { val: id.val - 2 });
147 }
148 Ok(EId { val: id.val + 1 })
149 }
150 pub fn prev(&self, id: EId) -> Result<EId> {
152 self.ensure_edge_id(id)?;
153 if Self::first_in_face(id) {
154 return Ok(EId { val: id.val + 2 });
155 }
156 Ok(EId { val: id.val - 1 })
157 }
158 pub fn edges_originating(&self, id: VId, result: &mut Vec<EId>) -> Result<()> {
160 self.ensure_vertex_id(id)?;
161 result.extend(
162 self.vertices_start_edges[id.val]
163 .iter()
164 .map(|x| EId { val: x }),
165 );
166 Ok(())
167 }
168 pub fn edges_ending(&self, id: VId, cache: &mut Vec<EId>, result: &mut Vec<EId>) -> Result<()> {
171 cache.clear();
172 self.edges_originating(id, cache)?;
173 for edge in cache {
174 match self.prev(*edge) {
175 Err(_) => {}
176 Ok(id) => result.push(id),
177 }
178 }
179 Ok(())
180 }
181 pub fn edges_all(&self, id: VId, cache: &mut Vec<EId>, result: &mut Vec<EId>) -> Result<()> {
184 cache.clear();
185 self.edges_originating(id, cache)?;
186 for edge in cache {
187 result.push(*edge);
188 match self.prev(*edge) {
189 Err(_) => {}
190 Ok(id) => result.push(id),
191 }
192 }
193 Ok(())
194 }
195 pub fn faces(&self, id: VId, cache: &mut Vec<EId>, result: &mut Vec<FId>) -> Result<()> {
198 cache.clear();
199 self.edges_originating(id, cache)?;
200 for edge in cache {
201 match self.face(*edge) {
202 Err(_) => {}
203 Ok(id) => result.push(id),
204 }
205 }
206 Ok(())
207 }
208 fn first_in_face(id: EId) -> bool {
210 id.val % 3 == 0
211 }
212 fn last_in_face(id: EId) -> bool {
214 id.val % 3 == 2
215 }
216 pub fn ensure_edge_id(&self, id: EId) -> Result<()> {
218 if id.val >= self.tails.len() {
219 return Err(ErrorKind::IncorrectEdgeID);
220 }
221 Ok(())
222 }
223 pub fn ensure_vertex_id(&self, id: VId) -> Result<()> {
225 if id.val >= self.vertices_start_edges.len() {
226 return Err(ErrorKind::IncorrectVertexID);
227 }
228 Ok(())
229 }
230}
231
232impl<IC> From<(IC, Vec<Option<EId>>, Vec<IC>)> for HalfEdge<IC>
235where
236 IC: IsIndexContainer,
237{
238 fn from(ev: (IC, Vec<Option<EId>>, Vec<IC>)) -> Self {
239 Self {
240 tails: ev.0,
241 twins: ev.1,
242 vertices_start_edges: ev.2,
243 }
244 }
245}
246
247impl<IC> Into<(IC, Vec<Option<EId>>, Vec<IC>)> for HalfEdge<IC>
248where
249 IC: IsIndexContainer,
250{
251 fn into(self) -> (IC, Vec<Option<EId>>, Vec<IC>) {
252 (self.tails, self.twins, self.vertices_start_edges)
253 }
254}
255
256impl<IC> Into<(IC, Vec<Option<EId>>)> for HalfEdge<IC>
257where
258 IC: IsIndexContainer,
259{
260 fn into(self) -> (IC, Vec<Option<EId>>) {
261 (self.tails, self.twins)
262 }
263}
264
265impl<IC> Into<Vec<IC>> for HalfEdge<IC>
266where
267 IC: IsIndexContainer,
268{
269 fn into(self) -> Vec<IC> {
270 self.vertices_start_edges
271 }
272}
273
274fn safe_append_at<IC>(vec: &mut Vec<IC>, capacity: usize, support: usize, i: usize, val: usize)
277where
278 IC: IsIndexContainer,
279{
280 if i >= vec.len() {
281 vec.resize(i + 1, IC::with_capacity_and_support_for(capacity, support));
282 }
283
284 vec[i].push(val);
285}