Skip to the content.

4. The model API

model wraps the active document with a small, Pythonic API for the things scripts do most: dimensions, global variables, rebuild control, mass properties and finding faces and edges. For everything else, model.doc is the full SOLIDWORKS API (chapter 5).

The examples assume a part like the one the test suite uses: a 100 × 60 × 20 mm block (Boss-Extrude1) with a Ø20 mm cylinder (Boss-Extrude2) standing on it.

```python live model # <Model ‘Part1’> model.title # ‘Part1’ - the window title


For a document that is not active, wrap it yourself: `Model(other_doc)`. To **create** geometry, assemblies
and drawings, see [Building models](/SolidWorks-Python/guide/12-building-models.html).

## Dimensions

Dimensions are addressed by their full name, `"<dimension>@<feature or sketch>"`, and values are SI:

```python live
depth = model.dims["D1@Boss-Extrude1"]          # 0.02
print(to(depth, mm), "mm")

model.dims["D1@Boss-Extrude1"] = 25 * mm        # updates and rebuilds
print(round(to(model.dims["D1@Boss-Extrude1"], mm), 6))
model.dims["D1@Boss-Extrude1"] = 20 * mm
Expression Result
model.dims[name] Value in SI units (m, or rad for angles). KeyError if the name does not exist
model.dims[name] = value Set (SI) and rebuild - unless inside model.batch()
name in model.dims Whether the dimension exists
model.dims.names() Names of all displayed dimensions
model.dims.items() {name: value} for all of them

```python live for name, value in model.dims.items().items(): print(f”{name:24} {to(value, mm):8.2f} mm”)


**Finding a name:** in SOLIDWORKS, select a dimension and look at the *Primary Value* box of the
PropertyManager (e.g. `D1@Boss-Extrude1`), or print `model.dims.names()`.

## Global variables

`model.globals` reads and writes the global variables of the equation manager:

```python live
model.globals["Width"] = 120 * mm       # creates or updates "Width" = 120mm
print(model.globals["Width"])           # 0.12 (SI)
model.globals["Count"] = 4              # int -> unitless number
print(model.globals.items())
del model.globals["Count"]
Write Stored as
float (e.g. 120 * mm) A length in mm - or in the variable’s existing unit (in, deg …)
int A plain number
str A raw expression, e.g. '"Width" / 2'

Reading returns SI when the expression is a number with a unit (120mm -> 0.12), otherwise the evaluated number (as float).

To let a global drive a dimension, add an equation through the API:

```python live model.globals[“Thick”] = 20 * mm model.doc.GetEquationMgr().Add2(-1, ‘“D1@Boss-Extrude1” = “Thick”’, True) model.rebuild() model.globals[“Thick”] = 30 * mm # the block follows print(round(to(model.dims[“D1@Boss-Extrude1”], mm), 6)) # 30.0 model.globals[“Thick”] = 20 * mm


## Batch edits

Every `dims[...] = ` and `globals[...] = ` rebuilds immediately. When you change many values, wrap
them in `model.batch()`: graphics and the FeatureManager tree are frozen and the model rebuilds
**once** at the end. Batches can be nested.

```python live
with model.batch():
    model.globals["Width"] = 110 * mm
    model.globals["Thick"] = 22 * mm
model.globals["Thick"] = 20 * mm

model.batch(rebuild=False) skips the final rebuild. model.rebuild() rebuilds changed features; model.rebuild(force=True) rebuilds everything.

Mass properties

```python live props = model.mass print(props[“mass”], “kg”) print(to(props[“volume”], mm**3), “mm^3”) print(props[“center”]) # Vec(x, y, z) in metres


Keys: `mass` (kg), `volume` (m³), `area` (m²), `center` (`Vec`, m), `density` (kg/m³). The values
come from the material and density set in the document (or its template).

## Features and planes

```python live
for f in model.features():                   # tree order, including hidden system features
    print(f.GetTypeName2(), f.Name)
boss = model.feature("Boss-Extrude1")        # by name, None if missing
print(boss.Name, boss.GetTypeName2())

model.planes returns the three default planes by position, so scripts also work with templates that rename them (XY PLANE, Plan de face …):

```python live front, top, right = model.planes print(model.planes.front.Name, model.planes.top.Name, model.planes.right.Name) model.planes.top.Select2(False, 0)


## Faces and edges

`model.faces` and `model.edges` return **queries**: lists you can filter with chainable methods.
Each item is an `IFace2` / `IEdge`, so the whole API is available on it.

```python live
faces = model.faces
print(len(faces), "faces,", len(faces.planar()), "planar,", len(faces.cylindrical()), "cylindrical")

top = faces.normal(Z)                        # planar faces whose outward normal is +Z
pin = faces.radius(10 * mm)                  # cylindrical faces of radius 10 mm
biggest = faces.planar().largest()
print(round(to(biggest.GetArea(), mm**2)), "mm^2")

vertical = model.edges.parallel(Z)           # straight edges along Z
print(len(vertical), "vertical edges")
Query Keeps
faces.planar() / faces.cylindrical() Flat / cylindrical faces
faces.normal(direction, tol=1e-6) Planar faces whose outward normal points along direction
faces.radius(r, tol=1e-9) Cylindrical faces with radius r
faces.area(lo, hi) Faces with lo <= area <= hi (m²)
faces.edges All edges of these faces (each once)
edges.linear() / edges.circular() Straight / circular edges
edges.parallel(direction, tol=1e-6) Straight edges parallel to direction (either sense)
edges.radius(r, tol=1e-9) Circular edges with radius r
edges.length(lo, hi) Edges with lo <= length <= hi (m)
q.where(predicate) Items for which predicate(item) is true
q.largest() / q.smallest() Biggest / smallest item (area or length), None if empty
q.sort(key=None, reverse=False) Sorted copy (default: by size)
q.select(append=False) Select the items in the viewport; returns how many were selected

Every filter returns a new query, so they chain:

```python live model.faces.normal(Z).largest().Select4(False, None) # one face, raw API n = model.faces.cylindrical().edges.circular().select() # all circular edges of the pin print(n, “edges selected”)


`where` takes any function - use the raw API inside:

```python live
small = model.faces.where(lambda f: f.GetArea() < 1000 * mm**2)
print(len(small), "faces smaller than 1000 mm^2")

Vectors

Vec is a tuple of three floats with a little arithmetic: -v, v.dot(w), v.length, v.unit(), v.angle(w) (radians). X, Y, Z are the unit axes, and API arrays convert directly:

```python live n = Vec(model.faces.normal(Z)[0].Normal) print(n, n.length, to(Vec(1, 1, 0).angle(X), deg))


## Bodies

`model.bodies()` returns the solid bodies of a part (`IBody2`); `model.bodies(solid=False)` the
surface bodies.

```python live
for body in model.bodies():
    print(body.Name, len(body.GetFaces()), "faces")