1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! The two public entry points: [`solve_meet_points`] (plain) and
//! [`solve_meet_points_with`] (cancellable, progress-reporting).
use BTreeMap;
use ;
/// Solves every tier's mast distance.
///
/// See the module docs for the model (vertex incidence), what the caller must
/// anchor (one scale reference per crown/pavilion/girdle block), and the
/// three-phase algorithm.
///
/// `gear_teeth_abs` is the index wheel's tooth count (see
/// [`indicatrix_formats::asc::AscSchedule::gear_teeth_abs`]). `tiers` must be in the
/// schedule's own file order: phase 1's dependency-order pass
/// (see the module docs' "three-phase algorithm") walks tiers in this same
/// file order and its result depends on it -- permuting the tier list changes
/// which mast a `DependencyOrder`-strategy tier solves to, not just the
/// order of the returned [`SolvedTier`]s. This is why
/// `Design::apply_edit(Edit::MoveTier { .. })` (in `indicatrix-cut-core`,
/// outside this crate) re-solves after moving a tier rather than reusing the
/// previous solve's masts.
///
/// Deterministic: two calls with identical inputs produce identical outputs. No
/// hashed iteration and no convex-hull library anywhere in this path.
///
/// Latency: `O(P^3)` per refinement sweep in the plane count `P`; see the
/// module docs' "Cost envelope" section for the measured figures. Never
/// cancels and reports no progress -- see [`solve_meet_points_with`] for
/// that; this is a thin wrapper passing a no-op [`SolveControl`], and above
/// [`MAX_PLANES`] it keeps the legacy behavior of returning an all-
/// [`SolveStrategy::Failed`](super::super::SolveStrategy::Failed) result instead of an error.
/// Cancellable, progress-reporting sibling of [`solve_meet_points`].
///
/// Same algorithm and same determinism guarantee: an unused `control`, i.e.
/// [`SolveControl::default`], reproduces [`solve_meet_points`] exactly, bit
/// for bit. Checks `control` at every cancel point (see the module docs,
/// "Cancellation and progress") and reports a [`SolveProgress`](super::super::SolveProgress)
/// at every point that has one.
///
/// # Errors
///
/// [`SolveError::NonFiniteInput`] when any tier carries a non-finite (NaN or
/// infinite) `angle_deg`, index, or `ScaleReference` mast (checked before any
/// solving starts, so this returns immediately -- see that variant's doc
/// comment for why); [`SolveError::TooManyPlanes`] when the design has more
/// than [`MAX_PLANES`] facet-plane instances; [`SolveError::Cancelled`] the
/// first time `control`'s cancel flag is observed set.