mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-08 10:41:09 +00:00
address review: size operator budgets from drawn segments plus per-subpath overhead
This commit is contained in:
@@ -448,11 +448,16 @@ struct Sample {
|
||||
/// output keeps a short stack from multiplying a simple path into billions of points.
|
||||
pub const MAX_OPERATOR_SEGMENTS: usize = 1 << 20;
|
||||
|
||||
/// `want` pieces (or copies) per input segment, reduced so the whole output stays within
|
||||
/// [`MAX_OPERATOR_SEGMENTS`] (never below 1, so the input itself always passes through).
|
||||
/// `want` pieces (or copies) per input segment, reduced so the whole output (segments times
|
||||
/// pieces, plus per-subpath overhead) stays within [`MAX_OPERATOR_SEGMENTS`] (never below 1, so the input itself always passes through).
|
||||
fn pieces_within_budget(paths: &[BezPath], want: usize) -> usize {
|
||||
let segs: usize = paths.iter().map(|p| p.elements().len()).sum();
|
||||
want.min(MAX_OPERATOR_SEGMENTS / segs.max(1)).max(1)
|
||||
// Count what is subdivided (drawn segments) and keep room for each subpath's own MoveTo/Close.
|
||||
let (mut segs, mut overhead) = (0usize, 0usize);
|
||||
for sub in paths.iter().flat_map(subs) {
|
||||
segs = segs.saturating_add(sub.segs.len());
|
||||
overhead = overhead.saturating_add(2);
|
||||
}
|
||||
want.min(MAX_OPERATOR_SEGMENTS.saturating_sub(overhead) / segs.max(1)).max(1)
|
||||
}
|
||||
|
||||
/// Split every segment into `m` pieces of equal arc length. Original vertices get the average of
|
||||
|
||||
@@ -438,3 +438,18 @@ fn stacked_expanding_operators_stay_within_the_segment_budget() {
|
||||
// Within the budget nothing changes: 4 segments × 11 pieces.
|
||||
assert_eq!(vertex_count(&zigzag(&[sq(0.0, 0.0, 100.0)], 1.0, 10.0, false)[0]), 44);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn many_short_open_paths_keep_their_requested_detail_within_the_budget() {
|
||||
// 1000 open lines at 1000 ridges: 1,001,000 segments fit the budget, so nothing is reduced.
|
||||
let lines: Vec<BezPath> = (0..1000)
|
||||
.map(|i| {
|
||||
let mut p = BezPath::new();
|
||||
p.move_to((0.0, i as f64));
|
||||
p.line_to((100.0, i as f64));
|
||||
p
|
||||
})
|
||||
.collect();
|
||||
let z = zigzag(&lines, 1.0, 1000.0, false);
|
||||
assert!(z.iter().all(|q| q.elements().len() == 1 + 1001));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user