Shape functions
Most of replicad is built around shape classes — Solid, Face, Edge and
friends. These wrap an OpenCascade topological shape and give you a chaining
API on top of it:
const box = makeBaseBox(10, 10, 10)
.fillet(1)
.shell(1, (f) => f.inPlane("XZ"));
Underneath, each of these methods calls a plain function that takes a shape and returns a new one. These functions are available on their own, from a separate entry point:
import { fuseShapes, filletShape, shellShape } from "replicad/shape-functions";
Most of them live only there: the main replicad entry point exports the
classes and the model building blocks, not the operations behind them. A few
names it has always exported — cast among them, along with the Curve and
Surface classes — stay available from both.
What they are
A shape function is stateless. It takes an OpenCascade topological shape (a
TopoDS_Shape), or anything wrapping one — a replicad Shape works fine — and
returns a raw TopoDS_Shape:
import { makeBaseBox, cast } from "replicad";
import { cutShape } from "replicad/shape-functions";
const base = makeBaseBox(10, 10, 10);
const tool = makeBaseBox(4, 4, 20);
// cutShape returns a TopoDS_Shape, not a replicad Solid
const cut = cutShape(base, tool);
Because they return raw shapes, you use cast — which stays on the main entry
point, since it builds the classes — to bring the result back into the class
hierarchy:
const solid = cast(cut);
solid.blobSTL();
The entry point covers the boolean operations (fuseShapes, cutShape,
intersectShapes), the modifications (filletShape, chamferShape,
shellShape, draftShape), meshing (mesh, meshEdges, triangulateFace),
export (exportShapeSTEP, exportShapeSTL, serializeShape), the geometry
helpers (faceNormalAt, faceCenter, curveTangentAt, …) and the topology
helpers.
The full list is in the shape functions API reference.
When to use them
For most models you do not need them — the class API is more pleasant to read and it manages memory for you.
They become useful when you are:
-
meshing or exporting a shape you did not build with replicad.
mesh,meshEdges,exportShapeSTEPandexportShapeSTLall take a raw shape, so you can display or write one out without building a wrapper for it:import { exportShapeSTEP } from "replicad/shape-functions";
const blob = exportShapeSTEP(someTopoDSShape); -
integrating with other OpenCascade code, where you already hold
TopoDS_Shapevalues and wrapping each one only to unwrap it again is noise. -
building your own abstraction on top of replicad.
makeCasterlets you map the eight topology kinds onto your own classes, the same way replicad builds its owncast.
Keep in mind that some class methods do more than call the matching function.
The transformations (translate, rotate, mirror, scale), as well as
outerWire and innerWires, delete the shape they are called on; the raw
functions never delete anything, so their inputs are yours to manage.
In the studio and the CLI
Both the studio and the CLI expose the shape functions, so you do not need to install anything to use them.
In a module-style model you can import them as you would in a normal project — the import is resolved by the runtime:
import { makeBaseBox, cast } from "replicad";
import { cutShape } from "replicad/shape-functions";
export function main() {
return cast(cutShape(makeBaseBox(10, 10, 10), makeBaseBox(4, 4, 20)));
}
In a function-style model, where you do not have imports, they are available on
the replicadShapeFns global, next to the replicad and oc globals:
const main = ({ makeBaseBox, cast }) => {
const base = makeBaseBox(10, 10, 10);
const tool = makeBaseBox(4, 4, 20);
return cast(replicadShapeFns.cutShape(base, tool));
};
In your own application
If you embed the replicad evaluator, pass the shape functions alongside replicad when you create it:
import * as replicad from "replicad";
import * as replicadShapeFns from "replicad/shape-functions";
import { createEvaluator } from "replicad-evaluator";
const evaluator = createEvaluator({
replicad,
shapeFns: replicadShapeFns,
oc,
});
Without shapeFns, models importing replicad/shape-functions will fail at
evaluation — everything else keeps working.
Both entry points share the same OpenCascade instance, so a single setOC call
is enough for both.