diff --git a/EtchBendLines/Bend.cs b/EtchBendLines/Bend.cs index b4705e8..9299668 100644 --- a/EtchBendLines/Bend.cs +++ b/EtchBendLines/Bend.cs @@ -10,7 +10,9 @@ namespace EtchBendLines { public Line Line { get; set; } - public double YIntercept + public MText BendNote { get; set; } + + public double YIntercept { get { return Line.YIntercept(); } } diff --git a/EtchBendLines/BendLineExtractor.cs b/EtchBendLines/BendLineExtractor.cs new file mode 100644 index 0000000..9d44c58 --- /dev/null +++ b/EtchBendLines/BendLineExtractor.cs @@ -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; + } + + /// + /// Maximum bend radius to be considered. Anything beyond this number + /// is a center line for rolling. + /// + public double MaxBendRadius { get; set; } = 4; + + /// + /// The regular expression pattern the bend note must match + /// + static readonly Regex bendNoteRegex = new Regex(@"(?UP|DOWN|DN)\s*(?\d*(\.\d*)?)°\s*R\s*(?\d*(\.\d*)?)"); + + public DxfDocument DxfDocument { get; private set; } + + public List GetBendLines() + { + var bends = new List(); + 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 GetBendNotes() + { + var bendNotes = new List(); + + 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 bendlines, IEnumerable 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 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; + } + } +} diff --git a/EtchBendLines/Program.cs b/EtchBendLines/Program.cs index 31be9dd..7aad3ef 100644 --- a/EtchBendLines/Program.cs +++ b/EtchBendLines/Program.cs @@ -52,9 +52,10 @@ namespace EtchBendLines { Console.WriteLine(filePath); - var dxf = LoadDoc(filePath); - var bendLines = GetBendLines(dxf); - var bendNotes = GetBendNotes(dxf); + var bendLineExtractor = new BendLineExtractor(filePath); + bendLineExtractor.MaxBendRadius = MaxBendRadius; + + var bendLines = bendLineExtractor.GetBendLines(); if (bendLines.Count == 0) { @@ -66,25 +67,11 @@ namespace EtchBendLines 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) { bendLine.Line.Layer = BendLayer; bendLine.Line.Color = AciColor.ByLayer; - } - - foreach (var note in bendNotes) - { - note.Layer = BendLayer; + bendLine.BendNote.Layer = BendLayer; } var upBends = bendLines.Where(b => b.Direction == BendDirection.Up); @@ -101,7 +88,7 @@ namespace EtchBendLines foreach (var etchLine in etchLines) { - var existing = dxf.Lines + var existing = bendLineExtractor.DxfDocument.Lines .Where(l => IsEtchLayer(l.Layer)) .FirstOrDefault(l => l.StartPoint.IsEqualTo(etchLine.StartPoint) && l.EndPoint.IsEqualTo(etchLine.EndPoint)); @@ -112,11 +99,11 @@ namespace EtchBendLines continue; } - dxf.AddEntity(etchLine); + bendLineExtractor.DxfDocument.AddEntity(etchLine); } } - dxf.Save(filePath); + bendLineExtractor.DxfDocument.Save(filePath); } static bool IsEtchLayer(Layer layer) @@ -133,166 +120,11 @@ namespace EtchBendLines return false; } - static void AssignBendDirections(IEnumerable bendlines, IEnumerable 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 { get { return double.Parse(ConfigurationManager.AppSettings["MaxBendRadius"]); } } - //static MText FindBendNote(Line bendLine, IEnumerable 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 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 GetBendLines(DxfDocument dxf) - { - var bends = new List(); - 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 GetBendNotes(DxfDocument dxf) - { - var bendNotes = new List(); - - 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 bends) { if (bends.Count == 0)