3. Geometry kernel APIs and Python bindings
Automated model preparation is only as capable as the geometry kernel underneath it. A kernel provides the mathematical and topological services that let a script create solids, heal gaps, imprint features, and query mass properties. Python rarely talks to a kernel directly; it goes through a binding layer. Understanding which kernel you are driving, and how the binding exposes it, determines what your automation can and cannot do.
Three kernels dominate industrial CAE preprocessing: OpenCASCADE Technology (OCCT), ACIS, and Parasolid. OCCT is open source and reachable from Python through pythonocc-core. ACIS and Parasolid are commercial kernels owned by Spatial (Dassault Systèmes) and Siemens respectively, and their Python access is normally indirect — through a host application's scripting API, a vendor SDK wrapper, or a C++/C# bridge. This chapter compares their access patterns and shows how to write kernel-aware preparation code.
What a Kernel Actually Exposes
Every kernel separates geometry (curves and surfaces) from topology (vertices, edges, faces, shells, solids). The topology is a boundary representation (B-rep): a solid is a closed shell of faces, each face is trimmed by edges, and each edge is bounded by vertices. Preparation operations act on this structure:
- Construction — extrude, revolve, loft, boolean union/cut/intersect.
- Healing — sew faces, fix small edges, remove slivers, unify same-domain faces.
- Defeaturing — suppress fillets, chamfers, holes, and bosses before meshing.
- Query — bounding box, volume, surface area, point classification, face normal.
- Translation — STEP, IGES, and native format read/write.
The binding's job is to map these C++ classes into Python objects with reference counting and exception translation. That mapping is where the three access patterns diverge.
OpenCASCADE via pythonocc-core
pythonocc-core is a SWIG-generated binding that mirrors OCCT's class names almost one-to-one. A face is TopoDS_Face, a solid is TopoDS_Solid, and algorithms live in packages such as BRepAlgoAPI, BRepBuilderAPI, and ShapeFix. Because the naming is faithful, OCCT documentation transfers directly to Python.
from OCC.Core.STEPControl import STEPControl_Reader
from OCC.Core.ShapeFix import ShapeFix_Shape
from OCC.Core.BRepAlgoAPI import BRepAlgoAPI_Fuse
from OCC.Core.GProp import GProp_GProps
from OCC.Core.BRepGProp import brepgprop_VolumeProperties
reader = STEPControl_Reader()
reader.ReadFile("bracket.step")
reader.TransferRoots()
shape = reader.OneShape()
fixer = ShapeFix_Shape(shape)
fixer.Perform()
healed = fixer.Shape()
props = GProp_GProps()
brepgprop_VolumeProperties(healed, props)
print("volume =", props.Mass())
Two practical notes. First, OCCT algorithms return a new shape; they do not mutate in place, so you must rebind your variable. Second, many operations report status through a boolean or an error code rather than raising, so check IsDone() after boolean and healing calls. A silent failure that returns the original shape is a common source of downstream meshing errors.
ACIS and Parasolid Access Patterns
ACIS and Parasolid are not distributed as standalone Python packages. Their Python access follows three patterns:
| Pattern | How it works | Typical use |
|---|---|---|
| Host application API | The CAD/CAE tool embeds the kernel and exposes a Python or macro API | Scripting inside the vendor tool |
| Vendor SDK wrapper | A C++ SDK is wrapped with pybind11 or SWIG by the integrator | Custom preprocessing pipelines |
| Inter-process bridge | Python calls a compiled service over a socket or COM/.NET boundary | Mixed-language enterprise stacks |
In ACIS, the core object is ENTITY, and a solid body is a BODY containing LUMP, SHELL, FACE, EDGE, and VERTEX entities. Healing is done through the api_* function family, for example api_clean_entity and api_fix_face. Parasolid uses a tagged-entity model: every object carries a PK_ENTITY_t tag, and functions are prefixed PK_, such as PK_BODY_fix and PK_FACE_find_gaps. Parasolid's session model requires you to start a session, create a partition, and roll back on failure — a pattern that must be respected in any wrapper.
Choosing an Access Path
For a pure-Python automation stack with no commercial CAD dependency, pythonocc-core is the pragmatic default: it installs from conda-forge, reads STEP and IGES, and exposes healing and defeaturing. Choose ACIS or Parasolid access when your models are native to those kernels and round-tripping through STEP would lose tolerant topology or feature history. In that case, drive the kernel through the host application's Python API rather than reimplementing a wrapper.
The diagram below contrasts the three access paths and the layer at which Python code meets each kernel.
A Reproducible Healing Example
Consider a STEP bracket that imports with two free edges along a seam. The goal is a watertight solid suitable for tetrahedral meshing. Using pythonocc-core, the workflow is: read, inspect, sew, fix, verify.
from OCC.Core.STEPControl import STEPControl_Reader
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Sewing
from OCC.Core.ShapeFix import ShapeFix_Shape, ShapeFix_Solid
from OCC.Core.TopAbs import TopAbs_SOLID
from OCC.Core.TopExp import TopExp_Explorer
reader = STEPControl_Reader()
reader.ReadFile("bracket.step")
reader.TransferRoots()
shape = reader.OneShape()
sewer = BRepBuilderAPI_Sewing(1e-4) # tolerance in model units
sewer.Add(shape)
sewer.Perform()
sewn = sewer.SewedShape()
fixer = ShapeFix_Shape(sewn)
fixer.SetPrecision(1e-4)
fixer.Perform()
fixed = fixer.Shape()
solid_fixer = ShapeFix_Solid(fixed)
solid = solid_fixer.SolidFromShell(fixed)
exp = TopExp_Explorer(solid, TopAbs_SOLID)
count = 0
while exp.More():
count += 1
exp.Next()
print("solids:", count)
Expected observable result: solids: 1 and a volume that matches the CAD reference within the sewing tolerance. If solids: 0, the shell is still open — lower the sewing tolerance or inspect free edges with BRepBuilderAPI_Sewing's NbFreeEdges(). If the volume is far off, the fixer likely merged distinct faces; reduce SetPrecision and re-run.
Practical Guidance
- Keep kernel calls in a thin adapter module so you can swap OCCT for ACIS or Parasolid without rewriting preparation logic.
- Always check operation status (
IsDone(), return codes, or exception) before consuming a result shape. - Log the shape type and solid count after every healing step; silent topology changes are the hardest bugs to trace.
- For ACIS and Parasolid, respect session and tag lifetimes; never hold a tag across a rollback.
With the access patterns clear, the next step is to apply them to concrete preparation tasks — importing, healing, and simplifying real models at scale.