compas_tf.connectors
¤
Free-standing connector elements usable as boolean cutters or joiners.
Three light parametric solids that mirror the shapes already produced inside the floor model, but exposed as standalone, reusable elements:
- :class:
ConnectorBoxElement— a box (width x depth x height). - :class:
ConnectorCylinderElement— a cylinder from an axis line + radius. - :class:
ConnectorWedgeElement— a triangular wedge prism, like the contact wedges placed between the quarter slabs and the oculus.
Each one implements the standard :class:compas_model.elements.Element
interface and additionally exposes boolean_geometry / boolean_geometries
(the transformed cutter mesh), so it can drive a
:class:compas_tf.solid_difference_modifier.SolidDifferenceModifier exactly like
:class:compas_tf.wedge.WedgeElement and
:class:compas_tf.joint_dowel.DowelElement do.
Classes¤
ConnectorBoxElement
¤
ConnectorBoxElement(width: float = 100.0, depth: float = 100.0, height: float = 100.0, transformation: Transformation | None = None, features: list | None = None, name: str | None = None)
A box-shaped connector centred on the element's local frame.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
width
|
float
|
Box size along local X. |
100.0
|
depth
|
float
|
Box size along local Y. |
100.0
|
height
|
float
|
Box size along local Z. |
100.0
|
transformation
|
:class:`compas.geometry.Transformation`
|
Placement of the box in the model. |
None
|
features
|
list[:class:`ConnectorBoxFeature`]
|
Features of the connector. |
None
|
name
|
str
|
Name of the element. |
None
|
ConnectorCylinderElement
¤
ConnectorCylinderElement(line: Line | None = None, radius: float = 50.0, sides: int = 16, transformation: Transformation | None = None, features: list | None = None, name: str | None = None)
A cylinder connector built from an axis line and a radius.
The cylinder is lofted between two sides-gon circles centred on the ends
of line (given in the element's local frame), perpendicular to it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line
|
:class:`compas.geometry.Line`
|
Cylinder axis in the element's local frame. Defaults to a 100 mm long axis along local Z. |
None
|
radius
|
float
|
Cylinder radius. |
50.0
|
sides
|
int
|
Number of polygon sides approximating the circle. |
16
|
transformation
|
:class:`compas.geometry.Transformation`
|
Placement of the cylinder in the model. |
None
|
features
|
list[:class:`ConnectorCylinderFeature`]
|
Features of the connector. |
None
|
name
|
str
|
Name of the element. |
None
|
ConnectorElement
¤
ConnectorElement(transformation: Transformation | None = None, features: list | None = None, name: str | None = None)
Rectangular connector box straddling the contact between two elements.
Local frame (before transformation):
+Xruns across the joint, toward the rib. The box spans[-BACK, +FRONT] = [-140, +265]along X (140 into the column, 265 into the rib), split at the contact plane (localx = 0). The total length (405) is the longest dimension, so it points toward the rib.+Yis horizontal along the contact face; the box isWIDTH = 21wide, centred on the placement point.+Zis up; the box top face is at localz = 0and the body hangs down toz = -HEIGHT = -350.
Build one oriented to a contact with :meth:from_contact: the placement
frame sits at the contact polygon's topmost point, with +X along the
horizontal contact normal (flipped to point toward the rib) and +Z along
world up.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
transformation
|
:class:`compas.geometry.Transformation`
|
Places the local box in the model (typically a world frame). |
None
|
features
|
list[:class:`ConnectorFeature`]
|
|
None
|
name
|
str
|
|
None
|
-
API Reference
connectors ClassesConnectorElement Methods:from_contact
Methods:¤
add_cutters
¤
Store cutter solids (e.g. the dowel cylinders) as a difference feature.
The meshes must be in the connector's local frame. Stored as a
:class:compas_tf.solid_difference_modifier.MeshCutFeature so the holes
travel with the connector through copy/serialization.
cutter_mesh
¤
The connector box in world coordinates (for boolean cutting).
overshoot grows the box ONLY at the top (local +Z, above z = 0)
by that amount. The box top sits at the contact's top edge, which is
coplanar with the column/rib top face - a cutter cap exactly coplanar
with a target face makes the mesh boolean difference unreliable (the same
reason the dowel cylinders overshoot, see :meth:cylinder_cutters), so
the top is pushed past that surface. The bottom (z = -HEIGHT) is a
BLIND pocket floor buried inside the material - extending it there would
only cut the pocket deeper than the connector, so it is left flush. The
in-plane (X/Y) footprint is unchanged. overshoot=0 returns the exact
box (legacy behaviour).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
overshoot
|
float
|
Extra length added at the TOP cap so the cut clears the coplanar top face cleanly (e.g. 25). The bottom is not extended. |
0.0
|
Returns:
| Type | Description |
|---|---|
class:`compas.datastructures.Mesh`
|
|
cylinder_cutters
¤
Cylindrical dowel cutters: two per side (column and rib).
A cylinder sits at each of the four positions from :meth:_dowel_grid
(two sides x two rows), each held in from the box boundaries by
EDGE_MARGIN_X * RADIUS horizontally and EDGE_MARGIN_Z * RADIUS
vertically - column side near x = -BACK, rib side near x = +FRONT.
Each cylinder's axis runs along the connector width
(local Y), with the given length and radius :attr:RADIUS. The two
sides carry the same vertical rows, just on opposite sides (so the
female/male distinction does not change the geometry).
Each cutter is extended by overshoot at both ends so its flat caps
clear the element surfaces: a cap exactly flush (coplanar) with a face
makes the boolean difference unreliable. The clipped hole still spans the
element; only the cutter overshoots, the nominal dowel length is length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
float
|
Cylinder length (e.g. the rib thickness). |
required |
overshoot
|
float
|
Extra length added at each cap so the cut passes cleanly through. |
25.0
|
Returns:
| Type | Description |
|---|---|
tuple[list[:class:`compas.datastructures.Mesh`], list[:class:`compas.datastructures.Mesh`]]
|
|
cylinder_elements
¤
cylinder_elements(length: float)
The four dowel cylinders as placed model elements (nominal length).
Same positions as :meth:cylinder_cutters - the shared
:meth:_dowel_grid (a margin in from the box boundaries, axis along
local Y) - but at the nominal length (no cutter overshoot); these
are the real dowels, added to the model like the wedge components.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
float
|
Cylinder length (e.g. the rib thickness). |
required |
Returns:
| Type | Description |
|---|---|
list[:class:`DowelCylinderElement`]
|
|
from_contact
classmethod
¤
from_contact(contact, toward, name: str | None = None) -> ConnectorElement
Create a connector oriented to a contact polygon.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contact
|
:class:`compas_model.interactions.Contact`
|
The contact whose polygon defines the placement. |
required |
toward
|
:class:`compas.geometry.Point`
|
A point on the rib side (e.g. the rib element's centroid). The local
|
required |
name
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
class:`ConnectorElement`
|
|
ConnectorWedgeElement
¤
ConnectorWedgeElement(length: float = 160.0, cylinder_radius: float = 10.0, cylinder_spacing: float = 320.0, cylinder_sides: int = 12, transformation: Transformation | None = None, features: list | None = None, name: str | None = None)
The floor contact wedge (copied from :class:compas_tf.wedge.WedgeElement),
exposed as a free connector that is sized and placed from an interface line.
The fixed triangular PROFILE (local YZ plane) is copied to
x = -length/2 and x = +length/2 and lofted into a closed triangular
prism — the exact wedge geometry used in
example_2_floor_model_booleans.py. The dowel axis (DOWEL_START ->
DOWEL_END) runs along local Y, and :meth:create_cylinders distributes
:class:ConnectorCylinderElement dowels along the wedge length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length
|
float
|
Prism length along local X (the wedge "target_length"). Usually set from
the interface edge via :meth: |
160.0
|
cylinder_radius
|
float
|
Radius of the dowel cylinders. |
10.0
|
cylinder_spacing
|
float
|
Approximate spacing between dowels along the wedge length. |
320.0
|
cylinder_sides
|
int
|
Polygon resolution of the dowel cylinders. |
12
|
transformation
|
:class:`compas.geometry.Transformation`
|
Placement of the wedge in the model. |
None
|
features
|
list[:class:`ConnectorWedgeFeature`]
|
Features of the connector. |
None
|
name
|
str
|
Name of the element. |
None
|
Attributes¤
boolean_geometries
property
¤
boolean_geometries: list
Cutter meshes contributed by the connector (the wedge solid).
boolean_geometry
property
¤
boolean_geometry: Mesh
Cutting geometry of the wedge — the wedge solid itself (model space),
so a plate carved by it is identical to the WedgeElement cut in
example_2. Use :meth:cutter_box instead for a box-shaped slot.
Methods:¤
build_mesh
¤
build_mesh() -> Mesh
Loft the fixed PROFILE between x = -length/2 and +length/2 (WedgeElement).
create_cylinders
¤
create_cylinders(horizontal: bool = True)
Distribute :class:ConnectorCylinderElement dowels along the wedge.
Mirrors WedgeElement.dowel_lines: the DOWEL axis (local Y) is
copied to max(int(length / spacing), 1) evenly-spaced stations along
local X.
By default the dowels are kept PARALLEL TO THE GROUND (world XY). The
raw dowel direction is the wedge's local Y = the contact normal, so on
an inclined wall (e.g. the oculus) the bolts would come out inclined
with the face. With horizontal=True each dowel's world axis is
projected onto the horizontal plane through its own centre - the faces
stay inclined as they are, only the bolt direction is flattened - and
the centre and nominal dowel length are preserved. On a vertical wall
the contact normal is already horizontal, so this is a no-op. Pass
horizontal=False for the perpendicular-to-face behaviour.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
horizontal
|
bool
|
Flatten the dowel axes parallel to the world XY plane (default). |
True
|
Returns:
| Type | Description |
|---|---|
list[:class:`ConnectorCylinderElement`]
|
|
cutter_box
¤
Oriented BOX cutter aligned to the wedge — its cutting geometry.
The box is built in the wedge's local frame so its biggest face (local
X-Z, length x profile-depth) coincides with the wedge's biggest side.
It is made massive along local Y (through, the joint normal) so it
slices clean through both plates, producing a straight rectangular slot
rather than a triangular one. Size is intentionally generous — the
boolean only removes the intersection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
through
|
float
|
Box extent along local Y (the cut-through direction). |
400.0
|
margin
|
float
|
Extra added to the X (length) and Z (depth) extents. |
0.0
|
Returns:
| Type | Description |
|---|---|
class:`compas.datastructures.Mesh`
|
The box cutter, with the wedge transformation applied (model space). |
end_polylines
¤
The wedge's two triangular end faces as co-wound closed polylines.
The prism is the PROFILE copied to x = -length/2 (bottom) and
x = +length/2 (top); both use the same PROFILE order, so vertex i
of the bottom matches vertex i of the top (same winding), exactly the
(bottom, top) representation a plate uses. Returned in model space
(the wedge transformation applied), to match :attr:boolean_geometry.
Returns:
| Type | Description |
|---|---|
tuple(:class:`compas.geometry.Polyline`, :class:`compas.geometry.Polyline`)
|
The |
from_contact
classmethod
¤
Create a wedge from a contact's longest top edge (see :meth:interface_line).
from_interface
classmethod
¤
Create a wedge centred on an interface edge.
The wedge frame is X = edge direction, Y = normal,
Z = X cross Y, placed at the edge midpoint. The wedge length is
the edge length minus 2 * length_margin (e.g. plate thickness), so
it is driven by the interface line length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
point - like
|
Endpoints of the interface edge. |
required |
end
|
point - like
|
Endpoints of the interface edge. |
required |
normal
|
vector - like
|
Contact normal (becomes the wedge's local Y / cylinder axis). |
required |
length_margin
|
float
|
Amount trimmed off each end of the edge to size the wedge length. |
0.0
|
**kwargs
|
Forwarded to |
{}
|
inclined_face_box_outlines
¤
The (bottom, top) rectangle outlines of each inclined-face box.
Same boxes as :meth:inclined_face_boxes, but as their two large-face
rectangles - bottom lying ON the incline, top depth into the
plate - returned co-wound (vertex i of bottom matches vertex i of
top), in model space. This is the minimal, parametric drilling /
fabrication form: feed a pair to a
:class:compas_tf.solid_difference_modifier.PrismCutFeature to get both
the box cutter (the loft) and the outlines (its minimal). One pair
per inclined face, in order [A-B, A-C].
inclined_face_boxes
¤
One oriented box per INCLINED wedge face (the two slants A-B, A-C).
Each box's large face lies on the incline (box X = wedge length, box Y =
the slant edge), and the box extends depth along that face's OUTWARD
normal - into the plate the face meets. Returned in model space (wedge
transform applied), so the box follows the inclined face exactly, with no
extra transform needed. The two boxes are returned in face order
[A-B, A-C] - one for each neighbour the wedge joins.
interface_line
staticmethod
¤
Return (start, end, normal) for a contact's longest top edge.
Mirrors the floor model's pick: collinear vertices are merged, edges
whose midpoint is at/above the polygon centroid count as "top", and the
longest such edge wins. normal is the contact polygon normal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contact
|
:class:`compas_model.interactions.Contact`
|
|
required |
Returns:
| Type | Description |
|---|---|
tuple(:class:`compas.geometry.Point`, :class:`compas.geometry.Point`, :class:`compas.geometry.Vector`)
|
|
DowelCylinderElement
¤
A cylindrical dowel connector.
Like the wedge components, this is a real model element (visible, serialized)
that is also used as a boolean cutter against the elements it joins. The
cylinder is built along the local Y axis, centred at the origin, and placed
by transformation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
radius
|
float
|
Cylinder radius. |
25.0
|
length
|
float
|
Cylinder length (the nominal dowel length, e.g. the rib thickness). |
100.0
|
transformation
|
:class:`compas.geometry.Transformation`
|
|
None
|
features
|
list[:class:`Feature`]
|
|
None
|
name
|
str
|
|
None
|
OuterRibConnectorElement
¤
OuterRibConnectorElement(transformation: Transformation | None = None, features: list | None = None, name: str | None = None)
Connector joining two quarters' outer ribs at a seam, from OBJ templates.
Unlike the parametric connectors above, this is a fixed fabrication shape
modelled in Rhino and shipped as three OBJ files in
data/OuterRibConnector/:
OuterRibConnector.obj— the connector body (the visible element);OuterRibConnector_cut0.obj— the MALE boolean cutter, to subtract from the rib on the local-Yside;OuterRibConnector_cut1.obj— the FEMALE boolean cutter, to subtract from the rib on the local+Yside.
The OBJs are modelled in the connector's LOCAL frame, deliberately offset so placement needs no further shifting:
- local
y = 0is the rib-rib interface plane. The body spansy in [-400, +400](one half into each rib) and each cutter overshoots the interface by 10, so no cutter cap is coplanar with a rib end face (a flush cap makes the boolean difference unreliable); - local
+Xpoints from the placement origin DOWN the rib end face; the body spansx in [138.5, 208.9], i.e. it hangs below the seam's top edge by that built-in offset; - local
Zspans the rib thickness (z in [-15, +15]).
:meth:from_contact builds the matching placement frame: origin at the
middle of the contact polygon's TOP edge, +X = world down, +Y = the
horizontal contact normal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
transformation
|
:class:`compas.geometry.Transformation`
|
Places the local template in the model (see :meth: |
None
|
features
|
list[:class:`compas_model.elements.element.Feature`]
|
|
None
|
name
|
str
|
|
None
|
-
API Reference
connectors ClassesOuterRibConnectorElement Methods:from_contact
Methods:¤
cutter_for
¤
cutter_for(point) -> Mesh
The cutter (world coordinates) for the rib on point's side of the seam.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
point
|
point - like
|
A world point identifying the rib, e.g. its centroid. On the
connector's local |
required |
Returns:
| Type | Description |
|---|---|
class:`compas.datastructures.Mesh`
|
|
cutter_meshes
¤
cutter_meshes() -> tuple
The (male, female) boolean cutters in WORLD coordinates.
The male cutter carves the rib on the connector's local -Y side,
the female cutter the rib on the +Y side. Use :meth:cutter_for to
pick the right one for a given rib automatically.
from_contact
classmethod
¤
from_contact(contact, name: str | None = None) -> OuterRibConnectorElement
Create a connector oriented to a rib-rib seam contact.
The placement frame: origin at the middle of the contact polygon's TOP
edge, +X = world down (into the seam face), +Y = the horizontal
contact normal — matching the local frame the OBJ templates are
modelled in, so the templates land on the seam with no extra offsets.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
contact
|
:class:`compas_model.interactions.Contact`
|
The seam contact between two outer ribs. |
required |
name
|
str
|
|
None
|
Returns:
| Type | Description |
|---|---|
class:`OuterRibConnectorElement`
|
|