mirror of
https://github.com/ajisaacs/OpenNest.git
synced 2026-11-14 08:05:07 -05:00
Geometry, nesting and import code now call PortableMath instead of System.Math for Sin, Cos, Tan, Atan, Atan2, Asin and Acos (Core, Engine, IO, Data; 269 calls in 64 files). A test fails if those projects call the runtime's trig again. With the runtime's trig, Windows and Linux disagreed in the last bit at non-quarter angles and the same job could nest differently: the learned-angle nests (a cross fixture) placed 23 parts in Strip on Windows and 28 on Linux. Now every Engine.Tests pin gives the same layout on both (3600 passing on Linux and on DesktopPC), Linux layouts are unchanged, and the learned-angle rows are re-pinned to the shared layouts, which pass the overlap and work-area checks, and run on every platform again. Fixes Project Memory 518f3b58.
109 lines
3.5 KiB
C#
109 lines
3.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using OpenNest.Geometry;
|
|
using OpenNest.Math;
|
|
|
|
namespace OpenNest.Bending
|
|
{
|
|
public class Bend
|
|
{
|
|
public static readonly Layer EtchLayer = new Layer("ETCH")
|
|
{
|
|
Color = Color.Green,
|
|
IsVisible = true,
|
|
};
|
|
|
|
private const double DefaultEtchLength = 1.0;
|
|
private const string BendEtchTag = "BendEtch";
|
|
|
|
public Vector StartPoint { get; set; }
|
|
public Vector EndPoint { get; set; }
|
|
public BendDirection Direction { get; set; }
|
|
public double? Angle { get; set; }
|
|
public double? Radius { get; set; }
|
|
public string NoteText { get; set; }
|
|
|
|
[System.Text.Json.Serialization.JsonIgnore]
|
|
public Entity SourceEntity { get; set; }
|
|
|
|
// Import-only identity of the original CAD annotation (not nest metadata).
|
|
[System.Text.Json.Serialization.JsonIgnore]
|
|
public ulong? SourceNoteHandle { get; set; }
|
|
|
|
public double Length => StartPoint.DistanceTo(EndPoint);
|
|
|
|
public double AngleRadians =>
|
|
Angle.HasValue ? OpenNest.Math.Angle.ToRadians(Angle.Value) : 0;
|
|
|
|
public Line ToLine() => new Line(StartPoint, EndPoint);
|
|
|
|
/// <summary>
|
|
/// Returns the angle of the bend line itself (not the bend angle).
|
|
/// Used for grain direction comparison.
|
|
/// </summary>
|
|
public double LineAngle => StartPoint.AngleTo(EndPoint);
|
|
|
|
/// <summary>
|
|
/// Generates etch mark entities for this bend (up bends only).
|
|
/// Returns 1" dashes at each end of the bend line, or the full line if shorter than 3".
|
|
/// </summary>
|
|
public List<Line> GetEtchEntities(double etchLength = DefaultEtchLength)
|
|
{
|
|
var result = new List<Line>();
|
|
if (Direction != BendDirection.Up)
|
|
return result;
|
|
|
|
var length = Length;
|
|
|
|
if (length < etchLength * 3.0)
|
|
{
|
|
result.Add(CreateEtchLine(StartPoint, EndPoint));
|
|
}
|
|
else
|
|
{
|
|
var angle = StartPoint.AngleTo(EndPoint);
|
|
var dx = PortableMath.Cos(angle) * etchLength;
|
|
var dy = PortableMath.Sin(angle) * etchLength;
|
|
|
|
result.Add(
|
|
CreateEtchLine(StartPoint, new Vector(StartPoint.X + dx, StartPoint.Y + dy))
|
|
);
|
|
result.Add(CreateEtchLine(new Vector(EndPoint.X - dx, EndPoint.Y - dy), EndPoint));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes existing etch entities from the list and regenerates from the given bends.
|
|
/// </summary>
|
|
public static void UpdateEtchEntities(List<Entity> entities, List<Bend> bends)
|
|
{
|
|
entities.RemoveAll(e => e.Tag == BendEtchTag);
|
|
if (bends == null)
|
|
return;
|
|
|
|
foreach (var bend in bends)
|
|
entities.AddRange(bend.GetEtchEntities());
|
|
}
|
|
|
|
private static Line CreateEtchLine(Vector start, Vector end)
|
|
{
|
|
return new Line(start, end)
|
|
{
|
|
Layer = EtchLayer,
|
|
Color = Color.Green,
|
|
Tag = BendEtchTag,
|
|
};
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
var dir = Direction.ToString();
|
|
var angle = Angle?.ToString("0.##") ?? "?";
|
|
var radius = Radius?.ToString("0.###") ?? "?";
|
|
return $"{dir} {angle}° R{radius}";
|
|
}
|
|
}
|
|
}
|