Resources Numerical accuracy Calculation policy

Assistant answers: what is above an element

Lists the elements whose bounding box starts within a distance above an element's top and overlaps its footprint, nearest first, with the gap in meters.

How the precision is kept

The boxes are taken from the 3D viewer's batches, whose positions are a Float32Array (ifc-model.js finishBatch), so every box coordinate and the gap computed from it come from 32-bit values. The comparison uses a fixed 0.02 m tolerance and the gap is rounded to 0.01 m. The answer itself says it is a survey from bounding boxes.

Open item. Take the boxes from the IFC engine's 64-bit mesh positions instead of the viewer's 32-bit batches.

Calculations under this policy

1 calculation 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.

ask-tools.js BimCraft 0.8.1 32-bit in part 1 calculation Reviewed

Tests tools/bimcraft-test/ask-test.mjs

Elements above, and the gap to each

32-bit in part

What sits over an element's footprint and how far above its top each one starts.

gap = max(0, lowest Y of the other element − top Y of this element)

The box corners come from the viewer's 32-bit positions (viewer3d.js keyBoundsMap reads ifc-vis.js boundsMapOf). The gap is rounded to two decimals of a meter in the answer. A 32-bit number in meters is spaced less than 0.0001 m apart below 1024 m, which is under that rounding.

  • ask-tools.js
  • lines 196 to 211
  • BimCraft 0.8.1
const reach = a.within_m ?? 3, tol = 0.02, top = tb.max[1];
const hit = [];
for (const [k, b] of app.bounds(ix.keys.filter((x) => x !== key))) {
  if (b.min[1] < top - tol || b.min[1] > top + reach) continue;
  if (b.max[0] < tb.min[0] || b.min[0] > tb.max[0] || b.max[2] < tb.min[2] || b.min[2] > tb.max[2]) continue;
  if (a.class && String(ix.value('cls', k - ix.keyBase)).toLowerCase() !== a.class.toLowerCase()) continue;
  hit.push({ key: k, gap: Math.max(0, b.min[1] - top) });
}
hit.sort((x, y) => x.gap - y.gap);
const pg = page(hit, a), shown = show(a, hit.map((h) => h.key));
const byClass = {};
for (const h of hit) { const cl = String(ix.value('cls', h.key - ix.keyBase) ?? '?'); byClass[cl] = (byClass[cl] || 0) + 1; }
return {
  model: app.name(), of: describe(ix, key), lookedAbove_m: reach, how: 'elements whose 3D bounding box starts within ' + reach + ' m above the top of the element and overlaps its footprint',
  total: hit.length, returned: pg.returned, next: pg.next, selected: shown, byClass, notes: ['A survey from bounding boxes: an element may be in the box without touching the footprint. Use a clash check for a decision.'],
  elements: pg.rows.map((h) => ({ ...describe(ix, h.key), gap_m: r2(h.gap) })),

In detail

Method
Axis-aligned bounding boxes in viewer space (meters, Y up): an element is listed when its lowest point is between top − 0.02 m and top + reach and its box overlaps the footprint box in X and Z.
Number types
Box corners are minima and maxima of Float32Array positions, moved by the model's placement matrix in 64-bit; the gap is a 64-bit difference of those.
Tolerances
0.02 m below the top (absolute); the reach above it is 3 m unless given.
Limits
A bounding box can overlap the footprint where the element itself does not; the tool's own note says to use a clash check for a decision.

Approach: 32-bit step, flagged

One step stores or exchanges 32-bit values that reach a number a person reads. It is listed here with its open item, and the step is either moved to 64-bit or the app will warn where the number is read.

Every policy that takes this approach