Resources Numerical accuracy Calculation policy

Entity info: volume, size, angle and area

Shows the volume and size of a selected group, component or mesh as it is placed, an arc's angle, the total area of selected faces, and the print check's size and volume.

How the precision is kept

The definition's own volume and box come from the model kernel in 64-bit and are scaled by the placement matrix: the volume by the absolute 3×3 determinant, each size by the length of the matching matrix column. Lengths, areas and volumes are formatted by the units module; a few values are rounded for the panel text only.

Calculations under this policy

5 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.

modelcraft.js ModelCraft 0.8.1 64-bit 5 calculations Reviewed

Tests None found by the review

Volume and size of a placed solid

64-bit

The volume of a closed group or component and its width, depth and height as placed.

k = ∛|det M₃ₓ₃|; volume = V × k × k × k; size_q = (max_q − min_q) × |column q|; retyped size → L ÷ |column q|

The full 3×3 determinant is used. Taking its cube root and cubing it again returns |det| only to within rounding, a step that multiplying by |det| directly would not add. A retyped size is divided by the column length to give the definition's own size.

  • modelcraft.js
  • lines 2545 to 2555
  • ModelCraft 0.8.1
  const k = Math.cbrt(Math.abs(inst.m[0] * (inst.m[5] * inst.m[10] - inst.m[9] * inst.m[6]) - inst.m[4] * (inst.m[1] * inst.m[10] - inst.m[9] * inst.m[2]) + inst.m[8] * (inst.m[1] * inst.m[6] - inst.m[5] * inst.m[2])));
  row(t('app.info.volume'), formatVolume(s.volume * k * k * k, u));
}
const bb = model.bbox(d);
// the size as placed: the definition's own size times this placement's scale along each of its axes
const sc = [0, 1, 2].map((q) => Math.hypot(inst.m[q * 4], inst.m[q * 4 + 1], inst.m[q * 4 + 2]));
if (bb) [t('app.info.width'), t('app.info.depth'), t('app.info.height')].forEach((lb, q) => {
  const own = bb.max[q] - bb.min[q], placed = own * sc[q];
  if (isStacked(d)) row(lb, formatLength(placed, u));   // 0.8 GH.2: the stack decides the size (change a factor)
  else if (placed > 1e-6) lenBox(lb, 'mc-size' + q, placed, (L) => model.change(t(d.kind === 'component' ? 'app.undo.resize_component' : 'app.undo.resize_group'), (m) => m.setDefSize(d.id, q, L / sc[q]), [d.id]));
  else row(lb, formatLength(0, u));

Volume and size of a placed mesh

64-bit

The volume of a closed mesh and its size as placed.

k = ∛|det M₃ₓ₃|; volume = V × k³; size_q = (max_q − min_q) × |column q|

The same scaling as for a solid: the mesh's own volume and bounds, times the cube of the cube root of the determinant and times each column's length.

  • modelcraft.js
  • lines 1687 to 1691
  • ModelCraft 0.8.1
const m = inst.m, k = Math.cbrt(Math.abs(m[0] * (m[5] * m[10] - m[9] * m[6]) - m[4] * (m[1] * m[10] - m[9] * m[2]) + m[8] * (m[1] * m[6] - m[5] * m[2])));
if (I.closed) row(t('app.info.volume'), formatVolume(I.volume * k * k * k, u));
const bb = src.bounds();
const sc = [0, 1, 2].map((q) => Math.hypot(m[q * 4], m[q * 4 + 1], m[q * 4 + 2]));
if (bb) [t('app.info.width'), t('app.info.depth'), t('app.info.height')].forEach((lb, q) => row(lb, formatLength((bb.max[q] - bb.min[q]) * sc[q], u)));

Arc angle

64-bit

The angle an arc sweeps, in degrees.

shown = round(sweep × 180 ÷ π × 100) ÷ 100

Converted with the 64-bit π and rounded to two decimals for the panel text. The stored arc is not changed.

  • modelcraft.js
  • line 2506
  • ModelCraft 0.8.1
if (ci.kind === 'arc' && ci.round) row(t('app.info.angle'), (Math.round((ci.sweep * 180) / Math.PI * 100) / 100) + '°');

Total area of selected faces

64-bit

The sum of the areas of the selected faces.

total = Σ face area

The areas are added in selection order in 64-bit and formatted once at the end.

  • modelcraft.js
  • line 2644
  • ModelCraft 0.8.1
if (nF) { let a = 0; for (const s of sel) if (s.t === 'f') { const f = def.faces.get(s.id); if (f) a += faceArea(def, f); } row(t('app.info.total_area'), formatArea(a, u)); }

Print check size and volume

64-bit

The size in millimeters and the volume in cubic centimeters shown after a print check.

shown size = round(mm × 10) ÷ 10; shown volume = round(mm³ ÷ 1000 × 10) ÷ 10 cm³

Both are rounded to one decimal for the text. The division by 1000 from mm³ to cm³ is exact as a conversion factor.

  • modelcraft.js
  • lines 3022 to 3026
  • ModelCraft 0.8.1
const mm = (v) => (Math.round(v * 10) / 10).toLocaleString(i18n.locale() === 'en-XA' ? 'en' : i18n.locale());
const facts = el('ul', { className: 'mc-print-facts' },
  el('li', {}, t(what === 'selection' ? 'app.print3d.what.sel' : 'app.print3d.what.all')),
  rep.size ? el('li', {}, t('app.print3d.size', { w: mm(rep.size[0]), d: mm(rep.size[1]), h: mm(rep.size[2]) })) : null,
  rep.volume != null ? el('li', {}, t('app.print3d.volume', { v: mm(rep.volume / 1000) })) : null,

In detail

Method
k = ∛|det M|, volume × k³; size along the definition's own axis q × length of column q.
Number types
64-bit numbers.
Tolerances
A placed size of 1e-6 or less is shown as zero and cannot be retyped.
Limits
Sizes are along the definition's own axes, not the model's, for a placement that is turned.

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.

Every policy that takes this approach