1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
/*
* GNU AFFERO GENERAL PUBLIC LICENSE
* Version 3, 19 November 2007
* Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
using System;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
namespace UVtools.Core.Gerber.Apertures;
public abstract class Aperture
{
#region Properties
/// <summary>
/// Gets the index of this aperture
/// </summary>
public int Index { get; set; }
/// <summary>
/// Gets the aperture name
/// </summary>
public string Name { get; set; } = string.Empty;
#endregion
protected Aperture() { }
protected Aperture(int index) { Index = index; }
protected Aperture(string name) { Name = name; }
protected Aperture(int index, string name) : this(index) { Name = name; }
public abstract void DrawFlashD3(Mat mat, SizeF xyPpmm, Point at, MCvScalar color, LineType lineType = LineType.EightConnected);
public static Aperture? Parse(string line, GerberDocument document)
{
var match = Regex.Match(line, @"\%ADD(\d+)(\S+),(\S+)\*\%");
if (!match.Success || match.Groups.Count < 4) return null;
if (!int.TryParse(match.Groups[1].Value, out var index)) return null;
//if (!char.TryParse(match.Groups[2].Value, out var type)) return null;
switch (match.Groups[2].Value)
{
case "C":
{
if (!double.TryParse(match.Groups[3].Value, out var diameter)) return null;
return new CircleAperture(index, diameter);
}
case "O":
{
var split = match.Groups[3].Value.Split('X', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (split.Length < 2) return null;
if (!float.TryParse(split[0], out var width)) return null;
if (!float.TryParse(split[1], out var height)) return null;
return new EllipseAperture(index, width, height);
}
case "R":
{
var split = match.Groups[3].Value.Split('X', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (split.Length < 2) return null;
if (!float.TryParse(split[0], out var width)) return null;
if (!float.TryParse(split[1], out var height)) return null;
return new RectangleAperture(index, width, height);
}
case "P":
{
var split = match.Groups[3].Value.Split('X', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (split.Length < 2) return null;
if (!double.TryParse(split[0], out var diameter)) return null;
if (!ushort.TryParse(split[1], out var vertices)) return null;
return new PolygonAperture(index, diameter, vertices);
}
default: // macro
{
if (!document.Macros.TryGetValue(match.Groups[2].Value, out var macro)) return null;
var parseLine = line.TrimEnd('%', '*');
var commaIndex = parseLine.IndexOf(',')+1;
if (commaIndex == 0) return null;
parseLine = parseLine[commaIndex..];
var args = new[] {"0"}.Concat(parseLine.Split('X', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)).ToArray();
foreach (var primitive in macro)
{
primitive.ParseExpressions(args);
}
return new MacroAperture(index, macro);
}
}
}
}
|