Namespace Hi.MachiningSteps
Classes
- MachineMotionStep
MachiningStep has spindle information. Note that the spindle information is only for milling behavior.
- MachiningStep
Represents a machining step enriched with physics, mapping and source metadata. The duration-based step property is based on the duration from previous-step to current-step.
- MachiningStep.CollidedKeyPair
A pair of collided keys that indicates two entities are in collision. A step's pairs are persisted together as one record (WriteBin(BinaryWriter, CollidedKeyPair[]), ReadBin(BinaryReader)).
- MachiningStepRecord
Internal Use Only. The record of one published MachiningStep as the result recording takes it: the step index, the snapshot of the step's source sentence, a copy of the motion step, the removal scalars, a copy of the collided pairs and a copy of the measured time – values and copies only, nothing that keeps the play alive: not the step's host, not its live source command, not its motion step. Of(MachiningStep) takes it the moment the step pipeline publishes the step, and the record is the step's values of that moment: what is written onto a step after it was published is not in it – the CSV mapping embedded after a play sets the steps' ActualTime, and the step-physics recompute replaces the force brief's tag in the step's SubstractionBrief (
MachiningStep.ReplaceMillingForceBriefTag); the recorder of the plan's P3 decides how those two are recorded. ActualTime has a value for the CSV-driven play alone, whose step-built action stamps the step before it is published.
- PresentAccess
Provides a value accessor bound with its PresentAttribute metadata.
- PresentAttribute
Attribute for presenting property information with localization support.
- ProgramZeroLegs
The two legs of a workpiece's program-zero chain as the step pipeline reads them off the workpiece's topology – program zero to geometry anchor and geometry anchor to program zero – in one immutable object that every step built on one workpiece instance refers to, in place of two 128-byte matrices embedded in every step (2026-10-05: over a whole play the embedded pair was one value on every step).
MachiningVolumeRemovalProcbuilds a holder when its step cache is refreshed (a workpiece instance swapped in, or the cache cleared) and hands it to every step until the next refresh; a holder is never written after it is built, so a reference to one is a whole pair or nothing. A step given one leg through its setter takes a holder of its own (ProgramToWorkpieceGeomMat4d, WorkpieceGeomToProgramMat4d). A record: two holders with the same legs are equal and print their legs, as the two matrices they replace did.
- PropertyAccess<TData>
Provides access to properties of a milling step with presentation information.
- StepActualTime
Wall-clock stamp of a machining step end — the controller-recorded timeline, as opposed to the simulated machine timeline (EndTimecode). Grouped into one optional sub-object so scenes that never map measured data (pure NC simulation, collision check, optimization) carry a single null reference per step. A CSV play stamps only the first step built after each row/idle boundary with the controller instant; the steps in between receive values extrapolated from the latest stamp along the machine timeline and are marked IsInterpolated. Persisted as one 20-byte record (WriteBin(BinaryWriter), StepActualTime(BinaryReader)); a step without a stamp has no record at all (the result recording's column is NULL), there is no record of a null stamp.
- StepBrief
Internal Use Only. The two briefs of one step as the step cache's
StepBrieftable holds them — a row read back: the step index, the MillingForceBrief in the record's state (null for the null record: the physics did not run on the step; the no-cut record; a computed brief) and the SeqPhysicsState (never null, every published step has one). The row type ofSqliteStepStorage.FindStepBriefsand of the readers a scan goes through (the step-physics recompute'sBriefReader, the NC optimization's segment read), beside StepLuggage, the row of the luggage table; the brief-into-DB chain's C4a. A row exists for exactly the published steps (the chain's C3), so a step without one is a step the store does not hold.
- StepConsignment
Internal Use Only. The step's luggage and its two briefs on their way to the step cache: kept on the MachiningStep as its creation cache (Hi.MachiningSteps.MachiningStep.ConsignmentCreationCache) from the step's construction until its rows are committed and the step is published (
MachiningActRunner.SeekClearStepLuggageCacheclears it once both have happened), and queued to the runner's writer as the item of one row of each table — the StepLuggage row and theStepBriefrow of the two briefs, written in one transaction (SqliteStepStorage.InsertStepConsignments; the brief-into-DB chain's C3) — and, since the chain's C4c, the values written onto the step while the consignment is live (WrittenValues: a script's step-built handler, a CSV program's data columns), as the rows of theStepVariabletable in the same transaction. One object a step, freed at the rendezvous.Since play-core migration P14 (D8) the luggage travels as bytes (LuggageBytes, the truth): the writer binds them to the row's columns and serialises nothing for the luggage -- the store encodes two of them into forms of its own first (HiNc's
SqliteStepStorage: the no-cut force array cut to its header, the contours deflated) and decodes them on read, so these bytes stay as the pipeline made them; the objects (StepLuggage) are parsed from the bytes on the first read and kept as a read cache.HasStep false is a consignment without a step: the force stage produced the luggage and the sequential stage faulted before the step was published — the store gets the luggage row alone, no
StepBriefrow, and the flush makes no ByDb rendezvous visit for it (there is no step whose cache could pair with it; a visit would park a stale ByDb for the index). A step whose sequential stage never ran (a stop with steps in flight) has no consignment at all.
- StepLuggage
The variable-size per-step data of a machining step that the step cache stores one row a step, one column a kind: the removal geometry (Substraction, every removing step), the engagement (LayerMillingEngagement) and the per-rotation force arrays (MillingForceLuggage) of the rotating-edge model, null where that model did not run for the step. The force stage's fixed-size scalar summary (
MillingForceBrief) and the sequential physics state (SeqPhysicsState) are not luggage: the step cache keeps them in a row of their own. The store keeps two of the columns in forms of its own (HiNc'sSqliteStepStorage: an untouched step's no-cut force array as its 8-byte header, a touched step's contact contours deflated) and undoes them on every read, so what a reader gets is what the step produced. A consumer reads only the kind it uses: one step through the step'sMachiningStep.TryGet…(the creation cache while the row is on its way to the store, the store's row after), a scan through the store one index segment at a time.
- StepLuggageBytes
Internal Use Only. The step's luggage as the three byte arrays the step cache takes, one a kind (play-core migration P14, D8): the
Substraction.WriteBin,LayerMillingEngagement.WriteBinandMillingForceLuggage.WriteBinlayouts, null for a kind the step did not produce. The pipeline fills the substraction and engagement kinds with the bytes the native geometry step answered and the force kind with the force record's bytes (the kernel's own doubles, D5); the consignment carries them to the store (LuggageBytes: the writer binds them to the row, serialising no object on its thread, D9), and every reader of a luggage object parses it from them on demand (Parse(), StepLuggage). The bytes are the truth; a parsed object is a read cache. The store keeps two of the kinds in forms of the file's own and decodes them back on every read (HiNc'sSqliteStepStorage): an untouched step's no-cut force array as its 8-byte header, the substraction's contours deflated behind its 13-byte header. The arrays here never take those forms.
- StepPhysicsAmendment
Internal Use Only. What the step-physics recompute changed on one published step, for the step cache to amend in place (
SqliteStepStorage.AmendStepPhysics, one transaction a chunk; the brief-into-DB chain's C4a): the force luggage when the force kernel reran on the step (null: the luggage row keeps its force column; the substraction and the engagement columns are never touched), and the step's two briefs after the recompute — the force brief in its tri-state (null: the physics did not run on the step), the sequential physics state always. Not a StepConsignment: a consignment is a step's luggage and briefs on their way to the store, whole rows written once; an amendment is a partial update of rows that exist.
- StepPresentCatalog
Internal Use Only. Expands the PresentAttribute-annotated properties of MachiningStep into the stable presentation-key dictionary (vector properties fan out to
.X/.Y/.Z, the cutter location to.X/.Y/.Z/.I/.J/.K).
- StepVariableValue
The values a step variable written onto a step can hold in the step cache (the brief-into-DB chain's C4c): a number of any numeric type, stored as a double (a bool as 1 / 0, as the step-property registry reads it), or a string; anything else is not stored. A value written as an
intreads back as adouble, in memory and from the store alike.
- SyntaxPieceRecord
Internal Use Only. The record of one executed SyntaxPiece as the result recording takes it: the snapshot of the piece's sentence and the piece's parse result as compact UTF-8 JSON. Taken on SyntaxPieceRan, on the player's thread. The snapshot is the one interned for the piece (Of(ISentenceCarrier)), the same object the step records built from the piece carry: the reference under which the recorder hands the piece its id. The JSON is the frozen bytes of a frozen piece, wrapped and not copied, or the live graph serialized at the call with CompactNanOptions, the freeze's encoding – the content of that moment: the pipeline may still write a piece until the next piece's first act entry, so a record taken before that boundary and the piece's frozen bytes agree byte for byte only from it on. A piece without a parse result has an empty CompactUtf8Json and HasJson false.
- WrittenStepValues
Internal Use Only. The values written onto one step under step-variable keys (this[string]: a script's step-built handler, a CSV program's data columns) while the step's consignment is live — kept on the consignment (WrittenValues) from the first write until the rendezvous frees it, and on the runner as the last published step's values (
MachiningActRunner.LastPublishedStepValues), so that a handler reading the previous step reads no row. The writer takes the values once (TakeForWrite()) and writes them with the step's rows; a value set after that is written to the store by the caller (Set(string, object) says so) and kept here for the readers until the consignment is freed. Every member takes the gate: the sequential stage writes while the writer thread reads. The writer takes the values of every published consignment, one that nothing was written onto included (TakeWrittenValuesForWrite() creates the object taken), so a value written after the flush always finds a taken object and reaches the store. The dictionary is allocated on the first value. The brief-into-DB chain's C4c.
Structs
- ClStripPosRecord
Internal Use Only. The record of one ClStripPos as the result recording takes it: the position's index, which is the index of the step built on it, and its program CL, the point and the normal (the whole dvec3d_t). Taken on PosAdded, where the position has no step yet – its state is the colour seed until the step pipeline's fourth stage publishes the step on it – so the index is Index, never a step's. A record struct: its
Equalsand==are the value equality of dvec3d_t, under which NaN differs from itself; the bit-for-bit comparison isBitEquals.
- StepBriefPin
Internal Use Only. The scope in which the calling thread holds one step's reads in hand — its two briefs, the values written onto it, or both: while it is alive, TryGetMillingForceBrief(out MillingForceBrief) and TryGetSeqPhysicsState(out SeqPhysicsState) of the step with that index answer the pinned briefs on this thread, and the step's indexer (this[string]) the pinned written values, ahead of the step's creation cache and the host's store read — so that a batch reader that read a segment of
StepBriefrows, or ofStepVariablerows, at once (the inspecting-slot scan, the step-file export) and the step-physics recompute, which has the briefs it just committed, can read the step's physics getters and its indexer without a store read per getter. Taken by PinBriefs(int, MillingForceBrief, SeqPhysicsState), PinBriefs(int, MillingForceBrief, SeqPhysicsState, IReadOnlyDictionary<string, object>) or PinWrittenValues(int, IReadOnlyDictionary<string, object>), released by Dispose(), which puts the thread's previous pin back (pins nest). Other threads never see it.
- StepVariableWrite
One write of a batch of step-variable values (WriteStepVariables(IReadOnlyList<StepVariableWrite>)): the step, the key and the value — a number (stored as a double) or a string, or null to take the key back off the step. The brief-into-DB chain's C4c.
- SubstractionBrief
The removal scalars of one MachiningStep, kept inline on the step: whether the cutter touched the stock, the axial cutting depth, the plural-filtered radial width, the material removal rate, and the tri-state of the step's force brief as the wire format's tag byte. Built once by the step pipeline's parallel physics stage from the substraction and the force stage's result; the two briefs themselves are not on the step — they live in the step cache (TryGetMillingForceBrief(out MillingForceBrief), TryGetSeqPhysicsState(out SeqPhysicsState)), and this struct is what the step keeps of the physics so that “did the cutter touch” and “did the physics run” are answered without a store read (the brief-into-DB chain's C4b, which folded the former
MillingInstanceobject into the step). Until the brief family cleanup of 2026-10-27 the struct kept the contact contours' bounding box on the tool running coordinate (56 bytes a step), which the product read only as its Z extent, the cutting depth: the depth is stored in its place (CuttingDepth_mm). Persisted as one 27-byte record (WriteBin(BinaryWriter), SubstractionBrief(BinaryReader)).
Interfaces
- IFlagText
temperary design for showing flag text.
- IMachiningResultSink
Internal Use Only. Where a play's results go as records: the result recording's boundary (the plan's P1), fed from three places on three threads – a strip position on PosAdded (the shell thread, after the pipeline's submit lock), a step and its two briefs after the step pipeline's fourth stage published it (the pump thread, through
MachiningActRunner.ResultSink), a syntax piece on SyntaxPieceRan (the player's thread). The three can run at once, so a sink is thread-safe, and nothing orders the three kinds against each other: the step of a position may arrive before or after the position, a piece before or after the steps built from it; a step's briefs follow its record on the same thread. Every record carries its own key – the step index of a position, of a step and of its briefs, the sentence snapshot of a piece and of the steps built from it, the same object (Of(ISentenceCarrier)) – so a store keeps the kinds apart and never assumes a position's row is there when its step's arrives. A sink has no lifetime of its own: no begin, no end, no flush; the recorder owns those. The recorder of the plan's P3 isHi.MachiningProcs.NcResultRecorder(HiNc).A sink never throws, never blocks the play and never calls back into the runner. The fourth stage guards its two calls all the same: a throw out of AddMachiningStep(MachiningStepRecord) or AddStepBrief(StepBrief) -- the record's own checks can throw -- is reported on the step as
Step-ResultRecord--Fault, the step stays published and the recording goes on without it; a throw out of AddClStripPos(in ClStripPosRecord) leaves the position's event handler and stops the play, a throw out of AddSyntaxPiece(SyntaxPieceRecord) leaves the piece event's handler. A sink that waits on a store holds the thread that called it -- the shell thread inside its play loop, the pump, the player -- so the recorder catches its own exceptions and keeps its own back-pressure off these threads.
- IMachiningService
The host of the machining steps: the project-level surface a step and the run-ops reach for the equipment, the tool house, the strip, the session and the stored per-step luggage.
- IMotionStepIndex
Abstraction for an object that carries a StepIndex — the 0-based ordinal of a machining motion step in execution order. Used as a cross-object alignment key so a step (MachiningStep), its cutter-location position (
ClStripPos), and the messages anchored to it (StepDiagnostic,StepScopedProgress) can be matched by the same ordinal without depending on a concrete type.Distinct from ISentenceIndexed: that ordinal counts NC source blocks, whereas this one counts produced motion steps — a single source block (e.g. a canned cycle) can fan out into several steps.
- IStepPropertyAccessHost
Narrow host contract for accessing the step-variable registry and registering new step variables. Exposed as a dedicated surface so pipelines that only need step-variable wiring (e.g. CsvRowSyntax) do not have to depend on the broader IMachiningService.
Enums
- StepLuggageKinds
The kinds of luggage a step's row of the step cache holds, one flag a column; a store answers which columns of a row are not NULL in these terms so a consumer can tell a stored kind from an absent one without decoding either.