discontinuedPackage jet_cad_floor_plan has been discontinued and replaced by jet_cad_2d_plan.

cutsOf function

({List<Cut?> cuts, List<(double, double)> merged}) cutsOf(
  1. HostFrame frame,
  2. List<(double, double)> stretches,
  3. List<(double, double)> openings
)

Where each of one host's openings cuts, and the host's merged cuts (spec 08 D8). openings are (centre, width) in ascending handle order; stretches and frame are the host's.

Each opening is placed on its own (placeCut): no opening's placement depends on another's. Then the admission (D8 as amended at execution, revised after Task 5's review and the final review's I1): the fitting openings are admitted in ascending handle order; each one's cut is added to the admitted cuts and merged (mergeCuts), and this opening is made no-fit and left out when that would leave frame

  • no piece longer than wallJoin.linear (a cut spanning the whole span, cuts covering it together, or cuts leaving only slivers): a wall keeps a piece; or
  • a piece that is not valid (isValidPiece: simple, anticlockwise and triangulable, the engine's own region check): an opening clamped against a slightly kinked joint can leave an end piece that is a sliver of the cap's lobe, and storing a piece the engine refuses would refuse the whole edit.

Otherwise it is kept. So a cut wall always generates a piece, every piece it generates is one the engine accepts, the outcome is deterministic, and an opening yields only when admitting it is what would empty the wall or leave it a piece it cannot store.

cuts[i] is null when opening i does not fit, from the start or by that rule; merged is the admitted cuts merged, empty when nothing cuts the host.

Implementation

({List<Cut?> cuts, List<(double, double)> merged}) cutsOf(HostFrame frame,
    List<(double, double)> stretches, List<(double, double)> openings) {
  final cuts = [for (final (c, w) in openings) placeCut(stretches, c, w)];
  final admitted = <(double, double)>[];
  var merged = const <(double, double)>[];
  // A piece's ring is a function of its span on [frame], so a span judged
  // valid once is not triangulated again by a later trial.
  final valid = <(double, double)>{};
  bool ok(_Piece p) {
    if (valid.contains(p.span)) return true;
    if (!isValidPiece(p.ring)) return false;
    valid.add(p.span);
    return true;
  }

  for (var i = 0; i < cuts.length; i++) {
    final c = cuts[i];
    if (c == null) continue;
    final trial = mergeCuts([...admitted, (c.a, c.b)]);
    final pieces = _pieces(frame, trial);
    if (pieces.isEmpty || !pieces.every(ok)) {
      cuts[i] = null;
    } else {
      admitted.add((c.a, c.b));
      merged = trial;
    }
  }
  return (cuts: cuts, merged: merged);
}