mirror of
https://github.com/gittrahan/support-fins.git
synced 2026-10-22 11:53:02 -05:00
- --rot is three.js Euler XYZ (Rx*Ry*Rz), the order printfins.com shows under the part, so a pose found on the site carries over - --fins-only maps the fins back onto the part as it is in the file; it can't take --rot, and writes nothing when there are no fins - a Support Fins 3MF (part + fins) is refused instead of finned again - settings the site would hide warn on stderr; -o can't overwrite the input; -- ends the options; Node 20.10+ - the summary rounds ties to even, word for word with Python's host_report
42 lines
1.8 KiB
JavaScript
42 lines
1.8 KiB
JavaScript
// The one-line result every host shows, from computeFins' stats: what was placed
|
|
// and -- quality first -- what wasn't: overhangs too shallow for a fin this way up,
|
|
// and pieces that start in mid-air. Same facts as the website's readout
|
|
// (web/ui/readout.js), shorter.
|
|
//
|
|
// Python hosts have the same line in py/supportfins_host.py host_report; keep the
|
|
// two word for word (plugins/cli/tests/cli.test.js checks them against each other
|
|
// when python3 is on the PATH).
|
|
|
|
// Python's f"{x:.1f}": an exact tie rounds to even (4.25 -> 4.2), where toFixed rounds up.
|
|
function oneDecimal(x) {
|
|
const t = x * 10;
|
|
const f = Math.floor(t);
|
|
const r = t - f === 0.5 ? (f % 2 === 0 ? f : f + 1) : Math.round(t);
|
|
return (r / 10).toFixed(1);
|
|
}
|
|
|
|
const plural = (n, one, many) => `${n} ${n === 1 ? one : many}`;
|
|
|
|
/** @param {object} stats computeFins(...).stats */
|
|
export function reportLine(stats) {
|
|
const walls = (stats.braces || 0) + (stats.props || 0); // tined + plain, as the site counts
|
|
let head = `${plural(walls, 'wall', 'walls')}, ${plural(stats.tines || 0, 'tine', 'tines')}`;
|
|
// Sway braces hold the tall sides, not an overhang: never added to the walls.
|
|
if (stats.swayBraces) head += `, ${plural(stats.swayBraces, 'sway brace', 'sway braces')}`;
|
|
const parts = [head];
|
|
const unserved = stats.unserved || 0;
|
|
if (unserved) {
|
|
parts.push(`${unserved} overhang${unserved === 1 ? ' is' : 's are'} too shallow `
|
|
+ 'for a fin this way up (tilt the part steeper)');
|
|
}
|
|
const floating = stats.floating || 0;
|
|
if (floating) {
|
|
const drop = oneDecimal(Number(stats.floatingDrop || 0));
|
|
parts.push((floating === 1
|
|
? `one piece isn't joined to the rest: it starts ${drop} mm up`
|
|
: `${floating} pieces aren't joined to the rest: the first starts ${drop} mm up`)
|
|
+ ', held only by supports');
|
|
}
|
|
return parts.join('; ');
|
|
}
|