Skip to main content

Checking a shape

Most mistakes in modelling announce themselves: a function stops with an error, and the errors page explains how to read it. A few do not. An operation can finish and return a shape that is not the one you meant:

  • A cut that misses leaves the shape as it was, with no error.
  • A fillet too large for the faces beside an edge can return a solid that is not valid.
  • A face made from several wires keeps a hole only when the hole's wire runs against the outline.
  • Extruding a wire gives a shell, not a solid.

So it pays to check a result, especially one the rest of a model builds on.

Ask the kernel​

The kernel answers questions about a shape with numbers and yes or no, rather than new shapes:

QuestionFunction
How much material is there?bitbybit.occt.shapes.solid.getSolidVolume, getSolidSurfaceArea
Is it a valid shape?bitbybit.occt.shapeFix.isValid
How big is it, and where?bitbybit.occt.analysis.measure.tightBoundingBox
How close are two shapes, and where?bitbybit.occt.analysis.measure.extrema
Do parts collide?bitbybit.occt.analysis.clashes.betweenShapes
What is it made of?bitbybit.occt.shapes.solid.debugInfo and the get* functions of each shape type

Here a cylinder is cut through a box, and the result's volume and validity are read back. A volume smaller than the box's 64 says the cut happened:

Bitbybit Platform

Cut a hole, then check the result in Rete

rete logoRete
Script Source (rete)
{
"id": "rete-v2-json",
"nodes": {
"box": {
"id": "box",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 4,
"length": 4,
"height": 4,
"center": [
0,
0,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
40,
40
]
},
"hole": {
"id": "hole",
"name": "bitbybit.occt.shapes.solid.createCylinder",
"customName": "cylinder",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"radius": 1,
"height": 6,
"center": [
0,
-3,
0
],
"direction": [
0,
1,
0
],
"angle": 360,
"originOnCenter": false
},
"inputs": {},
"position": [
40,
460
]
},
"tools": {
"id": "tools",
"name": "bitbybit.lists.createList",
"customName": "create list",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "hole",
"output": "result",
"data": {}
}
]
}
},
"position": [
460,
460
]
},
"cut": {
"id": "cut",
"name": "bitbybit.occt.booleans.difference",
"customName": "difference",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": false,
"strategy": "oneAfterAnother"
},
"inputs": {
"shape": {
"connections": [
{
"node": "box",
"output": "result",
"data": {}
}
]
},
"shapes": {
"connections": [
{
"node": "tools",
"output": "list",
"data": {}
}
]
}
},
"position": [
460,
40
]
},
"volume": {
"id": "volume",
"name": "bitbybit.occt.shapes.solid.getSolidVolume",
"customName": "get solid volume",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "cut",
"output": "result",
"data": {}
}
]
}
},
"position": [
880,
40
]
},
"valid": {
"id": "valid",
"name": "bitbybit.occt.shapeFix.isValid",
"customName": "is valid",
"async": true,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "cut",
"output": "result",
"data": {}
}
]
}
},
"position": [
880,
300
]
}
},
"modules": {}
}

In TypeScript the answer is written to the console. In Rete, point at the output of get solid volume or is valid to read the value it gave.

Repair what came from elsewhere​

Shapes read from STEP or IGES files, or made from imported meshes, sometimes arrive with gaps or faces that do not quite meet. bitbybit.occt.shapeFix checks and repairs them:

  • validityReport says which parts of a shape are faulty and why;
  • freeBoundaries finds the edges that bound only one face, the rims of the gaps;
  • basicShapeRepair closes small gaps and fixes wire and face defects, and fixShell and fixSolid repair shells and solids;
  • sewWithReport sews loose faces together into a shell and says what it joined.

Check with isValid, repair, and check again.

Every function​

FunctionWhat it does
basicShapeRepairRuns the kernel's general repair over a shape: closes small gaps, fixes wire and face defects and brings tolerances into the given range.
fixEdgeOrientationsAlongWireRebuilds a wire so its edges run head to tail in one direction along it.
fixShellRepairs a shell: turns its faces so they all face the same way and fixes its faces and edges.
fixSmallEdgeOnWireRemoves edges shorter than precsmall from a wire and closes the gaps they leave, so a tiny sliver no longer breaks a fillet or a face.
fixSolidRepairs a solid, or makes one from a closed shell, with its shells fixed and turned so the material is inside.
freeBoundariesFinds the edges of a shape that bound only one face, joined into wires: the rims of an open shell's openings, or a lone face's outline and holes.
isValidTells whether the shape is well formed, which a successful operation does not always guarantee.
orientClosedSolidTurns a closed solid so its material is inside, which gives an inside-out solid its positive volume back; only the orientation changes.
sewWithReportSews the faces of shapes together along edges that lie within tolerance of each other, as shapes.shell.sewFaces does, and reports what it joined and what it left open.
validityReportChecks a shape as isValid does and reports each faulty sub-shape with the checks it fails, and the spread of its tolerances.