Keeps a length tag on an element as an IFC property and lists tag values in schedules, in millimeters.
How the precision is kept
A length tag is read from the file in the file's length unit and shown in millimeters. Each conversion is one 64-bit multiplication followed by rounding to six decimals: six decimals of a millimeter when read, six decimals of the written value when stored. Schedules group rows by the rounded value.
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.
tags.jsBimCraft 0.8.164-bit3 calculationsReviewed
Tests tools/bimcraft-test/tags-test.mjs
Tag values of an element
64-bit
An element's tags as their kinds keep them, lengths in millimeters.
length in mm = round(value × unitMm × 1e6) ÷ 1e6
One multiplication by the unit factor, then rounding to six decimals of a millimeter. Yes-or-no tags become 1 or 0.
tags.js
lines 146 to 159
BimCraft 0.8.1
/** An element's tag values as their kinds keep them (length in mm); tags with no value are left out. */
export function tagValues(w, id, defs) {
const ps = w.readPset(id, TAGS_PSET);
if (!ps) return {};
const out = {};
for (const d of defs) {
if (!(d.name in ps)) continue;
let v = ps[d.name];
if (d.kind === 'yesno') v = asBool(v) ? 1 : 0;
else if (d.kind === 'length' && typeof v === 'number') v = Math.round(v * w.unitMm * 1e6) / 1e6;
if (v !== null && v !== undefined && v !== '') out[d.name] = v;
}
return out;
}
Tag value written to the file
64-bit
A tag as the IFC property that holds it.
stored length = round(u(value) × 1e6) ÷ 1e6
A length goes through the model writer's u() and is rounded to six decimals before it is written. Other kinds are written as given.
The rows of a tag schedule and the groups they fall in.
length column = round(value × unitMm × 1e6) ÷ 1e6
Length columns and a length group value are multiplied by the unit factor and rounded to six decimals. The group key is the JSON text of that rounded value.
tags.js
lines 324 to 332
BimCraft 0.8.1
const kinds = columns.map((c) => fieldKind(ix, defs, c));
const rr = elementRows(ix, { keys: pick ? [...pick] : null, columns });
for (const r of rr.rows) r.values = r.values.map((v, i) => (kinds[i] === 'length' && typeof v === 'number' ? Math.round(v * unitMm * 1e6) / 1e6 : v));
const groups = new Map();
for (const r of rr.rows) {
let g = groupBy ? ix.value(groupBy, r.key - ix.keyBase) : null;
if (groupBy && (g === undefined || g === null)) g = '';
if (groupBy && fieldKind(ix, defs, groupBy) === 'length' && typeof g === 'number') g = Math.round(g * unitMm * 1e6) / 1e6;
const k = JSON.stringify(g);
In detail
Method
Read: value × mm per file unit, then Math.round(v × 1e6) ÷ 1e6. Write: the model writer's u(value), rounded the same way.
Number types
64-bit numbers.
Limits
Rows are grouped by the text of the rounded value, so lengths that round to the same six decimals fall in one group.
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.