Skip to main content

Selecting

Features need to know which faces and edges to act on. part.faces(), part.edges(), part.vertices() and part.wires() return a ShapeList: a Python list with selection methods. Every method returns a new ShapeList, so selections chain:

from smlibpy import *

part = Box(40, 30, 20) - Cylinder(6, 30)

part.edges().parallel_to(Z) # the four vertical box edges
part.faces().planar().facing(Z) # the flat faces pointing up
part.edges().circles().top() # the hole's top rim
part.faces().cylinders().one().radius # 6.0

By position​

SelectorPicks
top(), bottom()highest / lowest (Z)
right(), left()furthest along +X / -X
back(), front()furthest along +Y / -Y
max_by(key), min_by(key)largest / smallest key
nearest(point)the shape closest to a point
at(point)shapes passing through a point
within(bbox)shapes inside a box

Position selectors compare shape centers and return every shape that ties, so box.faces().top() is one face but box.edges().top() is the four top edges.

By geometry​

SelectorPicks
of_type("cylinder", ...)faces of these surface types / edges of these curve types
lines(), circles()straight / circular edges
planar(), cylinders()planar / cylindrical faces
parallel_to(axis)straight edges along an axis, planar faces normal to it
perpendicular_to(axis)straight edges across an axis, planar faces containing it
facing(direction)faces whose outward normal points that way
convex(), concave(), smooth()edges on outside / inside corners, tangent edges
filter(predicate)anything you can test in Python

Face types are plane, cylinder, cone, sphere, torus, revolution, extrusion, bspline and offset; edge types are line, circle, ellipse and bspline.

Ordering and grouping​

faces = part.faces()
faces.sort_by("area") # also "length", "volume", "radius", an axis, or a function
faces.sort_by(Z, reverse=True)
faces.group_by(Z) # list of ShapeLists, lowest first
faces.largest(), faces.smallest()
part.edges().sort_by_distance((0, 0, 0))

Picking one​

A selection is always a list. Where an operation needs a single shape, a one-element list is accepted. To be explicit:

top = part.faces().top().one()    # exactly one, or an error explaining how many there are
first = part.edges().first
last = part.edges().sort_by(X).last

Combining selections​

a = part.edges().top()
b = part.edges().parallel_to(Z)
a | b # union
a & b # common to both
a - b # in a but not in b
a + b # concatenation

Going down the topology​

A selection expands to its parts: part.faces().top().edges() gives the edges of the top face, face.outer_wire() its boundary, face.inner_wires() its holes and edge.faces() the faces meeting at an edge. Single shapes offer the same: face.edges(), edge.vertices(), face.neighbors().

Seams​

Closed surfaces such as cylinders have a seam where the surface meets itself. Seams are not real edges and are left out of edges(); edges(seams=True) includes them.

Operators​

filter_by, sort_by and group_by take an axis, a type name or a function, and the operators >, <, >> and << sort, reverse-sort and take the top and bottom groups:

part.faces() >> Z     # same as part.faces().max_by(Z)
part.edges() < X # same as part.edges().sort_by(X, reverse=True)