Add more fast paths to the clipper
This commit is contained in:
parent
d08ff40cdf
commit
ca3a8852a6
|
@ -276,6 +276,16 @@ trait ContourClipper where Self::Edge: TEdge {
|
|||
fn contour_mut(&mut self) -> &mut Contour;
|
||||
|
||||
fn clip_against(&mut self, edge: Self::Edge) {
|
||||
// Fast path to avoid allocation in the no-clip case.
|
||||
match self.check_for_fast_clip(&edge) {
|
||||
FastClipResult::SlowPath => {}
|
||||
FastClipResult::AllInside => return,
|
||||
FastClipResult::AllOutside => {
|
||||
*self.contour_mut() = Contour::new();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let input = mem::replace(self.contour_mut(), Contour::new());
|
||||
for mut segment in input.iter() {
|
||||
// Easy cases.
|
||||
|
@ -334,6 +344,32 @@ trait ContourClipper where Self::Edge: TEdge {
|
|||
contour.push_segment(*segment);
|
||||
}
|
||||
}
|
||||
|
||||
fn check_for_fast_clip(&mut self, edge: &Self::Edge) -> FastClipResult {
|
||||
let mut result = None;
|
||||
for segment in self.contour_mut().iter() {
|
||||
let location = edge.trivially_test_segment(&segment);
|
||||
match (result, location) {
|
||||
(None, EdgeRelativeLocation::Outside) => {
|
||||
result = Some(FastClipResult::AllOutside);
|
||||
}
|
||||
(None, EdgeRelativeLocation::Inside) => {
|
||||
result = Some(FastClipResult::AllInside);
|
||||
}
|
||||
(Some(FastClipResult::AllInside), EdgeRelativeLocation::Inside) |
|
||||
(Some(FastClipResult::AllOutside), EdgeRelativeLocation::Outside) => {}
|
||||
(_, _) => return FastClipResult::SlowPath,
|
||||
}
|
||||
}
|
||||
result.unwrap_or(FastClipResult::AllOutside)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum FastClipResult {
|
||||
SlowPath,
|
||||
AllInside,
|
||||
AllOutside,
|
||||
}
|
||||
|
||||
// General convex polygon clipping in 2D
|
||||
|
@ -375,6 +411,7 @@ impl ContourPolygonClipper {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum EdgeRelativeLocation {
|
||||
Intersecting,
|
||||
Inside,
|
||||
|
|
Loading…
Reference in New Issue