← back to pin list

2b. Bridges for floating islands

kerfmaster pin list · Big capabilities

intentmixedd4What we want to build. Never claimed the present, so it cannot be stale — and must never be read as a description of the code.

Content last changed 2026-08-09 — computed from the item itself, not typed.

Contract — Bridges stage

This contract describes a stage we intend to build — it is NOT a description of the code.

takes topologymaterial-table

makes bridged-part

fails if An island left with no hold; a bridge on a visible feature; a width taken from a seeded guess and presented as a shop number.

Contract last changed 2026-08-06 — computed, not typed. Dated separately from the text above, so neither date can speak for the other.

1 open question blocks this pin

⚠ Known defects

This item's subject has a known defect in the code. Recorded and deliberately NOT fixed — recording a defect is not a licence to fix it. Source: cadmaster/defects.jsoncadmaster/KNOWN_DEFECTS.md, not this page — the text below is generated from the register so the two can never disagree.

Terminology fixed 2026-07-28 (Jordan). This stage is about bridges — connections that stay as part of the design and hold islands (text, art) in. It is NOT about tabs. A tab is the opposite: a connection made to be broken off easily later in manufacturing, applied at nest time to hold parts in the sheet — that is now item 3a. The spec previously used the two words as synonyms, which was wrong.

The problem. When a cut has an interior island — a piece of kept metal fully surrounded by cut-away area (the MVT play triangle inside its ring; the center of an ‘O’ or ‘A’; any stencil counter) — cutting the surrounding hole frees the island and it drops out. Bridges are the connections that hold the island to the surrounding metal so it stays in place — permanently, as part of the finished design. This is a real pipeline stage — placement below.

⚑ Needs Jordan’s shop knowledge to turn into real numbers — flagged below. (Aristide 2026-07-24: fold the stage into the pipeline now; the shop numbers are just the table values that fill the stage, they don’t block wiring it in.)

Build state, 2026-08-03 — this item had no status line at all, unlike 2a / 2c / 3b, so it read as an entirely unbuilt spec. About half of it ships. Built: the neck finder (bridges.find_necks), the island / bridge test (bridges.islands — raster the material, cut every candidate neck, label components once), width bands (bridges.suggest), the single decision path (bridges.review_marks), the CM_BRIDGE_OK / CM_BRIDGE_ADJUST / CM_SPACING_FLAG / CM_NOTES review layers, the review DXF and the mark-up-only DXF, and the board's bridge section. Not built: bridge GENERATION (sections 4 and 5 below), the angle optimiser (3a / 3b), a BRIDGES output layer, and post-time bridge gaps. bridges.py:21 says it plainly: "Nothing here edits geometry: it measures and reports." emit.py never imports bridges.

0. Where it sits in the pipeline

Full order: in → unit-detect → heal → QC topology (incl. island / connectivity detection) → BRIDGE GENERATION → lead-in/out + cut-order → nest → post.

1. Island detection (automatic)

Built, in bridges.islands(): raster the material with even-odd parity (not winding — a different rule, and the right one here) at ~20 thou/px, cut every candidate neck in that raster, then label connected components once. Anything that separates only because of those cuts was being held by them, so it is a real island and those necks are its bridges. Anything not joined to the main body even before the cuts is an island the file does not hold — an unbridged island. A plain donut hole doesn't flag; a floating positive shape does.

2. Bridge width — base table × modifiers, calibrated by real test cuts

Do NOT fake a pure-physics number. Strength ≈ width × thickness × material-strength; the load is the island’s size and leverage.

3. Bridge placement — structural, but respect the silhouette

3a. Consistent bridge ANGLE across the whole piece — Jordan's rule

Bridge placement is a document-level decision, not a per-island one. Jordan: find a line or angle from the artwork and use it for the bridges throughout the piece. Example: a text run mixing round and straight letterforms — place the bridges on the ‘Q’ island at 30°, and every other bridged letter (‘P’, ‘O’, ‘A’ …) gets its bridges at that same angle.

Why it matters: bridges are permanent and visible, so the piece must read as intentional. A set of individually-optimal bridges at scattered angles looks like damage; the same angle repeated looks like design. Consistency beats per-island optimum.

⚑ This supersedes pure per-island optimisation as the primary rule. Section 3’s structural guidance (shortest span, near centre of mass, never on a defining corner/tip) still applies — but as the tie-breaker within the chosen global angle, not as a free choice per island.

Algorithm sketch: (1) derive a dominant orientation from the artwork (text baseline, dominant straight edges) or take the operator’s angle; (2) for each island, cast the bridge along that angle and take the crossing that best satisfies the structural rules; (3) where the global angle gives a bad result (span far too long, or it lands on a defining tip), fall back by a defined rule rather than silently picking a different angle.

⚑ Answered — see 3b below for the decided angle rule.

3b. Angle rule — decided

First, a definition the rule needs. "Bridge at 30°" is ambiguous: it can mean (a) the bearing — where the bridge sits around the island, measured from the island’s centre, or (b) the crossing direction — the heading of the bridge span itself. We build (a): the angle is a bearing from the island centre, because that is what makes ‘Q’ and ‘P’ agree visually. The crossing direction is then whatever is perpendicular to the stroke at that point — always the shortest, strongest, least visible crossing.

Where the default angle comes from (Jordan: we decide per file, operator adjusts)

Auto-derive one angle per file, show it to the operator, let them override:

Symmetric shapes: same angle — CONFIRMED

Same bearing everywhere. No mirroring (Jordan, confirmed 2026-07-28). Parallel bridges give the piece one consistent "grain", which is what makes it read as intentional. Where an island needs two bridges, place them 180° apart on the same bearing — balanced and still parallel.

One angle per file, chosen by optimising across ALL islands — CONFIRMED

Jordan: "Per file, calculate the best angle. A human will ask for adjustments if necessary." This replaces the per-island fallback cascade previously proposed here, and it is a better formulation: rather than derive an angle from the dominant axis and then patch the islands it fails on, search the angle space and score each candidate against every island in the file at once, then take the winner.

Operator loop: report the chosen angle and the islands that scored worst under it, so a human can see where to look and adjust. Surfacing the weak spots is not the same as silently deviating — we still cut one consistent angle unless a human says otherwise.

When we touch bridges, and when we do not (Jordan, 2026-07-28)

The width table lives in Preferences (Jordan, 2026-07-28)

The numbers ship as defaults, not as constants. They belong in the operator Preferences panel, editable per laser and per location — what one shop has dialled in will not match another's machines. Same for the tab table (item 3a). Starting point offered and accepted as a starting point only, for .060 stainless: small text counters 0.080–0.100, medium islands 0.100–0.125, large islands 0.125–0.150, hard floor = material thickness.

src — Jordan 2026-07-28 (angle is per-file, we pick the default, operator adjusts; 30° was only an example). Same-angle/no-mirroring and one-optimised-angle-per-file CONFIRMED by Jordan 2026-07-28. The bearing-vs-crossing definition is Claude’s and still needs Jordan’s nod.

4. Workflow — auto-propose, human confirms

Software auto-detects islands and proposes bridges (position + width from the table), draws them on the comparison board like QC flags, and lets the operator nudge / resize / add / delete before posting. At post time a bridge is simply a gap left in the cut contour — the beam skips that span, so the metal there is never severed.

5. We GENERATE bridges — decided

Settled (Jordan 2026-07-28): the software generates the bridges; it does not merely detect missing ones. If the customer’s art has a floating island with no bridge, we create one. So bridge-generation is a real feature to build, not just a QC check.

⚑ Open: exact layer name (BRIDGES?), and what the client actually receives for review — a marked-up DXF, a PDF/PNG proof, or a link to our comparison board?

⚑ Needed from Jordan (shop numbers)

src — raised by Aristide 2026-07-24 (MVT-ICON play-triangle island); terminology, the consistent-angle rule, the generate-and-client-reviews decision, the leave-client-bridges-alone rule and the Preferences-owned width table from Jordan, 2026-07-28.

Related, 2026-08-06: a bridge is the deliberate version of a hold. Item 2d covers the accidental version — metal held together only because the composition overlaps it, which disappears when plates are split. Both are measured the same way, by weld chord; only one was designed.

OPEN CONFLICT (recorded 2026-08-09, needs Jordan/Aristide): the written rule for a two-bridge island — 180° apart on the same bearing, never on corners — disagrees with Aristide’s own worked answer for a compact rounded island (the MVT option-A file, 2026-08-06): the triangle there is held by THREE bridges ~120° apart, each ~0.22" wide, each sitting just OFF a triangle corner — short radial spans the written rule would forbid. For compact rounded islands the rulebook and the owner’s worked answer cannot both be the expected outcome. Until ruled: offer both layouts and say which rule each follows; do not silently pick.