Moved bend line extraction to separate class.

This commit is contained in:
AJ
2019-09-15 00:21:04 -04:00
parent 443912f8f8
commit 559f57fb44
3 changed files with 156 additions and 177 deletions

View File

@@ -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(); }
} }

View 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;
}
}
}

View File

@@ -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)