Reads the equipment schedule hidden in a foodservice drawing's item tags: one row per item, its quantity and the sheets that show it.
How the precision is kept
Quantities are the numbers typed in the tags, added in 64-bit. Which sheet shows a tag is decided by turning the tag's insertion point into each viewport's own axes and comparing it with the viewport's half width and half height, with no tolerance.
Calculations under this policy
3 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
For each sheet viewport, the half width and half height of the model area it shows.
k = h ÷ viewHeight; half width = w ÷ 2 ÷ k; half height = h ÷ 2 ÷ k
The scale is the viewport's paper height over the model height it shows; a viewport whose scale is not positive is skipped. The cosine and sine of the negative twist are kept for the inside test.
dwg-equipment.js
lines 38 to 41
BimCraft 0.8.1
const k = v.h / v.viewHeight;
if (!(k > 0)) continue;
const hw = v.w / 2 / k, hh = v.h / 2 / k, c = Math.cos(-v.twist), sn = Math.sin(-v.twist);
windows.push({ key: s.key, name: s.name, vx: v.vx, vy: v.vy, hw, hh, c, sn });
Sheets that show a point
64-bit
Which sheets show a given model point.
u = dx·cos − dy·sin, v = dx·sin + dy·cos; inside when |u| ≤ half width and |v| ≤ half height
The offset from the view point is turned into the viewport's axes and compared with the half sizes by exact comparison. A tag exactly on a viewport's edge counts as shown.
dwg-equipment.js
lines 44 to 52
BimCraft 0.8.1
const sheetsAt = (x, y) => {
const out = [];
for (const w of windows) {
const dx = x - w.vx, dy = y - w.vy;
const u = dx * w.c - dy * w.sn, v = dx * w.sn + dy * w.c; // into the viewport's own axes
if (Math.abs(u) <= w.hw && Math.abs(v) <= w.hh && !out.includes(w.key)) out.push(w.key);
}
return out;
};
Quantity of a row
64-bit
The scheduled quantity of an item tagged in several places.
qty = Σ tag quantities
Each tag's quantity is read with Number() and the values are added in order. The sum is written with String() and no rounding. If any tag's quantity is empty or not a number, the parts are listed instead of summed.
A row's quantity is the sum of its tags' quantities when every one is a number; otherwise the parts are listed joined by plus signs. A tag is on a sheet when its insertion point falls inside one of the sheet's viewport windows.
Number types
64-bit numbers parsed from attribute text.
Limits
The total is written with String() and no rounding, so tag quantities with decimal fractions can show a binary rounding tail (0.1 + 0.2 gives 0.30000000000000004).
Approach: 64-bit, direct
Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.