fix: close polygon offset shape and handle nest template load failure
Shape.OffsetEntity computed joins between consecutive offset segments but never joined the last segment back to the first, leaving the closing corner with a straight line instead of a proper miter/arc. Track the first entity and apply the same join logic after the loop. Also wrap nest template loading in try-catch so a corrupt template file doesn't crash the app on startup — falls back to default nest. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -463,6 +463,8 @@ namespace OpenNest.Geometry
|
|||||||
var offsetShape = new Shape();
|
var offsetShape = new Shape();
|
||||||
var definedShape = new ShapeProfile(this);
|
var definedShape = new ShapeProfile(this);
|
||||||
|
|
||||||
|
Entity firstEntity = null;
|
||||||
|
Entity firstOffsetEntity = null;
|
||||||
Entity lastEntity = null;
|
Entity lastEntity = null;
|
||||||
Entity lastOffsetEntity = null;
|
Entity lastOffsetEntity = null;
|
||||||
|
|
||||||
@@ -473,6 +475,12 @@ namespace OpenNest.Geometry
|
|||||||
if (offsetEntity == null)
|
if (offsetEntity == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (firstEntity == null)
|
||||||
|
{
|
||||||
|
firstEntity = entity;
|
||||||
|
firstOffsetEntity = offsetEntity;
|
||||||
|
}
|
||||||
|
|
||||||
switch (entity.Type)
|
switch (entity.Type)
|
||||||
{
|
{
|
||||||
case EntityType.Line:
|
case EntityType.Line:
|
||||||
@@ -482,12 +490,48 @@ namespace OpenNest.Geometry
|
|||||||
|
|
||||||
if (lastOffsetEntity != null && lastOffsetEntity.Type == EntityType.Line)
|
if (lastOffsetEntity != null && lastOffsetEntity.Type == EntityType.Line)
|
||||||
{
|
{
|
||||||
var lastLine = lastEntity as Line;
|
JoinOffsetLines(
|
||||||
var lastOffsetLine = lastOffsetEntity as Line;
|
(Line)lastEntity, (Line)lastOffsetEntity,
|
||||||
|
line, offsetLine,
|
||||||
|
distance, side, offsetShape);
|
||||||
|
}
|
||||||
|
|
||||||
if (lastLine == null || lastOffsetLine == null)
|
offsetShape.Entities.Add(offsetLine);
|
||||||
continue;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
offsetShape.Entities.Add(offsetEntity);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastOffsetEntity = offsetEntity;
|
||||||
|
lastEntity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the shape: join last offset entity back to first
|
||||||
|
if (lastOffsetEntity != null && firstOffsetEntity != null
|
||||||
|
&& lastOffsetEntity != firstOffsetEntity
|
||||||
|
&& lastOffsetEntity.Type == EntityType.Line
|
||||||
|
&& firstOffsetEntity.Type == EntityType.Line)
|
||||||
|
{
|
||||||
|
JoinOffsetLines(
|
||||||
|
(Line)lastEntity, (Line)lastOffsetEntity,
|
||||||
|
(Line)firstEntity, (Line)firstOffsetEntity,
|
||||||
|
distance, side, offsetShape);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var cutout in definedShape.Cutouts)
|
||||||
|
offsetShape.Entities.AddRange(((Shape)cutout.OffsetEntity(distance, side)).Entities);
|
||||||
|
|
||||||
|
return offsetShape;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void JoinOffsetLines(
|
||||||
|
Line lastLine, Line lastOffsetLine,
|
||||||
|
Line line, Line offsetLine,
|
||||||
|
double distance, OffsetSide side, Shape offsetShape)
|
||||||
|
{
|
||||||
Vector intersection;
|
Vector intersection;
|
||||||
|
|
||||||
if (Helper.Intersects(offsetLine, lastOffsetLine, out intersection))
|
if (Helper.Intersects(offsetLine, lastOffsetLine, out intersection))
|
||||||
@@ -509,25 +553,6 @@ namespace OpenNest.Geometry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetShape.Entities.Add(offsetLine);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
offsetShape.Entities.Add(offsetEntity);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastOffsetEntity = offsetEntity;
|
|
||||||
lastEntity = entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var cutout in definedShape.Cutouts)
|
|
||||||
offsetShape.Entities.AddRange(((Shape)cutout.OffsetEntity(distance, side)).Entities);
|
|
||||||
|
|
||||||
return offsetShape;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Entity OffsetEntity(double distance, Vector pt)
|
public override Entity OffsetEntity(double distance, Vector pt)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@@ -47,6 +47,17 @@ namespace OpenNest.Forms
|
|||||||
// BestFitCache.CreateEvaluator = (drawing, spacing) => GpuEvaluatorFactory.Create(drawing, spacing);
|
// BestFitCache.CreateEvaluator = (drawing, spacing) => GpuEvaluatorFactory.Create(drawing, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Nest CreateDefaultNest()
|
||||||
|
{
|
||||||
|
var nest = new Nest();
|
||||||
|
nest.Units = Properties.Settings.Default.DefaultUnit;
|
||||||
|
nest.PlateDefaults.EdgeSpacing = new Spacing(1, 1, 1, 1);
|
||||||
|
nest.PlateDefaults.PartSpacing = 1;
|
||||||
|
nest.PlateDefaults.Size = new OpenNest.Geometry.Size(100, 100);
|
||||||
|
nest.PlateDefaults.Quadrant = 1;
|
||||||
|
return nest;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetNestName(DateTime date, int id)
|
private string GetNestName(DateTime date, int id)
|
||||||
{
|
{
|
||||||
var month = date.Month.ToString().PadLeft(2, '0');
|
var month = date.Month.ToString().PadLeft(2, '0');
|
||||||
@@ -325,18 +336,25 @@ namespace OpenNest.Forms
|
|||||||
Nest nest;
|
Nest nest;
|
||||||
|
|
||||||
if (File.Exists(Properties.Settings.Default.NestTemplatePath))
|
if (File.Exists(Properties.Settings.Default.NestTemplatePath))
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var reader = new NestReader(Properties.Settings.Default.NestTemplatePath);
|
var reader = new NestReader(Properties.Settings.Default.NestTemplatePath);
|
||||||
nest = reader.Read();
|
nest = reader.Read();
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show(
|
||||||
|
$"Failed to load nest template:\n{ex.Message}\n\nA default nest will be created instead.",
|
||||||
|
"Template Error",
|
||||||
|
MessageBoxButtons.OK,
|
||||||
|
MessageBoxIcon.Warning);
|
||||||
|
nest = CreateDefaultNest();
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nest = new Nest();
|
nest = CreateDefaultNest();
|
||||||
nest.Units = Properties.Settings.Default.DefaultUnit;
|
|
||||||
nest.PlateDefaults.EdgeSpacing = new Spacing(0, 0, 0, 0);
|
|
||||||
nest.PlateDefaults.PartSpacing = 0;
|
|
||||||
nest.PlateDefaults.Size = new OpenNest.Geometry.Size(100, 100);
|
|
||||||
nest.PlateDefaults.Quadrant = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nest.DateCreated = DateTime.Now;
|
nest.DateCreated = DateTime.Now;
|
||||||
|
|||||||
Reference in New Issue
Block a user