Add CurveBoundaries::merge

This commit is contained in:
Hanno Braun 2023-10-06 12:50:05 +02:00
parent 3e6bd8cd14
commit 7cae10645e
3 changed files with 57 additions and 36 deletions

View File

@ -1,5 +1,3 @@
use std::collections::VecDeque;
use fj_math::Point;
use crate::geometry::{CurveBoundaries, CurveBoundary};
@ -38,40 +36,9 @@ impl CurveApprox {
&mut self,
new_segment: CurveApproxSegment,
) -> CurveApproxSegment {
let mut overlapping_segments = VecDeque::new();
let mut i = 0;
loop {
let Some((boundary, _)) = self.segments.inner.get(i) else {
break;
};
if boundary.overlaps(&new_segment.boundary) {
let segment = self.segments.inner.swap_remove(i);
overlapping_segments.push_back(segment);
continue;
}
i += 1;
}
let mut merged_boundary = new_segment.boundary;
let mut merged_segment = new_segment.points;
for (boundary, segment) in overlapping_segments {
assert!(
merged_boundary.overlaps(&boundary),
"Shouldn't merge segments that don't overlap."
);
merged_boundary = merged_boundary.union(boundary);
merged_segment.merge(&segment, boundary);
}
self.segments
.inner
.push((merged_boundary, merged_segment.clone()));
self.segments.inner.sort();
let (merged_boundary, merged_segment) = self
.segments
.merge(new_segment.boundary, new_segment.points);
CurveApproxSegment {
boundary: merged_boundary,

View File

@ -56,4 +56,8 @@ impl CurveBoundariesPayload for CurveApproxPoints {
fn make_subset(&mut self, boundary: CurveBoundary<Point<1>>) {
self.make_subset(boundary)
}
fn merge(&mut self, other: &Self, other_boundary: CurveBoundary<Point<1>>) {
self.merge(other, other_boundary)
}
}

View File

@ -1,3 +1,5 @@
use std::collections::VecDeque;
use fj_math::Point;
use crate::geometry::CurveBoundary;
@ -61,6 +63,50 @@ impl<T: CurveBoundariesPayload> CurveBoundaries<T> {
self.inner.retain(|(boundary, _)| !boundary.is_empty());
}
/// Merge the provided boundary into `self`
///
/// Return the merged boundary and payload.
pub fn merge(
&mut self,
new_boundary: CurveBoundary<Point<1>>,
new_payload: T,
) -> (CurveBoundary<Point<1>>, T) {
let mut overlapping_payloads = VecDeque::new();
let mut i = 0;
loop {
let Some((boundary, _)) = self.inner.get(i) else {
break;
};
if boundary.overlaps(&new_boundary) {
let payload = self.inner.swap_remove(i);
overlapping_payloads.push_back(payload);
continue;
}
i += 1;
}
let mut merged_boundary = new_boundary;
let mut merged_payload = new_payload;
for (boundary, payload) in overlapping_payloads {
assert!(
merged_boundary.overlaps(&boundary),
"Shouldn't merge boundaries that don't overlap."
);
merged_boundary = merged_boundary.union(boundary);
merged_payload.merge(&payload, boundary);
}
self.inner.push((merged_boundary, merged_payload.clone()));
self.inner.sort();
(merged_boundary, merged_payload)
}
}
impl<T: CurveBoundariesPayload> Default for CurveBoundaries<T> {
@ -76,9 +122,13 @@ pub trait CurveBoundariesPayload: Clone + Ord {
/// Reduce the payload to the subset defined by the provided boundary
fn make_subset(&mut self, boundary: CurveBoundary<Point<1>>);
/// Merge the provided payload
fn merge(&mut self, other: &Self, other_boundary: CurveBoundary<Point<1>>);
}
impl CurveBoundariesPayload for () {
fn reverse(&mut self) {}
fn make_subset(&mut self, _: CurveBoundary<Point<1>>) {}
fn merge(&mut self, _: &Self, _: CurveBoundary<Point<1>>) {}
}