Neotkotour

§1b · §1f — Colour

ColorStitch

One of the pass kinds in a Sandwich. It does exactly one job: for every fill line on the surface, it decides which filament prints that line. Everything you can build with it comes out of that one decision.

  • no gate
  • print-verified
  • since 2.3

Where ColorStitch Painter›Pro›a pass set toColorStitch›ADV…

Up to 2.4.5 the same dialog also opened from the Sandwich editor's Edit gradient… button. The editor is gone in 2.4.6, so the Painter is the only way in now.

What breaks without it

A solid fill gives you one colour per surface. If you want a blend you have three bad options in a stock slicer: print two regions and live with the seam, buy a filament that is already the colour you wanted, or give up. None of them let you say "60% of this surface in blue, the rest in yellow, mixed finely enough that my eye stops resolving it".

Stock

One tool owns the whole top surface. Colour boundaries are geometry: you draw them, the slicer obeys them, and every one of them is visible.

With ColorStitch

Every fill line gets its own tool. At 0.42 mm line width a 60 mm surface has around 170 of them, which is plenty for the eye to integrate a ratio instead of counting stripes.

It is worth being clear about what this is not doing. Nothing gets mixed. There is no gradient in the material. There are just lines of one filament sitting next to lines of another, in a sequence chosen so that any local window has roughly the ratio you asked for. The blending happens in your eye, and it is the same trick a newspaper photograph plays.

The setting that decides whether it works

The blend can only ever be as fine as the fill lines it is built from, so the top surface line width is the lever. Not the object-wide one: the top surface has its own. On a 0.4 mm nozzle the default lands around 0.42 mm and you can still count the lines on a finished part; coming down to about 0.30 mm is where two colours stop reading as stripes and the surface still prints cleanly. Lower does get finer, and the overlap between neighbouring lines stops being controllable, which costs you the finish. Reported from real prints rather than calculated.

Pattern styles

Pattern style picks where the sequence comes from. Only one is active at a time, on purpose: a hand-typed string, a MixedFilament recipe, a weave, a blend and a set of stripes cannot all drive the same pass. A line under the selector always tells you what the active style is doing, and it turns amber when that style overrides everything else.

StyleWhat it produces
Custom patternClick filament buttons to build a digit string by hand; the slicer loops it across the lines, so line 1 takes the first digit and it wraps. For exact repeating stripes you design yourself. Clear, ⌫ Undo digit and Invert live here.
MixedFilament recipePick one of your MixedFilament combinations (say F1+F2 50/50) and it becomes the whole pattern. Only shown when MixedFilament virtual digits are on. Switching to another style clears it.
Textile weaveReady-made weave structures, generated for you. Below.
Smooth blend, 2 coloursTwo filaments spread across the surface at a percentage split, dithered so the transition looks continuous. The one most people want.
Smooth blend, 3 coloursThree filaments at configurable percentages, with the middle colour concentrating around the centre.
Stripes, band sizes in mmBands of a set width in millimetres, so many of Colour 1, so many of Colour 2, repeating across the surface. New in 2.4.6; the old version counted lines, and that was the problem.
The redesigned ADV dialog: a Pattern style selector at the top, and below it only the controls belonging to the style you picked
The ADV… dialog. Pick a style and you only see that style's controls, which is why the panel stopped being a wall of fields that mostly did nothing.

Pattern lab

Every style, with the real sequence builder underneath. The strip is what the slicer will emit line by line; the square is that same sequence laid down at the pass angle; the swatch is what the whole thing resolves to once you step back from the part.

demo Pattern lab try Slow start against Even at 50%
real algorithm  · build_dithered_tools_2color, build_dithered_tools_3color, build_custom_bands and colormix_easing_apply, ported from SurfaceColorMix.cpp. The strip is the sequence, not a picture of one. Stripes turn your millimetres into lines at the real line spacing, which on a plain surface is what the engine's position sampling gives.
More simulators in the Playground →

Why the dither looks the way it does

The two-colour blend is a Bresenham line algorithm with one integer accumulator. It walks the sequence keeping a running count of how many B lines it has emitted, compares that against how many it should have emitted by now, and picks B when it is behind. The result has a property worth knowing: in any window of W lines, the fraction of B lands within 1/W of your target ratio. Locally correct everywhere, globally exact, and identical on every slice because there is no randomness in it anywhere.

The three-colour version runs three of those trackers at once and gives each line to whichever tool is furthest behind its own expected share. The share comes from a hat function centred on each colour's anchor, and Color overlap is the width of that hat. At overlap 0 the hats are triangles that barely touch, so you get three clean bands. At overlap 1 every colour has a non-zero chance everywhere, and the three fade through each other. The global percentages hold either way; only the local distribution changes shape.

It does not print line, change, line, change

This is the thing people get wrong about ColorStitch, and it is worth being clear about, because the wrong version makes the feature sound far more expensive than it is.

The sequence says which tool owns each fill line. It does not say what order the lines are printed in. Before emitting anything the engine groups the lines by unique tool and prints one block per tool, in first-occurrence order, so the first tool in the pattern goes down first. All of T2's lines, then all of T4's lines.

So a 50/50 dither across 170 fill lines costs one toolchange, not 169. The cost of a ColorStitch pass is the number of tools it uses, and nothing else. Two colours is one change, three is two. How finely they interleave across the surface is free.

Where this lives, if you want to check

SurfaceColorMix.cpp, in the unique-tool block merge: "Then group by UNIQUE tool_id; unique_tool_order = first-occurrence order so the first tool in the pattern prints first." The same grouping is what keeps the slice, the fill and the wipe-tower planner agreeing on the tool list.

The blend controls

ControlWhat it does
How much Color 1 / Color 2The percentage split. In the 3-colour blend, Color 3 automatically takes whatever is left.
Color overlapSoft to hard zones. How far each colour bleeds into its neighbour's territory in a 3-colour blend.
Transition shapeEven, Slow start (what you get when you first pick a blend style), Slow end, S-curve, Custom shape with a γ value, or Hard step.
Gradient scaleNew in 2.4.6. Fit to surface (real position) runs the gradient once across each surface, from where its lines really are, so a hole cannot shift it. Repeat every… mm repeats it at a fixed size, the same on every object whatever its line width.
Skip tiny areasSurfaces with fewer than N fill lines fall back to Color 1 alone. A four-line surface cannot express a ratio, and trying costs you toolchanges for nothing.
Invert direction ⇆Reverses the per-line sequence. Blend and stripe styles have this; Custom and Weave have their own Invert button instead.
Smooth blend with three colours at 32% and 37%, the third auto-filling the remaining 31%, 31% overlap and an Even transition, with the line strip and a square sample drawn at the pass angle
A three-colour blend at 32% / 37%, the third colour taking the remaining 31%, with 31% overlap and an Even transition. Both previews are live: the strip and the square sample drawn at the pass angle.

Textile weaves

Weave structures borrowed from real fabric construction, generated as pattern strings from two colours you pick.

WeavePatternLook
Plain (tafetán)1212Balanced 50/50, neither colour dominating.
Twill 2/2 (sarga)1122Diagonal weave. The real per-layer diagonal offset is not implemented, so today it prints as a static repeat. The dialog says so.
Twill 3/11112One colour dominates, the other marks a diagonal. Same offset caveat.
Satin 5 (satén)11112One colour covers about 80%; the other lands as scattered accent points.
Houndstooth1122 top
2211 penu
The classic pattern only appears where Top and Penultimate cross at 90°. The dialog writes the correct half for the surface you are editing and shows you the string for the other one.

Pick Colour A and Colour B to substitute into the weave. Set both to the same filament and Colour B gets nudged to the next one, because a one-colour weave is just a solid fill. Edit as custom pattern… copies the generated string into the Custom style so you can pull it apart by hand.

Print options

ControlWhat it does
Infill angle override-1 is auto. Scroll the mouse wheel over the pass preview bar to rotate it live and the bar's stripes turn with it. A fixed angle of 0 or more is honoured exactly in the G-code: the per-layer fill rotation gets locked out for that pass, so the print keeps the angle you set. Leave it on auto and the slicer alternates per layer, which gives a more uniform finish but means no static preview can match the print.
Gradient repetitions1 is a single pass across the surface; higher values repeat the pattern.
ColorStitch min. line lengthFill lines shorter than this (mm) keep the surrounding colour instead of getting their own tool. Default 0, meaning skip nothing. Raise it when a surface has a lot of small slivers and you would rather not pay a toolchange for a 2 mm segment.
Set your top surface pattern first

ColorStitch works correctly on Monotonic Line, and that is the setting to use: Quality → Top surface pattern → Monotonic Line. The slicer pre-splits the surface into individual straight paths before it assigns tools, and Monotonic Line is the pattern that hands them over one at a time. Plain Monotonic and Rectilinear look fine on a simple convex shape and mis-sequence on anything complicated.

Since 2.4.0 it also works out of the box on Monotonic, Rectilinear and Hilbert Curve, and the old "ColorStitch on Monotonic (continuous)" switch is gone because that behaviour is always on now. Concentric, Octogram and Archimedean work too, with a caveat: their line distribution is not uniform, so the dither is less predictable there. Getting a clean dither on Hilbert Curve in particular takes tuning and does not always come out.

Sizes, not counts

Up to 2.4.5 there was a setting here called Line distribution mode, with four choices for how a pattern got dealt out over the lines of a surface. It is gone in 2.4.6, because the thing it was working around is gone.

The old engine counted lines. A stripe was "so many lines of each colour", and a gradient was spread over the lines in some order. A line count is not a size, though, and three things nobody could see from the settings kept changing it: the line width can be different on every object on the plate, the lines sit a little closer than their width so neighbours overlap, and a hole or a bit of embossed text cuts a line in two, so the count grows while the surface stays the same.

Now the design lives in millimetres on the surface, measured from the object, and every line asks what colour the spot under it is. Nothing gets counted, so all three stop mattering at once.

demo One stripe setting, four objects set a band, then switch to counting lines
real algorithm  · the mm mode is compute_slot_per_line_band_mm: each line's position across the surface, measured from the object, compared with the band edges in mm by fmod over one cycle. The line count mode is the old way, bands of so many lines dealt out in print order, where a line cut by the hole counts twice. Line spacing is width − height·(1 − π/4), as in Flow.cpp. The part shapes are drawings.

Measured on a real plate before the change, one stripe setting on four keychains: the band came out between 6.79 and 7.20 mm, a different size on each one. After it, 8 mm typed once printed between 7.92 and 8.06 mm on all four. A band can only end between two lines, so it lands within one line of what you asked for, and that error does not pile up across the surface.

WhatHow it finds its lines, since 2.4.6
StripesSet in millimetres: Stripes, band sizes in mm (real size) in the style list. The dialog shows how many lines each band comes to at your line width, and how long one full cycle is.
GradientsGradient scale. Fit to surface runs the gradient once across each surface from where the lines really are; Repeat every… mm repeats it at a fixed size.
PatternsCustom pattern, MixedFilament recipe and Textile weave repeat at their natural size, one digit per line, instead of being stretched over the surface once.
HolesThe two pieces of a line cut by a hole sit at the same place across the surface, so they get the same colour.
Top and penultimateBoth measure from the same point on the object, so with the same angle they line up line by line.
Same walls on both, or they will not line up

For the top and the layer below it to line up, give both the same number of walls: turn off Only one wall on top surfaces, or match them another way. The slicer spaces the lines of each solid region so a whole number of them fits, and a different number of walls gives a different region, so the lines land in different places.

A project from an older version is converted when it opens, and a notice says how many gradients and stripe recipes changed. Gradients keep their shape. Stripes that were set in lines become millimetres, worked out from the default top surface line width, so they can come out slightly different from what the old version printed. 2.4.5 still has the old system.

What it looks like off the bed

This pair is the best argument for why the G-code view alone will mislead you, and it is the reason RealColor exists.

G-code preview of three rows of test tiles, each row sweeping the mix ratio of one filament against a dark blue, dithered along a Hilbert Curve infill. In G-code view the dither reads as scattered fragments
G-code view. Three rows of tiles, each sweeping one filament against a dark blue, dithered along a Hilbert Curve infill. On screen it reads as noise.
The same tiles printed: what looked like noise in the G-code view resolves into continuous tone
The same tiles, printed. The noise resolves into continuous tone, because your eye integrates the dither instead of resolving the individual lines.

The catch

  • A toolchange per tool, per pass. Cheaper than people expect, and the reason is below. What costs you is how many tools a pass uses, not how finely they interleave.
  • Small surfaces cannot hold a ratio. Twelve fill lines can express 1/12 steps and nothing finer. The dither is doing its job; there is just nothing to work with. Skip tiny areas exists for exactly this.
  • Auto angle and static previews disagree. On auto the fill direction alternates every layer, so the on-model preview and the print will not line up. The angle then reads auto in violet in the Painter's Pro department, to remind you. Set a fixed angle if you care about orientation.
  • Twills are not diagonal yet. Twill 2/2 and Twill 3/1 currently print as a static repeat, because the per-layer offset that makes a twill a twill is not implemented.
  • The painted preview lags the slicer. Since 2.4.6 the slicer places everything by position; the preview on the painted model has not caught up yet, so on a surface with holes, or with stripes in mm, a band can start in a slightly different place. Check the G-code in RealColor when it has to be exact.
  • Concentric and friends are a gamble. They work, the line distribution is just not uniform, so what you get is harder to predict than on Monotonic Line.