Table of Contents

Class RapidCutMonitor

Namespace
Hi.MachiningProcs
Assembly
HiMech.dll

Reports a rapid traverse that removed stock: the steps of one NC line that were commanded as rapid traverse (G00, IsRapid) and touched the workpiece fold into one Play-RapidCut–Detected validation warning, anchored on the line's first touching step and carrying the line's total removed volume and its largest cutting depth. A rapid move through material breaks the tool or crashes the machine on a real run, yet with the spindle turning the engine treats it as ordinary cutting: the collision rule (Detect(bool)) pairs flute and workpiece only while the spindle speed is zero, so such a line used to pass with no message at all. A rapid plunge after M05 (the direction stops, S stays modal) is not a zero-speed step and is reported here.

One instance per MachiningActRunner. Observe(in Sample, double, bool, out Report) runs on the sequential post-physics stage of every built step (one thread, step order), Flush(double, out Report) closes the last line at the end of a play and Reset() drops a pending line on a session reset; both run on the shell thread after WaitAll(), so no lock is needed. The fold is a pure function of the samples: a closed line comes back as a RapidCutMonitor.Report and the caller emits it at its own site (Emit(in Report, IProgress<StepDiagnostic>)); the forms that take a sink wrap the two.

Folding: consecutive rapid steps with the same LineKey (the NC line number, or the sentence itself where a runner has no line numbers) form one report; a feed step, a different line or the end of the play closes it. A line re-entered later (a subprogram loop) reports again, deliberately. The report is emitted only when the line's total removed volume reaches RapidCutVolumeThreshold_mm3 (default 0: any touch, as IsTouched reads it -- but a spring-back graze, IsSpringBackGraze, is no touch to the fold: under EnableDeflectionTransformation the rapid step after a deflected cut whose contact goes no deeper than that deflection -- the layer the cut left -- is cut and not reported, 2026-11-02). Zero-speed steps before any step has run with a spindle speed are skipped while collision detection is on — that rule owns them and raises Collision--Detected — and counted otherwise; a zero speed after that (an S0, a CL SPINDL/OFF, a CSV row back at 0 rpm) is a stop the collision rule leaves alone, like M05, and is counted.

public sealed class RapidCutMonitor
Inheritance
RapidCutMonitor
Inherited Members
Extension Methods

Fields

MessageId

Id of the warning this monitor emits.

public const string MessageId = "Play-RapidCut--Detected"

Field Value

string

Methods

Emit(in Report, IProgress<StepDiagnostic>)

Emits one closed rapid line as the Play-RapidCut–Detected validation warning, anchored on the line's first touching step.

public static void Emit(in RapidCutMonitor.Report report, IProgress<StepDiagnostic> sink)

Parameters

report RapidCutMonitor.Report

The closed line, from Observe(in Sample, double, bool, out Report) or Flush(double, out Report).

sink IProgress<StepDiagnostic>

Step-anchored sink for the report; no-op if null.

Flush(double, out Report)

Closes the pending rapid line: answers it as report when its total removed volume reaches volumeThreshold_mm3, then forgets it. Called by Observe(in Sample, double, bool, out Report) at a line boundary and by the session at the end of a play, for the last line; the caller emits the report (Emit(in Report, IProgress<StepDiagnostic>)).

public bool Flush(double volumeThreshold_mm3, out RapidCutMonitor.Report report)

Parameters

volumeThreshold_mm3 double

Line-total removed volume below which the line is not reported.

report RapidCutMonitor.Report

The closed line, when it is to be reported; default otherwise.

Returns

bool

True when a line closed and is to be reported.

Flush(double, IProgress<StepDiagnostic>)

Closes the pending rapid line and emits it on sink when it is to be reported: Flush(double, out Report) then Emit(in Report, IProgress<StepDiagnostic>).

public void Flush(double volumeThreshold_mm3, IProgress<StepDiagnostic> sink)

Parameters

volumeThreshold_mm3 double

Line-total removed volume below which the line is not reported.

sink IProgress<StepDiagnostic>

Step-anchored sink for the report; no-op if null.

Observe(in Sample, double, bool, out Report)

Feeds one built step, in step order. A feed step or a step of another line closes the pending rapid line (see Flush(double, out Report)); a rapid step that touched the stock opens or extends it – unless its touch was a spring-back graze (IsSpringBackGraze), which is read as no touch. The fold alone: when the step closed a line that is to be reported, the line comes back as report and the caller emits it (Emit(in Report, IProgress<StepDiagnostic>)); at most one line closes per step.

public bool Observe(in RapidCutMonitor.Sample sample, double volumeThreshold_mm3, bool collisionDetectionEnabled, out RapidCutMonitor.Report report)

Parameters

sample RapidCutMonitor.Sample

The step, see SampleOf(MachiningStep).

volumeThreshold_mm3 double

Line-total removed volume below which the line is not reported.

collisionDetectionEnabled bool

When true, steps with the spindle stopped are left to collision detection.

report RapidCutMonitor.Report

The line this step closed, when it is to be reported; default otherwise.

Returns

bool

True when a line closed and is to be reported.

Observe(in Sample, double, bool, IProgress<StepDiagnostic>)

Feeds one built step, in step order, and emits the line it closed on sink: Observe(in Sample, double, bool, out Report) then Emit(in Report, IProgress<StepDiagnostic>).

public void Observe(in RapidCutMonitor.Sample sample, double volumeThreshold_mm3, bool collisionDetectionEnabled, IProgress<StepDiagnostic> sink)

Parameters

sample RapidCutMonitor.Sample

The step, see SampleOf(MachiningStep).

volumeThreshold_mm3 double

Line-total removed volume below which the line is not reported.

collisionDetectionEnabled bool

When true, steps with the spindle stopped are left to collision detection.

sink IProgress<StepDiagnostic>

Step-anchored sink for the report; no-op if null.

Reset()

Session reset: forgets a pending line without reporting it, and forgets that a step has run with a spindle speed.

public void Reset()

SampleOf(MachiningStep)

Builds the monitor's view of a built step. The removed volume is the step's material removal rate (Mrr_mm3ds, the swept engagement cross-section times the tip feedrate) over the step duration — a geometry-only quantity, so the report needs no physics; a NaN rate (undefined tip feedrate) counts as 0 but the contact still counts. The sample reads no spring-back graze: the form for a step the play flagged one is SampleOf(MachiningStep, bool).

public static RapidCutMonitor.Sample SampleOf(MachiningStep step)

Parameters

step MachiningStep

A built step.

Returns

RapidCutMonitor.Sample

SampleOf(MachiningStep, bool)

SampleOf(MachiningStep) with the spring-back graze the play flagged the step's touch (2026-11-02): the pipeline's play-time answer for the step (MachiningParallelProc.SubstractionResult.IsSpringBackGraze, handed over by the sequential stage that samples the step; the step itself carries no such field), which the fold reads as no touch (IsSpringBackGraze). On an untouched step the flag means nothing and samples false.

public static RapidCutMonitor.Sample SampleOf(MachiningStep step, bool isSpringBackGraze)

Parameters

step MachiningStep

A built step.

isSpringBackGraze bool

The step's touch went no deeper than the layer the deflected cut before it left.

Returns

RapidCutMonitor.Sample