Skip to main content

Building an Upper Alignment Clamp

In this tutorial, you'll build an upper alignment clamp, based on the original design by TooTallToby. You build it entirely from the FluidCAD workspace: the toolbar, the sketch tools, the constraint bar and the feature dialogs. Every dialog writes a line of code into your file as you apply it, so the full code at the end is what the UI produced, not something you type.

It covers the rounded Rectangle and Slot tools, sketching on a face an operation produced, section views, dimensioning against the sketch axes, a symmetric extrusion and a symmetric cut, projecting a model edge in as a fixed reference, a tangent web built from four Tangent picks, construction planes at an offset, the 2D Mirror tool, and mirroring both solids and whole features.

Before you start​

Open a workspace and create a new part file: click + in the top bar and type upper-alignment-clamp.fluid.js. The new tab opens on an empty scene. The screenshots use the light theme; the sun/moon button at the top right switches it.

A few UI habits you will use throughout:

  • Ctrl+click adds an entity to the current selection. A plain click replaces it.
  • The constraint bar appears under the toolbar while you sketch. Its buttons are icons; hover one for its name. A button lights up only when the current selection makes sense for it.
  • Dimension is one button. What it writes depends on what you picked: an arc alone gives a radius, a circle a diameter, a point and an axis a distance.
  • The DOF pill at the bottom of the viewport counts the degrees of freedom left in a sketch and turns into Fully constrained when you are done.
  • Every feature dialog shows the statement it is about to write, just under the dialog. Apply (or Enter) writes it; Exit / Cancel (or Escape) discards it.
  • Inside a sketch, N looks straight down the sketch plane.

Step 1: The base plate​

Start a sketch on the XY plane​

Click Sketch in the toolbar. The dialog asks for a face or a plane, and the three origin planes appear in the viewport.

Sketch tool armed, waiting for a plane

Click the XY plane. The camera locks onto it, the sketch toolbar replaces the feature toolbar, and the constraint bar appears above the viewport. Leave the sketch options as they are.

An empty sketch on the XY plane

Draw the plate with the rounded Rectangle tool​

The plate is a 120 × 66 rectangle with R13 corners. That is one tool, not four lines and four fillets.

Click Rectangle. The button opens a small option menu; switch on Rounded and Centered. Rounded adds a corner-radius step to the gesture, and Centered grows the rectangle from its middle instead of from a corner.

The Rectangle tool's option menu with Rounded and Centered on

Click the origin for the centre. A W readout follows the mouse; type 120 and press Enter. The readout switches to H; type 66 and press Enter.

Rectangle tool: the width is set, the height comes next

The readout switches once more, to R. Type 13 and press Enter.

Rectangle tool: the corner radius

One gesture, and the outline arrives fully described: four lines and four corner arcs, tangent at every junction, the horizontals and verticals called out, the arcs all equal, the two 120 and 66 dimensions, one R13, and — because you clicked the origin — a midpoint tying the centre of the rectangle to it. The DOF pill reads Fully constrained.

The 120 × 66 outline with R13 corners, fully constrained

Extrude the plate​

Click Extrude on the toolbar. The dialog opens with the sketch already in its Sketch slot. Set Distance to 13. The green ghost is a live preview of the solid, and the statement under the dialog reads extrude(13).

Extrude dialog with the 13 mm ghost preview

Click Apply. The plate appears, an Extrude row joins the History panel, and the Shapes panel lists the new solid.

The extruded plate

Step 2: Cut the side notches​

Each end of the clamp has a 14-wide notch cut 10 deep into it. A notch like that is a slot — so use the Slot tool and let half of it hang outside the material.

Sketch on the top face​

Click Sketch again, but this time click the top face of the plate instead of a datum plane. The chip reads Face — Extrude: FluidCAD remembered which operation produced that face, so the sketch follows the plate if you change it later.

A sketch opened on the top face of the plate

Draw the slot​

Pick the Slot tool. Click a point on the horizontal axis about 10 mm in from the right edge for the first cap centre, then move right along the axis. A D readout gives the distance between the two cap centres; type 20 and press Enter.

Slot tool: the centre distance is typed

The readout switches to R. Type 7 and press Enter.

Slot tool: the cap radius

The slot arrives as two lines and two cap arcs, tangent at every junction, with equal radii, the 20 mm centre distance and the R7 dimension. Both cap centres landed on the horizontal axis while you drew, so the tool wrote those coincidents too — one degree of freedom is left, sliding along the axis.

Click the left cap's centre point, Ctrl+click the vertical axis, and click Dimension. Type 50. The notch bottoms out 10 mm in from the 60 mm edge, and the pill reads Fully constrained.

The slot dimensioned 50 mm from the vertical axis

Notice that the right-hand half of the slot sticks out past the edge of the plate. That is deliberate: there is no material there to remove, so the cut leaves exactly the open notch you want and you never have to draw the mouth of it.

Cut it, then mirror the cut​

Click Extrude on the toolbar. Select the Remove tab and switch on Through all. The red ghost is the material about to disappear, and the statement is simply cut().

Extrude dialog on the Remove tab with Through all

Click Apply.

One notch cut

Click Repeat in the toolbar and set Type to Mirror. Repeat takes its targets from the History panel: click the Cut row, and it lands in the Features slot. Then click the YZ plane in the viewport for the mirror plane. The ghost shows the second notch, and the statement reads repeat('mirror', 'yz', f).

Repeat dialog mirroring the notch across the YZ plane

Click Apply. Repeat mirrors the operation, not the solid — the notch is cut again on the other side.

Both notches

Step 3: The barrel and its bore​

A half-cylinder runs across the plate and gets bored through.

Sketch a half-disc on the XZ plane​

Click Sketch and pick the XZ plane. Because the plane cuts through the plate, Section view clips the near half away and you see the plate in cross-section.

An empty sketch on the XZ plane, the plate in section

Pick Center Arc. Click the origin for the centre, click a point out along the horizontal axis for the start, then sweep up and over to the left. While you sweep, the readout gives the included angle — type 180 and press Enter for exactly half a circle.

Center Arc: sweeping the arc, with the angle readout

Click the arc and click Dimension; type 31 for the radius. Then pick the Line tool and draw the closing line from one end of the arc to the other — snap to both endpoints and it arrives with the two coincidents and a horizontal already on it. That is the last degree of freedom: Fully constrained.

The closed half-disc, R31

Extrude it symmetrically​

Click Extrude on the toolbar. Set Direction to Symmetric and Total distance to 66. Symmetric splits the distance evenly across the sketch plane, so 33 mm goes each way and the barrel matches the 66 mm depth of the plate exactly. The statement reads extrude(66).symmetric().

Extrude dialog with the symmetric 66 mm ghost

Click Apply. With the Add tab selected the new solid fuses with the plate.

The barrel fused to the plate

Bore it through​

Click Sketch, pick the XZ plane again, and pick the Circle tool. Click the origin for the centre, type 36 and press Enter — the circle readout is a diameter. Then click the centre point, Ctrl+click the origin and click Coincident if the click did not already snap there.

A 36 mm circle on the barrel axis

Extrude, Remove tab, Symmetric, 66 again: cut(66).symmetric().

The symmetric bore cut

Click Apply.

The bored barrel

Step 4: The pipe mount web​

This is the interesting step. The web that carries the pipe boss is a smooth outline: two flanks running tangentially from the barrel up to a cap over the pipe. Nothing about its size is typed twice — the two arcs borrow their radius and centre from reference geometry.

A plane 20 mm in front​

Click Plane in the toolbar, click the XZ origin plane as the base, and set Offset to 20. The yellow quad previews the new plane and the statement reads plane('xz', 20).

Plane dialog, XZ offset by 20 mm

Click Apply, then click Sketch and pick the new plane.

Project the barrel's edge in​

Pick the Project tool. It suspends sketch editing so you can pick in the free 3D view; click the R31 arc where the barrel meets the plate. The statement reads project(e2.startEdges(edge().arc())) — FluidCAD wrote the selection as a rule rather than a fixed index, so it survives edits.

Project tool with the barrel's arc edge picked

Click Apply. Projected geometry comes in fixed: it adds no freedom to the sketch, and other constraints can lean on it. Select it and click Guide to turn it into construction geometry so it stays out of the profile.

Now the pipe. Click Guide with nothing selected to latch construction mode on, pick Circle, click a point on the vertical axis and type 16. Click its centre, Ctrl+click the horizontal axis, Dimension, 45.

The two guides: the projected barrel arc and the 16 mm pipe circle

Those two dash-dot curves are the whole plan for this sketch. Everything else will be constrained to them.

The tangent outline​

Click Guide again to unlatch it, then rough out the closed outline: Line from the barrel up to the right of the pipe, 3-Pt Arc over the top of the pipe, Line back down to the left, and a second 3-Pt Arc across the barrel to close the loop. Snap each start point to the previous end point and the four coincidents come for free. Do not try to be accurate — these are guesses.

Now state what the shape actually is, with the constraint bar:

  1. Click a flank, Ctrl+click the arc next to it, click Tangent. Four times, once per junction.
  2. Click the cap arc, Ctrl+click the pipe guide circle, click Concentric, then Equal.
  3. Click the bridge arc, Ctrl+click the projected barrel arc, click Concentric, then Equal.

The pill reads Fully constrained. The cap now lies exactly on the pipe circle, the bridge exactly on the barrel, and the tangency alone decides where the flanks touch down.

The tangent web profile, fully constrained

Nothing here says which tangent line you meant — a line tangent to two circles could sit on either side. The guesses decide: the solver keeps each line on the side you drew it, so drawing it roughly in the right place is the choice.

Extrude the web​

Extrude, Distance 11.

Extrude dialog with the 11 mm web ghost

Click Apply.

The web standing on the barrel

Step 5: The pipe boss, then mirror it​

Sketch the pipe on a second plane​

Click Plane, pick XZ again and set Offset to 35 — the far end of the pipe. Apply, then Sketch on it.

Pick Circle, click on the vertical axis and type 16; dimension its centre 45 from the horizontal axis, as before. Then pick Circle again and click the first circle's centre point — snapping there writes the coincident that makes the two circles concentric — and type 10.

Two concentric circles, 16 and 10, on the second plane

Extrude it back toward the web​

Extrude, Distance -15. A negative distance runs the other way along the plane's normal, back from y = 35 to the web at y = 20. The ring profile extrudes as a tube.

Extrude dialog with the -15 mm pipe ghost

Click Apply.

The pipe boss fused to the web

Mirror the whole mount​

The clamp carries the same mount on both sides. Click Mirror in the toolbar, click the body in the viewport for the Solids slot, then click the XZ plane. The green ghost is the mirrored copy and the statement reads mirror('xz', f2).

Unlike the Repeat you used for the notch, this mirrors the solid: the whole clamp is reflected and fused, which brings the mount across without repeating any of its features.

Mirror dialog with the mirrored body ghost

Click Apply. The plate and barrel are symmetric about XZ already, so only the mount actually changes.

Both pipe mounts

Step 6: Holes last​

Four counterbored mounting holes in the corners, and the bore through both pipes.

Two bolt holes and a 2D mirror​

Click Sketch and pick the top face of the plate again. Pick Circle, click near one corner and type 7. Dimension its centre 47 from the vertical axis and 20 from the horizontal axis.

Then pick the Mirror tool from the sketch toolbar. Click the circle for Geometry, click the Mirror line slot and click the vertical axis. The blue outline is the mirrored copy.

The 2D Mirror tool with the mirrored circle preview

Click Apply. Two fully-placed holes from one constrained circle.

Two 7 mm circles, fully constrained

Extrude, Remove, Through all, Apply.

The counterbores​

Do the same again with a bigger circle: Sketch on the top face, Circle ⌀15 on the same 47 / 20 dimensions, Mirror across the vertical axis.

Two 15 mm circles over the bolt holes

Extrude, Remove tab, Depth 4 — a shallow recess for the bolt head rather than a through hole.

Extrude dialog with the 4 mm counterbore ghost

Click Apply.

Mirror both cuts to the other side​

Click Repeat, set Type to Mirror, and click both Cut rows in the History panel — a repeat can carry more than one feature. Pick the XZ plane, and both the holes and their counterbores appear on the near side.

Repeat mirroring both cuts across the XZ plane

Click Apply.

Bore the pipes through​

One cut finishes both mounts at once. Click Sketch, pick the XZ plane, draw a Circle on the vertical axis, type 10, and dimension its centre 45 from the horizontal axis — the same place the pipe sits.

Extrude, Remove tab, Symmetric, Through all. Symmetric runs the cut both ways from the XZ plane, so one feature drills both pipes and the web behind each of them.

The symmetric through-bore for both pipes

Click Apply. That is the clamp.

The finished upper alignment clamp

Full code​

Everything above was written into upper-alignment-clamp.fluid.js by the dialogs. Open the code editor with the </> button on the left rail or Ctrl+B to read it. The listing below is the same model with tidier names; the coordinates you clicked will differ, but the constraints make the geometry identical.

Show the full code
// @screenshot waitForInput
import { arc, circle, cut, extrude, line, mirror, origin, plane, project, repeat,
sketch, xAxis, yAxis } from "fluidcad/core";
import { coincident, concentric, diameter, distance, equal, horizontal, midpoint,
radius, tangent, vertical } from "fluidcad/constraints";
import { edge } from "fluidcad/filters";

sketch('xy', () => {
const bottom = line([-47, -33], [47, -33]);
const br = arc([47, -33], [60, -20], [47, -20]);
const right = line([60, -20], [60, 20]);
const tr = arc([60, 20], [47, 33], [47, 20]);
const top = line([47, 33], [-47, 33]);
const tl = arc([-47, 33], [-60, 20], [-47, 20]);
const left = line([-60, 20], [-60, -20]);
const bl = arc([-60, -20], [-47, -33], [-47, -20]);
coincident(bottom.end(), br.start());
coincident(br.end(), right.start());
coincident(right.end(), tr.start());
coincident(tr.end(), top.start());
coincident(top.end(), tl.start());
coincident(tl.end(), left.start());
coincident(left.end(), bl.start());
coincident(bl.end(), bottom.start());
tangent(bottom, br);
tangent(br, right);
tangent(right, tr);
tangent(tr, top);
tangent(top, tl);
tangent(tl, left);
tangent(left, bl);
tangent(bl, bottom);
horizontal(bottom);
horizontal(top);
vertical(right);
vertical(left);
equal(br, tr);
equal(br, tl);
equal(br, bl);
distance(left, right, 120);
distance(bottom, top, 66);
radius(br, 13);
midpoint(origin(), bl.center(), tr.center());
});

const plate = extrude(13);

sketch(plate.endFaces(), () => {
const lower = line([50, -7], [70, -7]);
const outer = arc([70, -7], [70, 7], [70, 0]);
const upper = line([70, 7], [50, 7]);
const cap = arc([50, 7], [50, -7], [50, 0]);
coincident(lower.end(), outer.start());
coincident(outer.end(), upper.start());
coincident(upper.end(), cap.start());
coincident(cap.end(), lower.start());
tangent(lower, outer);
tangent(outer, upper);
tangent(upper, cap);
tangent(cap, lower);
equal(outer, cap);
distance(cap.center(), outer.center(), 20);
radius(outer, 7);
coincident(cap.center(), xAxis());
coincident(outer.center(), xAxis());
distance(cap.center(), yAxis(), 50);
});

const notch = cut();

repeat('mirror', 'yz', notch);

sketch('xz', () => {
const dome = arc([31, 0], [-31, 0], [0, 0]);
const flat = line([-31, 0], [31, 0]);
coincident(dome.center(), origin());
coincident(dome.start(), xAxis());
radius(dome, 31);
coincident(flat.start(), dome.end());
coincident(flat.end(), dome.start());
horizontal(flat);
});

const barrel = extrude(66).symmetric();

sketch('xz', () => {
const bore = circle([0, 0], 36);
coincident(bore.center(), origin());
diameter(bore, 36);
});

cut(66).symmetric();

const webPlane = plane('xz', 20);

sketch(webPlane, () => {
const domeArc = project(barrel.startEdges(edge().arc())).guide();
const pipe = circle([0, 45], 16).guide();
const right = line([32.57, 20.95], [6.88, 50.69]);
const cap = arc([6.88, 50.69], [-7.28, 50.69], [-0.2, 45.13]);
const left = line([-7.28, 50.69], [-32.98, 20.95]);
const bridge = arc([-32.98, 20.95], [32.57, 20.95], [-0.2, -16.38]).cw();
coincident(pipe.center(), yAxis());
diameter(pipe, 16);
distance(pipe.center(), xAxis(), 45);
coincident(cap.start(), right.end());
coincident(left.start(), cap.end());
coincident(bridge.start(), left.end());
coincident(bridge.end(), right.start());
tangent(right, cap);
tangent(cap, left);
tangent(left, bridge);
tangent(right, bridge);
concentric(cap, pipe);
equal(cap, pipe);
concentric(bridge, domeArc);
equal(bridge, domeArc);
});

extrude(11);

const pipePlane = plane('xz', 35);

sketch(pipePlane, () => {
const wall = circle([0, 45], 16);
const bore = circle([0, 45], 10);
diameter(wall, 16);
coincident(wall.center(), yAxis());
distance(wall.center(), xAxis(), 45);
coincident(bore.center(), wall.center());
diameter(bore, 10);
});

const mount = extrude(-15);

mirror('xz', mount);

sketch(plate.endFaces(), () => {
const bolt = circle([47, -20], 7);
diameter(bolt, 7);
distance(bolt.center(), yAxis(), 47);
distance(bolt.center(), xAxis(), 20);
mirror(yAxis(), bolt);
});

const holes = cut();

sketch(plate.endFaces(), () => {
const recess = circle([47, -20], 15);
diameter(recess, 15);
distance(recess.center(), yAxis(), 47);
distance(recess.center(), xAxis(), 20);
mirror(yAxis(), recess);
});

const counterbores = cut(4);

repeat('mirror', 'xz', holes, counterbores);

sketch('xz', () => {
const throughBore = circle([0, 45], 10);
diameter(throughBore, 10);
coincident(throughBore.center(), yAxis());
distance(throughBore.center(), xAxis(), 45);
});

cut().symmetric();
Open this model in the 3D viewer

What you practiced​

  • Rectangle with its Rounded and Centered options, and Slot with typed length and radius — one gesture each for a shape that would otherwise be a dozen statements
  • Sketching on a face an operation produced, and reading the Face — Extrude chip that keeps the reference alive through edits
  • Section view, which clips the model at the sketch plane so you can draw inside a solid
  • Dimension against the sketch's own X and Y axes instead of hard-coded coordinates, and the DOF pill as the check that you are done
  • Center Arc with a typed included angle, and closing a profile by snapping a Line onto both arc ends
  • Symmetric extrusions and cuts, which split the distance evenly across the sketch plane
  • Plane at an offset, twice, as scaffolding for geometry that does not sit on an origin plane
  • Project to bring a model edge into a sketch as fixed reference geometry, and Guide to keep reference curves out of the profile
  • Tangent, Concentric and Equal to build a smooth outline whose arcs inherit their size and position from reference geometry
  • The 2D Mirror tool for sketch geometry, the 3D Mirror tool for a whole solid, and Repeat → Mirror for whole features — three different things that all say "the other side"