Files
OpenNest/Posts/OpenNest.Posts.CincinnatiCIFiber/CIFiberPostProcessor.cs
T
aj 82feb78b0f feat(posts): add Cincinnati CI Fiber (TF5200) post-processor
New post-processor plugin OpenNest.Posts.CincinnatiCIFiber for the CI
Fiber laser family (nLight CLX / Beckhoff TF5200 / Precitec ProCutter,
e.g. the CI Fiber 4020 8kW). Named by machine family, not table size.

Emits the machine program contract of the Cincinnati-supplied sample NC
(12992-4SS_NEST.nc): V.E.* header, restart jump, per-part V.E.R4 blocks,
per-contour N labels with V.E.R3, skippable /L macro lines (L0/L2+G41
interior, L4+G42 exterior, L6 cut-on, ZHSOFF cut-end), G162 incremental
arc I/J, trimmed 3-decimal spaceless coordinates, CRLF, M50/M30/%.

Contour classification (interior vs exterior) derives from the material
side of the closed cut path, not hardcoded winding. SubProgramCall holes
are flattened to sheet coordinates (rotation-safe). Arc lead-ins are
rejected per TF5200 13.2.4.1 (first motion block after G41/G42 selection
must be linear). Table envelope (default 160.25 x 81.25 in) validated.

Tests: structure golden on a square-with-hole nest, rotated-hole flatten,
coordinate format, arc-lead-in rejection, table validation, suppressed/
scribe skipping, plus a SkippableFact regression against the real sample
NC (109 parts, 2071 contours, L2=1962, L4=109, perimeter vertices match
within 0.001). Fixtures configure through OpenNest.Tests/test-config.json
and the regression skips when absent.
2026-09-27 04:10:22 -04:00

103 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using OpenNest.CNC;
namespace OpenNest.Posts.CincinnatiCIFiber
{
/// <summary>
/// Post-processor for the CI Fiber family (e.g. the CI Fiber 4020 8kW with
/// nLight CLX / Beckhoff TF5200 / Precitec ProCutter). Named by machine
/// family, not table size: the same post drives other CI Fiber tables via
/// the configured table envelope. Emits the TF5200 skippable-macro program
/// structure of the machine sample (see <see cref="CIFiberProgramWriter"/>).
/// </summary>
public sealed class CIFiberPostProcessor : IConfigurablePostProcessor
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
WriteIndented = true,
Converters = { new JsonStringEnumConverter() },
};
public string Name => "Cincinnati CI Fiber";
public string Author => "OpenNest";
public string Description =>
"CI Fiber family laser (TF5200 / nLight CLX), e.g. CI Fiber 4020 8kW";
public CIFiberPostConfig Config { get; }
object IConfigurablePostProcessor.Config => Config;
public CIFiberPostProcessor()
{
var configPath = GetConfigPath();
if (File.Exists(configPath))
{
var json = File.ReadAllText(configPath);
Config =
JsonSerializer.Deserialize<CIFiberPostConfig>(json, JsonOptions)
?? new CIFiberPostConfig();
}
else
{
Config = new CIFiberPostConfig();
SaveConfig();
}
}
public CIFiberPostProcessor(CIFiberPostConfig config)
{
Config = config ?? throw new ArgumentNullException(nameof(config));
}
public void SaveConfig()
{
var configPath = GetConfigPath();
var json = JsonSerializer.Serialize(Config, JsonOptions);
File.WriteAllText(configPath, json);
}
private static string GetConfigPath()
{
var assemblyPath = typeof(CIFiberPostProcessor).Assembly.Location;
var dir = Path.GetDirectoryName(assemblyPath);
var name = Path.GetFileNameWithoutExtension(assemblyPath);
return Path.Combine(dir, name + ".json");
}
public void Post(Nest nest, Stream outputStream)
{
if (nest == null)
throw new ArgumentNullException(nameof(nest));
if (outputStream == null)
throw new ArgumentNullException(nameof(outputStream));
// CRLF file, ASCII (UTF-8 without BOM), matching the machine sample.
var encoding = new UTF8Encoding(false);
using var writer = new StreamWriter(
outputStream,
encoding,
1024,
leaveOpen: true
);
new CIFiberProgramWriter(Config).Write(nest, writer);
writer.Flush();
}
public void Post(Nest nest, string outputFile)
{
using var fs = new FileStream(
outputFile,
FileMode.Create,
FileAccess.Write
);
Post(nest, fs);
}
}
}