using System;
using System.Collections.Generic;
using OpenNest.Geometry;
namespace OpenNest.Converters
{
/// What a drawing does with a source entity.
public enum EntityRole
{
/// Cut through the material.
Cut,
/// Marked on the surface (a Scribe pass): never material.
Etch,
///
/// Shown with the part for reference only. It is kept out of the program, so it is never
/// cut, posted, nested against or verified.
///
Display,
}
///
/// Applies per-entity role overrides. An entity without an override keeps the role its layer
/// implies: mark layers (ETCH, SCRIBE, ENGRAVE) etch, everything else cuts.
///
public static class EntityRoles
{
public static EntityRole Default(Entity entity) =>
ScribeLayerRepair.IsMarkLayer(entity.Layer) ? EntityRole.Etch : EntityRole.Cut;
public static EntityRole Of(Entity entity, IReadOnlyDictionary overrides) =>
overrides != null && overrides.TryGetValue(entity.Id, out var role) ? role : Default(entity);
///
/// The entities a program is built from: display-only entities are left out and entities
/// whose override differs from their layer's role are replaced by copies, with the same
/// ID, on a layer the converters read as that role. Inputs are never mutated.
///
public static List ForProgram(IEnumerable entities, IReadOnlyDictionary overrides)
{
var result = new List();
foreach (var entity in entities)
{
if (overrides == null || !overrides.TryGetValue(entity.Id, out var role) || role == Default(entity))
{
result.Add(entity);
continue;
}
if (role == EntityRole.Display)
continue;
var copy = entity.Clone();
copy.Id = entity.Id;
copy.Layer = new Layer(role == EntityRole.Etch ? SpecialLayers.Scribe.Name : SpecialLayers.Cut.Name)
{
Color = entity.Layer?.Color ?? SpecialLayers.Cut.Color,
IsVisible = true,
};
result.Add(copy);
}
return result;
}
///
/// A drawing's unsuppressed display-only entities as copies in its program frame (source
/// coordinates shifted by -Source.Offset, before any program rotation).
///
public static List DisplayGeometry(Drawing drawing)
{
var result = new List();
if (drawing?.SourceEntities == null || drawing.EntityRoles == null || drawing.EntityRoles.Count == 0)
return result;
var offset = drawing.Source?.Offset ?? Vector.Zero;
foreach (var entity in drawing.SourceEntities)
{
if (drawing.SuppressedEntityIds.Contains(entity.Id) || Of(entity, drawing.EntityRoles) != EntityRole.Display)
continue;
var copy = entity.Clone();
copy.Id = entity.Id;
copy.Offset(-offset.X, -offset.Y);
result.Add(copy);
}
return result;
}
}
}