Writes the shape, areas, perimeter and volume of rooms, floor slabs and ceilings found from the drawn walls.
How the precision is kept
Areas and perimeters are computed in 64-bit square millimeters and millimeters from the room or building loop, then stored through the writer's rounding (6 decimals of the file unit for lengths, 1e-6 m² and 1e-6 m³ for areas and volumes). A shape is rewritten only when a short hash of its inputs, rounded to 0.01 mm, changes.
Open item. Use atan(6 ÷ 12) in degrees at full precision as the default roof pitch instead of 26.565.
Calculations under this policy
6 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.
Height, perimeters, floor areas and volume of a room.
h = elevation above − elevation; gross area = |shoelace(outline)|; volume = net area × h
The net area and net perimeter come from the loop found by model-rooms.js; the gross area and gross perimeter are computed here from the loop's outer outline. Volume is one product of net area and height. The seed point is stored rounded to 6 decimals of the file unit.
Thickness, perimeter, areas and volume of a floor slab.
net area = |A(outline)| − Σ |A(hole)|; volume = net area × thickness; solid from offset − thickness, depth = thickness
Hole areas are subtracted from the outline area in 64-bit mm². The perimeter is the outer outline only. Nothing is written when the change key matches the stored one.
Same area arithmetic as the floor slab. The solid starts at the ceiling height and is as deep as its thickness. Nothing is written when the change key matches the stored one.
A short key of what a shape was made from, used to decide whether to write it again.
numbers rounded to 0.01 mm → text → 32-bit FNV-1a hash + text length
Every number is rounded with Math.round(v × 100) ÷ 100 before the text is hashed with Math.imul in 32 bits. The key only decides whether shape and quantities are rewritten; it is not a stored measurement. Inputs that differ by less than the rounding step, or that collide in the 32-bit hash, give the same key.
model-slabs.js
lines 117 to 123
BimCraft 0.8.1
/** A short hash of what a shape is made from (rounded to 0.01 mm). */
function shapeKey(...parts) {
const s = JSON.stringify(parts, (k, v) => (typeof v === 'number' ? Math.round(v * 100) / 100 : v));
let h = 2166136261;
for (let i = 0; i < s.length; i++) { h ^= s.charCodeAt(i); h = Math.imul(h, 16777619); }
return (h >>> 0).toString(36) + s.length.toString(36);
}
Height a roof sits at
64-bit
The top of the tallest wall under a roof.
top = max(base offset + height) over the walls, else the level's height
A maximum of 64-bit sums starting from 0, so walls whose tops are all at or below 0 fall back to the level's height.
The overhang and thickness are exact products of 25.4. The pitch is the literal 26.565; atan(6 ÷ 12) is 26.56505…°, so the default is about 0.00005° short of a 6 in 12 slope. PitchDegrees is stored without rounding.
Shoelace area of the loop minus the areas of its holes; volume = net area × height or thickness; room height = elevation of the level above − elevation of the level, else the level's own height.
Number types
64-bit numbers; the change key is a 32-bit hash. Default sizes in inches are multiplied by 25.4, which is exact.
Tolerances
Change detection rounds every input number to 0.01 mm before hashing.
Limits
A change smaller than the 0.01 mm rounding step may leave the stored shape and quantities unchanged. Two different shapes that hash to the same 32-bit key would be treated as unchanged. The default roof pitch is the literal 26.565°, while atan(6 ÷ 12) is 26.56505…°.
Approach: 64-bit, stated limit
The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.