feat: add configurable chord tolerance for offset drawing and push geometry
Replace hardcoded PushChordTolerance constant with a configurable OffsetTolerance property on PlateView (default 0.001), giving smoother arc profiles in offset drawing and push-to-part collision detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -739,9 +739,7 @@ namespace OpenNest
|
|||||||
return pts.Count > 0;
|
return pts.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private const double PushChordTolerance = 0.01;
|
public static List<Line> GetPartLines(Part part, double chordTolerance = 0.001)
|
||||||
|
|
||||||
public static List<Line> GetPartLines(Part part)
|
|
||||||
{
|
{
|
||||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
var entities = ConvertProgram.ToGeometry(part.Program);
|
||||||
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
||||||
@@ -749,7 +747,7 @@ namespace OpenNest
|
|||||||
|
|
||||||
foreach (var shape in shapes)
|
foreach (var shape in shapes)
|
||||||
{
|
{
|
||||||
var polygon = shape.ToPolygonWithTolerance(PushChordTolerance);
|
var polygon = shape.ToPolygonWithTolerance(chordTolerance);
|
||||||
polygon.Offset(part.Location);
|
polygon.Offset(part.Location);
|
||||||
lines.AddRange(polygon.ToLines());
|
lines.AddRange(polygon.ToLines());
|
||||||
}
|
}
|
||||||
@@ -757,7 +755,7 @@ namespace OpenNest
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Line> GetPartLines(Part part, PushDirection facingDirection)
|
public static List<Line> GetPartLines(Part part, PushDirection facingDirection, double chordTolerance = 0.001)
|
||||||
{
|
{
|
||||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
var entities = ConvertProgram.ToGeometry(part.Program);
|
||||||
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
||||||
@@ -765,7 +763,7 @@ namespace OpenNest
|
|||||||
|
|
||||||
foreach (var shape in shapes)
|
foreach (var shape in shapes)
|
||||||
{
|
{
|
||||||
var polygon = shape.ToPolygonWithTolerance(PushChordTolerance);
|
var polygon = shape.ToPolygonWithTolerance(chordTolerance);
|
||||||
polygon.Offset(part.Location);
|
polygon.Offset(part.Location);
|
||||||
lines.AddRange(GetDirectionalLines(polygon, facingDirection));
|
lines.AddRange(GetDirectionalLines(polygon, facingDirection));
|
||||||
}
|
}
|
||||||
@@ -773,7 +771,7 @@ namespace OpenNest
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Line> GetOffsetPartLines(Part part, double spacing)
|
public static List<Line> GetOffsetPartLines(Part part, double spacing, double chordTolerance = 0.001)
|
||||||
{
|
{
|
||||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
var entities = ConvertProgram.ToGeometry(part.Program);
|
||||||
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
||||||
@@ -783,12 +781,12 @@ namespace OpenNest
|
|||||||
{
|
{
|
||||||
// Add chord tolerance to compensate for inscribed polygon chords
|
// Add chord tolerance to compensate for inscribed polygon chords
|
||||||
// being inside the actual offset arcs.
|
// being inside the actual offset arcs.
|
||||||
var offsetEntity = shape.OffsetEntity(spacing + PushChordTolerance, OffsetSide.Left) as Shape;
|
var offsetEntity = shape.OffsetEntity(spacing + chordTolerance, OffsetSide.Left) as Shape;
|
||||||
|
|
||||||
if (offsetEntity == null)
|
if (offsetEntity == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var polygon = offsetEntity.ToPolygonWithTolerance(PushChordTolerance);
|
var polygon = offsetEntity.ToPolygonWithTolerance(chordTolerance);
|
||||||
polygon.RemoveSelfIntersections();
|
polygon.RemoveSelfIntersections();
|
||||||
polygon.Offset(part.Location);
|
polygon.Offset(part.Location);
|
||||||
lines.AddRange(polygon.ToLines());
|
lines.AddRange(polygon.ToLines());
|
||||||
@@ -797,7 +795,7 @@ namespace OpenNest
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Line> GetOffsetPartLines(Part part, double spacing, PushDirection facingDirection)
|
public static List<Line> GetOffsetPartLines(Part part, double spacing, PushDirection facingDirection, double chordTolerance = 0.001)
|
||||||
{
|
{
|
||||||
var entities = ConvertProgram.ToGeometry(part.Program);
|
var entities = ConvertProgram.ToGeometry(part.Program);
|
||||||
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
var shapes = GetShapes(entities.Where(e => e.Layer != SpecialLayers.Rapid));
|
||||||
@@ -805,12 +803,12 @@ namespace OpenNest
|
|||||||
|
|
||||||
foreach (var shape in shapes)
|
foreach (var shape in shapes)
|
||||||
{
|
{
|
||||||
var offsetEntity = shape.OffsetEntity(spacing + PushChordTolerance, OffsetSide.Left) as Shape;
|
var offsetEntity = shape.OffsetEntity(spacing + chordTolerance, OffsetSide.Left) as Shape;
|
||||||
|
|
||||||
if (offsetEntity == null)
|
if (offsetEntity == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var polygon = offsetEntity.ToPolygonWithTolerance(PushChordTolerance);
|
var polygon = offsetEntity.ToPolygonWithTolerance(chordTolerance);
|
||||||
polygon.RemoveSelfIntersections();
|
polygon.RemoveSelfIntersections();
|
||||||
polygon.Offset(part.Location);
|
polygon.Offset(part.Location);
|
||||||
lines.AddRange(GetDirectionalLines(polygon, facingDirection));
|
lines.AddRange(GetDirectionalLines(polygon, facingDirection));
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ namespace OpenNest.Controls
|
|||||||
|
|
||||||
public bool DrawOffset { get; set; }
|
public bool DrawOffset { get; set; }
|
||||||
|
|
||||||
|
public double OffsetTolerance { get; set; } = 0.001;
|
||||||
|
|
||||||
public bool FillParts { get; set; }
|
public bool FillParts { get; set; }
|
||||||
|
|
||||||
public double RotateIncrementAngle { get; set; }
|
public double RotateIncrementAngle { get; set; }
|
||||||
@@ -491,7 +493,7 @@ namespace OpenNest.Controls
|
|||||||
if (offsetEntity == null)
|
if (offsetEntity == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var polygon = offsetEntity.ToPolygonWithTolerance(0.01);
|
var polygon = offsetEntity.ToPolygonWithTolerance(OffsetTolerance);
|
||||||
polygon.RemoveSelfIntersections();
|
polygon.RemoveSelfIntersections();
|
||||||
polygon.Offset(part.Location);
|
polygon.Offset(part.Location);
|
||||||
|
|
||||||
@@ -861,8 +863,8 @@ namespace OpenNest.Controls
|
|||||||
foreach (var part in stationaryParts)
|
foreach (var part in stationaryParts)
|
||||||
{
|
{
|
||||||
stationaryLines.Add(halfSpacing > 0
|
stationaryLines.Add(halfSpacing > 0
|
||||||
? Helper.GetOffsetPartLines(part.BasePart, halfSpacing, opposite)
|
? Helper.GetOffsetPartLines(part.BasePart, halfSpacing, opposite, OffsetTolerance)
|
||||||
: Helper.GetPartLines(part.BasePart, opposite));
|
: Helper.GetPartLines(part.BasePart, opposite, OffsetTolerance));
|
||||||
stationaryBoxes.Add(part.BoundingBox);
|
stationaryBoxes.Add(part.BoundingBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,8 +875,8 @@ namespace OpenNest.Controls
|
|||||||
{
|
{
|
||||||
// Get offset lines for the moving part (half-spacing, symmetric with stationary).
|
// Get offset lines for the moving part (half-spacing, symmetric with stationary).
|
||||||
var movingLines = halfSpacing > 0
|
var movingLines = halfSpacing > 0
|
||||||
? Helper.GetOffsetPartLines(selected.BasePart, halfSpacing, direction)
|
? Helper.GetOffsetPartLines(selected.BasePart, halfSpacing, direction, OffsetTolerance)
|
||||||
: Helper.GetPartLines(selected.BasePart, direction);
|
: Helper.GetPartLines(selected.BasePart, direction, OffsetTolerance);
|
||||||
|
|
||||||
var movingBox = selected.BoundingBox;
|
var movingBox = selected.BoundingBox;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user