Resources Numerical accuracy Calculation policy

STEP import: welding and meters

Turns each solid read from a STEP file into one welded mesh in meters.

How the precision is kept

cc-step delivers triangles in millimeters. Corners are merged on a grid tied to the tessellation tolerance and the kept corner is multiplied by 0.001 into a Float64Array. The grid only decides which corners are one; no coordinate is snapped to it.

Open item. Divide by 1000 instead of multiplying by 0.001, so the conversion to meters is correctly rounded.

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.

io/step-import.js ModelCraft 0.8.1 64-bit 1 calculation Reviewed

Tests tools/step-test/test.mjs

Welded corners in meters

64-bit

Merges corners that coincide and converts them from millimeters to meters.

key = round(x ÷ q), round(y ÷ q), round(z ÷ q); p (m) = p (mm) × 0.001

The constant MM = 0.001 has no exact binary value, so each product can differ from the correctly rounded p ÷ 1000 by one unit in the last place. The kept corner is the first one seen in its cell, with its own coordinates.

  • io/step-import.js
  • lines 26 to 37
  • ModelCraft 0.8.1
const q = Math.max(read.tol * 0.05, 1e-9);   // corners closer than this are one (a face's edge points meet its neighbour's)
const I = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
read.solids.forEach((s, si) => {
  const keyOf = new Map(), pts = [];
  const P = s.positions, nV = P.length / 3;
  const map = new Int32Array(nV);
  for (let v = 0; v < nV; v++) {
    const k = Math.round(P[v * 3] / q) + ',' + Math.round(P[v * 3 + 1] / q) + ',' + Math.round(P[v * 3 + 2] / q);
    let w = keyOf.get(k);
    if (w === undefined) { w = pts.length / 3; keyOf.set(k, w); pts.push(P[v * 3] * MM, P[v * 3 + 1] * MM, P[v * 3 + 2] * MM); }
    map[v] = w;
  }

In detail

Method
Weld key = round(coordinate ÷ q) per axis with q = max(0.05 × tessellation tolerance, 1e-9) mm; the first corner in a cell is kept. Triangles with two equal corners after welding are dropped and counted.
Number types
64-bit numbers; Float64Array for positions; Int32Array for indices.
Tolerances
q = max(0.05 × read.tol, 1e-9), in millimeters.
Limits
Two corners closer than q on either side of a cell boundary are not merged.

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