Skip to main content

connector()

A connector is a named coordinate frame attached to the part's geometry — an origin, an X direction and a Z normal. Mates in an assembly join connectors to connectors, so the connectors a part declares are its mating interface. Every instance of the part carries the same set.

In the viewport

  1. Click Connector on the toolbar. The Connector dialog docks on the right with its Source slot armed.
  2. Hover the model. Faces and edges float their anchor candidates — the centre of a face, the centre, start or end of an edge — as a translucent frame. Click the one you want; the chip shows it.
  3. Fill in the Name (a free c1-style default is prefilled). Adjust the frame-local Offset x / y / z and click the rotation stepper to turn the frame 90° about its own Z per click.
  4. Click Apply. The statement is written directly in the part body and the timeline's part row gains a connector under its N connectors toggle. In the viewport the connector renders as a small axis triad.

Angle bracket with its mating frames

The code behind it
bracket.part.js
import { part, sketch, line, circle, extrude, cut, plane, select, connector } from 'fluidcad/core';
import { face } from 'fluidcad/filters';
import { coincident, distance, fix, horizontal, vertical } from 'fluidcad/constraints';

// A 40 × 40 × 40 angle bracket, 4 mm thick, with two mounting holes in
// each leg — and named connectors on the faces other parts mate to. In a
// part file the connectors render as small axis triads on their geometry;
// an assembly mates to them as `bracket.connectors.<name>`.
export const bracket = part('Angle bracket', () => {
// The L profile on the front plane: base along X, upright along Z.
sketch('xz', () => {
const l1 = line([0, 0], [40, 0]);
const l2 = line([40, 0], [40, 4]);
const l3 = line([40, 4], [4, 4]);
const l4 = line([4, 4], [4, 40]);
const l5 = line([4, 40], [0, 40]);
const l6 = line([0, 40], [0, 0]);
coincident(l1.end(), l2.start());
coincident(l2.end(), l3.start());
coincident(l3.end(), l4.start());
coincident(l4.end(), l5.start());
coincident(l5.end(), l6.start());
coincident(l6.end(), l1.start());
horizontal(l1);
horizontal(l3);
horizontal(l5);
vertical(l2);
vertical(l4);
vertical(l6);
fix(l1.start(), [0, 0]);
distance(l1.start(), l1.end(), 40);
distance(l6.start(), l6.end(), 40);
distance(l2.start(), l2.end(), 4);
distance(l5.start(), l5.end(), 4);
});
extrude(40).symmetric();

// Mounting holes: two down through the base, two through the upright.
sketch(plane('xy', { offset: 4 }), () => {
circle([25, -12], 5);
circle([25, 12], 5);
});
cut(4);
sketch(plane('yz', { offset: 4 }), () => {
circle([-12, 25], 5);
circle([12, 25], 5);
});
cut(4);

// A face connector sits at the face's centre with Z along its outward
// normal — the frame another part's face is mated face-to-face against.
// The underside of the base:
connector('foot', select(face().planar().onPlane('xy', 0)));
// The back of the upright, for hanging the bracket on a wall or beam:
connector('back', select(face().planar().onPlane('yz', 0)));
// The two base holes: the top-of-base frame moved along its own X / Y
// to each hole centre, where a standoff or a bolt head seats.
connector('hole1', select(face().planar().onPlane('xy', 4))).offset(3, -12, 0);
connector('hole2', select(face().planar().onPlane('xy', 4))).offset(3, 12, 0);
});

The bracket names the faces a neighbour will touch — foot for the surface it stands on, back for the beam it hangs from — and the two holes a fastener seats in. In an assembly, mate('fastened', beam.connectors.side, bracket.connectors.back) hangs it on the beam.

Signature

connector(name, source, options?)
ArgumentMeaning
nameIdentifier, unique within the part. Reached as instance.connectors.<name>.
sourceThe geometry the frame is derived from — see below.
options.xDirectionOptional X direction (an axis name or vector), re-orthogonalised against the frame's Z.

Two chained modifiers move the frame after it is derived, in call order:

ModifierEffect
.offset(x, y?, z?)Translate the origin along the frame's own axes.
.rotate('x' | 'y' | 'z', degrees)Rotate the frame about one of its own axes, pivoting at its origin.

Where the frame comes from

SourceOriginZ
A planar face — select(face().onPlane('xy', 10))Face centreFace normal, pointing out of the solid
A cylindrical or conical face — select(face().cylinder())On the axis, at the face's mid-heightThe surface axis, always oriented up (or +Y / +X when horizontal), never toward the seam
A circular edge — select(edge().circle())Circle centreCircle axis
A straight edge — select(edge().line())Edge midpointEdge tangent
A vertexThe pointWorld Z
An anchored vertex — e.endFaces().center(), sel.start(), sel.end()The anchor pointThe anchored face or edge's own direction
A plane — plane('xy', { offset: 20 })Plane originPlane normal

The source must resolve to exactly one face, edge or vertex. A raw point is refused on purpose: a frame tied to geometry re-derives correctly when the part changes; a hard-coded point would drift.

Face frames follow the outward normal, so two parts mated face-to-face end up with their connector Zs pointing at each other — that is the default a mate assumes, and .flip() on the mate is how you get the other way round.

Rules

  • Declare connectors directly in the part body, not inside a sketch() or other callback — nested, the connector would register nowhere and the statement is refused.
  • Names are unique within a part; a part connector and an assembly connector may share a name.
  • Connectors are part-owned. There is no way to add one to a single instance from the assembly; edit the part, or use an assembly-level free frame (connector('name', [x, y, z]), see the assembly introduction).
  • The pen button on a connector chip in the mate dialog edits a part connector's name, offset and rotation from the assembly — the edit is written into the part file.