Resources Numerical accuracy Calculation policy

Form cage to exact solid: sewing and volume

The tolerances and the volume used when a Form cage is converted to exact B-rep geometry.

How the precision is kept

Each bicubic patch becomes a B-spline surface with the patch's 64-bit control points, and the faces are sewn within a tolerance scaled to the model size. The reported volume comes from OpenCascade's volume properties of the solid.

Calculations under this policy

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

form-brep.js PartCraft 0.8.1 64-bit 2 calculations Reviewed

Tests None found by the review

Sewing tolerance from model size

64-bit

The tolerance with which patch edges are joined.

tol = max(1e-7, 1e-7 × max |coordinate|)

Scaled to the largest absolute coordinate of the cage, with a floor of 1e-7. The face tolerance 1e-9 is absolute.

  • form-brep.js
  • lines 73 to 75
  • PartCraft 0.8.1
let size = 0;
for (const p of form.verts) size = Math.max(size, Math.abs(p[0]), Math.abs(p[1]), Math.abs(p[2]));
const sewTol = tol || Math.max(1e-7, 1e-7 * size);

Sewn solid and its volume

64-bit

Sews the faces, makes a solid, and measures its volume.

A closed shell becomes a solid, and a negative mass from OpenCascade flips its orientation. The volume in the report is OpenCascade's own double result.

  • form-brep.js
  • lines 35 to 60
  • PartCraft 0.8.1
/**
 * Sew faces into one shape: { shape, closed, free, shells, sew (for Modified) }. `closed`: no free edges → a solid (outward,
 * valid) is returned; otherwise the sewn shell(s).
 */
export function sewFaces(oc, T, faces, tol) {
  const sew = T(new oc.BRepBuilderAPI_Sewing(tol, true, true, true, false));
  for (const f of faces) sew.Add(f);
  sew.Perform(T(new oc.Message_ProgressRange()));
  const sewn = T(sew.SewedShape());
  const free = sew.NbFreeEdges();
  const shells = [];
  const ex = T(new oc.TopExp_Explorer(sewn, oc.TopAbs_ShapeEnum.TopAbs_SHELL, oc.TopAbs_ShapeEnum.TopAbs_SHAPE));
  for (; ex.More(); ex.Next()) shells.push(T(oc.TopoDS.Shell(T(ex.Current()))));
  if (free === 0 && shells.length === 1) {
    const ms = T(new oc.BRepBuilderAPI_MakeSolid(shells[0]));
    if (!ms.IsDone()) fail(t('form.brep.no_solid'));
    const solid = T(ms.Solid());
    oc.BRepLib.OrientClosedSolid(solid);
    const gp = T(new oc.GProp_GProps());
    oc.BRepGProp.VolumeProperties(solid, gp, false, false, false);
    let s = solid;
    if (gp.Mass() < 0) s = T(solid.Reversed());
    return { shape: s, closed: true, free, shells: 1, sew };
  }
  return { shape: sewn, closed: false, free, shells: shells.length, sew };
}

In detail

Method
Sewing tolerance = max(1e-7, 1e-7 × largest coordinate); volume by BRepGProp.VolumeProperties.
Number types
64-bit control points passed to gp_Pnt.
Tolerances
Sewing tolerance 1e-7 of the model size (at least 1e-7); face tolerance 1e-9 (absolute).
Limits
Patches at extraordinary points are a stated approximation of the limit surface (see the file header and the report's approx count).

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