Initial commit

This commit is contained in:
AJ
2018-08-31 07:25:48 -04:00
commit adecdc13e5
76 changed files with 7005 additions and 0 deletions

196
.gitignore vendored Normal file
View File

@@ -0,0 +1,196 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# If using the old MSBuild-Integrated Package Restore, uncomment this:
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.exe
*.bak
*.cache
[Bb]in
[Dd]ebug*/
*.lib
obj/
[Rr]elease*/
[Tt]est[Rr]esult*

226
PepLib.Dxf/DxfConverter.cs Normal file
View File

@@ -0,0 +1,226 @@
using PepLib.Codes;
using netDxf;
using netDxf.Entities;
using netDxf.Tables;
using System;
using PepProgram = PepLib.Program;
namespace PepLib.Dxf
{
public class DxfConverter
{
private const double RadToDeg = 180.0 / Math.PI;
private DxfDocument doc;
private Vector2 curpos;
private ProgrammingMode mode;
private readonly Layer cutLayer;
private readonly Layer rapidLayer;
private readonly Layer plateLayer;
public DxfConverter()
{
doc = new DxfDocument();
cutLayer = new Layer("Cut");
cutLayer.Color = AciColor.Red;
rapidLayer = new Layer("Rapid");
rapidLayer.Color = AciColor.Blue;
rapidLayer.LineType = LineType.Dashed;
plateLayer = new Layer("Plate");
plateLayer.Color = AciColor.Cyan;
}
public DxfDocument ConvertLoop(Loop loop)
{
doc = new DxfDocument();
AddProgram(loop);
return doc;
}
public DxfDocument ConvertPlate(Plate plate)
{
doc = new DxfDocument();
AddPlateOutline(plate);
foreach (var part in plate.Parts)
{
curpos = part.Location.ToDxfVector();
AddProgram(part.Program);
}
return doc;
}
public DxfDocument ConvertProgram(PepProgram program)
{
doc = new DxfDocument();
AddProgram(program);
return doc;
}
private void AddPlateOutline(Plate plate)
{
Vector2 pt1;
Vector2 pt2;
Vector2 pt3;
Vector2 pt4;
switch (plate.Quadrant)
{
case 1:
pt1 = new Vector2(0, 0);
pt2 = new Vector2(0, plate.Size.Height);
pt3 = new Vector2(plate.Size.Width, plate.Size.Height);
pt4 = new Vector2(plate.Size.Width, 0);
break;
case 2:
pt1 = new Vector2(0, 0);
pt2 = new Vector2(0, plate.Size.Height);
pt3 = new Vector2(-plate.Size.Width, plate.Size.Height);
pt4 = new Vector2(-plate.Size.Width, 0);
break;
case 3:
pt1 = new Vector2(0, 0);
pt2 = new Vector2(0, -plate.Size.Height);
pt3 = new Vector2(-plate.Size.Width, -plate.Size.Height);
pt4 = new Vector2(-plate.Size.Width, 0);
break;
case 4:
pt1 = new Vector2(0, 0);
pt2 = new Vector2(0, -plate.Size.Height);
pt3 = new Vector2(plate.Size.Width, -plate.Size.Height);
pt4 = new Vector2(plate.Size.Width, 0);
break;
default:
return;
}
doc.AddEntity(new Line(pt1, pt2) { Layer = plateLayer });
doc.AddEntity(new Line(pt2, pt3) { Layer = plateLayer });
doc.AddEntity(new Line(pt3, pt4) { Layer = plateLayer });
doc.AddEntity(new Line(pt4, pt1) { Layer = plateLayer });
}
private void AddProgram(PepProgram program)
{
mode = program.Mode;
foreach (var code in program)
{
switch (code.CodeType())
{
case CodeType.CircularMove:
var arc = (CircularMove)code;
AddCircularMove(arc);
break;
case CodeType.LinearMove:
var line = (LinearMove)code;
AddLinearMove(line);
break;
case CodeType.RapidMove:
var rapid = (RapidMove)code;
AddRapidMove(rapid);
break;
case CodeType.SubProgramCall:
var tmpmode = mode;
var subpgm = (PepLib.Codes.SubProgramCall)code;
AddProgram(subpgm.Loop);
mode = tmpmode;
break;
}
}
}
private void AddLinearMove(LinearMove line)
{
var pt = line.EndPoint.ToDxfVector();
if (mode == ProgrammingMode.Incremental)
pt += curpos;
var ln = new Line(curpos, pt);
ln.Layer = cutLayer;
doc.AddEntity(ln);
curpos = pt;
}
private void AddRapidMove(RapidMove rapid)
{
var pt = rapid.EndPoint.ToDxfVector();
if (mode == ProgrammingMode.Incremental)
pt += curpos;
var ln = new Line(curpos, pt);
ln.Layer = rapidLayer;
doc.AddEntity(ln);
curpos = pt;
}
private void AddCircularMove(CircularMove arc)
{
var center = arc.CenterPoint.ToDxfVector();
var endpt = arc.EndPoint.ToDxfVector();
if (mode == ProgrammingMode.Incremental)
{
endpt += curpos;
center += curpos;
}
// start angle in radians
var startAngle = Math.Atan2(
curpos.Y - center.Y,
curpos.X - center.X);
// end angle in radians
var endAngle = Math.Atan2(
endpt.Y - center.Y,
endpt.X - center.X);
// convert the angles to degrees
startAngle *= RadToDeg;
endAngle *= RadToDeg;
if (arc.Rotation == PepLib.RotationType.CW)
Swap(ref startAngle, ref endAngle);
var dx = endpt.X - center.X;
var dy = endpt.Y - center.Y;
var radius = Math.Sqrt(dx * dx + dy * dy);
if (startAngle.IsEqualTo(endAngle))
{
var circle = new Circle(center, radius);
circle.Layer = cutLayer;
doc.AddEntity(circle);
}
else
{
var arc2 = new Arc(center, radius, startAngle, endAngle);
arc2.Layer = cutLayer;
doc.AddEntity(arc2);
}
curpos = endpt;
}
private static void Swap<T>(ref T a, ref T b)
{
T c = a;
a = b;
b = c;
}
}
}

View File

@@ -0,0 +1,13 @@
using DxfVector = netDxf.Vector2;
using PepVector = PepLib.Vector;
namespace PepLib.Dxf
{
internal static class DxfExtensions
{
public static PepVector ToPepVector(this DxfVector v)
{
return new PepVector(v.X, v.Y);
}
}
}

View File

@@ -0,0 +1,13 @@
using DxfVector = netDxf.Vector2;
using PepVector = PepLib.Vector;
namespace PepLib.Dxf
{
internal static class PepExtensions
{
public static DxfVector ToDxfVector(this PepVector v)
{
return new DxfVector(v.X, v.Y);
}
}
}

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{E15A7403-B16D-4D11-A061-2F5E98DF36B0}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepLib.Dxf</RootNamespace>
<AssemblyName>PepLib.Dxf</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="netDxf">
<HintPath>..\..\lib\netDxf.dll</HintPath>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="DxfExtensions.cs" />
<Compile Include="DxfConverter.cs" />
<Compile Include="PepExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PepLib\PepLib.csproj">
<Project>{22360453-B878-49FA-A5DC-0D9C577DE902}</Project>
<Name>PepLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

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("PepLib.Dxf")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PepLib.Dxf")]
[assembly: AssemblyCopyright("Copyright © AJ Isaacs 2014")]
[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("5f159892-11c1-46f4-94be-ae9a7e81c1bc")]
// 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")]

BIN
PepLib.Dxf/lib/netDxf.dll Normal file

Binary file not shown.

6
PepLib.UI/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.0"/>
</startup>
</configuration>

895
PepLib.UI/LayoutView.cs Normal file
View File

@@ -0,0 +1,895 @@
using PepLib;
using PepLib.Codes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Pep.Controls
{
public class LayoutView : Control
{
private float scale;
private const int BorderWidth = 50;
private const float ZoomInFactor = 1.3f;
private const float ZoomOutFactor = 1.0f / ZoomInFactor;
private bool pathsNeedUpdated;
private GraphicsPath[] paths;
private PointF origin;
private Point lastPoint;
private readonly Brush layoutFillBrush;
private readonly Brush loopFillBrush;
private readonly Pen layoutBorderPen;
private readonly Pen loopBorderPen;
private readonly Pen rapidPen;
private readonly Pen originPen;
private readonly Pen edgeSpacingPen;
private ToolTip tooltip;
private bool isPanning;
private string selectedDrawing;
private readonly Font loopIdFont;
private Vector curpos;
private ProgrammingMode mode;
public Vector CurrentPoint { get; private set; }
public Plate Plate { get; set; }
public LayoutView()
{
paths = new GraphicsPath[0];
layoutFillBrush = new SolidBrush(Color.White);
loopFillBrush = new SolidBrush(Color.FromArgb(130, 204, 130));
loopFillBrush = new SolidBrush(Color.FromArgb(130, 204, 130));
tooltip = new ToolTip();
tooltip.UseAnimation = false;
tooltip.UseFading = false;
layoutBorderPen = new Pen(Color.Gray);
loopBorderPen = new Pen(Color.Green);
rapidPen = new Pen(Color.DodgerBlue) { DashPattern = new float[] { 10, 10 } };
originPen = new Pen(Color.Gray);
edgeSpacingPen = new Pen(Color.FromArgb(180, 180, 180)) { DashPattern = new float[] { 3, 3 } };
loopIdFont = new Font(DefaultFont, FontStyle.Bold | FontStyle.Underline);
scale = 1.0f;
origin = new PointF();
SetStyle(
ControlStyles.AllPaintingInWmPaint |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.UserPaint, true);
DrawRapid = false;
DrawBounds = false;
FillParts = true;
Plate = new Plate(60, 120);
Cursor = Cursors.Cross;
pathsNeedUpdated = true;
}
public bool DrawRapid { get; set; }
public bool DrawBounds { get; set; }
public bool FillParts { get; set; }
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
ZoomToFit();
}
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
float multiplier = Math.Abs(e.Delta / 120.0f);
if (e.Delta > 0)
ZoomToPoint(e.Location, (float)Math.Pow(ZoomInFactor, multiplier));
else
ZoomToPoint(e.Location, (float)Math.Pow(ZoomOutFactor, multiplier));
pathsNeedUpdated = true;
Invalidate();
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (e.Location == lastPoint)
return;
CurrentPoint = PointControlToWorld(e.Location);
if (e.Button == MouseButtons.Middle)
{
var diffx = e.X - lastPoint.X;
var diffy = e.Y - lastPoint.Y;
origin.X += diffx;
origin.Y += diffy;
Invalidate();
}
lastPoint = e.Location;
ShowTooltipForPartAtLocation(e.Location);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (e.Button == MouseButtons.Middle)
isPanning = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (e.Button == MouseButtons.Middle)
isPanning = false;
}
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
Focus();
if (e.Button == MouseButtons.Left)
{
var part = GetPartAtPoint(e.Location);
selectedDrawing = part?.DrawingName;
Invalidate();
}
}
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
if (e.Button == MouseButtons.Middle)
ZoomToFit();
}
protected override bool ProcessDialogKey(Keys keyData)
{
OnKeyDown(new KeyEventArgs(keyData));
return base.ProcessDialogKey(keyData);
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.KeyCode == Keys.Escape)
{
selectedDrawing = null;
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
curpos = new Vector();
e.Graphics.TranslateTransform(origin.X, origin.Y);
DrawPlate(e.Graphics);
DrawOrigin(e.Graphics);
}
private void DrawPlateInfo(Graphics g)
{
var font = new Font(Font.FontFamily, 10, FontStyle.Bold | FontStyle.Italic);
var location = new PointF(5, -LengthWorldToGui(Plate.Size.Height) - font.GetHeight());
g.DrawString(Plate.Size.ToString() + ", Qty: " + Plate.Duplicates, font, Brushes.Gray, location);
}
private void ShowTooltipForPartAtLocation(Point pt)
{
if (isPanning)
{
tooltip.Hide(this);
return;
}
var part = GetPartAtPoint(pt);
if (part == null)
{
tooltip.Hide(this);
return;
}
tooltip.ToolTipTitle = part.DrawingName;
var sb = new StringBuilder();
sb.AppendLine(string.Format("Qty on Sheet:\t{0}", Plate.GetQtyNested(part.DrawingName)));
sb.AppendLine(string.Format("Loop Name:\t{0}", part.Name));
sb.AppendLine(string.Format("Location:\t({0}, {1})", part.Location.X, part.Location.Y));
sb.AppendLine(string.Format("Rotation:\t{0}", AngleConverter.ToDegrees(part.Rotation)));
tooltip.Show(sb.ToString(), this, pt.X + 2, pt.Y + 2);
}
private void DrawOrigin(Graphics g)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
var w = 7.0f;
var hw = w / 2.0f;
var rect = new RectangleF(
-hw,
-hw,
w, w);
g.FillEllipse(Brushes.Orange, rect);
g.DrawEllipse(Pens.Red, rect);
g.SmoothingMode = SmoothingMode.HighSpeed;
}
private void DrawPlate(Graphics g)
{
Debug.WriteLine(Plate.Size.ToString());
var plateRect = new RectangleF
{
Width = LengthWorldToGui(Plate.Size.Width),
Height = LengthWorldToGui(Plate.Size.Height)
};
var edgeSpacingRect = new RectangleF
{
Width = LengthWorldToGui(Plate.Size.Width - Plate.EdgeSpacing.Left - Plate.EdgeSpacing.Right),
Height = LengthWorldToGui(Plate.Size.Height - Plate.EdgeSpacing.Top - Plate.EdgeSpacing.Bottom)
};
switch (Plate.Quadrant)
{
case 1:
plateRect.Location = PointWorldToGraph(0, 0);
edgeSpacingRect.Location = PointWorldToGraph(
Plate.EdgeSpacing.Left,
Plate.EdgeSpacing.Bottom);
break;
case 2:
plateRect.Location = PointWorldToGraph(-Plate.Size.Width, 0);
edgeSpacingRect.Location = PointWorldToGraph(
Plate.EdgeSpacing.Left - Plate.Size.Width,
Plate.EdgeSpacing.Bottom);
break;
case 3:
plateRect.Location = PointWorldToGraph(-Plate.Size.Width, -Plate.Size.Height);
edgeSpacingRect.Location = PointWorldToGraph(
Plate.EdgeSpacing.Left - Plate.Size.Width,
Plate.EdgeSpacing.Bottom - Plate.Size.Height);
break;
case 4:
plateRect.Location = PointWorldToGraph(0, -Plate.Size.Height);
edgeSpacingRect.Location = PointWorldToGraph(
Plate.EdgeSpacing.Left,
Plate.EdgeSpacing.Bottom - Plate.Size.Height);
break;
default:
return;
}
plateRect.Y -= plateRect.Height;
edgeSpacingRect.Y -= edgeSpacingRect.Height;
g.FillRectangle(layoutFillBrush, plateRect);
var viewBounds = new RectangleF(-origin.X, -origin.Y, Width, Height);
if (!edgeSpacingRect.Contains(viewBounds))
{
g.DrawRectangle(edgeSpacingPen,
edgeSpacingRect.X,
edgeSpacingRect.Y,
edgeSpacingRect.Width,
edgeSpacingRect.Height);
}
g.DrawRectangle(layoutBorderPen,
plateRect.X,
plateRect.Y,
plateRect.Width,
plateRect.Height);
DrawParts(g);
DrawPlateInfo(g);
}
private void DrawParts(Graphics g)
{
if (pathsNeedUpdated || paths.Length != Plate.Parts.Count)
UpdatePaths();
var viewBounds = new RectangleF(-origin.X, -origin.Y, Width, Height);
for (int i = 0; i < Plate.Parts.Count; ++i)
{
var part = Plate.Parts[i];
var path = paths[i];
var pathBounds = path.GetBounds();
if (!pathBounds.IntersectsWith(viewBounds))
continue;
if (DrawBounds)
DrawBox(g, part.BoundingBox);
if (part.DrawingName == selectedDrawing)
{
var brush = new SolidBrush(Color.Aqua);
var pen = new Pen(Color.Blue);
if (FillParts)
g.FillPath(brush, path);
g.DrawPath(pen, path);
}
else
{
if (FillParts)
g.FillPath(loopFillBrush, path);
g.DrawPath(loopBorderPen, path);
}
var pt = PointWorldToGraph(part.AbsoluteReferencePoint);
g.DrawString((i + 1).ToString(), loopIdFont, Brushes.Black, pt.X, pt.Y);
}
if (DrawRapid)
DrawRapids(g);
}
private void DrawProgram(GraphicsPath g, PepLib.Program pgm)
{
mode = pgm.Mode;
foreach (var code in pgm)
{
switch (code.CodeType())
{
case CodeType.CircularMove:
{
var arc = (CircularMove)code;
DrawArc(g, arc);
break;
}
case CodeType.LinearMove:
{
var line = (LinearMove)code;
DrawLine(g, line);
break;
}
case CodeType.RapidMove:
{
var rapid = (RapidMove)code;
DrawLine(g, rapid);
break;
}
case CodeType.SubProgramCall:
{
var tmpmode = mode;
var subpgm = (SubProgramCall)code;
if (subpgm.Loop != null)
{
g.StartFigure();
DrawProgram(g, subpgm.Loop);
}
mode = tmpmode;
break;
}
}
}
}
private void DrawLine(GraphicsPath g, LinearMove line)
{
var pt = line.EndPoint;
if (mode == ProgrammingMode.Incremental)
pt += curpos;
var pt1 = PointWorldToGraph(curpos);
var pt2 = PointWorldToGraph(pt);
g.AddLine(pt1, pt2);
if (line.Type == EntityType.ExternalLeadin || line.Type == EntityType.ExternalLeadout ||
line.Type == EntityType.InternalLeadin || line.Type == EntityType.InternalLeadout)
{
g.CloseFigure();
}
curpos = pt;
}
private void DrawLine(GraphicsPath g, RapidMove line)
{
var pt = line.EndPoint;
if (mode == ProgrammingMode.Incremental)
pt += curpos;
g.CloseFigure();
curpos = pt;
}
private void DrawArc(GraphicsPath g, CircularMove arc)
{
var endpt = arc.EndPoint;
var center = arc.CenterPoint;
if (mode == ProgrammingMode.Incremental)
{
endpt += curpos;
center += curpos;
}
// start angle in degrees
var startAngle = AngleConverter.ToDegrees(Math.Atan2(
curpos.Y - center.Y,
curpos.X - center.X));
// end angle in degrees
var endAngle = AngleConverter.ToDegrees(Math.Atan2(
endpt.Y - center.Y,
endpt.X - center.X));
endAngle = NormalizeAngle(endAngle);
startAngle = NormalizeAngle(startAngle);
if (arc.Rotation == RotationType.CCW && endAngle < startAngle)
endAngle += 360.0;
else if (arc.Rotation == RotationType.CW && startAngle < endAngle)
startAngle += 360.0;
var dx = endpt.X - center.X;
var dy = endpt.Y - center.Y;
var radius = Math.Sqrt(dx * dx + dy * dy);
var pt = PointWorldToGraph(center.X - radius, center.Y + radius);
var size = LengthWorldToGui(radius * 2.0);
if (startAngle.IsEqualTo(endAngle))
{
g.AddEllipse(pt.X, pt.Y, size, size);
}
else
{
var sweepAngle = -(endAngle - startAngle);
g.AddArc(pt.X, pt.Y, size, size,
(float)-startAngle, (float)sweepAngle);
if (arc.Type == EntityType.ExternalLeadin || arc.Type == EntityType.ExternalLeadout ||
arc.Type == EntityType.InternalLeadin || arc.Type == EntityType.InternalLeadout)
{
// hack to not have the graphics path fill the leadin/leadout area.
g.AddArc(pt.X, pt.Y, size, size, (float)(-startAngle + sweepAngle), (float)-sweepAngle);
g.CloseFigure();
}
}
curpos = endpt;
}
private void DrawRapids(Graphics g)
{
var pos = new Vector(0, 0);
for (int i = 0; i < Plate.Parts.Count; ++i)
{
var part = Plate.Parts[i];
var pgm = part.Program;
DrawLine(g, pos, part.Location, rapidPen);
pos = part.Location;
DrawRapids(g, pgm, ref pos);
}
}
private void DrawRapids(Graphics g, PepLib.Program pgm, ref Vector pos)
{
for (int i = 0; i < pgm.Count; ++i)
{
var code = pgm[i];
if (code.CodeType() == CodeType.SubProgramCall)
{
var subpgm = (SubProgramCall)code;
var loop = subpgm.Loop;
if (loop != null)
DrawRapids(g, loop, ref pos);
}
else
{
var motion = code as Motion;
if (motion != null)
{
if (pgm.Mode == ProgrammingMode.Incremental)
{
var endpt = motion.EndPoint + pos;
if (code.CodeType() == CodeType.RapidMove)
DrawLine(g, pos, endpt, rapidPen);
pos = endpt;
}
else
{
if (code.CodeType() == CodeType.RapidMove)
DrawLine(g, pos, motion.EndPoint, rapidPen);
pos = motion.EndPoint;
}
}
}
}
}
private void DrawLine(Graphics g, Vector pt1, Vector pt2, Pen pen)
{
var point1 = PointWorldToGraph(pt1);
var point2 = PointWorldToGraph(pt2);
g.DrawLine(pen, point1, point2);
}
private void DrawBox(Graphics g, Box box)
{
var rect = new RectangleF()
{
Location = PointWorldToGraph(box.Location),
Width = LengthWorldToGui(box.Width),
Height = LengthWorldToGui(box.Height)
};
g.DrawRectangle(Pens.Orange, rect.X, rect.Y - rect.Height, rect.Width, rect.Height);
}
private void UpdatePaths()
{
paths = new GraphicsPath[Plate.Parts.Count];
for (int i = 0; i < Plate.Parts.Count; ++i)
{
var part = Plate.Parts[i];
var path = new GraphicsPath();
curpos = part.Location;
DrawProgram(path, part.Program);
paths[i] = path;
}
pathsNeedUpdated = false;
}
public float LengthWorldToGui(double length)
{
return scale * (float)length;
}
public double LengthGuiToWorld(float length)
{
return length / scale;
}
/// <summary>
/// Returns a point with coordinates relative to the control from the graph.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Point PointGraphToControl(float x, float y)
{
return new Point((int)(x + origin.X), (int)(y + origin.Y));
}
/// <summary>
/// Returns a point with coordinates relative to the control from the graph.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public Point PointGraphToControl(PointF pt)
{
return PointGraphToControl(pt.X, pt.Y);
}
/// <summary>
/// Returns a point with coordinates relative to the control from the world.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Point PointWorldToControl(double x, double y)
{
return PointGraphToControl(PointWorldToGraph(x, y));
}
/// <summary>
/// Returns a point with coordinates relative to the control from the world.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public Point PointWorldToControl(Vector pt)
{
return PointGraphToControl(PointWorldToGraph(pt.X, pt.Y));
}
/// <summary>
/// Returns a point with coordinates relative to the graph from the control.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public PointF PointControlToGraph(int x, int y)
{
return new PointF(x - origin.X, y - origin.Y);
}
/// <summary>
/// Returns a point with coordinates relative to the graph from the control.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public PointF PointControlToGraph(Point pt)
{
return PointControlToGraph(pt.X, pt.Y);
}
/// <summary>
/// Returns a point with coordinates relative to the graph from the world.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public PointF PointWorldToGraph(double x, double y)
{
return new PointF(scale * (float)x, -scale * (float)y);
}
/// <summary>
/// Returns a point with coordinates relative to the graph from the world.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public PointF PointWorldToGraph(Vector pt)
{
return PointWorldToGraph(pt.X, pt.Y);
}
/// <summary>
/// Returns a point with coordinates relative to the world from the control.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Vector PointControlToWorld(int x, int y)
{
return PointGraphToWorld(PointControlToGraph(x, y));
}
/// <summary>
/// Returns a point with coordinates relative to the world from the control.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Vector PointControlToWorld2(int x, int y)
{
return PointGraphToWorld2(PointControlToGraph(x, y));
}
/// <summary>
/// Returns a point with coordinates relative to the world from the control.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public Vector PointControlToWorld(Point pt)
{
return PointGraphToWorld(PointControlToGraph(pt.X, pt.Y));
}
/// <summary>
/// Returns a point with coordinates relative to the world from the control.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public Vector PointControlToWorld2(Point pt)
{
return PointGraphToWorld2(PointControlToGraph(pt.X, pt.Y));
}
/// <summary>
/// Returns a point with coordinates relative to the world from the graph.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Vector PointGraphToWorld(float x, float y)
{
return new Vector(
MathHelper.RoundToNearest(x / scale, 0.03125),
MathHelper.RoundToNearest(y / -scale, 0.03125));
}
/// <summary>
/// Returns a point with coordinates relative to the world from the graph.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Vector PointGraphToWorld2(float x, float y)
{
return new Vector(x / scale, y / -scale);
}
/// <summary>
/// Returns a point with coordinates relative to the world from the graph.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public Vector PointGraphToWorld(PointF pt)
{
return PointGraphToWorld(pt.X, pt.Y);
}
/// <summary>
/// Returns a point with coordinates relative to the world from the graph.
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
public Vector PointGraphToWorld2(PointF pt)
{
return PointGraphToWorld2(pt.X, pt.Y);
}
public void RequestPathUpdate()
{
pathsNeedUpdated = true;
}
public void ZoomToPoint(Point pt, float zoomFactor)
{
var pt2 = PointControlToWorld(pt);
origin.X -= (float)(pt2.X * zoomFactor - pt2.X) * scale;
origin.Y += (float)(pt2.Y * zoomFactor - pt2.Y) * scale;
scale *= zoomFactor;
pathsNeedUpdated = true;
Invalidate();
}
public void ZoomToFit()
{
ZoomToArea(Plate.GetBoundingBox(true));
}
public void ZoomToPlate()
{
float px;
float py;
switch (Plate.Quadrant)
{
case 1:
px = 0;
py = 0;
break;
case 2:
px = (float)-Plate.Size.Width;
py = 0;
break;
case 3:
px = (float)-Plate.Size.Width;
py = (float)-Plate.Size.Height;
break;
case 4:
px = 0;
py = (float)-Plate.Size.Height;
break;
default:
return;
}
ZoomToArea(px, py, (float)Plate.Size.Width, (float)Plate.Size.Height);
}
public void ZoomToArea(Box box)
{
ZoomToArea(box.X, box.Y, box.Width, box.Height);
}
public void ZoomToArea(double x, double y, double width, double height)
{
if (width <= 0 || height <= 0)
return;
var a = (Height - BorderWidth) / height;
var b = (Width - BorderWidth) / width;
scale = (float)(a < b ? a : b);
var px = LengthWorldToGui(x);
var py = LengthWorldToGui(y);
var pw = LengthWorldToGui(width);
var ph = LengthWorldToGui(height);
origin.X = (Width - pw) * 0.5f - px;
origin.Y = (Height + ph) * 0.5f + py;
pathsNeedUpdated = true;
Invalidate();
}
private static double NormalizeAngle(double angle)
{
double r = angle % 360.0;
return r < 0 ? 360.0 + r : r;
}
public Part GetPartAtPoint(Point pt)
{
if (pathsNeedUpdated || paths.Length != Plate.Parts.Count)
UpdatePaths();
var pt2 = new PointF(pt.X - origin.X, pt.Y - origin.Y);
for (int i = Plate.Parts.Count - 1; i >= 0; i--)
{
var path = paths[i];
if (path.IsVisible(pt2))
return Plate.Parts[i];
}
return null;
}
}
}

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" 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>{7A7D21F5-8EF1-4A63-A65B-86D10BEDFC2A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepLib.UI</RootNamespace>
<AssemblyName>PepLib.UI</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</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>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="LayoutView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PepLib\PepLib.csproj">
<Project>{22360453-b878-49fa-a5dc-0d9c577de902}</Project>
<Name>PepLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

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("PepLib.UI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PepLib.UI")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[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("7a7d21f5-8ef1-4a63-a65b-86d10bedfc2a")]
// 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")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PepLib.UI.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PepLib.UI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PepLib.UI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

34
PepLib.sln Normal file
View File

@@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepLib", "PepLib\PepLib.csproj", "{22360453-B878-49FA-A5DC-0D9C577DE902}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepLib.Dxf", "PepLib.Dxf\PepLib.Dxf.csproj", "{E15A7403-B16D-4D11-A061-2F5E98DF36B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PepLib.UI", "PepLib.UI\PepLib.UI.csproj", "{7A7D21F5-8EF1-4A63-A65B-86D10BEDFC2A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{22360453-B878-49FA-A5DC-0D9C577DE902}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22360453-B878-49FA-A5DC-0D9C577DE902}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22360453-B878-49FA-A5DC-0D9C577DE902}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22360453-B878-49FA-A5DC-0D9C577DE902}.Release|Any CPU.Build.0 = Release|Any CPU
{E15A7403-B16D-4D11-A061-2F5E98DF36B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E15A7403-B16D-4D11-A061-2F5E98DF36B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E15A7403-B16D-4D11-A061-2F5E98DF36B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E15A7403-B16D-4D11-A061-2F5E98DF36B0}.Release|Any CPU.Build.0 = Release|Any CPU
{7A7D21F5-8EF1-4A63-A65B-86D10BEDFC2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A7D21F5-8EF1-4A63-A65B-86D10BEDFC2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A7D21F5-8EF1-4A63-A65B-86D10BEDFC2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A7D21F5-8EF1-4A63-A65B-86D10BEDFC2A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

17
PepLib/AngleConverter.cs Normal file
View File

@@ -0,0 +1,17 @@
using System;
namespace PepLib
{
public static class AngleConverter
{
public static double ToDegrees(double radians)
{
return 180.0 / Math.PI * radians;
}
public static double ToRadians(double degrees)
{
return Math.PI / 180.0 * degrees;
}
}
}

15
PepLib/ApplicationType.cs Normal file
View File

@@ -0,0 +1,15 @@

namespace PepLib
{
public enum ApplicationType
{
None = 0x0,
Laser = 0x1,
Flame = 0x2,
Punch = 0x3,
PlasmaPunch = 0x4,
Waterjet = 0x6,
LaserPunch = 0x7,
FlamePlasma = 0x9
}
}

154
PepLib/Box.cs Normal file
View File

@@ -0,0 +1,154 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PepLib
{
public class Box
{
public Box()
: this(0, 0, 0, 0)
{
}
public Box(double x, double y, double w, double h)
{
Location = new Vector(x, y);
Size = new PepLib.Size(0, 0);
Width = w;
Height = h;
}
public Vector Location;
public Vector Center
{
get { return new Vector(X + Width * 0.5, Y + Height * 0.5); }
}
public Size Size;
public double X
{
get { return Location.X; }
set { Location.X = value; }
}
public double Y
{
get { return Location.Y; }
set { Location.Y = value; }
}
public double Width
{
get { return Size.Width; }
set { Size.Width = value; }
}
public double Height
{
get { return Size.Height; }
set { Size.Height = value; }
}
public void MoveTo(double x, double y)
{
X = x;
Y = y;
}
public void MoveTo(Vector pt)
{
X = pt.X;
Y = pt.Y;
}
public void Offset(double x, double y)
{
X += x;
Y += y;
}
public void Offset(Vector voffset)
{
Location += voffset;
}
public double Left
{
get { return X; }
}
public double Right
{
get { return X + Width; }
}
public double Top
{
get { return Y + Height; }
}
public double Bottom
{
get { return Y; }
}
public double Area()
{
return Width * Height;
}
public double Perimeter()
{
return Width * 2 + Height * 2;
}
public bool IsIntersecting(Box box)
{
if (Left >= box.Right)
return false;
if (Right >= box.Left)
return false;
if (Top <= box.Bottom)
return false;
if (Bottom <= box.Top)
return false;
return true;
}
public bool Contains(Box box)
{
if (box.Left < Left)
return false;
if (box.Right > Right)
return false;
if (box.Bottom < Bottom)
return false;
if (box.Top > Top)
return false;
return true;
}
public bool Contains(Vector pt)
{
return pt.X >= Left && pt.X <= Right
&& pt.Y >= Bottom && pt.Y <= Top;
}
public override string ToString()
{
return string.Format("[Box: X={0}, Y={1}, Width={2}, Height={3}]", X, Y, Width, Height);
}
}
}

View File

@@ -0,0 +1,74 @@

namespace PepLib.Codes
{
public class CircularMove : Motion
{
public CircularMove()
{
}
public CircularMove(Vector endPoint, Vector centerPoint, RotationType rotation = RotationType.CCW)
{
EndPoint = endPoint;
CenterPoint = centerPoint;
Rotation = rotation;
}
public CircularMove(double x, double y, double i, double j, RotationType rotation = RotationType.CCW)
{
EndPoint = new Vector(x, y);
CenterPoint = new Vector(i, j);
Rotation = rotation;
}
public RotationType Rotation { get; set; }
public EntityType Type { get; set; }
public Vector CenterPoint { get; set; }
public override void Rotate(double angle)
{
base.Rotate(angle);
CenterPoint = CenterPoint.Rotate(angle);
}
public override void Rotate(double angle, Vector origin)
{
base.Rotate(angle, origin);
CenterPoint = CenterPoint.Rotate(angle, origin);
}
public override void Offset(double x, double y)
{
base.Offset(x, y);
CenterPoint = new Vector(CenterPoint.X + x, CenterPoint.Y + y);
}
public override void Offset(Vector voffset)
{
base.Offset(voffset);
CenterPoint += voffset;
}
public override CodeType CodeType()
{
return Codes.CodeType.CircularMove;
}
public override ICode Clone()
{
return new CircularMove(EndPoint, CenterPoint, Rotation)
{
Type = Type
};
}
public override string ToString()
{
return Rotation == RotationType.CW ?
string.Format("G02 X{0} Y{1} I{2} J{3}", EndPoint.X, EndPoint.Y, CenterPoint.X, CenterPoint.Y) :
string.Format("G03 X{0} Y{1} I{2} J{3}", EndPoint.X, EndPoint.Y, CenterPoint.X, CenterPoint.Y);
}
}
}

14
PepLib/Codes/CodeType.cs Normal file
View File

@@ -0,0 +1,14 @@

namespace PepLib.Codes
{
public enum CodeType
{
CircularMove,
Comment,
LinearMove,
RapidMove,
SetFeedrate,
SetKerf,
SubProgramCall
}
}

32
PepLib/Codes/Comment.cs Normal file
View File

@@ -0,0 +1,32 @@

namespace PepLib.Codes
{
public class Comment : ICode
{
public Comment()
{
}
public Comment(string value)
{
Value = value;
}
public string Value { get; set; }
public CodeType CodeType()
{
return Codes.CodeType.Comment;
}
public ICode Clone()
{
return new Comment(Value);
}
public override string ToString()
{
return ':' + Value;
}
}
}

View File

@@ -0,0 +1,13 @@
namespace PepLib.Codes
{
public enum EntityType
{
Display,
Scribe,
Cut,
InternalLeadin,
InternalLeadout,
ExternalLeadin,
ExternalLeadout
}
}

8
PepLib/Codes/ICode.cs Normal file
View File

@@ -0,0 +1,8 @@
namespace PepLib.Codes
{
public interface ICode
{
CodeType CodeType();
ICode Clone();
}
}

View File

@@ -0,0 +1,42 @@

namespace PepLib.Codes
{
public class LinearMove : Motion
{
public LinearMove()
: this(new Vector())
{
}
public LinearMove(double x, double y)
: this(new Vector(x, y))
{
}
public LinearMove(Vector endPoint)
{
EndPoint = endPoint;
Type = EntityType.Cut;
}
public EntityType Type { get; set; }
public override CodeType CodeType()
{
return Codes.CodeType.LinearMove;
}
public override ICode Clone()
{
return new LinearMove(EndPoint)
{
Type = Type
};
}
public override string ToString()
{
return string.Format("G01 X{0} Y{1}", EndPoint.X, EndPoint.Y);
}
}
}

32
PepLib/Codes/Motion.cs Normal file
View File

@@ -0,0 +1,32 @@

namespace PepLib.Codes
{
public abstract class Motion : IMovable, ICode
{
public Vector EndPoint { get; set; }
public virtual void Rotate(double angle)
{
EndPoint = EndPoint.Rotate(angle);
}
public virtual void Rotate(double angle, Vector origin)
{
EndPoint = EndPoint.Rotate(angle, origin);
}
public virtual void Offset(double x, double y)
{
EndPoint = new Vector(EndPoint.X + x, EndPoint.Y + y);
}
public virtual void Offset(Vector voffset)
{
EndPoint += voffset;
}
public abstract CodeType CodeType();
public abstract ICode Clone();
}
}

34
PepLib/Codes/RapidMove.cs Normal file
View File

@@ -0,0 +1,34 @@
namespace PepLib.Codes
{
public class RapidMove : Motion
{
public RapidMove()
{
}
public RapidMove(Vector endPoint)
{
EndPoint = endPoint;
}
public RapidMove(double x, double y)
{
EndPoint = new Vector(x, y);
}
public override CodeType CodeType()
{
return Codes.CodeType.RapidMove;
}
public override ICode Clone()
{
return new RapidMove(EndPoint);
}
public override string ToString()
{
return string.Format("G00 X{0} Y{1}", EndPoint.X, EndPoint.Y);
}
}
}

View File

@@ -0,0 +1,32 @@

namespace PepLib.Codes
{
public class SetFeedrate : ICode
{
public SetFeedrate()
{
}
public SetFeedrate(double value)
{
Value = value;
}
public double Value { get; set; }
public CodeType CodeType()
{
return Codes.CodeType.SetFeedrate;
}
public ICode Clone()
{
return new SetFeedrate(Value);
}
public override string ToString()
{
return string.Format("F{0}", Value);
}
}
}

34
PepLib/Codes/SetKerf.cs Normal file
View File

@@ -0,0 +1,34 @@

namespace PepLib.Codes
{
public class SetKerf : ICode
{
public SetKerf(KerfType kerf = KerfType.Left)
{
Kerf = kerf;
}
public KerfType Kerf { get; set; }
public CodeType CodeType()
{
return Codes.CodeType.SetKerf;
}
public ICode Clone()
{
return new SetKerf(Kerf);
}
public override string ToString()
{
if (Kerf == KerfType.None)
return "G40";
if (Kerf == KerfType.Left)
return "G41";
return "G42";
}
}
}

View File

@@ -0,0 +1,85 @@

namespace PepLib.Codes
{
public class SubProgramCall : ICode
{
private double rotation;
private Loop loop;
public SubProgramCall()
{
}
public SubProgramCall(int loopId, int repeatCount, double rotation)
{
LoopId = loopId;
RepeatCount = repeatCount;
Rotation = rotation;
}
/// <summary>
/// The id associated with the current set loop.
/// </summary>
public int LoopId { get; set; }
/// <summary>
/// Number of times the loop is cut.
/// </summary>
public int RepeatCount { get; set; }
/// <summary>
/// Gets or sets the loop associated with the loop id.
/// </summary>
public Loop Loop
{
get { return loop; }
set
{
loop = (Loop)value.Clone();
UpdateLoopRotation();
}
}
/// <summary>
/// Gets or sets the current rotation of the loop in degrees.
/// </summary>
public double Rotation
{
get { return rotation; }
set
{
rotation = value;
UpdateLoopRotation();
}
}
private void UpdateLoopRotation()
{
if (loop != null)
{
var diffAngle = AngleConverter.ToRadians(rotation) - loop.Rotation;
if (!diffAngle.IsEqualTo(0.0))
loop.Rotate(diffAngle);
}
}
public CodeType CodeType()
{
return Codes.CodeType.SubProgramCall;
}
public ICode Clone()
{
return new SubProgramCall(LoopId, RepeatCount, Rotation)
{
Loop = Loop
};
}
public override string ToString()
{
return string.Format("G92 L{0} R{1} P{2}", LoopId, RepeatCount, Rotation);
}
}
}

229
PepLib/Drawing.cs Normal file
View File

@@ -0,0 +1,229 @@
using System;
using System.Collections.Generic;
using System.IO;
using PepLib.IO;
namespace PepLib
{
public class Drawing
{
public DrawingInfo Info { get; set; }
public List<Loop> Loops { get; set; }
public Drawing()
{
Loops = new List<Loop>();
}
public static Drawing Load(string nestfile)
{
var reader = new DrawingReader();
reader.Read(nestfile);
return reader.Drawing;
}
public static Drawing Load(Stream stream)
{
var reader = new DrawingReader();
reader.Read(stream);
return reader.Drawing;
}
public static bool TryLoad(string nestfile, out Drawing drawing)
{
try
{
drawing = Load(nestfile);
}
catch (Exception)
{
drawing = null;
return false;
}
return true;
}
public static bool TryLoad(Stream stream, out Drawing drawing)
{
try
{
drawing = Load(stream);
}
catch (Exception)
{
drawing = null;
return false;
}
return true;
}
#region DrawingInfo wrapper properties
public string Name
{
get { return Info.Name; }
set { Info.Name = value; }
}
public string Revision
{
get { return Info.Revision; }
set { Info.Revision = value; }
}
public string Customer
{
get { return Info.Customer; }
set { Info.Customer = value; }
}
public string Description
{
get { return Info.Description; }
set { Info.Description = value; }
}
public string Comment
{
get { return Info.Comment; }
set { Info.Comment = value; }
}
public string Notes
{
get { return Info.Notes; }
set { Info.Notes = value; }
}
public string Source
{
get { return Info.Source; }
set { Info.Source = value; }
}
public DateTime CreationDate
{
get { return Info.CreationDate; }
set { Info.CreationDate = value; }
}
public DateTime LastModifiedDate
{
get { return Info.LastModifiedDate; }
set { Info.LastModifiedDate = value; }
}
public DateTime LastReferenceDate
{
get { return Info.LastReferenceDate; }
set { Info.LastReferenceDate = value; }
}
public int MachineNumber
{
get { return Info.MachineNumber; }
set { Info.MachineNumber = value; }
}
public ApplicationType Application
{
get { return Info.Application; }
set { Info.Application = value; }
}
public int MaterialNumber
{
get { return Info.MaterialNumber; }
set { Info.MaterialNumber = value; }
}
public string MaterialGrade
{
get { return Info.MaterialGrade; }
set { Info.MaterialGrade = value; }
}
public string Specification
{
get { return Info.Specification; }
set { Info.Specification = value; }
}
public string Hardness
{
get { return Info.Hardness; }
set { Info.Hardness = value; }
}
public GrainType Grain
{
get { return Info.Grain; }
set { Info.Grain = value; }
}
public string ProgrammedBy
{
get { return Info.ProgrammedBy; }
set { Info.ProgrammedBy = value; }
}
public string CreatedBy
{
get { return Info.CreatedBy; }
set { Info.CreatedBy = value; }
}
public string Errors
{
get { return Info.Errors; }
set { Info.Errors = value; }
}
public DrawingType Type
{
get { return Info.Type; }
set { Info.Type = value; }
}
public string UserDefined1
{
get { return Info.UserDefined1; }
set { Info.UserDefined1 = value; }
}
public string UserDefined2
{
get { return Info.UserDefined2; }
set { Info.UserDefined2 = value; }
}
public string UserDefined3
{
get { return Info.UserDefined3; }
set { Info.UserDefined3 = value; }
}
public string UserDefined4
{
get { return Info.UserDefined4; }
set { Info.UserDefined4 = value; }
}
public string UserDefined5
{
get { return Info.UserDefined5; }
set { Info.UserDefined5 = value; }
}
public string UserDefined6
{
get { return Info.UserDefined6; }
set { Info.UserDefined6 = value; }
}
#endregion
}
}

109
PepLib/DrawingInfo.cs Normal file
View File

@@ -0,0 +1,109 @@
using System;
using System.IO;
using System.Text;
using PepLib.IO;
namespace PepLib
{
public class DrawingInfo
{
public string Name { get; set; }
public string Revision { get; set; }
public string Customer { get; set; }
public string Description { get; set; }
public string Comment { get; set; }
public string Notes { get; set; }
public string Source { get; set; }
public DateTime CreationDate { get; set; }
public DateTime LastModifiedDate { get; set; }
public DateTime LastReferenceDate { get; set; }
public int MachineNumber { get; set; }
public ApplicationType Application { get; set; }
public int MaterialNumber { get; set; }
public string MaterialGrade { get; set; }
public string Specification { get; set; }
public string Hardness { get; set; }
public GrainType Grain { get; set; }
public string ProgrammedBy { get; set; }
public string CreatedBy { get; set; }
public string Errors { get; set; }
public DrawingType Type { get; set; }
public string UserDefined1 { get; set; }
public string UserDefined2 { get; set; }
public string UserDefined3 { get; set; }
public string UserDefined4 { get; set; }
public string UserDefined5 { get; set; }
public string UserDefined6 { get; set; }
public static DrawingInfo Load(string nestFile)
{
var reader = new DrawingInfoReader();
reader.Read(nestFile);
return reader.Info;
}
public static DrawingInfo Load(Stream stream)
{
var reader = new DrawingInfoReader();
reader.Read(stream);
return reader.Info;
}
public static bool TryLoad(string nestfile, out DrawingInfo drawingInfo)
{
try
{
drawingInfo = Load(nestfile);
}
catch (Exception)
{
drawingInfo = null;
return false;
}
return true;
}
public static bool TryLoad(Stream stream, out DrawingInfo drawingInfo)
{
try
{
drawingInfo = Load(stream);
}
catch (Exception)
{
drawingInfo = null;
return false;
}
return true;
}
}
}

12
PepLib/DrawingType.cs Normal file
View File

@@ -0,0 +1,12 @@

namespace PepLib
{
public enum DrawingType
{
None = 0x20,
Drawing = 0x44,
Product = 0x50,
Rotary = 0x52,
Tool = 0x54
}
}

17
PepLib/Generic.cs Normal file
View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PepLib
{
public static class Generic
{
public static void Swap<T>(ref T a, ref T b)
{
T c = a;
a = b;
b = c;
}
}
}

11
PepLib/GrainType.cs Normal file
View File

@@ -0,0 +1,11 @@

namespace PepLib
{
public enum GrainType
{
No = 0x0,
Yes = 0x1,
Soft = 0x2,
Hard = 0x3
}
}

10
PepLib/IMovable.cs Normal file
View File

@@ -0,0 +1,10 @@
namespace PepLib
{
public interface IMovable
{
void Rotate(double angle);
void Rotate(double angle, Vector origin);
void Offset(double x, double y);
void Offset(Vector voffset);
}
}

View File

@@ -0,0 +1,100 @@
using System;
using System.IO;
using System.Text;
namespace PepLib.IO
{
public sealed class DrawingInfoReader
{
public DrawingInfo Info { get; private set; }
public DrawingInfoReader()
{
Info = new DrawingInfo();
}
public DrawingInfoReader(DrawingInfo info)
{
Info = info;
}
public void Read(Stream stream)
{
Info.Name = ReadString(0xC8, ref stream);
Info.Revision = ReadString(0x20, ref stream);
Info.CreationDate = DateTime.Parse(ReadString(0xA, ref stream));
Info.LastModifiedDate = DateTime.Parse(ReadString(0xA, ref stream));
Info.LastReferenceDate = DateTime.Parse(ReadString(0xA, ref stream));
Info.Description = ReadString(0xC8, ref stream);
Info.Customer = ReadString(0x40, ref stream);
Info.Comment = ReadString(0x40, ref stream);
Info.Notes = ReadString(0x400, ref stream);
Info.Grain = (GrainType)ReadByte(ref stream);
stream.Seek(0x9, SeekOrigin.Current);
Info.MaterialNumber = int.Parse(ReadString(0x40, ref stream));
Info.MaterialGrade = ReadString(0x10, ref stream);
Info.ProgrammedBy = ReadString(0x40, ref stream);
Info.CreatedBy = ReadString(0x40, ref stream);
Info.Type = (DrawingType)ReadByte(ref stream);
stream.Seek(0x4, SeekOrigin.Current);
Info.Errors = ReadString(0x64, ref stream);
Info.Hardness = ReadString(0x20, ref stream);
Info.Specification = ReadString(0x40, ref stream);
stream.Seek(0x2, SeekOrigin.Current);
Info.UserDefined1 = ReadString(0x20, ref stream);
Info.UserDefined2 = ReadString(0x20, ref stream);
Info.UserDefined3 = ReadString(0x20, ref stream);
Info.UserDefined4 = ReadString(0x40, ref stream);
Info.UserDefined5 = ReadString(0x40, ref stream);
Info.UserDefined6 = ReadString(0x40, ref stream);
Info.MachineNumber = ReadByte(ref stream);
stream.Seek(0x1, SeekOrigin.Current);
Info.Application = (ApplicationType)ReadByte(ref stream);
}
public void Read(string nestFile)
{
if (!File.Exists(nestFile))
{
var msg = string.Format("File Not Found: {0}", nestFile);
throw new FileNotFoundException(msg);
}
Stream stream = null;
string name;
try
{
ZipHelper.ExtractByExtension(nestFile, ".dir", out name, out stream);
Read(stream);
}
finally
{
if (stream != null)
stream.Close();
}
}
private static string ReadString(int length, ref Stream stream)
{
var buffer = new byte[length];
stream.Read(buffer, 0, length);
return Encoding.Default.GetString(buffer).Trim();
}
private static byte ReadByte(ref Stream stream)
{
var buffer = new byte[0x1];
stream.Read(buffer, 0, 1);
return buffer[0];
}
}
}

112
PepLib/IO/DrawingReader.cs Normal file
View File

@@ -0,0 +1,112 @@
using Ionic.Zip;
using System;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
namespace PepLib.IO
{
public sealed class DrawingReader
{
public Drawing Drawing { get; private set; }
public DrawingReader()
{
Drawing = new Drawing();
}
public DrawingReader(Drawing drawing)
{
Drawing = drawing;
}
public void Read(Stream stream)
{
var drawing = new Drawing();
var zipStream = new ZipInputStream(stream);
ZipEntry theEntry;
while ((theEntry = zipStream.GetNextEntry()) != null)
{
var size = 2048;
var data = new byte[size];
var memstream = new MemoryStream();
while (true)
{
size = zipStream.Read(data, 0, data.Length);
if (size > 0)
{
memstream.Write(data, 0, size);
memstream.Flush();
}
else break;
}
memstream.Seek(0, SeekOrigin.Begin);
var extension = Path.GetExtension(theEntry.FileName);
switch (extension)
{
case ".dir":
LoadInfo(memstream);
memstream.Close();
continue;
}
if (Regex.IsMatch(extension, "loop-\\d\\d\\d"))
drawing.Loops.Add(ReadLoop(theEntry.FileName, memstream));
memstream.Close();
}
zipStream.Close();
}
public void Read(string nestFile)
{
if (!File.Exists(nestFile))
{
var msg = string.Format("File Not Found: {0}", nestFile);
throw new FileNotFoundException(msg);
}
Stream stream = null;
try
{
stream = new FileStream(nestFile, FileMode.Open);
Read(stream);
}
finally
{
if (stream != null)
stream.Close();
}
}
private void LoadInfo(Stream stream)
{
try
{
Drawing.Info = DrawingInfo.Load(stream);
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
Debug.WriteLine(exception.StackTrace);
}
}
private Loop ReadLoop(string name, Stream stream)
{
var reader = new LoopReader();
reader.Read(name, stream);
return reader.Loop;
}
}
}

134
PepLib/IO/LoopReader.cs Normal file
View File

@@ -0,0 +1,134 @@
using System;
using System.IO;
using PepLib.Codes;
namespace PepLib.IO
{
internal sealed class LoopReader
{
public Loop Loop { get; private set; }
public LoopReader()
{
Loop = new Loop();
}
public LoopReader(Loop loop)
{
Loop = loop;
}
public void Read(string name, Stream stream)
{
var pgm = Program.Load(stream);
Loop.Name = name;
Loop.AddRange(pgm);
LoadInfo();
}
private void LoadInfo()
{
for (int i = Loop.Count - 1; i >= 0; --i)
{
var code = Loop[i];
if (code.CodeType() != CodeType.Comment)
continue;
var comment = (Comment)code;
if (LoadInfo(comment.Value))
Loop.RemoveAt(i);
}
}
private bool LoadInfo(string value)
{
if (value.StartsWith("REF"))
{
ParseReferenceData(value);
return true;
}
if (value.StartsWith("DRAWING"))
{
ParseDrawingData(value);
return true;
}
if (value.StartsWith("DXF"))
{
ParseDxfData(value);
return true;
}
return false;
}
private void ParseReferenceData(string data)
{
var parts = data.Split(',');
if (parts.Length != 3)
return;
int xindex = parts[0].IndexOf('X');
parts[0] = parts[0].Remove(0, xindex);
double x = 0;
double y = 0;
var xsplit = parts[0].Split('=');
if (xsplit.Length == 2)
x = ReadDouble(xsplit[1]);
var ysplit = parts[1].Split('=');
if (ysplit.Length == 2)
y = ReadDouble(ysplit[1]);
var datesplit = parts[2].Split('=');
if (datesplit.Length == 2)
{
DateTime date;
DateTime.TryParse(datesplit[1], out date);
Loop.LastReferenceDate = date;
}
Loop.ReferencePoint = new Vector(x, y);
}
private void ParseDrawingData(string data)
{
var index = data.IndexOf('=');
if (index == -1)
Loop.DrawingName = string.Empty;
Loop.DrawingName = data.Remove(0, index + 1).Trim();
}
private void ParseDxfData(string data)
{
var index = data.IndexOf('=');
if (index == -1)
Loop.DxfPath = string.Empty;
Loop.DxfPath = data.Remove(0, index + 1).Trim();
}
private static double ReadDouble(string s, double defaultValue = 0.0)
{
double f;
if (!double.TryParse(s, out f))
return defaultValue;
return f;
}
}
}

View File

@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PepLib.IO
{
public class MaterialDataReader
{
public List<MaterialData> Materials { get; set; }
public MaterialDataReader()
{
Materials = new List<MaterialData>();
}
public void Read(Stream stream)
{
const int dataLength = 2000;
var count = stream.Length / dataLength;
for (int i = 0; i < count; i++)
{
var data = new MaterialData();
int id;
int.TryParse(ReadString(64, ref stream), out id);
data.Id = id;
data.Grade = ReadString(16, ref stream);
data.Name = ReadString(200, ref stream);
Materials.Add(data);
stream.Position = i * dataLength;
}
}
public void Read(string file)
{
if (!File.Exists(file))
{
var msg = string.Format("File Not Found: {0}", file);
throw new FileNotFoundException(msg);
}
Stream stream = null;
try
{
stream = File.OpenRead(file);
Read(stream);
}
finally
{
if (stream != null)
stream.Close();
}
}
private static string ReadString(int length, ref Stream stream)
{
var buffer = new byte[length];
stream.Read(buffer, 0, length);
return Encoding.Default.GetString(buffer).Trim();
}
private static byte ReadByte(ref Stream stream)
{
var buffer = new byte[0x1];
stream.Read(buffer, 0, 1);
return buffer[0];
}
}
public class MaterialData
{
public int Id { get; set; }
public string Name { get; set; }
public string Grade { get; set; }
}
}

124
PepLib/IO/NestInfoReader.cs Normal file
View File

@@ -0,0 +1,124 @@
using System;
using System.IO;
using System.Text;
namespace PepLib.IO
{
internal sealed class NestInfoReader
{
public NestInfo Info { get; private set; }
public NestInfoReader()
{
Info = new NestInfo();
}
public NestInfoReader(NestInfo info)
{
Info = info;
}
public void Read(Stream stream)
{
var binReader = new BinaryReader(stream);
Info.Name = ReadString(0xC8, ref stream);
Info.DateCreated = DateTime.Parse(ReadString(0xA, ref stream));
Info.DateLastModified = DateTime.Parse(ReadString(0xA, ref stream));
Info.LoopCount = binReader.ReadInt16();
Info.ProgramCount = binReader.ReadInt16();
Info.Customer = ReadString(0x40, ref stream);
Info.ProgrammedBy = ReadString(0x40, ref stream);
Info.Comments = ReadString(0x40, ref stream);
// skip 2 bytes
stream.Seek(0x2, SeekOrigin.Current);
Info.MaterialNumber = int.Parse(ReadString(0x40, ref stream));
Info.MaterialGrade = ReadString(0x10, ref stream);
// skip 2 bytes
stream.Seek(0x2, SeekOrigin.Current);
Info.Notes = ReadString(0x400, ref stream);
Info.PostedAs = ReadString(0x64, ref stream);
Info.Errors = ReadString(0x64, ref stream);
Info.UserDefined1 = ReadString(0x20, ref stream);
Info.UserDefined2 = ReadString(0x20, ref stream);
Info.UserDefined3 = ReadString(0x20, ref stream);
Info.UserDefined4 = ReadString(0x40, ref stream);
Info.UserDefined5 = ReadString(0x40, ref stream);
Info.UserDefined6 = ReadString(0x40, ref stream);
Info.DefaultPlateSize = ReadString(0x1E, ref stream);
Info.Kerf = ReadString(0x3, ref stream);
// skip 4 bytes
stream.Seek(0x4, SeekOrigin.Current);
switch (ReadByte(ref stream))
{
case 0:
Info.Status = StatusType.ToBeCut;
break;
case 1:
Info.Status = StatusType.Quote;
break;
case 2:
Info.Status = StatusType.HasBeenCut;
break;
case 3:
Info.Status = StatusType.Temp;
break;
default:
Info.Status = StatusType.ToBeCut;
break;
}
// skip 16 bytes
stream.Seek(16, SeekOrigin.Current);
Info.PlateCount = binReader.ReadInt16();
}
public void Read(string nestFile)
{
if (!File.Exists(nestFile))
{
var msg = string.Format("File Not Found: {0}", nestFile);
throw new FileNotFoundException(msg);
}
Stream stream = null;
string name;
try
{
ZipHelper.ExtractByExtension(nestFile, ".dir", out name, out stream);
Read(stream);
}
finally
{
if (stream != null)
stream.Close();
}
}
private static string ReadString(int length, ref Stream stream)
{
var buffer = new byte[length];
stream.Read(buffer, 0, length);
return Encoding.Default.GetString(buffer).Trim();
}
private static byte ReadByte(ref Stream stream)
{
var buffer = new byte[0x1];
stream.Read(buffer, 0, 1);
return buffer[0];
}
}
}

181
PepLib/IO/NestReader.cs Normal file
View File

@@ -0,0 +1,181 @@
using Ionic.Zip;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace PepLib.IO
{
public sealed class NestReader
{
public Nest Nest { get; private set; }
private readonly Dictionary<string, Stream> plates;
private readonly Dictionary<string, Stream> loops;
public NestReader()
: this(new Nest())
{
}
public NestReader(Nest nest)
{
Nest = nest;
plates = new Dictionary<string, Stream>();
loops = new Dictionary<string, Stream>();
}
public void Read(Stream stream)
{
const string plateExtensionPattern = "plate-\\d\\d\\d";
const string loopExtensionPattern = "loop-\\d\\d\\d";
var zipStream = new ZipInputStream(stream);
ZipEntry theEntry;
while ((theEntry = zipStream.GetNextEntry()) != null)
{
var size = 2048;
var data = new byte[size];
var memstream = new MemoryStream();
while (true)
{
size = zipStream.Read(data, 0, data.Length);
if (size > 0)
{
memstream.Write(data, 0, size);
memstream.Flush();
}
else break;
}
memstream.Seek(0, SeekOrigin.Begin);
var extension = Path.GetExtension(theEntry.FileName);
switch (extension)
{
case ".dir":
LoadInfo(memstream);
memstream.Close();
continue;
case ".report":
LoadReport(memstream);
memstream.Close();
continue;
case ".dwg-info":
LoadDrawingInfo(memstream);
memstream.Close();
continue;
default:
Debug.WriteLine("Unknown file: " + theEntry.FileName);
break;
}
if (Regex.IsMatch(extension, loopExtensionPattern))
loops.Add(theEntry.FileName, memstream);
else if (Regex.IsMatch(extension, plateExtensionPattern))
plates.Add(theEntry.FileName, memstream);
}
zipStream.Close();
foreach (var loop in loops)
Nest.Loops.Add(ReadLoop(loop.Key, loop.Value));
Nest.ResolveLoops();
foreach (var plate in plates)
Nest.Plates.Add(ReadPlate(plate.Key, plate.Value));
}
public void Read(string nestFile)
{
if (!File.Exists(nestFile))
{
var msg = string.Format("File Not Found: {0}", nestFile);
throw new FileNotFoundException(msg);
}
Stream stream = null;
try
{
stream = new FileStream(nestFile, FileMode.Open);
Read(stream);
}
finally
{
if (stream != null)
stream.Close();
}
}
private void LoadInfo(Stream stream)
{
try
{
Nest.Info = NestInfo.Load(stream);
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
Debug.WriteLine(exception.StackTrace);
}
}
private void LoadReport(Stream stream)
{
try
{
Nest.Report = Report.Load(stream);
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
Debug.WriteLine(exception.StackTrace);
}
}
private void LoadDrawingInfo(Stream stream)
{
var reader = new BinaryReader(stream);
var buffer = new byte[2000];
while (stream.Read(buffer, 0, buffer.Length) > 0)
{
var name = Encoding.Default.GetString(buffer, 200, 200);
var qty = BitConverter.ToInt32(buffer, 432);
var drawing = new NestDrawing();
drawing.Name = Encoding.Default.GetString(buffer, 200, 200).Trim();
drawing.QtyRequired = BitConverter.ToInt32(buffer, 432);
Nest.Drawings.Add(drawing);
}
}
private Loop ReadLoop(string name, Stream stream)
{
var reader = new LoopReader();
reader.Read(name, stream);
return reader.Loop;
}
private Plate ReadPlate(string name, Stream stream)
{
var reader = new PlateReader();
reader.Read(name, stream, Nest);
return reader.Plate;
}
}
}

322
PepLib/IO/PlateReader.cs Normal file
View File

@@ -0,0 +1,322 @@
using System.IO;
using PepLib.Codes;
namespace PepLib.IO
{
internal sealed class PlateReader
{
public Plate Plate { get; private set; }
public PlateReader()
{
Plate = new Plate();
Plate.Duplicates = 1;
}
public PlateReader(Plate plate)
{
Plate = plate;
}
public void Read(string name, Stream stream, Nest nest)
{
var pos = new Vector(0, 0);
var pgm = Program.Load(stream);
Plate.Name = name;
foreach (var code in pgm)
{
switch (code.CodeType())
{
case CodeType.CircularMove:
{
var arc = (CircularMove)code;
pos = arc.EndPoint;
break;
}
case CodeType.LinearMove:
{
var line = (LinearMove)code;
pos = line.EndPoint;
break;
}
case CodeType.RapidMove:
{
var rapid = (RapidMove)code;
pos = rapid.EndPoint;
break;
}
case CodeType.Comment:
{
var comment = (Comment)code;
LoadInfo(comment.Value);
break;
}
case CodeType.SubProgramCall:
{
var subpgm = (SubProgramCall)code;
var loop = nest.GetLoop(subpgm.LoopId);
var part = Part.Create(loop, pos, AngleConverter.ToRadians(subpgm.Rotation));
Plate.Parts.Add(part);
break;
}
}
}
}
private void LoadInfo(string value)
{
if (value.StartsWith("POSTED FILES"))
ParsePostedFiles(value);
else if (value.StartsWith("HEAT LOT"))
ParseHeatLot(value);
else if (value.StartsWith("SPACING"))
ParseSpacing(value);
else if (value.StartsWith("CUT A TOTAL OF "))
ParseNumberOfDuplicates(value);
else if (value.StartsWith("EDGES,"))
ParseEdgeSpacing(value);
else if (value.StartsWith("PLATE SCALING"))
ParsePlateSize(value);
else if (value.StartsWith("MACHINE"))
ParseMachine(value);
else if (value.StartsWith("MATERIAL"))
ParseMaterial(value);
else if (value.StartsWith("GRADE"))
ParseGrade(value);
else if (value.StartsWith("DESCRIPTION"))
ParseDescription(value);
else if (value.StartsWith("PLATE THICKNESS"))
ParseThickness(value);
else if (value.StartsWith("DENSITY"))
ParseDensity(value);
else if (value.StartsWith("TORCHES"))
ParseTorchCount(value);
}
private void ParseNumberOfDuplicates(string data)
{
var parts = data.Split(' ');
if (parts.Length != 7)
return;
int dup;
int.TryParse(parts[4], out dup);
Plate.Duplicates = dup;
}
private void ParsePostedFiles(string data)
{
if (data.Length < 14)
return;
Plate.PostedFiles = data.Remove(0, 14).Trim();
}
private void ParseHeatLot(string data)
{
if (data.Length < 9)
return;
Plate.HeatLot = data.Remove(0, 9).Trim();
}
private void ParseSpacing(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
double spacing;
double.TryParse(parts[1], out spacing);
Plate.PartSpacing = spacing;
}
private void ParseEdgeSpacing(string data)
{
var parts = data.Split(',');
if (parts.Length != 5)
return;
var leftSplit = parts[1].Split('=');
if (leftSplit.Length == 2)
{
double x;
double.TryParse(leftSplit[1], out x);
Plate.EdgeSpacing.Left = x;
}
var bottomSplit = parts[2].Split('=');
if (bottomSplit.Length == 2)
{
double x;
double.TryParse(bottomSplit[1], out x);
Plate.EdgeSpacing.Bottom = x;
}
var rightSplit = parts[3].Split('=');
if (rightSplit.Length == 2)
{
double x;
double.TryParse(rightSplit[1], out x);
Plate.EdgeSpacing.Right = x;
}
var topSplit = parts[4].Split('=');
if (topSplit.Length == 2)
{
double x;
double.TryParse(topSplit[1], out x);
Plate.EdgeSpacing.Top = x;
}
}
private void ParsePlateSize(string data)
{
var quadrantIndex = data.IndexOf("QUADRANT");
if (quadrantIndex != -1)
{
var plateData = data.Remove(quadrantIndex);
var plateDataSplit = plateData.Split('=');
if (plateDataSplit.Length == 2)
{
Size plateSize;
Size.TryParse(plateDataSplit[1], out plateSize);
Plate.Size = plateSize;
}
var quadrantData = data.Remove(0, quadrantIndex);
var quadrantDataSplit = quadrantData.Split('=');
if (quadrantDataSplit.Length == 2)
{
int quadrant;
int.TryParse(quadrantDataSplit[1], out quadrant);
Plate.Quadrant = quadrant;
}
}
else
{
var plateDataSplit = data.Split('=');
if (plateDataSplit.Length == 2)
{
Size plateSize;
Size.TryParse(plateDataSplit[1], out plateSize);
Plate.Size = plateSize;
}
}
}
private void ParseMachine(string data)
{
var parts = data.Split(',');
if (parts.Length != 2)
return;
var machineSplit = parts[0].Split('=');
if (machineSplit.Length == 2)
{
int num;
int.TryParse(machineSplit[1], out num);
Plate.Machine.Id = num;
}
Plate.Machine.Name = parts[1].Trim();
}
private void ParseMaterial(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
int material;
int.TryParse(parts[1], out material);
Plate.Material.Id = material;
}
private void ParseGrade(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
Plate.Material.Grade = parts[1].Trim();
}
private void ParseDescription(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
Plate.Description = parts[1].Trim();
}
private void ParseThickness(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
double thickness;
double.TryParse(parts[1], out thickness);
Plate.Thickness = thickness;
}
private void ParseDensity(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
double density;
double.TryParse(parts[1], out density);
Plate.Material.Density = density;
}
private void ParseTorchCount(string data)
{
var parts = data.Split('=');
if (parts.Length != 2)
return;
int torchCount;
int.TryParse(parts[1], out torchCount);
Plate.TorchCount = torchCount;
}
}
}

404
PepLib/IO/ProgramReader.cs Normal file
View File

@@ -0,0 +1,404 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using PepLib.Codes;
namespace PepLib.IO
{
internal sealed class ProgramReader
{
private const int BufferSize = 200;
private int codeIndex;
private CodeBlock block;
private CodeSection section;
public Program Program { get; private set; }
public ProgramReader()
{
Program = new Program();
}
public ProgramReader(Program program)
{
Program = program;
}
public void Read(Stream stream)
{
foreach (var line in GetLines(stream))
{
block = ParseBlock(line);
ProcessCurrentBlock();
}
}
private IEnumerable<string> GetLines(Stream stream)
{
var buffer = new byte[BufferSize];
while (stream.Read(buffer, 0, BufferSize) > 0)
{
yield return Encoding.ASCII.GetString(buffer);
}
}
private CodeBlock ParseBlock(string line)
{
var block = new CodeBlock();
Code code = null;
for (int i = 0; i < line.Length; ++i)
{
var c = line[i];
if (char.IsLetter(c))
block.Add((code = new Code(c)));
else if (c == ':')
{
block.Add((new Code(c, line.Remove(0, i + 1).Trim())));
break;
}
else if (code != null)
code.Value += c;
}
return block;
}
private void ProcessCurrentBlock()
{
var code = GetFirstCode();
while (code != null)
{
switch (code.Id)
{
case ':':
Program.Add(new Comment(code.Value));
code = GetNextCode();
break;
case 'G':
int value = int.Parse(code.Value);
switch (value)
{
case 0:
case 1:
section = CodeSection.Line;
ReadLine(value == 0);
code = GetCurrentCode();
break;
case 2:
case 3:
section = CodeSection.Arc;
ReadArc(value == 2 ? RotationType.CW : RotationType.CCW);
code = GetCurrentCode();
break;
case 92:
section = CodeSection.SubProgram;
ReadSubProgram();
code = GetCurrentCode();
break;
case 40:
Program.Add(new SetKerf() { Kerf = KerfType.None });
code = GetNextCode();
break;
case 41:
Program.Add(new SetKerf() { Kerf = KerfType.Left });
code = GetNextCode();
break;
case 42:
Program.Add(new SetKerf() { Kerf = KerfType.Right });
code = GetNextCode();
break;
default:
code = GetNextCode();
break;
}
break;
case 'F':
Program.Add(new SetFeedrate() { Value = double.Parse(code.Value) });
code = GetNextCode();
break;
default:
code = GetNextCode();
break;
}
}
}
private void ReadLine(bool isRapid)
{
double x = 0;
double y = 0;
var type = EntityType.Cut;
while (section == CodeSection.Line)
{
var code = GetNextCode();
if (code == null)
{
section = CodeSection.Unknown;
break;
}
switch (code.Id)
{
case 'X':
x = double.Parse(code.Value);
break;
case 'Y':
y = double.Parse(code.Value);
break;
case ':':
{
var value = code.Value.Trim().ToUpper();
switch (value)
{
case "EXTERNAL LEAD-IN":
type = EntityType.ExternalLeadin;
break;
case "EXTERNAL LEAD-OUT":
type = EntityType.ExternalLeadout;
break;
case "INTERNAL LEAD-IN":
type = EntityType.InternalLeadin;
break;
case "INTERNAL LEAD-OUT":
type = EntityType.InternalLeadout;
break;
case "DISPLAY":
type = EntityType.Display;
break;
}
break;
}
default:
section = CodeSection.Unknown;
break;
}
}
if (isRapid)
Program.Add(new RapidMove(x, y));
else
Program.Add(new LinearMove(x, y) { Type = type });
}
private void ReadArc(RotationType rotation)
{
double x = 0;
double y = 0;
double i = 0;
double j = 0;
var type = EntityType.Cut;
while (section == CodeSection.Arc)
{
var code = GetNextCode();
if (code == null)
{
section = CodeSection.Unknown;
break;
}
switch (code.Id)
{
case 'X':
x = double.Parse(code.Value);
break;
case 'Y':
y = double.Parse(code.Value);
break;
case 'I':
i = double.Parse(code.Value);
break;
case 'J':
j = double.Parse(code.Value);
break;
case ':':
{
var value = code.Value.Trim().ToUpper();
switch (value)
{
case "EXTERNAL LEAD-IN":
type = EntityType.ExternalLeadin;
break;
case "EXTERNAL LEAD-OUT":
type = EntityType.ExternalLeadout;
break;
case "INTERNAL LEAD-IN":
type = EntityType.InternalLeadin;
break;
case "INTERNAL LEAD-OUT":
type = EntityType.InternalLeadout;
break;
case "DISPLAY":
type = EntityType.Display;
break;
}
break;
}
default:
section = CodeSection.Unknown;
break;
}
}
Program.Add(new CircularMove()
{
EndPoint = new Vector(x, y),
CenterPoint = new Vector(i, j),
Rotation = rotation,
Type = type
});
}
private void ReadSubProgram()
{
int l = 0;
int r = 0;
double p = 0;
while (section == CodeSection.SubProgram)
{
var code = GetNextCode();
if (code == null)
{
section = CodeSection.Unknown;
break;
}
switch (code.Id)
{
case 'L':
l = int.Parse(code.Value);
break;
case 'R':
r = int.Parse(code.Value);
break;
case 'P':
p = double.Parse(code.Value);
break;
default:
section = CodeSection.Unknown;
break;
}
}
Program.Add(new SubProgramCall() { LoopId = l, RepeatCount = r, Rotation = p });
}
private Code GetNextCode()
{
codeIndex++;
if (codeIndex >= block.Count)
return null;
return block[codeIndex];
}
private Code GetCurrentCode()
{
if (codeIndex >= block.Count)
return null;
return block[codeIndex];
}
private Code GetFirstCode()
{
if (block.Count == 0)
return null;
codeIndex = 0;
return block[codeIndex];
}
private class Code
{
public Code(char id)
{
Id = id;
Value = string.Empty;
}
public Code(char id, string value)
{
Id = id;
Value = value;
}
public char Id { get; private set; }
public string Value { get; set; }
public override string ToString()
{
return Id + Value;
}
}
private class CodeBlock : List<Code>
{
public void Add(char id, string value)
{
Add(new Code(id, value));
}
public override string ToString()
{
var builder = new StringBuilder();
foreach (var code in this)
builder.Append(code.ToString() + " ");
return builder.ToString();
}
}
private enum CodeSection
{
Unknown,
Arc,
Line,
SubProgram
}
}
}

378
PepLib/IO/ReportReader.cs Normal file
View File

@@ -0,0 +1,378 @@
using System;
using System.Diagnostics;
using System.IO;
namespace PepLib.IO
{
internal sealed class ReportReader
{
public Report Report { get; private set; }
public ReportReader()
{
Report = new Report();
}
public ReportReader(Report report)
{
Report = report;
}
public void Read(Stream stream)
{
var reader = new StreamReader(stream);
Report.Drawing dwg = null;
Report.Plate plt = null;
var section = Section.Unknown;
string line;
while ((line = reader.ReadLine()) != null)
{
var equalIndex = line.IndexOf('=');
if (equalIndex != -1)
{
var valueIndex = equalIndex + 1;
var key = line.Substring(0, equalIndex).Trim();
var value = line.Substring(valueIndex, line.Length - valueIndex).Trim();
switch (section)
{
case Section.NestHeader:
ReadNestHeaderData(key, value);
break;
case Section.NestedPlates:
ReadNestedPlatesData(key, value, plt);
break;
case Section.QuantitiesNested:
ReadQuantitiesNestedData(key, value, dwg);
break;
case Section.Unknown:
break;
}
}
else
{
var category = line.Trim();
switch (category)
{
case "Nest header":
section = Section.NestHeader;
continue;
case "Nested plates":
section = Section.NestedPlates;
continue;
case "Quantities nested":
section = Section.QuantitiesNested;
continue;
}
switch (section)
{
case Section.NestedPlates:
if (category.StartsWith("Plate"))
Report.Plates.Add((plt = new Report.Plate()));
break;
case Section.QuantitiesNested:
if (category.StartsWith("Drawing"))
Report.Drawings.Add((dwg = new Report.Drawing()));
break;
default:
Debug.WriteLine("Unknown category: " + category);
break;
}
}
}
}
public void Read(string nestFile)
{
if (!File.Exists(nestFile))
{
var msg = string.Format("File Not Found: {0}", nestFile);
throw new FileNotFoundException(msg);
}
Stream stream = null;
string name;
try
{
ZipHelper.ExtractByExtension(nestFile, ".report", out name, out stream);
Read(stream);
}
finally
{
if (stream != null)
stream.Close();
}
}
private void ReadNestHeaderData(string key, string value)
{
switch (key)
{
case "Program":
Report.Name = value;
break;
case "Customer name":
Report.Customer = value;
break;
case "Date programmed":
DateTime date;
DateTime.TryParse(value, out date);
Report.DateProgrammed = date;
break;
case "Material":
Report.Material = value;
break;
case "Programmed by":
Report.ProgrammedBy = value;
break;
case "Machine":
Report.Machine = value;
break;
case "Comments":
Report.Comments = value;
break;
case "Remarks":
Report.Remarks = value;
break;
default:
Debug.WriteLine(string.Format("Report.ReadNestHeaderData: \"{0}\" not implemented", key));
break;
}
}
private void ReadNestedPlatesData(string key, string value, Report.Plate plt)
{
switch (key)
{
case "Plate number":
plt.Name = value;
break;
case "Thickness":
plt.Thickness = ParseDouble(value);
break;
case "Plate Size":
ReadPlateSize(value, plt);
break;
case "Material":
plt.MaterialNumber = ParseInt32(value);
break;
case "Grade":
plt.MaterialGrade = value;
break;
case "Material Description":
plt.MaterialDescription = value;
break;
case "Dup plates":
plt.Quantity = int.Parse(value);
break;
case "Plate Util":
plt.PlateUtilization = ParsePercent(value);
break;
case "Material Util":
plt.MaterialUtilization = ParsePercent(value);
break;
case "Total Area1":
plt.Area1 = ParseDouble(value);
break;
case "Total Area2":
plt.Area2 = ParseDouble(value);
break;
case "Bubble pierces":
plt.BubblePierceCount = ParseInt32(value);
break;
case "Total cutting time":
ReadCuttingTime(value, Report);
break;
case "Cutting feedrate":
Report.CutFeedrate = ParseInt32(value);
break;
case "Rapid feedrate":
Report.RapidFeedrate = ParseInt32(value);
break;
default:
Debug.WriteLine(string.Format("Report.ReadNestedPlatesData: \"{0}\" not implemented", key));
break;
}
}
private void ReadQuantitiesNestedData(string key, string value, Report.Drawing dwg)
{
switch (key)
{
case "Customer Name":
dwg.Customer = value;
break;
case "Drawing Name":
dwg.Name = value;
break;
case "Revision":
dwg.Revision = value;
break;
case "Qty Req":
dwg.QtyRequired = ParseInt32(value);
break;
case "Qty Nstd":
dwg.QtyNested = ParseInt32(value);
break;
case "# of Pierces":
dwg.PierceCount = ParseInt32(value);
break;
case "Intersections":
dwg.IntersectionCount = ParseInt32(value);
break;
case "Area1*":
dwg.Area1 = ParseDouble(value);
break;
case "Area2**":
dwg.Area2 = ParseDouble(value);
break;
case "% of Material":
dwg.PercentOfMaterial = ParsePercent(value);
break;
case "% of Time":
dwg.PercentOfCutTime = ParsePercent(value);
dwg.TotalCutTime =
TimeSpan.FromTicks((long)(Report.TotalCutTime.Ticks * dwg.PercentOfCutTime / 100.0));
break;
default:
Debug.WriteLine(string.Format("Report.ReadQuantitiesNestedData: \"{0}\" not implemented", key));
break;
}
}
private void ReadPlateSize(string value, Report.Plate plt)
{
var a = value.ToUpper().Split('X');
var x = float.Parse(a[0]);
var y = float.Parse(a[1]);
if (x < y)
{
plt.Width = x;
plt.Length = y;
}
else
{
plt.Width = y;
plt.Length = x;
}
}
private void ReadCuttingTime(string value, Report report)
{
var parts = value.Split(',');
int hrs = 0, min = 0, sec = 0;
foreach (var part in parts)
{
if (part.Contains("hr"))
hrs = int.Parse(part.Remove(part.IndexOf("hr")));
else if (part.Contains("min"))
min = int.Parse(part.Remove(part.IndexOf("min")));
else if (part.Contains("sec"))
sec = int.Parse(part.Remove(part.IndexOf("sec")));
}
report.TotalCutTime = new TimeSpan(hrs, min, sec);
}
private static double ParsePercent(string s, double defaultValue = 0.0)
{
var t = s.TrimEnd('%', ' ');
double f;
if (!double.TryParse(t, out f))
{
Debug.WriteLine("Failed to convert \"" + s + "\" from percent string to double");
return defaultValue;
}
return f;
}
private static double ParseDouble(string s, double defaultValue = 0.0)
{
double f;
if (!double.TryParse(s, out f))
{
Debug.WriteLine("Failed to convert \"" + s + "\" from string to double");
return defaultValue;
}
return f;
}
private static int ParseInt32(string s, int defaultValue = 0)
{
int i;
if (!int.TryParse(s, out i))
{
Debug.WriteLine("Failed to convert \"" + s + "\" from string to int");
return defaultValue;
}
return i;
}
private enum Section
{
Unknown,
NestHeader,
NestedPlates,
QuantitiesNested,
}
}
}

104
PepLib/IniConfig.cs Normal file
View File

@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace PepLib
{
public class IniConfig
{
public List<Node> Nodes;
public IniConfig()
{
Nodes = new List<Node>();
}
private static int LeadingWhitespaceCount(string s)
{
for (int i = 0; i < s.Length; ++i)
if (s[i] != ' ') return i;
return 0;
}
public Node FindNode(string path)
{
return FindNode(path, Nodes);
}
private Node FindNode(string path, List<Node> nodes)
{
var a = path.Split('/');
var b = nodes.FirstOrDefault(node =>
{
if (node is KeyNode)
{
var c = node as KeyNode;
return c.Name.ToUpper() == a[0].ToUpper();
}
else
{
return node.Value == a[0].Trim();
}
});
string path2 = string.Empty;
for (int i = 1; i < a.Length; ++i)
path2 += a[i] + '/';
if (b == null || a.Length == 1)
return b;
else
return FindNode(path2.TrimEnd('/'), b.Children);
}
public static IniConfig Load(string file)
{
var doc = new IniConfig();
var reader = new StreamReader(file);
Node currentNode = null;
string line;
while ((line = reader.ReadLine()) != null)
{
int spaces = LeadingWhitespaceCount(line) / 2;
var node = new Node();
node.Value = line.Trim();
var keyNode = KeyNode.Parse(node);
if (keyNode != null)
node = keyNode;
int currentdepth = currentNode != null ? currentNode.Level : 0;
if (spaces == 0)
doc.Nodes.Add(node);
else if (spaces == currentdepth)
currentNode.Parent.AddChild(node);
else if (spaces > currentdepth)
currentNode.AddChild(node);
else if (spaces < currentdepth)
{
var n = currentNode.Parent;
while (spaces < n.Level)
n = n.Parent;
n.Parent.AddChild(node);
}
currentNode = node;
}
reader.Close();
return doc;
}
}
}

10
PepLib/KerfType.cs Normal file
View File

@@ -0,0 +1,10 @@

namespace PepLib
{
public enum KerfType
{
None,
Left,
Right
}
}

57
PepLib/Loop.cs Normal file
View File

@@ -0,0 +1,57 @@
using System;
using PepLib.Codes;
namespace PepLib
{
public class Loop : Program
{
public Loop()
{
Mode = ProgrammingMode.Incremental;
}
public string Name { get; set; }
public Vector ReferencePoint { get; set; }
public DateTime LastReferenceDate { get; set; }
public string DrawingName { get; set; }
public string DxfPath { get; set; }
public override void Rotate(double angle)
{
base.Rotate(angle);
ReferencePoint = ReferencePoint.Rotate(angle);
}
public override void Rotate(double angle, Vector origin)
{
base.Rotate(angle, origin);
ReferencePoint = ReferencePoint.Rotate(angle);
}
public object Clone()
{
var loop = new Loop()
{
Name = this.Name,
ReferencePoint = this.ReferencePoint,
LastReferenceDate = this.LastReferenceDate,
DrawingName = this.DrawingName,
DxfPath = this.DxfPath,
Rotation = this.Rotation
};
var codes = new ICode[this.Count];
for (int i = 0; i < this.Count; ++i)
codes[i] = this[i].Clone();
loop.AddRange(codes);
return loop;
}
}
}

9
PepLib/Machine.cs Normal file
View File

@@ -0,0 +1,9 @@
namespace PepLib
{
public class Machine
{
public int Id { get; set; }
public string Name { get; set; }
}
}

11
PepLib/Material.cs Normal file
View File

@@ -0,0 +1,11 @@
namespace PepLib
{
public class Material
{
public int Id { get; set; }
public string Grade { get; set; }
public double Density { get; set; }
}
}

55
PepLib/MathHelper.cs Normal file
View File

@@ -0,0 +1,55 @@
using System;
namespace PepLib
{
public static class MathHelper
{
public const double HalfPI = Math.PI * 0.5;
public const double TwoPI = Math.PI * 2.0;
public static double NormalizeAngleRad(double angle)
{
double r = angle % TwoPI;
return r < 0 ? TwoPI + r : r;
}
public static double NormalizeAngleDeg(double angle)
{
double r = angle % 360.0;
return r < 0 ? 360.0 + r : r;
}
public static bool IsAngleBetween(double angle, double a1, double a2, bool reversed = false)
{
if (reversed)
Generic.Swap(ref a1, ref a2);
var diff = NormalizeAngleRad(a2 - a1);
// full circle
if (a2.IsEqualTo(a1))
return true;
a1 = NormalizeAngleRad(angle - a1);
a2 = NormalizeAngleRad(a2 - angle);
return diff >= a1 - Tolerance.Epsilon ||
diff >= a2 - Tolerance.Epsilon;
}
public static double RoundDownToNearest(double num, double factor)
{
return factor == 0 ? num : Math.Floor(num / factor) * factor;
}
public static double RoundUpToNearest(double num, double factor)
{
return factor == 0 ? num : Math.Ceiling(num / factor) * factor;
}
public static double RoundToNearest(double num, double factor)
{
return factor == 0 ? num : Math.Round(num / factor) * factor;
}
}
}

271
PepLib/Nest.cs Normal file
View File

@@ -0,0 +1,271 @@
using System;
using System.Collections.Generic;
using System.IO;
using PepLib.Codes;
using PepLib.IO;
namespace PepLib
{
public class Nest
{
public Nest()
{
Info = new NestInfo();
Report = new Report();
Loops = new List<Loop>();
Plates = new List<Plate>();
Drawings = new List<NestDrawing>();
}
public NestInfo Info { get; set; }
public Report Report { get; set; }
public List<Loop> Loops { get; set; }
public List<Plate> Plates { get; set; }
public List<NestDrawing> Drawings { get; set; }
public void ResolveLoops()
{
for (int i = 0; i < Loops.Count; ++i)
{
var loop = Loops[i];
ResolveLoops(loop);
}
}
private void ResolveLoops(Program pgm)
{
for (int i = 0; i < pgm.Count; ++i)
{
var code = pgm[i];
if (code.CodeType() != CodeType.SubProgramCall)
continue;
var subpgmcall = (SubProgramCall)code;
var loop = GetLoop(subpgmcall.LoopId);
if (loop == null)
throw new Exception("Loop not found");
subpgmcall.Loop = loop;
}
}
public int GetQtyNested(string drawing)
{
int qty = 0;
foreach (var plate in Plates)
qty += plate.GetQtyNested(drawing);
return qty;
}
private string GetLoopName(int loopId)
{
return string.Format("{0}.loop-{1}", Info.Name, loopId.ToString().PadLeft(3, '0'));
}
private Loop GetLoop(string name)
{
for (int i = 0; i < Loops.Count; ++i)
{
if (Loops[i].Name == name)
return Loops[i];
}
return null;
}
public Loop GetLoop(int id)
{
string name = GetLoopName(id);
return GetLoop(name);
}
public static Nest Load(string nestfile)
{
var reader = new NestReader();
reader.Read(nestfile);
return reader.Nest;
}
public static Nest Load(Stream stream)
{
var reader = new NestReader();
reader.Read(stream);
return reader.Nest;
}
public static bool TryLoad(string nestfile, out Nest nest)
{
try
{
nest = Load(nestfile);
}
catch (Exception)
{
nest = null;
return false;
}
return true;
}
public static bool TryLoad(Stream stream, out Nest nest)
{
try
{
nest = Load(stream);
}
catch (Exception)
{
nest = null;
return false;
}
return true;
}
#region NestInfo wrapper properties
public string Name
{
get { return Info.Name; }
set { Info.Name = value; }
}
public DateTime CreationDate
{
get { return Info.DateCreated; }
set { Info.DateCreated = value; }
}
public DateTime LastModifiedDate
{
get { return Info.DateLastModified; }
set { Info.DateLastModified = value; }
}
public StatusType Status
{
get { return Info.Status; }
set { Info.Status = value; }
}
public int LoopCount
{
get { return Info.LoopCount; }
set { Info.LoopCount = value; }
}
public int PlateCount
{
get { return Info.PlateCount; }
set { Info.PlateCount = value; }
}
public string Comment
{
get { return Info.Comments; }
set { Info.Comments = value; }
}
public string Customer
{
get { return Info.Customer; }
set { Info.Customer = value; }
}
public string ProgrammedBy
{
get { return Info.ProgrammedBy; }
set { Info.ProgrammedBy = value; }
}
public int MaterialNumber
{
get { return Info.MaterialNumber; }
set { Info.MaterialNumber = value; }
}
public string MaterialGrade
{
get { return Info.MaterialGrade; }
set { Info.MaterialGrade = value; }
}
public string Notes
{
get { return Info.Notes; }
set { Info.Notes = value; }
}
public string DefaultPlateSize
{
get { return Info.DefaultPlateSize; }
set { Info.DefaultPlateSize = value; }
}
public string Kerf
{
get { return Info.Kerf; }
set { Info.Kerf = value; }
}
public string PostedAs
{
get { return Info.PostedAs; }
set { Info.PostedAs = value; }
}
public string Errors
{
get { return Info.Errors; }
set { Info.Errors = value; }
}
public string UserDefined1
{
get { return Info.UserDefined1; }
set { Info.UserDefined1 = value; }
}
public string UserDefined2
{
get { return Info.UserDefined2; }
set { Info.UserDefined2 = value; }
}
public string UserDefined3
{
get { return Info.UserDefined3; }
set { Info.UserDefined3 = value; }
}
public string UserDefined4
{
get { return Info.UserDefined4; }
set { Info.UserDefined4 = value; }
}
public string UserDefined5
{
get { return Info.UserDefined5; }
set { Info.UserDefined5 = value; }
}
public string UserDefined6
{
get { return Info.UserDefined6; }
set { Info.UserDefined6 = value; }
}
#endregion
}
}

14
PepLib/NestDrawing.cs Normal file
View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PepLib
{
public class NestDrawing
{
public string Name { get; set; }
public int QtyRequired { get; set; }
}
}

68
PepLib/NestIndex.cs Normal file
View File

@@ -0,0 +1,68 @@
using System.Collections.Generic;
using System.IO;
using System.Text;
using PepLib.IO;
namespace PepLib
{
public class NestIndex
{
public string Directory { get; set; }
public List<NestInfo> Entries;
public NestIndex()
{
Entries = new List<NestInfo>();
}
public string GetPath(NestInfo entry)
{
return Path.Combine(Directory, entry.Name + ".zip");
}
public static NestIndex LoadFromDir(string directory)
{
var file = Path.Combine(directory, "pepfiles.lfn");
return Load(file);
}
public static NestIndex Load(string file)
{
if (!File.Exists(file))
return null;
var index = new NestIndex() { Directory = Path.GetDirectoryName(file) };
var stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var reader = new StreamReader(stream);
var buffer = new char[4000];
while (reader.Read(buffer, 0, buffer.Length) > 0)
{
var memstream = new MemoryStream(Encoding.Default.GetBytes(buffer));
var inforeader = new NestInfoReader();
inforeader.Read(memstream);
index.Entries.Add(inforeader.Info);
}
reader.Close();
return index;
}
public static NestIndex Build(string directory)
{
var index = new NestIndex() { Directory = directory };
foreach (var file in System.IO.Directory.GetFiles(directory, "*.zip"))
{
var reader = new NestInfoReader();
reader.Read(file);
index.Entries.Add(reader.Info);
}
return index;
}
}
}

99
PepLib/NestInfo.cs Normal file
View File

@@ -0,0 +1,99 @@
using System;
using System.IO;
using PepLib.IO;
namespace PepLib
{
public class NestInfo
{
public string Name { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateLastModified { get; set; }
public StatusType Status { get; set; }
public int LoopCount { get; set; }
public int ProgramCount { get; set; }
public int PlateCount { get; set; }
public string Comments { get; set; }
public string Customer { get; set; }
public string ProgrammedBy { get; set; }
public int MaterialNumber { get; set; }
public string MaterialGrade { get; set; }
public string Notes { get; set; }
public string DefaultPlateSize { get; set; }
public string Kerf { get; set; }
public string PostedAs { get; set; }
public string Errors { get; set; }
public string UserDefined1 { get; set; }
public string UserDefined2 { get; set; }
public string UserDefined3 { get; set; }
public string UserDefined4 { get; set; }
public string UserDefined5 { get; set; }
public string UserDefined6 { get; set; }
public static NestInfo Load(string nestFile)
{
var reader = new NestInfoReader();
reader.Read(nestFile);
return reader.Info;
}
public static NestInfo Load(Stream stream)
{
var reader = new NestInfoReader();
reader.Read(stream);
return reader.Info;
}
public static bool TryLoad(string nestFile, out NestInfo nestInfo)
{
try
{
nestInfo = Load(nestFile);
}
catch (Exception)
{
nestInfo = null;
return false;
}
return true;
}
public static bool TryLoad(Stream stream, out NestInfo nestInfo)
{
try
{
nestInfo = Load(stream);
}
catch (Exception)
{
nestInfo = null;
return false;
}
return true;
}
}
}

88
PepLib/Node.cs Normal file
View File

@@ -0,0 +1,88 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace PepLib
{
public class Node
{
private Node parent;
public List<Node> Children;
public Node()
{
Children = new List<Node>();
}
public Node Parent
{
get { return parent; }
set
{
parent = value;
UpdateDepth();
}
}
public string Value { get; set; }
private void UpdateDepth()
{
if (Parent != null)
Level = Parent.Level + 1;
else
Level = 0;
foreach (var node in Children)
node.Parent = this;
}
public int Level { get; protected set; }
public void AddChild(Node node)
{
node.Parent = this;
Children.Add(node);
}
public void Write(TextWriter writer)
{
writer.WriteLine("".PadLeft(Level * 2) + this.ToString());
foreach (var node in Children)
node.Write(writer);
}
public override string ToString()
{
return Value;
}
}
public class KeyNode : Node
{
public string Name;
public static KeyNode Parse(Node node)
{
var index = node.Value.IndexOf('=');
if (index == -1)
return null;
return new KeyNode()
{
Name = node.Value.Remove(index),
Value = node.Value.Remove(0, index + 1).Trim()
};
}
public override string ToString()
{
return string.Format("{0}={1}", Name, Value);
}
}
}

123
PepLib/Part.cs Normal file
View File

@@ -0,0 +1,123 @@
using System;
namespace PepLib
{
public class Part : IMovable
{
private Loop baseLoop;
private Vector location;
private Part()
{
BoundingBox = new Box();
}
public Box BoundingBox { get; protected set; }
public Vector Location
{
get { return location; }
set
{
BoundingBox.Offset(value - location);
location = value;
}
}
public string Name
{
get { return baseLoop.Name; }
set { baseLoop.Name = value; }
}
/// <summary>
/// Reference point relative to the part location.
/// </summary>
public Vector ReferencePoint
{
get { return baseLoop.ReferencePoint; }
set { baseLoop.ReferencePoint = value; }
}
/// <summary>
/// Reference point relative to the zero point.
/// </summary>
public Vector AbsoluteReferencePoint
{
get { return baseLoop.ReferencePoint + location; }
set { baseLoop.ReferencePoint = value - location; }
}
public DateTime LastReferenceDate
{
get { return baseLoop.LastReferenceDate; }
set { baseLoop.LastReferenceDate = value; }
}
public string DrawingName
{
get { return baseLoop.DrawingName; }
set { baseLoop.DrawingName = value; }
}
public string DxfPath
{
get { return baseLoop.DxfPath; }
set { baseLoop.DxfPath = value; }
}
public double Rotation
{
get { return baseLoop.Rotation; }
}
public void Rotate(double angle)
{
baseLoop.Rotate(angle);
location = Location.Rotate(angle);
UpdateBounds();
}
public void Rotate(double angle, Vector origin)
{
baseLoop.Rotate(angle);
location = Location.Rotate(angle, origin);
UpdateBounds();
}
public void Offset(double x, double y)
{
location = new Vector(location.X + x, location.Y + y);
BoundingBox.Offset(x, y);
}
public void Offset(Vector voffset)
{
location += voffset;
BoundingBox.Offset(voffset);
}
public Program Program
{
get { return baseLoop; }
}
public void UpdateBounds()
{
BoundingBox = baseLoop.GetBoundingBox();
BoundingBox.Offset(Location);
}
public static Part Create(Loop loop, Vector location, double rotation = 0.0)
{
var part = new Part();
part.baseLoop = (Loop)loop.Clone();
part.baseLoop.Mode = ProgrammingMode.Incremental;
part.baseLoop.Rotate(rotation);
part.Location = location;
part.UpdateBounds();
return part;
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PepLib
{
public static class PartListExtensions
{
public static Box GetBoundingBox(this List<Part> parts)
{
if (parts.Count == 0)
return new Box();
var firstpart = parts[0];
double minX = firstpart.BoundingBox.X;
double minY = firstpart.BoundingBox.Y;
double maxX = firstpart.BoundingBox.X + firstpart.BoundingBox.Width;
double maxY = firstpart.BoundingBox.Y + firstpart.BoundingBox.Height;
foreach (var part in parts)
{
var box = part.BoundingBox;
if (box.Left < minX)
minX = box.Left;
if (box.Right > maxX)
maxX = box.Right;
if (box.Bottom < minY)
minY = box.Bottom;
if (box.Top > maxY)
maxY = box.Top;
}
return new Box(minX, minY, maxX - minX, maxY - minY);
}
}
}

111
PepLib/PepLib.csproj Normal file
View File

@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" 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>{22360453-B878-49FA-A5DC-0D9C577DE902}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PepLib</RootNamespace>
<AssemblyName>PepLib</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="DotNetZip, Version=1.10.1.0, Culture=neutral, PublicKeyToken=6583c7c814667745, processorArchitecture=MSIL">
<HintPath>..\..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="AngleConverter.cs" />
<Compile Include="ApplicationType.cs" />
<Compile Include="Box.cs" />
<Compile Include="Codes\CircularMove.cs" />
<Compile Include="Codes\EntityType.cs" />
<Compile Include="Codes\Motion.cs" />
<Compile Include="Codes\RapidMove.cs" />
<Compile Include="Codes\SubProgramCall.cs" />
<Compile Include="Codes\Comment.cs" />
<Compile Include="Codes\CodeType.cs" />
<Compile Include="Codes\ICode.cs" />
<Compile Include="Generic.cs" />
<Compile Include="IniConfig.cs" />
<Compile Include="IO\MaterialDataReader.cs" />
<Compile Include="NestDrawing.cs" />
<Compile Include="NestIndex.cs" />
<Compile Include="IO\ProgramReader.cs" />
<Compile Include="KerfType.cs" />
<Compile Include="Codes\LinearMove.cs" />
<Compile Include="MathHelper.cs" />
<Compile Include="Node.cs" />
<Compile Include="Part.cs" />
<Compile Include="PartListExtensions.cs" />
<Compile Include="RotationType.cs" />
<Compile Include="Codes\SetFeedrate.cs" />
<Compile Include="Codes\SetKerf.cs" />
<Compile Include="IMovable.cs" />
<Compile Include="ProgrammingMode.cs" />
<Compile Include="Tolerance.cs" />
<Compile Include="IO\DrawingInfoReader.cs" />
<Compile Include="Drawing.cs" />
<Compile Include="DrawingInfo.cs" />
<Compile Include="DrawingType.cs" />
<Compile Include="GrainType.cs" />
<Compile Include="IO\DrawingReader.cs" />
<Compile Include="IO\LoopReader.cs" />
<Compile Include="IO\NestReader.cs" />
<Compile Include="Loop.cs" />
<Compile Include="Machine.cs" />
<Compile Include="Material.cs" />
<Compile Include="Nest.cs" />
<Compile Include="NestInfo.cs" />
<Compile Include="IO\NestInfoReader.cs" />
<Compile Include="Util.cs" />
<Compile Include="Plate.cs" />
<Compile Include="PlateListExtensions.cs" />
<Compile Include="IO\PlateReader.cs" />
<Compile Include="Size.cs" />
<Compile Include="Program.cs" />
<Compile Include="IO\ReportReader.cs" />
<Compile Include="Spacing.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Report.cs" />
<Compile Include="Report.Drawing.cs" />
<Compile Include="Report.Plate.cs" />
<Compile Include="StatusType.cs" />
<Compile Include="Vector.cs" />
<Compile Include="ZipHelper.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

266
PepLib/Plate.cs Normal file
View File

@@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PepLib
{
public class Plate : IMovable
{
public Plate()
: this(60, 120)
{
}
public Plate(double width, double length)
: this(new Size(width, length))
{
}
public Plate(Size size)
{
EdgeSpacing = new Spacing();
Size = size;
Machine = new Machine();
Material = new Material();
Parts = new List<Part>();
Quadrant = 1;
}
public string Name { get; set; }
public string PostedFiles { get; set; }
public string HeatLot { get; set; }
public double Thickness { get; set; }
public double PartSpacing { get; set; }
public Spacing EdgeSpacing { get; set; }
public Size Size { get; set; }
public Machine Machine { get; set; }
public Material Material { get; set; }
public List<Part> Parts { get; set; }
public string Description { get; set; }
public int Duplicates { get; set; }
public int Quadrant { get; set; }
public int TorchCount { get; set; }
public void Rotate90CCW(bool keepSameQuadrant = true)
{
Size = new Size(Size.Width, Size.Height);
Rotate(MathHelper.HalfPI);
if (keepSameQuadrant)
{
switch (Quadrant)
{
case 1:
Offset(Size.Width, 0);
break;
case 2:
Offset(0, Size.Height);
break;
case 3:
Offset(-Size.Width, 0);
break;
case 4:
Offset(0, -Size.Height);
break;
}
}
else
{
Quadrant = Quadrant > 3 ? 1 : Quadrant + 1;
}
}
public void Rotate90CW(bool keepSameQuadrant = true)
{
const double oneAndHalfPI = Math.PI * 1.5;
Size = new Size(Size.Width, Size.Height);
Rotate(oneAndHalfPI);
if (keepSameQuadrant)
{
switch (Quadrant)
{
case 1:
Offset(0, Size.Height);
break;
case 2:
Offset(-Size.Width, 0);
break;
case 3:
Offset(0, -Size.Height);
break;
case 4:
Offset(Size.Width, 0);
break;
}
}
else
{
Quadrant = Quadrant < 2 ? 4 : Quadrant - 1;
}
}
public void Rotate180(bool keepSameQuadrant = true)
{
if (keepSameQuadrant)
{
Vector centerpt;
switch (Quadrant)
{
case 1:
centerpt = new Vector(Size.Width * 0.5, Size.Height * 0.5);
break;
case 2:
centerpt = new Vector(-Size.Width * 0.5, Size.Height * 0.5);
break;
case 3:
centerpt = new Vector(-Size.Width * 0.5, -Size.Height * 0.5);
break;
case 4:
centerpt = new Vector(Size.Width * 0.5, -Size.Height * 0.5);
break;
default:
return;
}
Rotate(Math.PI, centerpt);
}
else
{
Rotate(Math.PI);
Quadrant = (Quadrant + 2) % 4;
if (Quadrant == 0)
Quadrant = 4;
}
}
public void Rotate(double angle)
{
for (int i = 0; i < Parts.Count; ++i)
{
var part = Parts[i];
part.Rotate(angle);
}
}
public void Rotate(double angle, Vector origin)
{
for (int i = 0; i < Parts.Count; ++i)
{
var part = Parts[i];
part.Rotate(angle, origin);
}
}
public void Offset(double x, double y)
{
for (int i = 0; i < Parts.Count; ++i)
{
var part = Parts[i];
part.Offset(x, y);
}
}
public void Offset(Vector voffset)
{
for (int i = 0; i < Parts.Count; ++i)
{
var part = Parts[i];
part.Offset(voffset);
}
}
public int GetQtyNested(string drawing)
{
var name = drawing.ToUpper();
return Parts.Count(p => p.DrawingName.ToUpper() == name);
}
public Box GetBoundingBox(bool includeParts)
{
var plateBox = new Box();
switch (Quadrant)
{
case 1:
plateBox.X = 0;
plateBox.Y = 0;
break;
case 2:
plateBox.X = (float)-Size.Width;
plateBox.Y = 0;
break;
case 3:
plateBox.X = (float)-Size.Width;
plateBox.Y = (float)-Size.Height;
break;
case 4:
plateBox.X = 0;
plateBox.Y = (float)-Size.Height;
break;
default:
return new Box();
}
plateBox.Width = Size.Width;
plateBox.Height = Size.Height;
if (!includeParts)
return plateBox;
var boundingBox = new Box();
var partsBox = Parts.GetBoundingBox();
boundingBox.X = partsBox.Left < plateBox.Left
? partsBox.Left
: plateBox.Left;
boundingBox.Y = partsBox.Bottom < plateBox.Bottom
? partsBox.Bottom
: plateBox.Bottom;
boundingBox.Width = partsBox.Right > plateBox.Right
? partsBox.Right - boundingBox.X
: plateBox.Right - boundingBox.X;
boundingBox.Height = partsBox.Top > plateBox.Top
? partsBox.Top - boundingBox.Y
: plateBox.Top - boundingBox.Y;
return boundingBox;
}
}
}

View File

@@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace PepLib
{
public static class PlateListExtensions
{
public static void JoinLikePlates(this List<Report.Plate> plates)
{
START:
for (int i = 0; i < plates.Count; ++i)
{
var p1 = plates[i];
for (int j = 0; j < plates.Count; ++j)
{
var p2 = plates[j];
if (i == j)
continue;
if (p1.Width != p2.Width)
continue;
if (p1.Length != p2.Length)
continue;
if (p1.MaterialDescription != p2.MaterialDescription)
continue;
if (p1.Thickness != p2.Thickness)
continue;
p1.Quantity += p2.Quantity;
plates.Remove(p2);
goto START;
}
}
}
}
}

367
PepLib/Program.cs Normal file
View File

@@ -0,0 +1,367 @@
using System.Collections.Generic;
using System.IO;
using PepLib.Codes;
using PepLib.IO;
using System;
namespace PepLib
{
public class Program : List<ICode>, IMovable
{
private ProgrammingMode mode;
public Program(ProgrammingMode mode = ProgrammingMode.Absolute)
{
Mode = mode;
}
public ProgrammingMode Mode
{
get { return mode; }
set
{
if (value == ProgrammingMode.Absolute)
SetProgrammingModeAbs();
else
SetProgrammingModeInc();
}
}
public double Rotation { get; protected set; }
private void SetProgrammingModeInc()
{
if (mode == ProgrammingMode.Incremental)
return;
var pos = new Vector(0, 0);
for (int i = 0; i < Count; ++i)
{
var code = this[i];
var motion = code as Motion;
if (motion != null)
{
var pos2 = motion.EndPoint;
motion.Offset(-pos.X, -pos.Y);
pos = pos2;
}
}
mode = ProgrammingMode.Incremental;
}
private void SetProgrammingModeAbs()
{
if (mode == ProgrammingMode.Absolute)
return;
var pos = new Vector(0, 0);
for (int i = 0; i < Count; ++i)
{
var code = this[i];
var motion = code as Motion;
if (motion != null)
{
motion.Offset(pos);
pos = motion.EndPoint;
}
}
mode = ProgrammingMode.Absolute;
}
public virtual void Rotate(double angle)
{
var mode = Mode;
SetProgrammingModeAbs();
for (int i = 0; i < Count; ++i)
{
var code = this[i];
if (code.CodeType() == CodeType.SubProgramCall)
{
var subpgm = (SubProgramCall)code;
if (subpgm.Loop != null)
subpgm.Loop.Rotate(angle);
}
if (code is IMovable == false)
continue;
var code2 = (IMovable)code;
code2.Rotate(angle);
}
if (mode == ProgrammingMode.Incremental)
SetProgrammingModeInc();
Rotation = MathHelper.NormalizeAngleRad(Rotation + angle);
}
public virtual void Rotate(double angle, Vector origin)
{
var mode = Mode;
SetProgrammingModeAbs();
for (int i = 0; i < Count; ++i)
{
var code = this[i];
if (code.CodeType() == CodeType.SubProgramCall)
{
var subpgm = (SubProgramCall)code;
if (subpgm.Loop != null)
subpgm.Loop.Rotate(angle);
}
if (code is IMovable == false)
continue;
var code2 = (IMovable)code;
code2.Rotate(angle, origin);
}
if (mode == ProgrammingMode.Incremental)
SetProgrammingModeInc();
Rotation = MathHelper.NormalizeAngleRad(Rotation + angle);
}
public void Offset(double x, double y)
{
var mode = Mode;
SetProgrammingModeAbs();
for (int i = 0; i < Count; ++i)
{
var code = this[i];
if (code is IMovable == false)
continue;
var code2 = (IMovable)code;
code2.Offset(x, y);
}
if (mode == ProgrammingMode.Incremental)
SetProgrammingModeInc();
}
public void Offset(Vector voffset)
{
var mode = Mode;
SetProgrammingModeAbs();
for (int i = 0; i < Count; ++i)
{
var code = this[i];
if (code is IMovable == false)
continue;
var code2 = (IMovable)code;
code2.Offset(voffset);
}
if (mode == ProgrammingMode.Incremental)
SetProgrammingModeInc();
}
public Box GetBoundingBox()
{
var origin = new Vector(0, 0);
return GetBoundingBox(ref origin);
}
private Box GetBoundingBox(ref Vector pos)
{
double minX = 0.0;
double minY = 0.0;
double maxX = 0.0;
double maxY = 0.0;
for (int i = 0; i < Count; ++i)
{
var code = this[i];
switch (code.CodeType())
{
case CodeType.LinearMove:
{
var line = (LinearMove)code;
var pt = Mode == ProgrammingMode.Absolute ?
line.EndPoint :
line.EndPoint + pos;
if (pt.X > maxX)
maxX = pt.X;
else if (pt.X < minX)
minX = pt.X;
if (pt.Y > maxY)
maxY = pt.Y;
else if (pt.Y < minY)
minY = pt.Y;
pos = pt;
break;
}
case CodeType.RapidMove:
{
var line = (RapidMove)code;
var pt = Mode == ProgrammingMode.Absolute
? line.EndPoint
: line.EndPoint + pos;
if (pt.X > maxX)
maxX = pt.X;
else if (pt.X < minX)
minX = pt.X;
if (pt.Y > maxY)
maxY = pt.Y;
else if (pt.Y < minY)
minY = pt.Y;
pos = pt;
break;
}
case CodeType.CircularMove:
{
var arc = (CircularMove)code;
var radius = arc.CenterPoint.DistanceTo(arc.EndPoint);
Vector endpt;
Vector centerpt;
if (Mode == ProgrammingMode.Incremental)
{
endpt = arc.EndPoint + pos;
centerpt = arc.CenterPoint + pos;
}
else
{
endpt = arc.EndPoint;
centerpt = arc.CenterPoint;
}
double minX1;
double minY1;
double maxX1;
double maxY1;
if (pos.X < endpt.X)
{
minX1 = pos.X;
maxX1 = endpt.X;
}
else
{
minX1 = endpt.X;
maxX1 = pos.X;
}
if (pos.Y < endpt.Y)
{
minY1 = pos.Y;
maxY1 = endpt.Y;
}
else
{
minY1 = endpt.Y;
maxY1 = pos.Y;
}
var startAngle = pos.AngleFrom(centerpt);
var endAngle = endpt.AngleFrom(centerpt);
// switch the angle to counter clockwise.
if (arc.Rotation == RotationType.CW)
Generic.Swap(ref startAngle, ref endAngle);
startAngle = MathHelper.NormalizeAngleRad(startAngle);
endAngle = MathHelper.NormalizeAngleRad(endAngle);
if (MathHelper.IsAngleBetween(MathHelper.HalfPI, startAngle, endAngle))
maxY1 = centerpt.Y + radius;
if (MathHelper.IsAngleBetween(Math.PI, startAngle, endAngle))
minX1 = centerpt.X - radius;
const double oneHalfPI = Math.PI * 1.5;
if (MathHelper.IsAngleBetween(oneHalfPI, startAngle, endAngle))
minY1 = centerpt.Y - radius;
if (MathHelper.IsAngleBetween(MathHelper.TwoPI, startAngle, endAngle))
maxX1 = centerpt.X + radius;
if (maxX1 > maxX)
maxX = maxX1;
if (minX1 < minX)
minX = minX1;
if (maxY1 > maxY)
maxY = maxY1;
if (minY1 < minY)
minY = minY1;
pos = endpt;
break;
}
case CodeType.SubProgramCall:
{
var subpgm = (SubProgramCall)code;
var box = subpgm.Loop.GetBoundingBox(ref pos);
if (box.Left < minX)
minX = box.Left;
if (box.Right > maxX)
maxX = box.Right;
if (box.Bottom < minY)
minY = box.Bottom;
if (box.Top > maxY)
maxY = box.Top;
break;
}
}
}
return new Box(minX, minY, maxX - minX, maxY - minY);
}
public static Program Load(Stream stream)
{
var reader = new ProgramReader();
reader.Read(stream);
return reader.Program;
}
}
}

View File

@@ -0,0 +1,8 @@
namespace PepLib
{
public enum ProgrammingMode
{
Absolute,
Incremental
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
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("PepLib")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PepLib")]
[assembly: AssemblyCopyright("Copyright © AJ Isaacs 2014")]
[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("e62db743-a781-4092-8b6d-bd90f7b25cd1")]
// 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")]

53
PepLib/Report.Drawing.cs Normal file
View File

@@ -0,0 +1,53 @@
using System;
namespace PepLib
{
public partial class Report
{
public class Drawing
{
public string Customer { get; set; }
public string Name { get; set; }
public string Revision { get; set; }
public int QtyRequired { get; set; }
public int QtyNested { get; set; }
public int QtyRemaining
{
get { return QtyRequired - QtyNested; }
}
public double CutDistance { get; set; }
public double ScribeDistance { get; set; }
public double BevelDistance { get; set; }
public TimeSpan TotalCutTime { get; set; }
public int PierceCount { get; set; }
public int IntersectionCount { get; set; }
public double Area1 { get; set; }
public double Area2 { get; set; }
public bool IncludeRemnantInCost { get; set; }
public double NetWeight1 { get; set; }
public double NetWeight2 { get; set; }
public double GrossWeight { get; set; }
public double PercentOfMaterial { get; set; }
public double PercentOfCutTime { get; set; }
}
}
}

35
PepLib/Report.Plate.cs Normal file
View File

@@ -0,0 +1,35 @@

namespace PepLib
{
public partial class Report
{
public class Plate
{
public string Name { get; set; }
public double Thickness { get; set; }
public double Width { get; set; }
public double Length { get; set; }
public int MaterialNumber { get; set; }
public string MaterialGrade { get; set; }
public string MaterialDescription { get; set; }
public int Quantity { get; set; }
public double PlateUtilization { get; set; }
public double MaterialUtilization { get; set; }
public double Area1 { get; set; }
public double Area2 { get; set; }
public int BubblePierceCount { get; set; }
}
}
}

125
PepLib/Report.cs Normal file
View File

@@ -0,0 +1,125 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using PepLib.IO;
namespace PepLib
{
public partial class Report
{
public Report()
{
Drawings = new List<Report.Drawing>();
Plates = new List<Report.Plate>();
}
public List<Report.Drawing> Drawings { get; set; }
public List<Report.Plate> Plates { get; set; }
public string Name { get; set; }
public string Customer { get; set; }
public DateTime DateProgrammed { get; set; }
public string Material { get; set; }
public string ProgrammedBy { get; set; }
public string Machine { get; set; }
public string Comments { get; set; }
public string Remarks { get; set; }
public TimeSpan TotalCutTime { get; set; }
public double TotalGasUsed { get; set; }
public double TotalRapidDistance { get; set; }
public int TotalHeadRaises { get; set; }
public double CutFeedrate { get; set; }
public double RapidFeedrate { get; set; }
public TimeSpan PierceTime { get; set; }
public int PlateCount()
{
return Plates.Sum(plate => plate.Quantity);
}
public int ProgramCount()
{
return Plates.Count;
}
public double CutDistance()
{
return Drawings.Sum(dwg => dwg.CutDistance);
}
public double ScribeDistance()
{
return Drawings.Sum(dwg => dwg.ScribeDistance);
}
public double BevelDistance()
{
return Drawings.Sum(dwg => dwg.BevelDistance);
}
public int TotalPierceCount()
{
return Drawings.Sum(dwg => dwg.PierceCount);
}
public static Report Load(string nestFile)
{
var reader = new ReportReader();
reader.Read(nestFile);
return reader.Report;
}
public static Report Load(Stream stream)
{
var reader = new ReportReader();
reader.Read(stream);
return reader.Report;
}
public static bool TryLoad(string nestfile, out Report report)
{
try
{
report = Load(nestfile);
}
catch (Exception)
{
report = null;
return false;
}
return true;
}
public static bool TryLoad(Stream stream, out Report report)
{
try
{
report = Load(stream);
}
catch (Exception)
{
report = null;
return false;
}
return true;
}
}
}

16
PepLib/RotationType.cs Normal file
View File

@@ -0,0 +1,16 @@

namespace PepLib
{
public enum RotationType
{
/// <summary>
/// Clockwise
/// </summary>
CW,
/// <summary>
/// Counter-Clockwise
/// </summary>
CCW
}
}

45
PepLib/Size.cs Normal file
View File

@@ -0,0 +1,45 @@
namespace PepLib
{
public class Size
{
public Size(double height, double width)
{
Height = height;
Width = width;
}
public double Height { get; set; }
public double Width { get; set; }
public static Size Parse(string size)
{
var a = size.ToUpper().Split('X');
var height = double.Parse(a[0]);
var width = double.Parse(a[1]);
return new Size(height, width);
}
public static bool TryParse(string s, out Size size)
{
try
{
size = Parse(s);
}
catch
{
size = new Size(0, 0);
return false;
}
return true;
}
public override string ToString()
{
return string.Format("{0} x {1}", Height, Width);
}
}
}

27
PepLib/Spacing.cs Normal file
View File

@@ -0,0 +1,27 @@

namespace PepLib
{
public class Spacing
{
public Spacing()
: this(0, 0, 0, 0)
{
}
public Spacing(double l, double b, double r, double t)
{
Left = l;
Bottom = b;
Right = r;
Top = t;
}
public double Left { get; set; }
public double Bottom { get; set; }
public double Right { get; set; }
public double Top { get; set; }
}
}

11
PepLib/StatusType.cs Normal file
View File

@@ -0,0 +1,11 @@

namespace PepLib
{
public enum StatusType
{
ToBeCut,
Quote,
HasBeenCut,
Temp
}
}

14
PepLib/Tolerance.cs Normal file
View File

@@ -0,0 +1,14 @@
using System;
namespace PepLib
{
public static class Tolerance
{
public const double Epsilon = 0.0001;
public static bool IsEqualTo(this double a, double b, double tolerance = Epsilon)
{
return Math.Abs(b - a) <= tolerance;
}
}
}

32
PepLib/Util.cs Normal file
View File

@@ -0,0 +1,32 @@
using System;
using System.Diagnostics;
using System.IO;
namespace PepLib
{
public static class Util
{
public static string GetNestFileFormat(string filename)
{
try
{
var name = Path.GetFileName(filename);
var ext = Path.GetExtension(name);
if (name.LastIndexOf(ext) > 5 && !name.Contains("-"))
name = name.Insert(5, "-");
if (name.LastIndexOf(ext) > 8 && char.IsLetter(name[8]))
name = name.Remove(8, 1);
return Path.Combine(Path.GetDirectoryName(filename), name);
}
catch (SystemException ex)
{
Debug.WriteLine(ex.Message);
}
return string.Empty;
}
}
}

124
PepLib/Vector.cs Normal file
View File

@@ -0,0 +1,124 @@
using System;
namespace PepLib
{
public struct Vector
{
public double X;
public double Y;
public Vector(double x, double y)
{
X = x;
Y = y;
}
public double DistanceTo(Vector pt)
{
double vx = pt.X - this.X;
double vy = pt.Y - this.Y;
return Math.Sqrt(vx * vx + vy * vy);
}
public double DistanceTo(double x, double y)
{
double vx = x - this.X;
double vy = y - this.Y;
return Math.Sqrt(vx * vx + vy * vy);
}
public double Angle()
{
return MathHelper.NormalizeAngleRad(Math.Atan2(Y, X));
}
public double AngleTo(Vector pt)
{
return (pt - this).Angle();
}
public double AngleFrom(Vector pt)
{
return (this - pt).Angle();
}
public static Vector operator +(Vector pt1, Vector pt2)
{
return new Vector(pt1.X + pt2.X, pt1.Y + pt2.Y);
}
public static Vector operator -(Vector pt1, Vector pt2)
{
return new Vector(pt1.X - pt2.X, pt1.Y - pt2.Y);
}
public static Vector operator -(Vector pt)
{
return new Vector(-pt.X, -pt.Y);
}
public static bool operator ==(Vector pt1, Vector pt2)
{
return pt1.DistanceTo(pt2) <= Tolerance.Epsilon;
}
public static bool operator !=(Vector pt1, Vector pt2)
{
return !(pt1 == pt2);
}
public Vector Rotate(double angle)
{
var v = new Vector();
double cos = Math.Cos(angle);
double sin = Math.Sin(angle);
v.X = X * cos - Y * sin;
v.Y = X * sin + Y * cos;
return v;
}
public Vector Rotate(double angle, Vector origin)
{
var v = new Vector();
var pt = this - origin;
double cos = Math.Cos(angle);
double sin = Math.Sin(angle);
v.X = pt.X * cos - pt.Y * sin + origin.X;
v.Y = pt.X * sin + pt.Y * cos + origin.Y;
return v;
}
public Vector Clone()
{
return new Vector(X, Y);
}
public override bool Equals(object obj)
{
if (!(obj is Vector))
return false;
var pt = (Vector)obj;
return (X.IsEqualTo(pt.X)) && (Y.IsEqualTo(pt.Y));
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override string ToString()
{
return string.Format("[Vector: X:{0}, Y:{1}]", X, Y);
}
}
}

116
PepLib/ZipHelper.cs Normal file
View File

@@ -0,0 +1,116 @@
using Ionic.Zip;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
namespace PepLib
{
public static class ZipHelper
{
/// <summary>
/// Returns the files that match the specified pattern.
/// </summary>
/// <param name="file">Input zip file.</param>
/// <param name="pattern">Pattern to match.</param>
/// <param name="names">Names of the files that match the pattern.</param>
/// <param name="streams">Data of the files that match the pattern.</param>
/// <returns></returns>
public static int ExtractByPattern(string file, string pattern, out string[] names, out Stream[] streams)
{
var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
var zipStream = new ZipInputStream(fileStream);
var nameList = new List<string>();
var streamList = new List<Stream>();
ZipEntry theEntry;
while ((theEntry = zipStream.GetNextEntry()) != null)
{
if (!Regex.IsMatch(theEntry.FileName, pattern))
continue;
nameList.Add(theEntry.FileName);
var memstream = new MemoryStream();
var size = 2048;
var data = new byte[size];
while (true)
{
size = zipStream.Read(data, 0, data.Length);
if (size > 0)
{
memstream.Write(data, 0, size);
memstream.Flush();
}
else break;
}
memstream.Seek(0, SeekOrigin.Begin);
streamList.Add(memstream);
}
zipStream.Close();
names = nameList.ToArray();
streams = streamList.ToArray();
return streams.Length;
}
/// <summary>
/// Returns the first file found that matches the specified file extension.
/// </summary>
/// <param name="file">Input zip file.</param>
/// <param name="extension">Extension to match.</param>
/// <param name="name">The name of the file that matches the file extension.</param>
/// <param name="stream">The data of the file that matches the file extension.</param>
/// <returns></returns>
public static bool ExtractByExtension(string file, string extension, out string name, out Stream stream)
{
var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
var zipStream = new ZipInputStream(fileStream);
var memstream = new MemoryStream();
ZipEntry theEntry;
while ((theEntry = zipStream.GetNextEntry()) != null)
{
if (Path.GetExtension(theEntry.FileName) != extension)
continue;
int size = 2048;
var data = new byte[size];
while (true)
{
size = zipStream.Read(data, 0, data.Length);
if (size > 0)
{
memstream.Write(data, 0, size);
memstream.Flush();
}
else break;
}
zipStream.Close();
memstream.Seek(0, SeekOrigin.Begin);
stream = memstream;
name = theEntry.FileName;
return true;
}
zipStream.Close();
memstream.Close();
stream = null;
name = null;
return false;
}
}
}

4
PepLib/packages.config Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DotNetZip" version="1.10.1" targetFramework="net40" />
</packages>