solvers, meshers: stop with Cancelled at each loop's natural points

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-15 10:39:40 -04:00
1 parent a2d646a75e
commit 5fcbee028e
12 files changed
+47 -1

No files matched your search

+3
View File
@@ -276,6 +276,7 @@ pub fn hex_mesh(surface: &BoundarySurface, faces: &[Option<Surface>], field: &dy
};
let mut reasons: Vec<String> = Vec::new();
for &method in methods {
fieldcraft_model::progress::check()?;
let mut last = None;
match method {
HexMethod::Extrude | HexMethod::Revolve => {
@@ -287,6 +288,7 @@ pub fn hex_mesh(surface: &BoundarySurface, faces: &[Option<Surface>], field: &dy
}
};
for setup in setups {
fieldcraft_model::progress::check()?;
// The cross-section is laid out once per frame; refinement retries reuse it.
let prepared = match layered::prepare(&ctx, setup) {
Ok(p) => p,
@@ -364,6 +366,7 @@ fn candidate_setups(ctx: &Ctx, method: HexMethod) -> std::result::Result<Vec<lay
fn with_refinement(ctx: &Ctx, method: HexMethod, run: impl Fn(u32) -> Result<Raw>) -> Result<HexMesh> {
let mut last = Error::Failed("no attempt".into());
for refine in 0..=MAX_REFINE {
fieldcraft_model::progress::check()?;
match run(refine).and_then(|raw| finish(&Cells::one(ctx), raw, method)) {
Ok(mesh) => return Ok(mesh),
Err(e @ Error::Failed(_)) => last = e,
+1
View File
@@ -251,6 +251,7 @@ pub fn octree_hex_mesh(surface: &BoundarySurface, field: &dyn SizeField, options
let mut hints: Vec<P> = Vec::new();
let mut retries: Vec<String> = Vec::new();
for attempt in 0..options.attempts {
fieldcraft_model::progress::check()?;
let cap = if attempt == 0 {
options.max_elements
} else {
+1
View File
@@ -460,6 +460,7 @@ pub fn improve(cx: &mut TetComplex, ctx: &Context, o: &ImproveOptions) -> Result
stats.passes += 1;
fieldcraft_model::progress::stage("Improvement pass", Some(o.max_passes as f64), "");
fieldcraft_model::progress::count(stats.passes as f64);
fieldcraft_model::progress::check()?;
let before = match carried.take() {
Some(b) => b,
None => indicators(cx)?,
+2
View File
@@ -491,6 +491,7 @@ pub fn quality_mesh(surface: &BoundarySurface, cdt: &TetMesh, analytic: Vec<Opti
progress::stage("Refinement round", Some(o.rounds as f64), "");
for round in 0..o.rounds {
progress::count((round + 1) as f64);
progress::check()?;
let stats = refine::refine(&mut cx, &ctx, &ropt)?;
let quiet = stats.interior + stats.boundary == 0;
let stopped = stats.stopped.clone();
@@ -514,6 +515,7 @@ pub fn quality_mesh(surface: &BoundarySurface, cdt: &TetMesh, analytic: Vec<Opti
}
// Put the boundary vertices on the exact surfaces (the tessellation is within its chordal
// tolerance of them).
progress::check()?;
progress::stage("Snapping to the geometry", None, "");
report.unsnapped = snap_to_geometry(&mut cx, &exact, true)?;
let c = cx.compact()?;
+4
View File
@@ -263,6 +263,10 @@ pub fn refine(cx: &mut TetComplex, ctx: &Context, o: &RefineOptions) -> Result<R
while head < queue.len() {
let t = queue.get(head).copied().unwrap_or(NONE);
head += 1;
// A round can insert hundreds of thousands of vertices: stop between them when asked.
if head.is_multiple_of(1024) {
fieldcraft_model::progress::check()?;
}
// Keep the queue's memory bounded: drop the processed prefix now and then.
if head > 1 << 20 {
queue.drain(..head);