Moved bend line extraction to separate class.
This commit is contained in:
@@ -10,7 +10,9 @@ namespace EtchBendLines
|
|||||||
{
|
{
|
||||||
public Line Line { get; set; }
|
public Line Line { get; set; }
|
||||||
|
|
||||||
public double YIntercept
|
public MText BendNote { get; set; }
|
||||||
|
|
||||||
|
public double YIntercept
|
||||||
{
|
{
|
||||||
get { return Line.YIntercept(); }
|
get { return Line.YIntercept(); }
|
||||||
}
|
}
|
||||||
|
|||||||
145
EtchBendLines/BendLineExtractor.cs
Normal file
145
EtchBendLines/BendLineExtractor.cs
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
using netDxf;
|
||||||
|
using netDxf.Entities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace EtchBendLines
|
||||||
|
{
|
||||||
|
class BendLineExtractor
|
||||||
|
{
|
||||||
|
public BendLineExtractor(string dxfFile)
|
||||||
|
{
|
||||||
|
DxfDocument = DxfDocument.Load(dxfFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BendLineExtractor(DxfDocument dxfDocument)
|
||||||
|
{
|
||||||
|
DxfDocument = dxfDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum bend radius to be considered. Anything beyond this number
|
||||||
|
/// is a center line for rolling.
|
||||||
|
/// </summary>
|
||||||
|
public double MaxBendRadius { get; set; } = 4;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The regular expression pattern the bend note must match
|
||||||
|
/// </summary>
|
||||||
|
static readonly Regex bendNoteRegex = new Regex(@"(?<direction>UP|DOWN|DN)\s*(?<angle>\d*(\.\d*)?)°\s*R\s*(?<radius>\d*(\.\d*)?)");
|
||||||
|
|
||||||
|
public DxfDocument DxfDocument { get; private set; }
|
||||||
|
|
||||||
|
public List<Bend> GetBendLines()
|
||||||
|
{
|
||||||
|
var bends = new List<Bend>();
|
||||||
|
var bendNotes = GetBendNotes();
|
||||||
|
|
||||||
|
foreach (var line in DxfDocument.Lines)
|
||||||
|
{
|
||||||
|
if (line.Linetype.Name != "CENTERX2" && line.Layer.Name != "BEND")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var bend = new Bend
|
||||||
|
{
|
||||||
|
Line = line,
|
||||||
|
Direction = BendDirection.Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
bends.Add(bend);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignBendDirections(bends, bendNotes);
|
||||||
|
|
||||||
|
return bends.Where(b => b.Radius <= MaxBendRadius).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MText> GetBendNotes()
|
||||||
|
{
|
||||||
|
var bendNotes = new List<MText>();
|
||||||
|
|
||||||
|
foreach (var text in DxfDocument.MTexts)
|
||||||
|
{
|
||||||
|
var textAsUpper = text.Value.ToUpper();
|
||||||
|
|
||||||
|
if (textAsUpper.Contains("UP") || textAsUpper.Contains("DOWN"))
|
||||||
|
{
|
||||||
|
bendNotes.Add(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bendNotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AssignBendDirections(IEnumerable<Bend> bendlines, IEnumerable<MText> bendNotes)
|
||||||
|
{
|
||||||
|
foreach (var bendline in bendlines)
|
||||||
|
{
|
||||||
|
var bendNote = FindBendNote(bendline.Line, bendNotes);
|
||||||
|
|
||||||
|
if (bendNote == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bendline.BendNote = bendNote;
|
||||||
|
|
||||||
|
var note = bendNote.Value.ToUpper();
|
||||||
|
|
||||||
|
if (note.Contains("UP"))
|
||||||
|
bendline.Direction = BendDirection.Up;
|
||||||
|
|
||||||
|
else if (note.Contains("DOWN") || note.Contains("DN"))
|
||||||
|
bendline.Direction = BendDirection.Down;
|
||||||
|
|
||||||
|
var match = bendNoteRegex.Match(note);
|
||||||
|
|
||||||
|
if (match.Success)
|
||||||
|
{
|
||||||
|
bendline.Radius = double.Parse(match.Groups["radius"].Value);
|
||||||
|
bendline.Angle = double.Parse(match.Groups["angle"].Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MText FindBendNote(Line bendLine, IEnumerable<MText> bendNotes)
|
||||||
|
{
|
||||||
|
var bendNotesList = bendNotes.ToList();
|
||||||
|
|
||||||
|
for (int i = bendNotesList.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var note = bendNotesList[i];
|
||||||
|
var notePos = note.Position.ToVector2();
|
||||||
|
var perpendicularPoint = bendLine.PointPerpendicularTo(notePos);
|
||||||
|
var dist = notePos.DistanceTo(perpendicularPoint);
|
||||||
|
var maxAcceptableDist = note.Height * 2.0;
|
||||||
|
|
||||||
|
if (dist > maxAcceptableDist)
|
||||||
|
bendNotesList.RemoveAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bendNotesList.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var closestNote = bendNotesList.First();
|
||||||
|
var p1 = closestNote.Position.ToVector2();
|
||||||
|
var p2 = bendLine.ClosestPointOnLineTo(p1);
|
||||||
|
var dist2 = p1.DistanceTo(p2);
|
||||||
|
|
||||||
|
for (int i = 1; i < bendNotesList.Count; i++)
|
||||||
|
{
|
||||||
|
var note = bendNotesList[i];
|
||||||
|
var p3 = note.Position.ToVector2();
|
||||||
|
var p4 = bendLine.ClosestPointOnLineTo(p3);
|
||||||
|
var dist = p3.DistanceTo(p4);
|
||||||
|
|
||||||
|
if (dist < dist2)
|
||||||
|
{
|
||||||
|
dist2 = dist;
|
||||||
|
closestNote = note;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return closestNote;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,9 +52,10 @@ namespace EtchBendLines
|
|||||||
{
|
{
|
||||||
Console.WriteLine(filePath);
|
Console.WriteLine(filePath);
|
||||||
|
|
||||||
var dxf = LoadDoc(filePath);
|
var bendLineExtractor = new BendLineExtractor(filePath);
|
||||||
var bendLines = GetBendLines(dxf);
|
bendLineExtractor.MaxBendRadius = MaxBendRadius;
|
||||||
var bendNotes = GetBendNotes(dxf);
|
|
||||||
|
var bendLines = bendLineExtractor.GetBendLines();
|
||||||
|
|
||||||
if (bendLines.Count == 0)
|
if (bendLines.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -66,25 +67,11 @@ namespace EtchBendLines
|
|||||||
Console.WriteLine($"Found {bendLines.Count} bend lines.");
|
Console.WriteLine($"Found {bendLines.Count} bend lines.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bendNotes.Count == 0)
|
|
||||||
{
|
|
||||||
Console.WriteLine("No bend notes found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Found {bendNotes.Count} bend notes.");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var bendLine in bendLines)
|
foreach (var bendLine in bendLines)
|
||||||
{
|
{
|
||||||
bendLine.Line.Layer = BendLayer;
|
bendLine.Line.Layer = BendLayer;
|
||||||
bendLine.Line.Color = AciColor.ByLayer;
|
bendLine.Line.Color = AciColor.ByLayer;
|
||||||
}
|
bendLine.BendNote.Layer = BendLayer;
|
||||||
|
|
||||||
foreach (var note in bendNotes)
|
|
||||||
{
|
|
||||||
note.Layer = BendLayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var upBends = bendLines.Where(b => b.Direction == BendDirection.Up);
|
var upBends = bendLines.Where(b => b.Direction == BendDirection.Up);
|
||||||
@@ -101,7 +88,7 @@ namespace EtchBendLines
|
|||||||
|
|
||||||
foreach (var etchLine in etchLines)
|
foreach (var etchLine in etchLines)
|
||||||
{
|
{
|
||||||
var existing = dxf.Lines
|
var existing = bendLineExtractor.DxfDocument.Lines
|
||||||
.Where(l => IsEtchLayer(l.Layer))
|
.Where(l => IsEtchLayer(l.Layer))
|
||||||
.FirstOrDefault(l => l.StartPoint.IsEqualTo(etchLine.StartPoint) && l.EndPoint.IsEqualTo(etchLine.EndPoint));
|
.FirstOrDefault(l => l.StartPoint.IsEqualTo(etchLine.StartPoint) && l.EndPoint.IsEqualTo(etchLine.EndPoint));
|
||||||
|
|
||||||
@@ -112,11 +99,11 @@ namespace EtchBendLines
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dxf.AddEntity(etchLine);
|
bendLineExtractor.DxfDocument.AddEntity(etchLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dxf.Save(filePath);
|
bendLineExtractor.DxfDocument.Save(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsEtchLayer(Layer layer)
|
static bool IsEtchLayer(Layer layer)
|
||||||
@@ -133,166 +120,11 @@ namespace EtchBendLines
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AssignBendDirections(IEnumerable<Bend> bendlines, IEnumerable<MText> bendNotes)
|
|
||||||
{
|
|
||||||
foreach (var bendline in bendlines)
|
|
||||||
{
|
|
||||||
var bendNote = FindBendNote(bendline.Line, bendNotes);
|
|
||||||
|
|
||||||
if (bendNote == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var note = bendNote.Value.ToUpper().Replace("SHARP", "R0");
|
|
||||||
|
|
||||||
if (note.Contains("UP"))
|
|
||||||
bendline.Direction = BendDirection.Up;
|
|
||||||
|
|
||||||
else if (note.Contains("DOWN") || note.Contains("DN"))
|
|
||||||
bendline.Direction = BendDirection.Down;
|
|
||||||
|
|
||||||
var match = bendNoteRegex.Match(note);
|
|
||||||
|
|
||||||
if (match.Success)
|
|
||||||
{
|
|
||||||
bendline.Radius = double.Parse(match.Groups["radius"].Value);
|
|
||||||
bendline.Angle = double.Parse(match.Groups["angle"].Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static double MaxBendRadius
|
static double MaxBendRadius
|
||||||
{
|
{
|
||||||
get { return double.Parse(ConfigurationManager.AppSettings["MaxBendRadius"]); }
|
get { return double.Parse(ConfigurationManager.AppSettings["MaxBendRadius"]); }
|
||||||
}
|
}
|
||||||
|
|
||||||
//static MText FindBendNote(Line bendLine, IEnumerable<MText> bendNotes)
|
|
||||||
// {
|
|
||||||
// var startPoint = new Vector2(bendLine.StartPoint.X, bendLine.StartPoint.Y);
|
|
||||||
// var endPoint = new Vector2(bendLine.EndPoint.X, bendLine.EndPoint.Y);
|
|
||||||
// var angle = startPoint.AngleTo(endPoint);
|
|
||||||
|
|
||||||
// if (angle >= 180.0)
|
|
||||||
// angle -= 180.0;
|
|
||||||
|
|
||||||
// const double ANGLE_TOLERANCE = 0.001;
|
|
||||||
|
|
||||||
// var bendNotesWithSameAngle = bendNotes.Where(n => Math.Abs(n.Rotation - angle) < ANGLE_TOLERANCE).ToList();
|
|
||||||
|
|
||||||
// var midPoint = bendLine.MidPoint();
|
|
||||||
|
|
||||||
// MText closestNote = bendNotes.First();
|
|
||||||
// Vector2 closestPoint = closestNote.Position.ToVector2();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// foreach (var note in bendNotes)
|
|
||||||
// {
|
|
||||||
// var pt = note.Position.ToVector2();
|
|
||||||
// var dist = midPoint.DistanceTo(pt);
|
|
||||||
|
|
||||||
// if (dist < distance)
|
|
||||||
// {
|
|
||||||
// closestNote = note;
|
|
||||||
// distance = dist;
|
|
||||||
// closestPoint = pt;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var distToBendNote = closestNote.Position.ToVector2().DistanceTo(midPoint);
|
|
||||||
|
|
||||||
// if (distToBendNote > 18)
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
// return closestNote;
|
|
||||||
// }
|
|
||||||
|
|
||||||
static MText FindBendNote(Line bendLine, IEnumerable<MText> bendNotes)
|
|
||||||
{
|
|
||||||
var bendNotesList = bendNotes.ToList();
|
|
||||||
|
|
||||||
for (int i = bendNotesList.Count - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
var note = bendNotesList[i];
|
|
||||||
var notePos = note.Position.ToVector2();
|
|
||||||
var perpendicularPoint = bendLine.PointPerpendicularTo(notePos);
|
|
||||||
var dist = notePos.DistanceTo(perpendicularPoint);
|
|
||||||
var maxAcceptableDist = note.Height * 2.0;
|
|
||||||
|
|
||||||
if (dist > maxAcceptableDist)
|
|
||||||
bendNotesList.RemoveAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bendNotesList.Count == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var closestNote = bendNotesList.First();
|
|
||||||
var p1 = closestNote.Position.ToVector2();
|
|
||||||
var p2 = bendLine.ClosestPointOnLineTo(p1);
|
|
||||||
var dist2 = p1.DistanceTo(p2);
|
|
||||||
|
|
||||||
for (int i = 1; i < bendNotesList.Count; i++)
|
|
||||||
{
|
|
||||||
var note = bendNotesList[i];
|
|
||||||
var p3 = note.Position.ToVector2();
|
|
||||||
var p4 = bendLine.ClosestPointOnLineTo(p3);
|
|
||||||
var dist = p3.DistanceTo(p4);
|
|
||||||
|
|
||||||
if (dist < dist2)
|
|
||||||
{
|
|
||||||
dist2 = dist;
|
|
||||||
closestNote = note;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return closestNote;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DxfDocument LoadDoc(string file)
|
|
||||||
{
|
|
||||||
return DxfDocument.Load(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<Bend> GetBendLines(DxfDocument dxf)
|
|
||||||
{
|
|
||||||
var bends = new List<Bend>();
|
|
||||||
var bendNotes = GetBendNotes(dxf);
|
|
||||||
|
|
||||||
foreach (var line in dxf.Lines)
|
|
||||||
{
|
|
||||||
if (line.Linetype.Name != "CENTERX2" && line.Layer.Name != "BEND")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var bend = new Bend
|
|
||||||
{
|
|
||||||
Line = line,
|
|
||||||
Direction = BendDirection.Unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
bends.Add(bend);
|
|
||||||
}
|
|
||||||
|
|
||||||
AssignBendDirections(bends, bendNotes);
|
|
||||||
|
|
||||||
return bends.Where(b => b.Radius <= MaxBendRadius).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<MText> GetBendNotes(DxfDocument dxf)
|
|
||||||
{
|
|
||||||
var bendNotes = new List<MText>();
|
|
||||||
|
|
||||||
foreach (var text in dxf.MTexts)
|
|
||||||
{
|
|
||||||
var textAsUpper = text.Value.ToUpper();
|
|
||||||
|
|
||||||
if (textAsUpper.Contains("UP") || textAsUpper.Contains("DOWN"))
|
|
||||||
{
|
|
||||||
bendNotes.Add(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bendNotes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PartType GetPartType(List<Bend> bends)
|
static PartType GetPartType(List<Bend> bends)
|
||||||
{
|
{
|
||||||
if (bends.Count == 0)
|
if (bends.Count == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user