First commit.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class CircularMove : Motion
|
||||
{
|
||||
public CircularMove()
|
||||
{
|
||||
}
|
||||
|
||||
public CircularMove(double x, double y, double i, double j, RotationType rotation = RotationType.CCW)
|
||||
: this(new Vector(x, y), new Vector(i, j), rotation)
|
||||
{
|
||||
}
|
||||
|
||||
public CircularMove(Vector endPoint, Vector centerPoint, RotationType rotation = RotationType.CCW)
|
||||
{
|
||||
EndPoint = endPoint;
|
||||
CenterPoint = centerPoint;
|
||||
Rotation = rotation;
|
||||
Layer = LayerType.Cut;
|
||||
}
|
||||
|
||||
public LayerType Layer { get; set; }
|
||||
|
||||
public RotationType Rotation { get; set; }
|
||||
|
||||
public Vector CenterPoint { get; set; }
|
||||
|
||||
public double Radius
|
||||
{
|
||||
get { return CenterPoint.DistanceTo(EndPoint); }
|
||||
}
|
||||
|
||||
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 Type
|
||||
{
|
||||
get { return CodeType.CircularMove; }
|
||||
}
|
||||
|
||||
public override ICode Clone()
|
||||
{
|
||||
return new CircularMove(EndPoint, CenterPoint, Rotation)
|
||||
{
|
||||
Layer = Layer
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultDecimalPlaces);
|
||||
}
|
||||
|
||||
public override string ToString(int decimalPlaces)
|
||||
{
|
||||
var dp = "N" + decimalPlaces;
|
||||
var x = EndPoint.X.ToString(dp);
|
||||
var y = EndPoint.Y.ToString(dp);
|
||||
var i = CenterPoint.X.ToString(dp);
|
||||
var j = CenterPoint.Y.ToString(dp);
|
||||
|
||||
return Rotation == RotationType.CW ?
|
||||
string.Format("G02 X{0} Y{1} I{2} J{3}", x, y, i, j) :
|
||||
string.Format("G03 X{0} Y{1} I{2} J{3}", x, y, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public enum CodeType
|
||||
{
|
||||
CircularMove,
|
||||
Comment,
|
||||
LinearMove,
|
||||
RapidMove,
|
||||
SetFeedrate,
|
||||
SetKerf,
|
||||
SubProgramCall
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class Comment : ICode
|
||||
{
|
||||
public Comment()
|
||||
{
|
||||
}
|
||||
|
||||
public Comment(string value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public CodeType Type
|
||||
{
|
||||
get { return CodeType.Comment; }
|
||||
}
|
||||
|
||||
public ICode Clone()
|
||||
{
|
||||
return new Comment(Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ':' + Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class Feedrate : ICode
|
||||
{
|
||||
public const int UseDefault = -1;
|
||||
|
||||
public const int UseMax = -2;
|
||||
|
||||
public Feedrate()
|
||||
{
|
||||
}
|
||||
|
||||
public Feedrate(double value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public double Value { get; set; }
|
||||
|
||||
public CodeType Type
|
||||
{
|
||||
get { return CodeType.SetFeedrate; }
|
||||
}
|
||||
|
||||
public ICode Clone()
|
||||
{
|
||||
return new Feedrate(Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("F{0}", Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public interface ICode
|
||||
{
|
||||
CodeType Type { get; }
|
||||
|
||||
ICode Clone();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class Kerf : ICode
|
||||
{
|
||||
public Kerf(KerfType kerf = KerfType.Left)
|
||||
{
|
||||
Value = kerf;
|
||||
}
|
||||
|
||||
public KerfType Value { get; set; }
|
||||
|
||||
public CodeType Type
|
||||
{
|
||||
get { return CodeType.SetKerf; }
|
||||
}
|
||||
|
||||
public ICode Clone()
|
||||
{
|
||||
return new Kerf(Value);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
switch (Value)
|
||||
{
|
||||
case KerfType.Left:
|
||||
return "G41";
|
||||
|
||||
case KerfType.Right:
|
||||
return "G42";
|
||||
|
||||
case KerfType.None:
|
||||
return "G40";
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public enum KerfType
|
||||
{
|
||||
None,
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public enum LayerType
|
||||
{
|
||||
Display,
|
||||
Scribe,
|
||||
Cut,
|
||||
Leadin,
|
||||
Leadout
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
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;
|
||||
Layer = LayerType.Cut;
|
||||
}
|
||||
|
||||
public LayerType Layer { get; set; }
|
||||
|
||||
public override CodeType Type
|
||||
{
|
||||
get { return CodeType.LinearMove; }
|
||||
}
|
||||
|
||||
public override ICode Clone()
|
||||
{
|
||||
return new LinearMove(EndPoint)
|
||||
{
|
||||
Layer = Layer
|
||||
};
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultDecimalPlaces);
|
||||
}
|
||||
|
||||
public override string ToString(int decimalPlaces)
|
||||
{
|
||||
var dp = "N" + decimalPlaces;
|
||||
return string.Format("G01 X{0} Y{1}", EndPoint.X.ToString(dp), EndPoint.Y.ToString(dp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public enum Mode
|
||||
{
|
||||
Absolute,
|
||||
Incremental
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public abstract class Motion : ICode
|
||||
{
|
||||
protected const int DefaultDecimalPlaces = 4;
|
||||
|
||||
public Vector EndPoint { get; set; }
|
||||
|
||||
public bool UseExactStop { get; set; }
|
||||
|
||||
public int Feedrate { get; set; }
|
||||
|
||||
protected Motion()
|
||||
{
|
||||
Feedrate = CNC.Feedrate.UseDefault;
|
||||
}
|
||||
|
||||
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 Type { get; }
|
||||
|
||||
public abstract ICode Clone();
|
||||
|
||||
public abstract string ToString(int decimalPlaces);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,477 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenNest.Geometry;
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public List<ICode> Codes;
|
||||
|
||||
private Mode mode;
|
||||
|
||||
public Program(Mode mode = Mode.Absolute)
|
||||
{
|
||||
Codes = new List<ICode>();
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
public Mode Mode
|
||||
{
|
||||
get { return mode; }
|
||||
set
|
||||
{
|
||||
if (value == Mode.Absolute)
|
||||
SetModeAbs();
|
||||
else
|
||||
SetModeInc();
|
||||
}
|
||||
}
|
||||
|
||||
public double Rotation { get; protected set; }
|
||||
|
||||
private void SetModeInc()
|
||||
{
|
||||
if (mode == Mode.Incremental)
|
||||
return;
|
||||
|
||||
ConvertMode.ToIncremental(this);
|
||||
|
||||
mode = Mode.Incremental;
|
||||
}
|
||||
|
||||
private void SetModeAbs()
|
||||
{
|
||||
if (mode == Mode.Absolute)
|
||||
return;
|
||||
|
||||
ConvertMode.ToAbsolute(this);
|
||||
|
||||
mode = Mode.Absolute;
|
||||
}
|
||||
|
||||
public virtual void Rotate(double angle)
|
||||
{
|
||||
var mode = Mode;
|
||||
|
||||
SetModeAbs();
|
||||
|
||||
for (int i = 0; i < Codes.Count; ++i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
|
||||
if (code.Type == CodeType.SubProgramCall)
|
||||
{
|
||||
var subpgm = (SubProgramCall)code;
|
||||
|
||||
if (subpgm.Program != null)
|
||||
subpgm.Program.Rotate(angle);
|
||||
}
|
||||
|
||||
if (code is Motion == false)
|
||||
continue;
|
||||
|
||||
var code2 = (Motion)code;
|
||||
|
||||
code2.Rotate(angle);
|
||||
}
|
||||
|
||||
if (mode == Mode.Incremental)
|
||||
SetModeInc();
|
||||
|
||||
Rotation = Angle.NormalizeRad(Rotation + angle);
|
||||
}
|
||||
|
||||
public virtual void Rotate(double angle, Vector origin)
|
||||
{
|
||||
var mode = Mode;
|
||||
|
||||
SetModeAbs();
|
||||
|
||||
for (int i = 0; i < Codes.Count; ++i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
|
||||
if (code.Type == CodeType.SubProgramCall)
|
||||
{
|
||||
var subpgm = (SubProgramCall)code;
|
||||
|
||||
if (subpgm.Program != null)
|
||||
subpgm.Program.Rotate(angle);
|
||||
}
|
||||
|
||||
if (code is Motion == false)
|
||||
continue;
|
||||
|
||||
var code2 = (Motion)code;
|
||||
|
||||
code2.Rotate(angle, origin);
|
||||
}
|
||||
|
||||
if (mode == Mode.Incremental)
|
||||
SetModeInc();
|
||||
|
||||
Rotation = Angle.NormalizeRad(Rotation + angle);
|
||||
}
|
||||
|
||||
public virtual void Offset(double x, double y)
|
||||
{
|
||||
var mode = Mode;
|
||||
|
||||
SetModeAbs();
|
||||
|
||||
for (int i = 0; i < Codes.Count; ++i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
|
||||
if (code is Motion == false)
|
||||
continue;
|
||||
|
||||
var code2 = (Motion)code;
|
||||
|
||||
code2.Offset(x, y);
|
||||
}
|
||||
|
||||
if (mode == Mode.Incremental)
|
||||
SetModeInc();
|
||||
}
|
||||
|
||||
public virtual void Offset(Vector voffset)
|
||||
{
|
||||
var mode = Mode;
|
||||
|
||||
SetModeAbs();
|
||||
|
||||
for (int i = 0; i < Codes.Count; ++i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
|
||||
if (code is Motion == false)
|
||||
continue;
|
||||
|
||||
var code2 = (Motion)code;
|
||||
|
||||
code2.Offset(voffset);
|
||||
}
|
||||
|
||||
if (mode == Mode.Incremental)
|
||||
SetModeInc();
|
||||
}
|
||||
|
||||
public void LineTo(double x, double y)
|
||||
{
|
||||
Codes.Add(new LinearMove(x, y));
|
||||
}
|
||||
|
||||
public void LineTo(Vector pt)
|
||||
{
|
||||
Codes.Add(new LinearMove(pt));
|
||||
}
|
||||
|
||||
public void MoveTo(double x, double y)
|
||||
{
|
||||
Codes.Add(new RapidMove(x, y));
|
||||
}
|
||||
|
||||
public void MoveTo(Vector pt)
|
||||
{
|
||||
Codes.Add(new RapidMove(pt));
|
||||
}
|
||||
|
||||
public void ArcTo(double x, double y, double i, double j, RotationType rotation)
|
||||
{
|
||||
Codes.Add(new CircularMove(x, y, i, j, rotation));
|
||||
}
|
||||
|
||||
public void ArcTo(Vector endpt, Vector center, RotationType rotation)
|
||||
{
|
||||
Codes.Add(new CircularMove(endpt, center, rotation));
|
||||
}
|
||||
|
||||
public void AddSubProgram(Program program)
|
||||
{
|
||||
Codes.Add(new SubProgramCall(program, program.Rotation));
|
||||
}
|
||||
|
||||
public ICode this[int index]
|
||||
{
|
||||
get { return Codes[index]; }
|
||||
set { Codes[index] = value; }
|
||||
}
|
||||
|
||||
public int Length
|
||||
{
|
||||
get { return Codes.Count; }
|
||||
}
|
||||
|
||||
public void Merge(Program pgm)
|
||||
{
|
||||
// Set the program to be merged to the same Mode as the current.
|
||||
pgm.Mode = this.Mode;
|
||||
|
||||
if (Mode == Mode.Absolute)
|
||||
{
|
||||
bool isRapid = false;
|
||||
|
||||
// Check if the first motion code is a rapid move
|
||||
foreach (var code in pgm.Codes)
|
||||
{
|
||||
if (code is Motion == false)
|
||||
continue;
|
||||
|
||||
var motion = (Motion)code;
|
||||
|
||||
isRapid = motion.GetType() == typeof(RapidMove);
|
||||
break;
|
||||
}
|
||||
|
||||
// If the first motion code is not a rapid, move to the origin.
|
||||
if (!isRapid)
|
||||
MoveTo(0, 0);
|
||||
|
||||
Codes.AddRange(pgm.Codes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Codes.AddRange(pgm.Codes);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector EndPoint()
|
||||
{
|
||||
switch (Mode)
|
||||
{
|
||||
case Mode.Absolute:
|
||||
{
|
||||
for (int i = Codes.Count; i >= 0; --i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
var motion = code as Motion;
|
||||
|
||||
if (motion == null) continue;
|
||||
|
||||
return motion.EndPoint;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Mode.Incremental:
|
||||
{
|
||||
var pos = new Vector(0, 0);
|
||||
|
||||
for (int i = 0; i < Codes.Count; ++i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
var motion = code as Motion;
|
||||
|
||||
if (motion == null) continue;
|
||||
|
||||
pos += motion.EndPoint;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector(0, 0);
|
||||
}
|
||||
|
||||
public Box BoundingBox()
|
||||
{
|
||||
var origin = new Vector(0, 0);
|
||||
return BoundingBox(ref origin);
|
||||
}
|
||||
|
||||
private Box BoundingBox(ref Vector pos)
|
||||
{
|
||||
double minX = 0.0;
|
||||
double minY = 0.0;
|
||||
double maxX = 0.0;
|
||||
double maxY = 0.0;
|
||||
|
||||
for (int i = 0; i < Codes.Count; ++i)
|
||||
{
|
||||
var code = Codes[i];
|
||||
|
||||
switch (code.Type)
|
||||
{
|
||||
case CodeType.LinearMove:
|
||||
{
|
||||
var line = (LinearMove)code;
|
||||
var pt = Mode == Mode.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 == Mode.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 == Mode.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 = Angle.NormalizeRad(startAngle);
|
||||
endAngle = Angle.NormalizeRad(endAngle);
|
||||
|
||||
if (Angle.IsBetweenRad(Angle.HalfPI, startAngle, endAngle))
|
||||
maxY1 = centerpt.Y + radius;
|
||||
|
||||
if (Angle.IsBetweenRad(Math.PI, startAngle, endAngle))
|
||||
minX1 = centerpt.X - radius;
|
||||
|
||||
const double oneHalfPI = Math.PI * 1.5;
|
||||
|
||||
if (Angle.IsBetweenRad(oneHalfPI, startAngle, endAngle))
|
||||
minY1 = centerpt.Y - radius;
|
||||
|
||||
if (Angle.IsBetweenRad(Angle.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.Program.BoundingBox(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 object Clone()
|
||||
{
|
||||
var pgm = new Program()
|
||||
{
|
||||
mode = this.mode,
|
||||
Rotation = this.Rotation
|
||||
};
|
||||
|
||||
var codes = new ICode[Length];
|
||||
|
||||
for (int i = 0; i < Length; ++i)
|
||||
codes[i] = this.Codes[i].Clone();
|
||||
|
||||
pgm.Codes.AddRange(codes);
|
||||
|
||||
return pgm;
|
||||
}
|
||||
|
||||
public List<Entity> ToGeometry()
|
||||
{
|
||||
return ConvertProgram.ToGeometry(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class RapidMove : Motion
|
||||
{
|
||||
public RapidMove()
|
||||
{
|
||||
Feedrate = CNC.Feedrate.UseMax;
|
||||
}
|
||||
|
||||
public RapidMove(Vector endPoint)
|
||||
{
|
||||
EndPoint = endPoint;
|
||||
}
|
||||
|
||||
public RapidMove(double x, double y)
|
||||
{
|
||||
EndPoint = new Vector(x, y);
|
||||
}
|
||||
|
||||
public override CodeType Type
|
||||
{
|
||||
get { return CodeType.RapidMove; }
|
||||
}
|
||||
|
||||
public override ICode Clone()
|
||||
{
|
||||
return new RapidMove(EndPoint);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(DefaultDecimalPlaces);
|
||||
}
|
||||
|
||||
public override string ToString(int decimalPlaces)
|
||||
{
|
||||
var dp = "N" + decimalPlaces;
|
||||
return string.Format("G00 X{0} Y{1}", EndPoint.X.ToString(dp), EndPoint.Y.ToString(dp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
namespace OpenNest.CNC
|
||||
{
|
||||
public class SubProgramCall : ICode
|
||||
{
|
||||
private double rotation;
|
||||
private Program program;
|
||||
|
||||
public SubProgramCall()
|
||||
{
|
||||
}
|
||||
|
||||
public SubProgramCall(Program program, double rotation)
|
||||
{
|
||||
this.program = program;
|
||||
this.Rotation = rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The program ID.
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the program.
|
||||
/// </summary>
|
||||
public Program Program
|
||||
{
|
||||
get { return program; }
|
||||
set
|
||||
{
|
||||
program = value;
|
||||
UpdateProgramRotation();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the rotation of the program in degrees.
|
||||
/// </summary>
|
||||
public double Rotation
|
||||
{
|
||||
get { return rotation; }
|
||||
set
|
||||
{
|
||||
rotation = value;
|
||||
UpdateProgramRotation();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotates the program by the difference of the current
|
||||
/// rotation set in the sub program call and the program.
|
||||
/// </summary>
|
||||
private void UpdateProgramRotation()
|
||||
{
|
||||
if (program != null)
|
||||
{
|
||||
var diffAngle = Angle.ToRadians(rotation) - program.Rotation;
|
||||
|
||||
if (!diffAngle.IsEqualTo(0.0))
|
||||
program.Rotate(diffAngle);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the code type.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CodeType Type
|
||||
{
|
||||
get { return CodeType.SubProgramCall; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a shallow copy.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ICode Clone()
|
||||
{
|
||||
return new SubProgramCall(program, Rotation);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("G65 P{0} R{1}", Id, Rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user