Table of Contents

Class TransformationUtil

Namespace
Hi.NcParsers.Syntaxs
Assembly
HiMech.dll

Utilities for the ProgramToMcTransform chain. Each entry is {Source, Kind, Mat4d}; entries are composed in order with pure matrix multiplication (GetComposedTransform(JsonObject)).

KindKey partitions the entries by contour validity:

  • KindStatic — the matrix is valid across the whole block, applicable to any interpolated point along the contour.
  • KindDynamic — the matrix is a block-endpoint snapshot of a rotary-state-dependent transform (RTCP rotary-dynamic). Composing it produces a correct endpoint MC, but interpolated points along the contour must be derived per-step by motion semantics (ClLinearMcMotionSemantic); do not apply it to interpolated ProgramXyz.
Both kinds carry a real Mat4d so composition stays a pure matrix product — no entry has a missing matrix. Use HasDynamicEntry(JsonObject) to detect the dynamic-rotary state without consulting a sibling section flag.
public static class TransformationUtil
Inheritance
TransformationUtil
Inherited Members

Fields

KindDynamic

The entry's Mat4d is a block-endpoint snapshot only; intermediate contour points must be resolved by per-step IK in motion semantics.

public const string KindDynamic = "Dynamic"

Field Value

string

KindKey

JSON key for the entry's contour-validity classification. Value must be KindStatic or KindDynamic.

public const string KindKey = "Kind"

Field Value

string

KindStatic

The entry's Mat4d is valid for any point along the contour.

public const string KindStatic = "Static"

Field Value

string

Mat4dKey

JSON key for the Mat4d snapshot inside each chain entry.

public const string Mat4dKey = "Mat4d"

Field Value

string

PivotTransformSource

Canonical source name for the RTCP pivot transform — the kinematic transform from Pn (post-G54, post-G68.2) to MC at the block's endpoint ABC. Contributed by PivotTransformationSyntax. Must be the last entry written into the chain so that all Pn-frame operations (tilt, tool-height, coord-offset) are accumulated before the final kinematic IK; this ordering is enforced by the syntax- chain registration order, not by the writer API.

public const string PivotTransformSource = "PivotTransform"

Field Value

string

SourceKey

JSON key for the transform origin label inside each chain entry.

public const string SourceKey = "Source"

Field Value

string

ToolHeightCompensationSource

Canonical source name for the tool-height-compensation entry (tool-normal · offset_mm along the current tool axis). Matches the ToolHeightCompensation section key read for Offset_mm.

public const string ToolHeightCompensationSource = "ToolHeightCompensation"

Field Value

string

Methods

AddOrReplaceTransform(JsonObject, string, string, Mat4d)

Adds or replaces a named transformation entry in the chain. If an entry with the same source already exists, it is replaced in-place. Otherwise the new entry is appended. kind must be KindStatic or KindDynamic.

public static void AddOrReplaceTransform(JsonObject json, string source, string kind, Mat4d mat)

Parameters

json JsonObject
source string
kind string
mat Mat4d

GetComposedTransform(JsonObject)

Composes all entries in the chain into a single block-endpoint Mat4d (left-to-right multiplication). Pure multiplication — no special cases, no kinematic lookup. The returned matrix is valid only for the block's endpoint state; see ProgramToMcTransform for the endpoint-semantic contract.

public static Mat4d GetComposedTransform(JsonObject json)

Parameters

json JsonObject

Returns

Mat4d

GetComposedTransformAtAbc(JsonObject, Vec3d, Vec3d, IMachineKinematics, double)

Composes the chain into the Mat4d valid at an INTERPOLATED contour point whose rotary state is stepAbc_rad, by rebuilding every KindDynamic entry at that rotary state while keeping every KindStatic entry's stored snapshot. The per-step dual of GetComposedTransform(JsonObject), which is endpoint-only when the chain carries a Dynamic entry.

public static Mat4d GetComposedTransformAtAbc(JsonObject json, Vec3d stepAbc_rad, Vec3d endpointAbc_rad, IMachineKinematics kinematics, double toolHeightOffset_mm)

Parameters

json JsonObject

The block's JSON sections carrying the chain.

stepAbc_rad Vec3d

The interpolated point's MC rotary state in radians (NaN axes are treated as 0, mirroring ResolveEndpointAbc(LazyLinkedListNode<SyntaxPiece>, IMachineAxisConfig)).

endpointAbc_rad Vec3d

The block-endpoint MC rotary state in radians — the state the stored Dynamic snapshots were built at.

kinematics IMachineKinematics

The machine kinematics; null keeps every stored snapshot.

toolHeightOffset_mm double

The block's ToolHeightCompensation offset in mm (the value its Dynamic height entry was built with).

Returns

Mat4d

Remarks

Rebuild rules, per Dynamic entry source:

With a null kinematics every entry keeps its stored snapshot, collapsing to GetComposedTransform(JsonObject) — correct for the only kinematics-less Dynamic corner (the G43p4RtcpSyntax UnitZ height fallback, whose matrix does not depend on ABC).

GetTransformBySource(JsonObject, string)

Gets a specific entry's Mat4d by source name. Returns identity if not found.

public static Mat4d GetTransformBySource(JsonObject json, string source)

Parameters

json JsonObject
source string

Returns

Mat4d

HasDynamicEntry(JsonObject)

Returns true if any entry in the chain carries KindDynamic. Used by motion-form selection (LinearMotionSyntax) and ProgramXyz strategy dispatch (ProgramXyzUtil) to detect RTCP-rotary-dynamic state without consulting a flag on a sibling section. Throws if any entry lacks KindKey.

public static bool HasDynamicEntry(JsonObject json)

Parameters

json JsonObject

Returns

bool

MakePivotTransformMat(IMachineKinematics, Vec3d)

Builds the PivotTransformSource Mat4d — an empirically-constructed Pn→MC rigid-affine transform at the block's endpoint ABC. Equivalent to kinematics.PnToMc(pn_input, normal).Point when applied to a Pn-frame point, but expressed as a reusable Mat4d so the chain stays a pure matrix product (no per-point IK call inside GetComposedTransform(JsonObject)).

The pre-pivot anchor is the machine-zero attacher point McToPn(0).Point as a pure translation — the same origin anchor HardNc keeps in HardNcEnv.AttacherAtMcZeroOnTableCoordinate. Program-frame vectors already point along the Pn (table-buckle) axes, so only K(0)'s translation may enter the anchor. Folding the full K(0) (its linear part encodes per-axis motion sense — a workpiece-side linear axis contributes a negated row) would flip those axes' program components before the IK; on a machine whose Z rides the table (e.g. the B-x7000 WAC chain, table branch Base→Z→B→W) that mirrored every program Z and, at B≈180°, threw the resolved MC off by twice the pivot-to-attacher distance (~3.5 m).

Requiring machine files to be modelled the other way instead — workpiece-side axes negative, which makes K(0)'s linear part the identity and the two constructions equivalent — was evaluated as an alternative to this fix and deliberately rejected. IMachineKinematics resolves either axis direction, so a file that positions correctly through PnToMc(DVec3d, out DVec3d) has to position correctly through this transform as well; a precondition enforced here and nowhere else would only make one consumer diverge from the kinematics on files every other consumer accepts. The modelling convention governs how MC values read against the machine panel, and belongs to a check on the data when it loads — never to this matrix.

Constructed by probing McToPn(DVec3d) at the four standard basis points (origin + XYZ unit vectors) at the target ABC to derive K(abc); returns T(McToPn(0).Point) · K(abc).GetInverse(). Topology- agnostic — works for any affine kinematic chain regardless of axis order. Legacy PnToMc(DVec3d, out DVec3d) remains the reference oracle.

public static Mat4d MakePivotTransformMat(IMachineKinematics kinematics, Vec3d abc_rad)

Parameters

kinematics IMachineKinematics
abc_rad Vec3d

Returns

Mat4d

MakePivotTransformMat(IMachineKinematics, Vec3d, Mat4d)

Variant anchored to an arbitrary pre-pivot frame: builds the PivotTransformSource Mat4d preFrameToPn · K(abc)⁻¹ that maps a point of the chain's accumulated pre-pivot frame directly to MC at the block's endpoint ABC. The two-parameter overload is this variant specialised to the NC pipeline's machine-zero program frame (preFrameToPn = T(McToPn(0).Point), translation only — see its remarks for why K(0)'s linear part must stay out); the CLSF pipeline passes its workpiece→Pn fixture-topology matrix instead, so the pivot entry absorbs the workpiece placement together with the kinematics.

public static Mat4d MakePivotTransformMat(IMachineKinematics kinematics, Vec3d abc_rad, Mat4d preFrameToPn)

Parameters

kinematics IMachineKinematics
abc_rad Vec3d
preFrameToPn Mat4d

Returns

Mat4d

MakeToolHeightMat(IMachineKinematics, Vec3d, double)

Builds the tool-height-compensation Mat4d for a given rotary state: translate by (tool-normal at abc_rad) · height_mm. Pure translation (no rotation component); combines with the downstream PivotTransformSource to form the full Pn→MC IK.

public static Mat4d MakeToolHeightMat(IMachineKinematics kinematics, Vec3d abc_rad, double height_mm)

Parameters

kinematics IMachineKinematics
abc_rad Vec3d
height_mm double

Returns

Mat4d