diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 8e3658b8e..578831c23 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -86,51 +86,47 @@ impl PartialCycle { mut self, objects: &Objects, ) -> Result, ValidationError> { - let half_edges = { - let last_vertex = { - let last_half_edge = self - .half_edges - .last_mut() - .expect("Can't build cycle without any half-edges"); + // To create a cycle, we need to make sure that all its half-edges + // connect to each other. Let's start with all the connections between + // the first and the last half-edge. + let mut previous_vertex = None; + for half_edge in &mut self.half_edges { + let back_vertex = previous_vertex.unwrap_or_default(); + let front_vertex = + half_edge.front().surface_form().into_full(objects)?; - let surface_vertex = - last_half_edge.front().surface_form().into_full(objects)?; - - *last_half_edge = last_half_edge.clone().merge_with( - PartialHalfEdge::default().with_front_vertex( + *half_edge = half_edge.clone().merge_with( + PartialHalfEdge::default() + .with_back_vertex( + PartialVertex::default().with_surface_form(back_vertex), + ) + .with_front_vertex( PartialVertex::default() - .with_surface_form(surface_vertex.clone()), + .with_surface_form(front_vertex.clone()), ), - ); + ); - surface_vertex - }; + previous_vertex = Some(MaybePartial::from(front_vertex)); + } - let (half_edges, _) = self.half_edges.into_iter().fold( - Ok((Vec::new(), last_vertex)), - |result: Result<_, ValidationError>, half_edge| { - let (mut half_edges, previous_vertex) = result?; + // We're not quite done yet. We need to close the cycle, by connecting + // the last half-edge back around to the first one. + if let Some(half_edge) = self.half_edges.first_mut() { + let back_vertex = previous_vertex.unwrap_or_default(); - let half_edge = half_edge - .update_partial(|half_edge| { - let [back, _] = half_edge.vertices(); - let back = back.update_partial(|partial| { - partial.with_surface_form(previous_vertex) - }); + *half_edge = half_edge.clone().merge_with( + PartialHalfEdge::default().with_back_vertex( + PartialVertex::default().with_surface_form(back_vertex), + ), + ); + } - half_edge.with_back_vertex(back) - }) - .into_full(objects)?; - - let front = half_edge.front().surface_form().clone(); - half_edges.push(half_edge); - - Ok((half_edges, front)) - }, - )?; - - half_edges - }; + // All connections made! All that's left is to build the half-edges. + let mut half_edges = Vec::new(); + for half_edge in self.half_edges { + let half_edge = half_edge.into_full(objects)?; + half_edges.push(half_edge); + } Ok(objects.cycles.insert(Cycle::new(half_edges))?) }