Skip to main content

Rib

rib() turns a sketch line (the spine) into a thickened wall that grows until it meets the surrounding solids. It's the standard tool for adding stiffening webs inside shelled parts.

// @screenshot waitForInput
import { sketch, rect, extrude, shell, hLine, rib, fillet } from 'fluidcad/core';

sketch("top", () => {
rect(100, 50).centered();
})

const box = extrude(30)
const s = shell(-4, box.endFaces())
fillet(2, s.internalEdges())

sketch(box.endFaces(), () => {
hLine([-50+4, 0], 30)
});

rib(5).draft(2);

Basic rib

The first argument is the wall thickness. The rib is centered on the spine, extruded perpendicular to the sketch plane, and conformed to fit the surrounding cavity.

Thickness direction

The sign of the thickness controls which way the rib grows from the sketch plane:

  • Positive (e.g. 5): extrudes opposite the sketch normal — typically into the cavity when the sketch sits on top of a face
  • Negative (e.g. -5): extrudes along the sketch normal

Extending the spine

By default the rib's length matches the sketch wire exactly. Call .extend() to push the wall's endpoints outward until they blend into the surrounding walls:

// @screenshot waitForInput
import { sketch, rect, extrude, shell, hLine, rib, fillet } from 'fluidcad/core';

sketch("top", () => {
rect(100, 50).centered();
})

const box = extrude(30)
const s = shell(-4, box.endFaces())
fillet(2, s.internalEdges())

sketch(box.endFaces(), () => {
hLine([-50, 0], 30)
});

rib(5).extend().draft(2);

Rib with .extend()

This is useful when you draw a short spine but want the rib to terminate cleanly against the cavity wall.

Parallel mode

.parallel() flips the extrusion direction from "perpendicular to the sketch plane" to "in-plane, perpendicular to the spine". The sketch line itself becomes one face of the wall.

This is the more natural way to draw ribs that follow a side profile — sketch a slanted line on the front plane, and the rib grows down/sideways to meet the surrounding shell:

// @screenshot waitForInput
import { sketch, move, rect, extrude, shell, rib, fillet, aLine } from 'fluidcad/core';

sketch("top", () => {
rect(100, 50).centered();
})

const box = extrude(30)
const s = shell(-4, box.endFaces())
fillet(2, s.internalEdges())

sketch("front", () => {
move([-50+4, 20])
aLine(-45, 20)
});

rib(5).parallel();

Parallel rib

Combine .parallel() with .extend() to make the rib reach into the cavity walls at both ends:

// @screenshot waitForInput
import { sketch, move, rect, extrude, shell, rib, fillet, aLine } from 'fluidcad/core';

sketch("top", () => {
rect(100).centered();
})

const box = extrude(30)
const s = shell(-4, box.endFaces())
fillet(2, s.internalEdges())

sketch("front", () => {
move([-40, 20])
aLine(-45, 20)
});

rib(5).parallel().extend().draft(-3);

Parallel rib with extend and draft

Draft

Add a taper with .draft(angle). Positive angles narrow the rib toward its tip; negative angles widen it:

rib(5).draft(2) // 2° taper, narrowing
rib(5).draft(-3) // 3° taper, widening

Only the long wall faces taper — the small cap faces at the spine endpoints stay vertical.

Scoping the rib

By default a rib finds all solids in the scene to fuse with. Use .scope() to limit which solids the rib conforms to and fuses with — it works on its own, no need to combine with .new():

rib(5).scope(target) // only consider `target` when conforming + fusing

.new() keeps the rib as a separate solid instead of fusing. Whenever you use .new() you should also pass a .scope(...) so the rib still has a target cavity to conform to:

// @screenshot waitForInput
import { sketch, move, rect, extrude, shell, rib, fillet, aLine, circle } from 'fluidcad/core';

sketch("top", () => {
rect(100, 50).centered();
})

const box = extrude(30)
const sh = shell(-4, box.endFaces())
fillet(2, sh.internalEdges())

sketch("top", () => {
circle(30)
});

const s = extrude(50).draft(-5)

sketch("front", () => {
move([-40, 20])
aLine(45, 20)
});

rib(5).parallel().extend().new().scope(s).draft(-4);

Rib scoped to a different solid

Here the rib is attached to a tapered cylinder rather than the outer box — the scope tells the rib which walls to conform to.

Curved enclosures

The rib conforms to whatever cavity surrounds it, so it works inside curved or circular shells just as well as rectangular ones:

// @screenshot waitForInput
import { sketch, move, extrude, shell, rib, fillet, aLine, circle } from 'fluidcad/core';

sketch("top", () => {
circle(80)
})

const box = extrude(30)
const sh = shell(-4, box.endFaces())
const s = fillet(2, sh.internalEdges())

sketch("front", () => {
move([-40, 20])
aLine(-45, 20)
});

rib(5).parallel().extend().draft(3).new().scope(s);

Rib inside a circular cavity

Patterning ribs

Capture the rib in a variable and pass it to repeat() to pattern it around an axis:

// @screenshot waitForInput
import { sketch, move, rect, extrude, shell, rib, fillet, aLine, circle, repeat } from 'fluidcad/core';

sketch("top", () => {
rect(100).centered();
})

const box = extrude(30)
const sh = shell(-4, box.endFaces())
fillet(2, sh.internalEdges())

sketch("top", () => {
circle(30)
});

const s = extrude(50).draft(-5)

sketch("front", () => {
move([-40, 20])
aLine(45, 20)
});

const r = rib(5).parallel().extend().new().scope(s).draft(-4);

repeat("circular", "z", {
count: 6,
angle: 360
}, r)

Circular pattern of ribs

The sketch plane can be tilted too — pair a rotated plane() with a circular pattern to fan ribs out at an angle:

// @screenshot waitForInput
import { sketch, move, rect, extrude, shell, rib, fillet, aLine, repeat, plane } from 'fluidcad/core';

sketch("top", () => {
rect(80).centered();
})

const box = extrude(30)
const s = shell(-4, box.endFaces())
fillet(2, s.internalEdges())

sketch("top", () => {
rect(30).centered();
});

extrude(50)

const p = plane("front", { rotateY: 45 })

sketch(p, () => {
move([-40, 18])
aLine(45, 20)
});

const r = rib(6).parallel().extend().draft(-1);

repeat("circular", "z", {
count: 4,
angle: 360
}, r)

Pattern of ribs on a rotated plane

Accessing geometry

const r = rib(5).extend()

r.startFaces() // profile face at the sketch plane
r.endFaces() // face where the rib meets the cavity wall
r.sideFaces() // long wall faces of the rib
r.capFaces() // small cap faces at the spine endpoints
r.startEdges() // edges on the start faces
r.endEdges() // edges on the end faces
r.sideEdges() // edges along the side walls
r.capEdges() // edges on the cap faces

Fusion scope

rib(5).add() // fuse with all touching solids (default)
rib(5).scope(target) // limit conform + fuse to `target`
rib(5).new().scope(target) // keep as separate solid, conform to `target`