Resources Numerical accuracy Calculation policy

Cabinet material sizes, grooves and drill files

Holds the thicknesses of the sheet materials and edge bands, derives the groove and sheet size from the picks, and writes the drill and G-code files.

How the precision is kept

The inch thicknesses are separate typed table entries, not converted from the millimeter ones, so the table sets the accuracy. The derived values are 64-bit; two outputs round on purpose: band thicknesses to 4 decimals and hole positions in the XML to 0.001.

Calculations under this policy

5 calculations in 2 source files. 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.

addons/cabinetcraft/lib/materials.js CadCraft 0.8.2 64-bit 3 calculations Reviewed

Tests None found by the review

Material and band thicknesses

Exact

The thickness of each library sheet and edge band in millimeters and in inches.

Each entry carries its own mm and inch number as typed; the inch figure is not computed from the mm figure (for example 15 mm is 0.5906 in and 18 mm is 0.75 in). A job in inches uses the inch column.

  • addons/cabinetcraft/lib/materials.js
  • lines 30 to 37
  • CadCraft 0.8.2
export const MATERIALS = [
  M('melamine-18', 'carcass', 18, 0.75), M('melamine-16', 'carcass', 16, 0.625), M('ply-18', 'carcass', 18, 0.75), M('ply-15', 'carcass', 15, 0.5906),
  M('hdf-8', 'back', 8, 0.3125, 'none'), M('hdf-3', 'back', 3, 0.125, 'none'), M('ply-6', 'back', 6, 0.25, 'none'),
  M('mdf-painted-18', 'fronts', 18, 0.75), M('laminate-19', 'fronts', 19, 0.75), M('veneer-ply-18', 'fronts', 18, 0.75), M('melamine-front-18', 'fronts', 18, 0.75),
  M('hardwood-19', 'frame', 19, 0.75), M('hardwood-25', 'frame', 25, 1),
  M('drawer-ply-15', 'drawer', 15, 0.5906), M('drawer-melamine-16', 'drawer', 16, 0.625),
  M('drawer-bottom-hdf-6', 'drawer-bottom', 6, 0.25, 'none'), M('drawer-bottom-ply-9', 'drawer-bottom', 9, 0.375, 'none'),
];

Rules from the material picks

64-bit

The thicknesses, groove and band thicknesses that the construction rules use.

groove = min(tback, 0.6 × tcarcass)

Groove depth is min(back thickness, 0.6 × carcass thickness) in 64-bit; band thickness is rounded with Math.round(x × 1e4) ÷ 1e4. A custom material is read in the job unit without conversion.

  • addons/cabinetcraft/lib/materials.js
  • lines 81 to 99
  • CadCraft 0.8.2
/** `say(key)` writes a library word key in the person's language (identity in the tests); a custom name is kept as typed. */
export function rulesFromPicks(unit, picks, { say = (k) => k, custom = [], over = {} } = {}) {
  const P = cleanPicks(picks, custom);
  const inch = unit === 'in';
  const th = (m) => thicknessIn(m, unit);
  const nm = (m) => writtenName(m, say, unit);
  const car = find(P.carcass, custom), back = find(P.back, custom), fr = find(P.fronts, custom), dr = find(P.drawer, custom), db = find(P.drawerBottom, custom);
  const band = (id) => { const b = find(id, custom); return { code: nm(b), thickness: Math.round(th(b) * 1e4) / 1e4 }; };
  const r = {
    t: th(car), carcass: nm(car),
    backT: th(back), groove: Math.min(th(back), th(car) * 0.6), backMat: nm(back),
    frontT: th(fr), frontMat: nm(fr),
    drawerT: th(dr), drawerMat: nm(dr),
    drawerBottomT: th(db), drawerBottomMat: nm(db),
    bandCarcass: band(P.bandCarcass), bandFront: band(P.bandFront), bandDrawer: band(P.bandDrawer),
  };
  // the groove follows the back unless the shop typed one; the shop's own numbers (over) win over everything above
  return rulesFor(unit, { ...r, ...over });
}

Sheet size for a material

64-bit

The sheet width and height a material is cut from.

in = round(mm ÷ 25.4 × 4) ÷ 4

For inch jobs the stock size in millimeters is divided by 25.4 (exact) and rounded to the nearest quarter inch with Math.round(x × 4) ÷ 4, so 2440 mm becomes 96 in. A sheet typed by the person is used as typed.

  • addons/cabinetcraft/lib/materials.js
  • lines 107 to 121
  • CadCraft 0.8.2
/** The sheet a material is cut from: by the written name and thickness, else the default sheet of the job. */
export function sheetFor(name, thickness, { picks = DEFAULT_PICKS, custom = [], say = (k) => k, unit = 'mm', fallback = { w: 2440, h: 1220 } } = {}) {
  const P = cleanPicks(picks, custom);
  const k = unit === 'in' ? 25.4 : 1;
  for (const id of [P.carcass, P.back, P.fronts, P.drawer, P.drawerBottom]) {
    const m = find(id, custom);
    if (!m) continue;
    if (writtenName(m, say, unit) === name) {
      if (m.sheet && typeof m.sheet === 'object') return { w: m.sheet.w, h: m.sheet.h };   // typed in the job's unit
      const s = SHEETS[m.sheet];
      if (s) return { w: Math.round((s.w / k) * 4) / 4, h: Math.round((s.h / k) * 4) / 4 };
    }
  }
  return { w: fallback.w, h: fallback.h };
}
addons/cabinetcraft/lib/export.js CadCraft 0.8.2 64-bit 2 calculations Reviewed

Tests None found by the review

Hole positions in the drill XML

64-bit

The x and y of each hole as written in the drill file.

x = round(x × 1000) ÷ 1000

Rounded to three decimals with Math.round(x × 1000) ÷ 1000 in the file unit; diameter and depth are written as given.

  • addons/cabinetcraft/lib/export.js
  • line 53
  • CadCraft 0.8.2
for (const h of pl.holes) { holes++; out.push('    <hole kind="' + xe(h.kind) + '" x="' + xe(Math.round(h.x * 1000) / 1000) + '" y="' + xe(Math.round(h.y * 1000) / 1000) + '" diameter="' + xe(h.d) + '" depth="' + xe(h.depth) + '" side="' + xe(h.side || 'both') + '"' + (h.face && h.face !== pl.face ? ' face="' + xe(h.face) + '"' : '') + (h.edge ? ' edge="' + xe(h.edge) + '"' : '') + '/>'); }

G-code scale and thickness

64-bit

The unit scale and cut depth passed to the sheet G-code writer.

thickness_mm = thickness × scale

The scale is 25.4 for inch jobs and 1 otherwise, and the cut depth is the material thickness times that scale; one multiplication in 64-bit.

  • addons/cabinetcraft/lib/export.js
  • lines 89 to 103
  • CadCraft 0.8.2
export function gcodeFiles(job, sheetsGcode, { unit = 'mm', name = 'Job', ...opts } = {}) {
  const out = [];
  const scale = unit === 'in' ? 25.4 : 1;
  job.mats.forEach((m, i) => {
    if (!m.result.placed.length) return;
    const sub = { ...job, mats: [{ ...m, sheetBase: 0 }], seq: job.seq };
    const dxf = nestDxf(sub, { units: unit });
    const thickness = m.thickness * scale;
    const slug = (name + ' ' + m.material).replace(/[^A-Za-z0-9._-]+/g, '_').slice(0, 60);
    const files = sheetsGcode(dxf, { ...opts, scale, thickness, name: slug });
    for (const f of files.files || files) out.push({ ...f, material: m.material, thickness: m.thickness, group: i, notes: [...(f.notes || [])] });
    if (files.notes && files.notes.length) out.push({ notesOnly: true, material: m.material, notes: files.notes });
  });
  return out;
}

In detail

Method
groove = min(back thickness, 0.6 × carcass thickness); sheet size in inches = round(mm ÷ 25.4 × 4) ÷ 4; G-code thickness = thickness × 25.4 for inch jobs.
Number types
64-bit numbers.
Tolerances
None; rounding steps are 1e-4 (band thickness), 0.25 in (sheet size) and 0.001 (XML hole x, y in the file unit).
Limits
The drill CSV writes h.x and h.y unrounded while the drill XML rounds them to 0.001, so the two files can differ in the last digits. Inch values in the table: 15 mm is listed as 0.5906 in (15 ÷ 25.4 = 0.590551), 18 mm as 0.75 in (18 ÷ 25.4 = 0.7087), band 1 mm as 0.04 in (0.03937), 2 mm as 0.08 in, 0.4 mm as 0.016 in and 0.5 mm as 0.02 in.

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.

Every policy that takes this approach