First commit.

This commit is contained in:
AJ
2019-09-06 17:28:34 -04:00
commit 3ef94813ac
11 changed files with 697 additions and 0 deletions

32
.gitignore vendored Normal file
View File

@@ -0,0 +1,32 @@
#Ignore thumbnails created by Windows
Thumbs.db
#Ignore files built by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
.vs/
#Nuget packages folder
packages/

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "netDxf"]
path = netDxf
url = https://github.com/haplokuon/netDxf.git

31
EtchBendLines.sln Normal file
View File

@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29123.88
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EtchBendLines", "EtchBendLines\EtchBendLines.csproj", "{229C2FB9-6AD6-4A5D-B83A-D1146573D6F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "netDxf", "netDxf\netDxf\netDxf.csproj", "{785380E0-CEB9-4C34-82E5-60D0E33E848E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{229C2FB9-6AD6-4A5D-B83A-D1146573D6F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{229C2FB9-6AD6-4A5D-B83A-D1146573D6F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{229C2FB9-6AD6-4A5D-B83A-D1146573D6F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{229C2FB9-6AD6-4A5D-B83A-D1146573D6F9}.Release|Any CPU.Build.0 = Release|Any CPU
{785380E0-CEB9-4C34-82E5-60D0E33E848E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{785380E0-CEB9-4C34-82E5-60D0E33E848E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{785380E0-CEB9-4C34-82E5-60D0E33E848E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{785380E0-CEB9-4C34-82E5-60D0E33E848E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4EF8ADDD-D992-4DED-BB58-F4DC0F53A4A3}
EndGlobalSection
EndGlobal

6
EtchBendLines/App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

150
EtchBendLines/Bend.cs Normal file
View File

@@ -0,0 +1,150 @@
using netDxf;
using netDxf.Entities;
using netDxf.Tables;
using System;
using System.Collections.Generic;
namespace EtchBendLine
{
public class Bend
{
const double RadPerDeg = Math.PI / 180.0;
public Line Line { get; set; }
public double YIntercept
{
get { return Line.YIntercept(); }
}
public double Slope
{
get { return Line.Slope(); }
}
public bool IsVertical
{
get { return Line.IsVertical(); }
}
public bool IsHorizontal
{
get { return Line.IsHorizontal(); }
}
public bool IsCollinearTo(Bend bend)
{
if (bend.IsVertical || this.IsVertical)
return (bend.IsVertical && this.IsVertical && bend.YIntercept == this.YIntercept);
if (bend.YIntercept != this.YIntercept)
return false;
return bend.Slope == this.Slope;
}
public List<Line> GetEtchLines(double etchLength)
{
var lines = new List<Line>();
var etchLayer = new Layer("ETCH")
{
Color = AciColor.Green,
};
var startPoint = new Vector2(Line.StartPoint.X, Line.StartPoint.Y);
var endPoint = new Vector2(Line.EndPoint.X, Line.EndPoint.Y);
var bendLength = startPoint.DistanceTo(endPoint);
if (bendLength < (etchLength * 3.0))
{
var fullLengthLine = new Line(Line.StartPoint, Line.EndPoint)
{
Layer = etchLayer
};
lines.Add(fullLengthLine);
return lines;
}
else
{
var angle = startPoint.AngleTo(endPoint);
if (Line.IsVertical())
{
var x = Line.StartPoint.X;
var bottomY1 = Line.StartPoint.Y < Line.EndPoint.Y ? Line.StartPoint.Y : Line.EndPoint.Y;
var bottomY2 = bottomY1 + etchLength;
var topY1 = Line.StartPoint.Y > Line.EndPoint.Y ? Line.StartPoint.Y : Line.EndPoint.Y;
var topY2 = topY1 - etchLength;
var p1 = new Vector2(x, bottomY1);
var p2 = new Vector2(x, bottomY2);
var p3 = new Vector2(x, topY1);
var p4 = new Vector2(x, topY2);
var bottomPoint = Line.StartPoint.Y < Line.EndPoint.Y ? Line.StartPoint : Line.EndPoint;
var bottomOffsetPoint = new Vector2(bottomPoint.X, bottomPoint.Y + etchLength);
var line1 = new Line(p1, p2)
{
Layer = etchLayer
};
var line2 = new Line(p3, p4)
{
Layer = etchLayer
};
lines.Add(line1);
lines.Add(line2);
}
else
{
var start = Line.StartPoint.ToVector2();
var end = Line.EndPoint.ToVector2();
var x1 = Math.Cos(angle);
var y1 = Math.Sin(angle);
var p1 = new Vector2(start.X, start.Y);
var p2 = new Vector2(start.X + x1, start.Y + y1);
var p3 = new Vector2(end.X, end.Y);
var p4 = new Vector2(end.X - x1, end.Y - y1);
var line1 = new Line(p1, p2)
{
Layer = etchLayer
};
var line2 = new Line(p3, p4)
{
Layer = etchLayer
};
lines.Add(line1);
lines.Add(line2);
}
}
return lines;
}
public BendDirection Direction { get; set; }
public double Length
{
get
{
var x = Line.EndPoint.X - Line.StartPoint.X;
var y = Line.EndPoint.Y - Line.StartPoint.Y;
return Math.Sqrt(x * x + y * y);
}
}
}
}

View File

@@ -0,0 +1,9 @@
namespace EtchBendLine
{
public enum BendDirection
{
Up,
Down,
Unknown
}
}

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{229C2FB9-6AD6-4A5D-B83A-D1146573D6F9}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>EtchBendLine</RootNamespace>
<AssemblyName>EtchBendLine</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Bend.cs" />
<Compile Include="BendDirection.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\netDxf\netDxf\netDxf.csproj">
<Project>{785380e0-ceb9-4c34-82e5-60d0e33e848e}</Project>
<Name>netDxf</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

102
EtchBendLines/Extensions.cs Normal file
View File

@@ -0,0 +1,102 @@
using netDxf;
using netDxf.Entities;
using System;
namespace EtchBendLine
{
public static class Extensions
{
const double TwoPI = Math.PI * 2.0;
public static Vector2 ToVector2(this Vector3 pt)
{
return new Vector2(pt.X, pt.Y);
}
public static bool IsVertical(this Line line)
{
return line.StartPoint.X == line.EndPoint.X;
}
public static bool IsHorizontal(this Line line)
{
return line.StartPoint.Y == line.EndPoint.Y;
}
public static double Slope(this Line line)
{
if (line.IsVertical())
return double.NaN;
var p1 = line.StartPoint;
var p2 = line.EndPoint;
return Math.Round((p2.Y - p1.Y) / (p2.X - p1.X), 4);
}
public static double YIntercept(this Line line)
{
var p1 = line.StartPoint;
var p2 = line.EndPoint;
var slope = line.Slope();
// y = mx + b
return Math.Round(p1.Y - slope * p1.X, 4);
}
public static Vector2 PointPerpendicularTo(this Line line, Vector2 pt)
{
var startPoint = line.StartPoint.ToVector2();
var endPoint = line.EndPoint.ToVector2();
var d1 = pt - startPoint;
var d2 = endPoint - startPoint;
var dotProduct = d1.X * d2.X + d1.Y * d2.Y;
var lengthSquared = d2.X * d2.X + d2.Y * d2.Y;
var param = dotProduct / lengthSquared;
if (param < 0)
return startPoint;
else if (param > 1)
return endPoint;
else
{
return new Vector2(
startPoint.X + param * d2.X,
startPoint.Y + param * d2.Y);
}
}
public static Vector2 MidPoint(this Line line)
{
var x = (line.StartPoint.X + line.EndPoint.X) * 0.5;
var y = (line.StartPoint.Y + line.EndPoint.Y) * 0.5;
return new Vector2(x, y);
}
public static double DistanceTo(this Vector2 startPoint, Vector2 endPoint)
{
var x = endPoint.X - startPoint.X;
var y = endPoint.Y - startPoint.Y;
return Math.Sqrt(x * x + y * y);
}
public static double AngleTo(this Vector2 startPoint, Vector2 endPoint)
{
var x = endPoint.X - startPoint.X;
var y = endPoint.Y - startPoint.Y;
return NormalizeRad(Math.Atan2(y, x));
}
static double NormalizeRad(double angle)
{
double r = angle % TwoPI;
return r < 0 ? TwoPI + r : r;
}
}
}

266
EtchBendLines/Program.cs Normal file
View File

@@ -0,0 +1,266 @@
using netDxf;
using netDxf.Entities;
using netDxf.Tables;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EtchBendLine
{
class Program
{
const double ETCH_LENGTH = 1.0;
static Layer BendLayer = new Layer("BEND")
{
Color = AciColor.Yellow
};
static void Main(string[] args)
{
var path = AppDomain.CurrentDomain.BaseDirectory;
var files = Directory.GetFiles(path, "*.dxf", SearchOption.AllDirectories);
if (files == null || files.Length == 0)
{
Console.WriteLine($"No DXF files founds. Place DXF files in \"{AppDomain.CurrentDomain.BaseDirectory}\" and run this program again.");
PressAnyKeyToExit();
return;
}
foreach (var file in files)
{
AddEtchLines(file);
Console.WriteLine("----------------------------------------------------------------");
}
PressAnyKeyToExit();
}
static void PressAnyKeyToExit()
{
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
static void AddEtchLines(string filePath)
{
var name = Path.GetFileNameWithoutExtension(filePath);
Console.WriteLine($"Adding etch lines to file \"{name}\"");
var dxf = LoadDoc(filePath);
var bendLines = GetBendLines(dxf);
var bendNotes = GetBendNotes(dxf);
if (bendLines.Count == 0)
{
Console.WriteLine("No bend lines found.");
return;
}
else
{
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;
}
AssignBendDirections(bendLines, bendNotes);
var upBends = bendLines.Where(b => b.Direction == BendDirection.Up);
Console.WriteLine($"{upBends.Count()} up bends, {bendLines.Count - upBends.Count()} down bends.");
foreach (var bendline in upBends)
{
var etchLines = bendline.GetEtchLines(ETCH_LENGTH);
dxf.AddEntity(etchLines);
}
dxf.Save(filePath);
}
static void AssignBendDirections(IEnumerable<Bend> bendlines, IEnumerable<MText> bendNotes)
{
foreach (var bendline in bendlines)
{
var bendNote = FindBendNote(bendline.Line, bendNotes);
if (bendNote == null)
continue;
bendNote.Layer = BendLayer;
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;
}
}
//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 list = bendNotes.ToList();
var shortestDist = double.MaxValue;
var shortestDistIndex = -1;
for (int i = 0; i < list.Count; i++)
{
var note = list[i];
var notePos = note.Position.ToVector2();
var perpendicularPoint = bendLIne.PointPerpendicularTo(notePos);
var dist = notePos.DistanceTo(perpendicularPoint);
if (dist < shortestDist)
{
shortestDistIndex = i;
shortestDist = dist;
}
}
if (shortestDistIndex == -1)
return null;
var bendNote = list[shortestDistIndex];
var maxAcceptableDist = bendNote.Height * 2.0;
if (shortestDist > maxAcceptableDist)
return null;
return bendNote;
}
static Vector2? FindClosestPoint(Vector2 originPoint, List<Vector2> pts)
{
if (pts == null || pts.Any() == false)
return null;
var closest = pts[0];
var distance = originPoint.DistanceTo(closest);
for (int i = 1; i < pts.Count; i++)
{
var pt = pts[i];
var dist = originPoint.DistanceTo(pt);
if (dist < distance)
{
distance = dist;
closest = pts[i];
}
}
return closest;
}
static DxfDocument LoadDoc(string file)
{
return DxfDocument.Load(file);
}
static List<Bend> GetBendLines(DxfDocument dxf)
{
var bends = new List<Bend>();
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);
}
return bends;
}
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;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EtchBendLine")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EtchBendLine")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("229c2fb9-6ad6-4a5d-b83a-d1146573d6f9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

1
netDxf Submodule

Submodule netDxf added at 67789bfe70