Modeling basics
CadFlow models exact boundary-representation geometry through an explicit Model session. Most parts follow the same sequence:
primitive or profile → feature → boolean → transform → inspect → export
Units and coordinates
The modern frontend accepts plain numeric values and requires the caller to use one consistent unit system. Millimetres are conventional in the repository examples:
WIDTH_MM = 80.0
DEPTH_MM = 50.0
THICKNESS_MM = 8.0
The world frame is right-handed with +Z as the default construction axis. A box starts at the origin and extends in positive X, Y, and Z. A cylinder uses +Z unless it is rotated.
CadFlow does not silently convert raw numeric arguments in Model. If a workflow uses millimetres, keep geometry, tolerances, deflections, and validation thresholds in millimetres as well.
Create primitives
with cad.Model() as model:
block = model.box(width=80, depth=50, height=8)
pin = model.cylinder(radius=6, height=20)
ball = model.sphere(radius=10)
taper = model.cone(radius1=12, radius2=6, height=25)
Primitives return Shape handles in the same model session.
Build profiles and features
Turn a closed wire into a face, then extrude it:
with cad.Model() as model:
outline = model.polyline(
((0, 0, 0), (40, 0, 0), (40, 25, 0), (0, 25, 0)),
closed=True,
)
face = model.face(outline)
body = model.extrude(face, 0, 0, 6)
Other feature operations include:
revolve(profile, degrees, axis, origin)loft(profiles, solid=True, ruled=False)sweep(profile, path, solid=True, frenet=False)fillet(shape, radius, edges=[...])chamfer(shape, distance, edges=[...])shell(shape, thickness, faces=[...])
For non-planar work, bezier_surface, fit_surface, ruled_surface, filling_surface, and gordon_surface remain native operations.
Combine and remove material
Booleans operate on shapes owned by the same model:
with cad.Model() as model:
base = model.box(80, 50, 8)
boss = model.translate(model.cylinder(14, 14), 40, 25, 6)
body = model.union(base, boss)
bore = model.translate(model.cylinder(5, 20), 40, 25, 4)
body = model.cut(body, bore)
assert body.validate().ok
assert body.topology["solids"] == 1
union, cut, and intersect perform exact OCCT booleans in the full backend. Check that the operation changed the intended metric when correctness matters:
before = body.volume
result = model.cut(body, tool)
if result.volume >= before:
raise RuntimeError("cut did not remove material")
Transform shapes
Transforms return new shapes; they do not mutate the input:
moved = model.translate(shape, x=10, y=0, z=5)
turned = model.rotate(moved, degrees=90, axis=(0, 1, 0))
paired = model.mirror(turned, normal=(1, 0, 0))
scaled = model.scale(paired, factor=0.5, center=(0, 0, 0))
This functional style makes intermediate geometry inspectable and keeps feature construction replayable.
Select topology deliberately
The native frontend exposes deterministic zero-based face handles with model.faces(shape) and indexed selection for fillet, chamfer, and shell. Query topology before relying on an index:
print(body.topology)
report = model.preflight("fillet", body, 2.0, edges=[0, 3])
if report.ok:
rounded = model.fillet(body, 2.0, edges=[0, 3])
else:
print(report.to_dict())
Index selection is appropriate inside a controlled feature history. For durable references across edits and replay, use the compatibility layer's semantic tags and selectors.