Skip to main content

Color

color() paints faces or whole solids. Colours are part of the model: they survive later features, follow the geometry through fillets and booleans, and are written into STEP exports.

Colour has no dialog — the statement is written in the editor. Select the faces first (a select() with a filter, or a feature accessor such as e.endFaces()), then call color() with a CSS colour: a name ("red", "steelblue"), a hex value ("#e74c3c") or an rgb(...) string.

Colored faces

The code behind it
painted.part.js
import { sketch, extrude, color, select } from 'fluidcad/core';
import { line } from 'fluidcad/core';
import { face } from 'fluidcad/filters';
import { coincident, distance, fix, horizontal, vertical } from "fluidcad/constraints";

sketch("xy", () => {
const sg1 = line([-50, -30], [50, -30]);
const sg2 = line([50, -30], [50, 30]);
const sg3 = line([50, 30], [-50, 30]);
const sg4 = line([-50, 30], [-50, -30]);
coincident(sg1.end(), sg2.start());
coincident(sg2.end(), sg3.start());
coincident(sg3.end(), sg4.start());
coincident(sg4.end(), sg1.start());
horizontal(sg1);
vertical(sg2);
horizontal(sg3);
vertical(sg4);
fix(sg1.start(), [-50, -30]);
distance(sg1.start(), sg1.end(), 100);
distance(sg2.start(), sg2.end(), 60);
})

// A 100 × 60 × 30 block.
const e = extrude(30)

// Paint the last selection: select() finds every circular face (there are
// none on a plain block, so this paints nothing here) …
select(face().circle())
color("red")

// … and paint a face accessor directly: the extrude's top face turns orange.
color("orange", e.endFaces())

Colouring a selection

color() with one argument paints the last selection. With no selection at all it paints every face in the current context:

select(face().parallelTo("xy"))
color("#3498db") // every horizontal face

select(face().cylinder())
color("silver") // every cylindrical face

Colouring a whole object

Pass a scene object instead of faces and every face of its solids is painted — the quickest way to give a part a base colour, which single faces can then override:

const body = extrude(30)
color("steelblue", body) // base colour for every face

select(face().onPlane("xy", 30))
color("tomato") // repaint just the top face

Colours survive later features

Paint a face, then keep modelling: fillet, chamfer, fuse, cut and the rest carry colours forward onto the faces they produce.

Color preserved through fillet

The code behind it

The top face is painted before the fillet. After it, the trimmed top face is still orange, and so is the fillet's arc face — colours transfer onto modified faces and bleed onto the new geometry next to them.

fillet-color.part.js
import { sketch, extrude, color, select, fillet } from 'fluidcad/core';
import { circle } from 'fluidcad/core';
import { face } from 'fluidcad/filters';

sketch("xy", () => {
circle([0, 0], 40);
})

const e = extrude(50)

select(face().onPlane("xy", 50))
color("orange")

// Coloring before the fillet still works — the orange survives the
// modification, and the new arc face inherits the color from its neighbor.
fillet(5, e.endEdges())

When a coloured face is split — by a cut across it, say — every surviving piece keeps the colour. When a coloured face is removed entirely, its colour goes with it.

Colour bleeding

New geometry fused into a coloured shape inherits the colour of the faces around it:

Color bleeding onto fused geometry

The code behind it
bleed.part.js
import { sketch, extrude, color, select } from 'fluidcad/core';
import { circle } from 'fluidcad/core';
import { face } from 'fluidcad/filters';

sketch("xy", () => {
circle([0, 0], 80)
})
extrude(50)

select(face().cylinder())
color("red")

// A second extrude fuses into the colored solid. Faces that came from the
// new extrude inherit the red color via "color bleeding" — colors spread
// across edges to adjacent uncolored new faces.
sketch("xy", () => {
circle([50, 0], 40)
})
extrude(25)

Bleeding only reaches faces that came from new geometry. Faces that already existed and were left uncoloured stay uncoloured. The same rule covers fillet arcs, chamfer surfaces and the section faces of a cut.

Explicit fuse() color rule

In a fuse the first input is dominant:

  • if the first input carries colours, they propagate to the result and bleed onto the other inputs;
  • if the first input has no colours, the result is uncoloured even when other inputs were painted.

fuse() first input dominates

The code behind it
fuse-first.part.js
import { sketch, extrude, color, select, fuse } from 'fluidcad/core';
import { circle } from 'fluidcad/core';
import { face } from 'fluidcad/filters';

sketch("xy", () => {
circle([0, 0], 80)
})
extrude(50)

select(face().cylinder())
color("red")

sketch("xy", () => {
circle([50, 0], 40)
})
extrude(25).new()

// Explicit fuse(): the FIRST input wins. Its color (red) propagates to the
// fused result. If the first input had no color, the result would stay
// uncolored even when later inputs are colored.
fuse()

With an uncoloured first input nothing propagates — painting later inputs has no effect on the result:

fuse() first input uncolored — result stays uncolored

The code behind it
fuse-uncolored.part.js
import { sketch, extrude, color, select, fuse } from 'fluidcad/core';
import { circle } from 'fluidcad/core';
import { face } from 'fluidcad/filters';

sketch("xy", () => {
circle([0, 0], 80)
})
extrude(50).new()

sketch("xy", () => {
circle([50, 0], 40)
})
extrude(25).new()

// Color the SECOND solid only.
select(face().onPlane("xy", 25))
color("red")

// First input has no color → the fused result stays uncolored, even though
// the second input is red.
fuse()

So the order of the Boolean dialog's Solids chips — the argument order — chooses whose colouring wins: put the solid whose colours you want to keep first.

Export

Colours go into STEP files (the export dialog's colour toggle and the CLI's --no-colors flag turn that off) and are shown for imported STEP files that carry them. See Export.