diff --git a/crates/fj-kernel/src/partial/maybe_partial.rs b/crates/fj-kernel/src/partial/maybe_partial.rs index 973f0ccb6..dc8edd741 100644 --- a/crates/fj-kernel/src/partial/maybe_partial.rs +++ b/crates/fj-kernel/src/partial/maybe_partial.rs @@ -105,6 +105,28 @@ impl MaybePartial { } impl MaybePartial { + /// Access the back vertex + pub fn back(&self) -> Option> { + match self { + Self::Full(full) => Some(full.back().clone().into()), + Self::Partial(partial) => { + let [back, _] = &partial.vertices; + back.clone() + } + } + } + + /// Access the front vertex + pub fn front(&self) -> Option> { + match self { + Self::Full(full) => Some(full.front().clone().into()), + Self::Partial(partial) => { + let [_, front] = &partial.vertices; + front.clone() + } + } + } + /// Access the vertices pub fn vertices(&self) -> [Option>; 2] { match self { diff --git a/crates/fj-kernel/src/partial/objects/cycle.rs b/crates/fj-kernel/src/partial/objects/cycle.rs index 3b3167b70..f4df40e7c 100644 --- a/crates/fj-kernel/src/partial/objects/cycle.rs +++ b/crates/fj-kernel/src/partial/objects/cycle.rs @@ -160,21 +160,46 @@ impl PartialCycle { } /// Build a full [`Cycle`] from the partial cycle - pub fn build(self, objects: &Objects) -> Cycle { + pub fn build(mut self, objects: &Objects) -> Cycle { let surface = self.surface.expect("Need surface to build `Cycle`"); let surface_for_edges = surface.clone(); let half_edges = { + let last_vertex = self + .half_edges + .last_mut() + .and_then(|half_edge| { + half_edge.front().map(|vertex| (half_edge, vertex)) + }) + .and_then(|(half_edge, vertex)| { + vertex.surface_form().map(|surface_vertex| { + (half_edge, vertex, surface_vertex) + }) + }) + .map(|(half_edge, vertex, surface_vertex)| { + let surface_vertex = surface_vertex + .update_partial(|surface_vertex| { + surface_vertex.with_surface(Some(surface.clone())) + }) + .into_full(objects); + + *half_edge = + half_edge.clone().update_partial(|half_edge| { + half_edge.with_front_vertex(Some( + vertex.update_partial(|vertex| { + vertex.with_surface_form(Some( + surface_vertex.clone(), + )) + }), + )) + }); + + surface_vertex + }); + let (half_edges, _) = self.half_edges.into_iter().fold( - (Vec::new(), None), - |(mut half_edges, previous), next| { - let previous_half_edge: Option = previous; - - let previous_vertex = previous_half_edge.map(|half_edge| { - let [_, vertex] = half_edge.vertices().clone(); - vertex.surface_form().clone() - }); - - let next = next + (Vec::new(), last_vertex), + |(mut half_edges, previous_vertex), half_edge| { + let half_edge = half_edge .update_partial(|half_edge| { let [from, _] = half_edge.vertices.clone(); let from = from.map(|vertex| { @@ -189,9 +214,10 @@ impl PartialCycle { }) .into_full(objects); - half_edges.push(next.clone()); + let front = half_edge.front().surface_form().clone(); + half_edges.push(half_edge); - (half_edges, Some(next)) + (half_edges, Some(front)) }, );