Skip to main content

Defining connectors

A connector is a named coordinate frame attached to a part's geometry. Joints are built between connectors, so a part declares them where other parts will attach: on the pin axis, for a hinge leaf. The frame's Z axis is the axis a revolute joint turns about and a slider travels along.

In the viewport

  1. Click Connector on the toolbar. The dialog shows an empty Source slot.
  2. Hover the round edge at the front end of the middle knuckle (the one the Extrude made; the outer two are its repeats). A translucent frame appears at the edge's centre, Z along the tube: the suggested anchor. Hovering a face suggests its centre instead; hovering a straight edge offers its centre, start and end.
  3. Click to take the anchor. Type knuckle in Name. Offset and Rotation stay at zero: the frame is exactly where the anchor put it, which is where the other leaf's first knuckle will end. Click Apply.
  4. Repeat with the same edge, name it pin, and type 24 in the Offset Z field. The frame's Z axis is the pin axis, so the offset slides the frame 24 mm along the tube, past the gap and the front knuckle, to the very end where the pin's head will sit.

Connector dialog

The History panel folds the two under a 2 connectors row at the bottom of the part. The frames stay visible as small triads in the viewport.

The fixed leaf with its connectors
The code behind it
hinge-leaf-fixed.part.js
import { origin, xAxis, yAxis, part, sketch, line, circle, extrude, cut, repeat, fillet, connector } from 'fluidcad/core';
import { coincident, horizontal, vertical, midpoint, distance, diameter, fix } from 'fluidcad/constraints';
import { edge } from 'fluidcad/filters';

// The part container: everything inside the callback belongs to the
// "Fixed leaf". Exporting it is what lets an assembly insert() it later.
export const fixedLeaf = part('Fixed leaf', () => {
// Leaf outline, drawn with the Rectangle tool on the XY plane: 30 mm wide,
// 60 mm along the pin axis (Y). The four lines are guesses; the constraints
// below are what the tool wrote to pin the rectangle down.
sketch('xy', () => {
const b = line([0, -28.96], [30, -28.96]);
const r = line([30, -28.96], [30, 31.04]);
const t = line([30, 31.04], [0, 31.04]);
const l = line([0, 31.04], [0, -28.96]);
// corners: each line ends where the next one starts
coincident(b.end(), r.start());
coincident(r.end(), t.start());
coincident(t.end(), l.start());
coincident(l.end(), b.start());
// square it up
horizontal(b);
vertical(r);
horizontal(t);
vertical(l);
// the two dimensions (double-click a label in the viewport to change them)
distance(b.start(), b.end(), 30);
distance(r.start(), r.end(), 60);
// centre the left edge on the origin: the pin axis runs through the
// middle of the leaf, and the outline cannot slide
midpoint(origin(), t.end(), b.start());
});
// Extrude dialog, Add tab, Distance 3: the leaf plate.
const leaf = extrude(3);
// One screw hole: a circle sketched on the plate's top face, then the
// Extrude dialog's Remove tab (a cut) with Through all. The circle is a
// guess; the two dimensions to the sketch axes place it 20 mm from the
// pin edge and 10 mm from the end of the plate.
sketch(leaf.endFaces(), () => {
const hole = circle([22.92, -25.08], 4);
diameter(hole, 4);
distance(hole.center(), xAxis(), 20);
distance(hole.center(), yAxis(), 20);
});
const hole = cut();
// Repeat dialog: the same cut two more times, 20 mm apart along Y.
repeat('linear', 'y', { count: 3, offset: 20 }, hole);
// Fillet tool, radius 4, on the two corners away from the pin — the
// vertical edges that lie on the plane x = 30.
fillet(4, leaf.sideEdges(edge().onPlane('yz', 30)));
// One knuckle: an 8 mm ring sketched on the front plane, centred 4 mm
// above the leaf so the tube sits on the plate's edge, then extruded 12 mm
// along the pin axis, symmetric about the sketch plane (6 mm each way).
sketch('xz', () => {
const outer = circle([0, 4], 8);
diameter(outer, 8);
fix(outer.center(), [0, 4]);
});
const knuckle = extrude(12).symmetric();
// Three knuckles on this leaf, 24 mm apart and centred on the first one:
// the other leaf's two knuckles fill the gaps between them.
repeat('linear', 'y', { count: 3, offset: 24, centered: true }, knuckle);
// The 4 mm bore for the pin: a circle on the front plane, cut Through all
// in both directions so one cut drills all three knuckles.
sketch('xz', () => {
const bore = circle([0, 4], 4);
diameter(bore, 4);
fix(bore.center(), [0, 4]);
});
cut().symmetric();

// Connector tool: two mate frames on the pin axis, both anchored on the
// round edge at the front end of the middle knuckle, so their Z axis is
// the pin axis. 'knuckle' is where the other leaf's first knuckle ends;
// 'pin' is slid 24 mm along that Z axis, past the gap and the end knuckle,
// to the very end of the tube where the pin's head lands.
connector('knuckle', knuckle.startEdges(edge().notLine()).center());
connector('pin', knuckle.startEdges(edge().notLine()).center()).offset(0, 0, 24);
});

Each connector() statement names its anchor by the geometry it came from: the knuckle extrude's start edges, filtered to the round ones, then .center(). The pin connector adds .offset(0, 0, 24), which is the dialog's Offset field, measured along the frame's own axes. Because the anchor is derived from geometry, both frames move with the part when a dimension changes; the repeated knuckles cannot be anchored directly, which is why the tube's end is reached with an offset from the original.

note

connector() must be called directly in the part() body, and a connector's name must be unique within its part. Connectors are the part's mating interface: an assembly refers to them as instance.connectors.pin.

The swing leaf and the pin

The hinge needs two more parts. Create hinge-leaf-swing.part.js and hinge-pin.part.js with the + tab button and build them the same way. Both files are below in full.

The swing leaf mirrors the fixed one: it extends to the other side of the pin axis, and its two knuckles fall into the fixed leaf's gaps. Its ring is sketched on a plane 18 mm in front of the front plane (the Plane dialog, type Offset), extruded 12 mm and repeated once, 24 mm along; the bore is the same symmetric Through all cut. Its one connector sits at the far end of that first knuckle, the same point on the pin axis as the fixed leaf's knuckle connector.

The swing leaf
The code behind it
hinge-leaf-swing.part.js
import { origin, xAxis, yAxis, part, sketch, line, circle, extrude, cut, repeat, fillet, plane, connector } from 'fluidcad/core';
import { coincident, horizontal, vertical, midpoint, distance, diameter, fix } from 'fluidcad/constraints';
import { edge } from 'fluidcad/filters';

// The swing leaf mirrors the fixed leaf: it grows to -X from the pin axis,
// and its two knuckles fill the gaps between the fixed leaf's three.
export const swingLeaf = part('Swing leaf', () => {
sketch('xy', () => {
const b = line([-30, -28.96], [0, -28.96]);
const r = line([0, -28.96], [0, 31.04]);
const t = line([0, 31.04], [-30, 31.04]);
const l = line([-30, 31.04], [-30, -28.96]);
coincident(b.end(), r.start());
coincident(r.end(), t.start());
coincident(t.end(), l.start());
coincident(l.end(), b.start());
horizontal(b);
vertical(r);
horizontal(t);
vertical(l);
distance(b.start(), b.end(), 30);
distance(r.start(), r.end(), 60);
// the right edge is on the pin axis, centred on the origin
midpoint(origin(), r.start(), r.end());
});
const leaf = extrude(3);

sketch(leaf.endFaces(), () => {
const hole = circle([-22.92, -25.08], 4);
diameter(hole, 4);
distance(hole.center(), xAxis(), 20);
distance(hole.center(), yAxis(), 20);
});
const hole = cut();
repeat('linear', 'y', { count: 3, offset: 20 }, hole);

fillet(4, leaf.sideEdges(edge().onPlane('yz', -30)));

// The first knuckle fills the fixed leaf's front gap, 18 mm in front of
// the origin, so the ring is sketched on a plane offset from the front
// plane (Plane dialog: Offset, base "front", 18 — the front plane's
// normal points to -Y, so a positive offset moves towards the viewer).
sketch(plane('xz', { offset: 18 }), () => {
const outer = circle([0, 4], 8);
diameter(outer, 8);
fix(outer.center(), [0, 4]);
});
const knuckle = extrude(-12);
// Repeat dialog: the second knuckle 24 mm along, in the other gap.
repeat('linear', 'y', { count: 2, offset: 24 }, knuckle);

// The bore, cut Through all both ways from the front plane: it drills
// both knuckles even though the plane itself sits in the gap between them.
sketch('xz', () => {
const bore = circle([0, 4], 4);
diameter(bore, 4);
fix(bore.center(), [0, 4]);
});
cut().symmetric();

// One connector, at the far end of the first knuckle: the same point on
// the pin axis as the fixed leaf's 'knuckle' connector.
connector('knuckle', knuckle.endEdges(edge().notLine()).center());
});

The pin is a 4 mm shaft with a head, drawn on the same axis and starting from a plane 30 mm in front of the front plane, where the fixed leaf's tube ends. Its connector sits where the head meets the shaft.

The pin
The code behind it
hinge-pin.part.js
import { part, sketch, circle, extrude, chamfer, plane, connector } from 'fluidcad/core';
import { diameter, fix } from 'fluidcad/constraints';

// A 4 mm pin, 60 mm long, with a small head. Drawn on the same axis as the
// knuckles (x = 0, z = 4), starting at the front end of the fixed leaf's
// tube (30 mm in front of the front plane) so it drops straight into the
// hinge.
export const pin = part('Pin', () => {
sketch(plane('xz', { offset: 30 }), () => {
const c = circle([0, 4], 4);
diameter(c, 4);
fix(c.center(), [0, 4]);
});
const shaft = extrude(-60);
// a lead-in chamfer on the far end
chamfer(0.5, shaft.endEdges());

sketch(plane('xz', { offset: 30 }), () => {
const c = circle([0, 4], 7);
diameter(c, 7);
fix(c.center(), [0, 4]);
});
const head = extrude(1.5);

// The mate frame: where the head meets the shaft, Z along the pin.
connector('shaft', head.startEdges().center());
});

Next: Showing how to export the part.