Files
PepApi.Core/PepLib.Core/Program.cs
AJ 7c5b4ded5f chore(PepLib.Core): remove unused using directives and clean up formatting
Remove unnecessary System, System.Collections.Generic, System.IO, and
System.Linq using directives that were flagged by IDE analyzers. Also
includes minor whitespace and code style normalization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 07:52:17 -05:00

365 lines
11 KiB
C#

using PepLib.Codes;
using PepLib.IO;
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;
}
}
}