Files
OpenNest/Posts/OpenNest.Posts.Cincinnati/CincinnatiHeadRaise.cs
T
ajandClaude Opus 5.5 2b3f8e7b52 fix(posts): Cincinnati CL sub-program frames, head raises and dead settings
Part sub-program calls restored the sheet frame with G92 at the part
corner while the tool sat at the sub-program's last endpoint, shifting
every later part. The call now raises the head, rapids back to local 0,0
and restores there. Parts share a sub-program only when their posted
toolpaths match, so per-part lead-ins are kept.

Suppressed moves are left uncut: the cut resumes with a rapid past them.

Head raises go before the rapid that leaves a feature, one per rapid:
the safety raise now precedes the rapid to a new part instead of
following its first feature, and sub-program mode no longer posts M47
then M47 P2000. M47Mode.Auto posts M47 before rapids longer than
M47OverrideDistanceThreshold and /M47 otherwise. ExteriorM47 applies to
the contour spanning the part's cut extents.

The sheet GOTO targets FeatureLineNumberStart and is omitted without line
numbers. PrepareForNest pre-selects only the gas- and thickness-matching
library. Part programs are read through absolute copies, never switched
to absolute in place.

Removes the unimplemented UseSheetSubprograms, CoordModeBetweenParts and
ProcessParameterMode (G89Mode); old configs still load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 01:56:28 -04:00

38 lines
1.5 KiB
C#

namespace OpenNest.Posts.Cincinnati;
/// <summary>
/// Chooses the M47 head raise (§3.47) written before the rapid that leaves a feature.
/// </summary>
internal static class CincinnatiHeadRaise
{
/// <param name="isSafetyHeadraise">True when the rapid goes to a different part.</param>
/// <param name="isExterior">True when the feature just cut is a part exterior.</param>
/// <param name="rapidDistance">Travel to the next pierce; null when unknown.</param>
/// <returns>The block to write, or null for no head raise.</returns>
internal static string Line(
CincinnatiPostConfig config,
bool isSafetyHeadraise,
bool isExterior,
double? rapidDistance
)
{
if (isSafetyHeadraise && config.SafetyHeadraiseDistance.HasValue)
return $"M47 P{config.SafetyHeadraiseDistance.Value} (Safety Headraise)";
var mode = isExterior ? config.ExteriorM47 : config.InteriorM47;
return mode switch
{
M47Mode.Always => "M47",
M47Mode.BlockDelete => "/M47",
M47Mode.Auto => IsLongRapid(config, rapidDistance) ? "M47" : "/M47",
_ => null,
};
}
// Unknown travel, or no threshold configured, always gets the full raise.
private static bool IsLongRapid(CincinnatiPostConfig config, double? rapidDistance) =>
config.M47OverrideDistanceThreshold is not { } threshold
|| rapidDistance is not { } distance
|| distance > threshold;
}