Skip to main content

Asking a shape about itself

The functions in bitbybit.occt.shapes.shape work on a shape of any kind, a vertex, a wire or a whole compound alike. Most of them ask a question; two clean a shape up.

Merging seams​

A boolean leaves the faces of its inputs as they were cut, so two boxes fused into one keep a seam wherever their faces now lie on one plane. unifySameDomain merges faces that lie on the same surface into one face, and edges that continue each other on one curve into one edge. booleans.union does it for you unless keepEdges is true; after a difference, a fillet or an import with many small faces, calling it yourself gives a clean shape whose faces are easier to select and to fillet.

Here two crossing boxes are fused with their edges kept, so seams run across the top. Beside them is the same union after unifySameDomain, with one face per flat side:

Bitbybit Platform

A union's seams merged away in Rete

rete logoRete
Script Source (rete)
{
"id": "rete-v2-json",
"nodes": {
"long": {
"id": "long",
"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": 2,
"height": 2,
"center": [
0,
1,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
40,
40
]
},
"wide": {
"id": "wide",
"name": "bitbybit.occt.shapes.solid.createBox",
"customName": "box",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"width": 2,
"length": 4,
"height": 2,
"center": [
1,
1,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
40,
520
]
},
"boxes": {
"id": "boxes",
"name": "bitbybit.lists.createList",
"customName": "create list",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "long",
"output": "result",
"data": {}
},
{
"node": "wide",
"output": "result",
"data": {}
}
]
}
},
"position": [
460,
40
]
},
"union": {
"id": "union",
"name": "bitbybit.occt.booleans.union",
"customName": "union",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"keepEdges": true,
"strategy": "oneAfterAnother"
},
"inputs": {
"shapes": {
"connections": [
{
"node": "boxes",
"output": "list",
"data": {}
}
]
}
},
"position": [
880,
40
]
},
"unified": {
"id": "unified",
"name": "bitbybit.occt.shapes.shape.unifySameDomain",
"customName": "unify same domain",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"unifyEdges": true,
"unifyFaces": true,
"concatBSplines": true
},
"inputs": {
"shape": {
"connections": [
{
"node": "union",
"output": "result",
"data": {}
}
]
}
},
"position": [
1300,
40
]
},
"beside": {
"id": "beside",
"name": "bitbybit.occt.transforms.translate",
"customName": "translate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
7,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "unified",
"output": "result",
"data": {}
}
]
}
},
"position": [
1720,
40
]
}
},
"modules": {}
}

unifyFaces and unifyEdges choose what is merged, and concatBSplines joins neighboring B-spline edges into one where it can.

Removing edges left inside a face​

A split, or a general fuse, cuts a face only where a cutting edge crosses it. Where the edge lies inside the face and reaches none of its sides, the face keeps that piece of edge as an internal edge: it is drawn and selectable, but bounds nothing. purgeInternalEdges removes such edges and rebuilds the faces around them. An edge that bounds any face of the shape stays, and a shape with nothing to remove comes back as it was.

Here a box is split by a short segment lying on its top, which leaves the segment as an edge inside the top face. Beside it is the same box after purgeInternalEdges:

Bitbybit Platform

A split's leftover edge purged 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": 2,
"center": [
0,
1,
0
],
"originOnCenter": true
},
"inputs": {},
"position": [
40,
40
]
},
"segment": {
"id": "segment",
"name": "bitbybit.occt.shapes.edge.line",
"customName": "line",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"start": [
-1,
2,
0
],
"end": [
1,
2,
0
]
},
"inputs": {},
"position": [
40,
520
]
},
"cutters": {
"id": "cutters",
"name": "bitbybit.lists.createList",
"customName": "create list",
"async": false,
"drawable": false,
"data": {},
"inputs": {
"listElements": {
"connections": [
{
"node": "segment",
"output": "result",
"data": {}
}
]
}
},
"position": [
460,
520
]
},
"pieces": {
"id": "pieces",
"name": "bitbybit.occt.operations.splitShapeWithShapes",
"customName": "split shape with shapes",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"localFuzzyTolerance": 0.0001,
"nonDestructive": false
},
"inputs": {
"shape": {
"connections": [
{
"node": "box",
"output": "result",
"data": {}
}
]
},
"shapes": {
"connections": [
{
"node": "cutters",
"output": "list",
"data": {}
}
]
}
},
"position": [
880,
40
]
},
"split": {
"id": "split",
"name": "bitbybit.lists.getItem",
"customName": "get item",
"async": false,
"drawable": false,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"index": 0,
"clone": true
},
"inputs": {
"list": {
"connections": [
{
"node": "pieces",
"output": "result",
"data": {}
}
]
}
},
"position": [
1300,
40
]
},
"purged": {
"id": "purged",
"name": "bitbybit.occt.shapes.shape.purgeInternalEdges",
"customName": "purge internal edges",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": true,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
}
},
"inputs": {
"shape": {
"connections": [
{
"node": "split",
"output": "result",
"data": {}
}
]
}
},
"position": [
1720,
40
]
},
"beside": {
"id": "beside",
"name": "bitbybit.occt.transforms.translate",
"customName": "translate",
"async": true,
"drawable": true,
"data": {
"genericNodeData": {
"hide": false,
"oneOnOne": false,
"flatten": 0,
"forceExecution": false
},
"translation": [
6,
0,
0
]
},
"inputs": {
"shape": {
"connections": [
{
"node": "purged",
"output": "result",
"data": {}
}
]
}
},
"position": [
2140,
40
]
}
},
"modules": {}
}

unifySameDomain does not remove these edges: it merges faces and edges, while an internal edge has no neighbour to merge with.

Questions a shape answers​

  • What it is: getShapeType says vertex, edge, wire, face, shell, solid or compound; isNull says the handle holds nothing, which a failed operation can return.
  • Which way it faces: getOrientation reads forward, reversed, internal or external. For a face it decides which side its normal points to.
  • Whether two handles are one shape: isSame is true when both share geometry and placement, whatever their orientation; isEqual also needs the same orientation; isPartner only needs the same geometry, however placed. A face you got back from getFaces is the same as the one you selected earlier when isSame says so.
  • Flags the kernel keeps: isClosed, isConvex, isInfinite, isFree, isLocked, isModified and isChecked read flags OCCT stores on a shape. They are set by the operation that made it and are not checks of their own: to know whether a shape is valid, use shapeFix.isValid (see Checking a shape).

Every function​

FunctionWhat it does
getOrientationReads which way the shape is oriented: forward, reversed, internal or external, which for a face decides which side its normal points to.
getShapeTypeReads what kind of shape this is: vertex, edge, wire, face, shell, solid, compound or another kernel type.
isCheckedTells whether the kernel has already run its validity check on the shape.
isClosedTells whether the kernel has the shape flagged as closed, such as a wire that loops back to its start or a shell with no gaps.
isConvexTells whether the kernel has the shape flagged as convex.
isEqualTells whether two handles point at the same geometry with the same placement and orientation.
isFreeTells whether the kernel has the shape flagged as free, that is, not held inside another shape.
isInfiniteTells whether the kernel has the shape flagged as infinite, such as an unbounded plane or line.
isLockedTells whether the kernel has the shape flagged as locked against changes.
isModifiedTells whether the kernel has the shape flagged as modified since it was last checked.
isNotEqualTells whether two handles differ in geometry, placement or orientation.
isNullTells whether the shape is empty: a handle that holds no geometry, which an operation that failed can return.
isPartnerTells whether two handles share the same underlying geometry, even if placed or oriented differently.
isSameTells whether two handles share the same geometry and placement, ignoring orientation.
purgeInternalEdgesRemoves the edges that lie inside a face without bounding it, such as the segment a split leaves on a face, and rebuilds the faces around them.
unifySameDomainMerges faces that lie on the same surface and edges that lie on the same curve into single faces and edges, which cleans up the seams a boolean or a fuse leaves behind.