- PepSettings: add DrawingsDirectory property for DXF endpoint config - DrawingDxfExporter: support subprogram calls, skip non-cut linear moves, remove spurious radians-to-degrees conversion on arc angles, set AC1018 DXF version - DrawingReader: handle .loop-info/.cadsnapshot entries gracefully, derive DrawingInfo from loop names when .info entry is absent, use FileShare.Read - DrawingInfoReader: use TryParse instead of Parse for material number - Drawing: make GetLoopName public (used by DrawingDxfExporter) - ZipHelper: use FileShare.Read to allow concurrent readers on Windows/Linux - NestFilterData: skip status filter when value is "All" Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
112 lines
3.1 KiB
C#
112 lines
3.1 KiB
C#
using PepLib.Models;
|
|
using System.IO.Compression;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace PepLib.IO
|
|
{
|
|
public sealed class DrawingReader
|
|
{
|
|
public Drawing Drawing { get; private set; }
|
|
|
|
public DrawingReader()
|
|
{
|
|
Drawing = new Drawing();
|
|
}
|
|
|
|
public DrawingReader(Drawing drawing)
|
|
{
|
|
Drawing = drawing;
|
|
}
|
|
|
|
public void Read(Stream stream)
|
|
{
|
|
using (var zip = new ZipArchive(stream, ZipArchiveMode.Read, leaveOpen: true))
|
|
{
|
|
foreach (var entry in zip.Entries)
|
|
{
|
|
using var entryStream = entry.Open();
|
|
var memstream = new MemoryStream();
|
|
entryStream.CopyTo(memstream);
|
|
memstream.Seek(0, SeekOrigin.Begin);
|
|
|
|
var extension = Path.GetExtension(entry.FullName);
|
|
|
|
switch (extension)
|
|
{
|
|
case ".dir":
|
|
LoadInfo(memstream);
|
|
memstream.Close();
|
|
continue;
|
|
|
|
case ".loop-info":
|
|
case ".cadsnapshot":
|
|
memstream.Close();
|
|
continue;
|
|
}
|
|
|
|
if (Regex.IsMatch(extension, "loop-\\d\\d\\d"))
|
|
Drawing.Loops.Add(ReadLoop(entry.FullName, memstream));
|
|
|
|
memstream.Close();
|
|
}
|
|
}
|
|
|
|
if (Drawing.Info == null)
|
|
Drawing.Info = DeriveInfoFromLoops();
|
|
|
|
Drawing.ResolveLoops();
|
|
}
|
|
|
|
public void Read(string nestFile)
|
|
{
|
|
if (!File.Exists(nestFile))
|
|
{
|
|
var msg = string.Format("File Not Found: {0}", nestFile);
|
|
throw new FileNotFoundException(msg);
|
|
}
|
|
|
|
Stream stream = null;
|
|
|
|
try
|
|
{
|
|
stream = new FileStream(nestFile, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
Read(stream);
|
|
}
|
|
finally
|
|
{
|
|
if (stream != null)
|
|
stream.Close();
|
|
}
|
|
}
|
|
|
|
private void LoadInfo(Stream stream)
|
|
{
|
|
Drawing.Info = DrawingInfo.Load(stream);
|
|
}
|
|
|
|
private DrawingInfo DeriveInfoFromLoops()
|
|
{
|
|
var info = new DrawingInfo();
|
|
|
|
if (Drawing.Loops.Count > 0)
|
|
{
|
|
// Loop names follow the pattern "{DrawingName}.loop-XXX"
|
|
var loopName = Drawing.Loops[0].Name;
|
|
var suffix = loopName.LastIndexOf(".loop-", StringComparison.OrdinalIgnoreCase);
|
|
info.Name = suffix >= 0 ? loopName.Substring(0, suffix) : loopName;
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
private Loop ReadLoop(string name, Stream stream)
|
|
{
|
|
var reader = new LoopReader();
|
|
reader.Read(name, stream);
|
|
|
|
return reader.Loop;
|
|
}
|
|
}
|
|
}
|
|
|