Open core: don’t reinvent the wheel — build your fenestration software on ours.

Skip to main content

Creating an operation does not by itself put it on a part. During BOM build, for each
profile line the engine asks, for every candidate operation, “does this apply to this
profile?”
That test is isMatch, and an operation is attached only when
all of these pass:

Check Set by Passes when…
Level Rule 158 The profile’s level (frame / sash / mullion / coupler / glazing bead / sub) matches the operation’s level condition. Blank = any.
Side Rule 153 The profile sits on the operation’s target side (top / bottom / left / right).
Reference 1 Rule 154 Blank, or the part’s Reference 1 equals the value (case-insensitive).
Reference 2 Rule 155 Blank, or the part’s Reference 2 equals the value (case-insensitive).
Leaf number (multi-leaf parts) The specific leaf of a multi-leaf part matches the operation’s target.

For mullion, coupler and grid profiles there are extra geometric checks — orientation,
whether the operation’s centre falls within the profile’s span, and the mullion position
condition — so that an operation lands only on the bar it actually belongs to.

#1 cause of a “missing” notch: the part Reference gate
If rule 154 sets Reference 1 = "SL500", the operation attaches only to
a part whose Reference 1 is exactly SL500. A co-located profile with a
different or empty Reference gets no notch — and this looks like a bug but is rules/data
configuration. Fix it by setting the part’s Reference to match, or by clearing the Reference
condition on the rule. (Note: affect design does not gate notch matching — that
correlation is a red herring.)
Meeting Rail / Astragal → Frame Top & Bottom: two different “levels”, easy to confuse
A Meeting Rail or Astragal notch that must land on the outer frame’s Top/Bottom profile
(not the divider’s own profile) is authored at the divider’s own assembly level
(rules.level — 34 for Meeting Rail, 39 for Astragal) but with rule 158‘s
level condition set to 1 (Frame) — not to the divider’s own level. These are
two independent numbers that happen to share the word “level”:

  • rules.level (→ PartsNotching.levelID at runtime, via
    rules.parent_level — see below) says which kind of divider this rule belongs
    to
    (33-39 = coupler/mullion/interlock/meeting-rail/astragal family).
  • Rule 158 / PartsNotching.ifLevel says which profile the finished
    operation should attach to
    (1=frame, 2=sash, 3=mullion, …).

For this specific “reflect onto the frame” pattern, the attach gate does not match a plain
frame profile’s own level (3) against the divider’s assembly level (34/39) — a frame-level
profile has no level-34/39 identity to match. Instead it confirms the notch’s divider actually
belongs to that physical frame (same shape, walked up from the notch’s parent), gated on
PartsNotching.levelID falling in the 33-39 divider-family range at all. That field is
populated at runtime from the rule’s parent_level database column (not
level) — the two must be authored equal (e.g. both 34, or both 39) for a
Meeting-Rail/Astragal frame notch. If parent_level is left at a stale/default value
while level is correctly set, the notch is created and looks complete in every other
respect, but silently never attaches to the frame — no error, just an empty Machining Dialog.
Once authored correctly, no code changes are needed: this path is pre-existing, shared by Meeting
Rail and Astragal identically.

Checking the wrong BOM row
In a design where the divider separates two operable sashes (e.g. a French/Tilt-Turn pair with an
Astragal between them), the sash’s own top rail (profile level 5, e.g. stockcode family 3V…)
is a different profile from the outer main frame’s Top1 rail (profile level 3, e.g. stockcode
family 3M1…/mainframe). A Frame-level (ifLevel=1) notch only ever attaches
to the latter — check the BOM row’s actual stockcode before concluding a notch is missing.

What ends up on the BOM line

Once attached, each operation is formatted into the BOM notch text in metric, imperial-decimal
and imperial-fraction forms, carrying the machine id, distance, pattern, tool, sequence,
lead/trail angles, feed direction and the source series-rule id. These strings are
what the cut list and shop reports display.