Editor/Effigy/FeatureDiagnostic.cs
using System;
using System.Collections.Generic;
namespace Effigy;
/// <summary>Whether the feature produced geometry. An error means it did not; a warning means it
/// did, and you should look at it.</summary>
public enum DiagnosticSeverity
{
Warning,
Error
}
/// <summary>
/// Why a feature failed or degraded, in the three parts a person can act on: what is wrong, why
/// with this model's numbers, and what to do instead.
///
/// A single string cannot do this. The UI styles the three parts differently, ParameterLabel puts
/// the red ring on the control that is actually wrong, and remedies want to be a list — and
/// sometimes a button that does the thing.
/// </summary>
public sealed class FeatureDiagnostic
{
public DiagnosticSeverity Severity;
public string Problem;
public string Cause;
public List<string> Remedies = new();
/// <summary>Which parameter's control to highlight, matching <see cref="IParam.Label"/>, or
/// null when the failure is not a single field.</summary>
public string ParameterLabel;
/// <summary>When set, the dialog can offer a button that writes this into the named
/// parameter — handing the user the number rather than only telling them it.</summary>
public float? SuggestedValue;
public FeatureDiagnostic() { }
public FeatureDiagnostic( DiagnosticSeverity severity, string problem, string cause = null,
string parameterLabel = null, float? suggestedValue = null, params string[] remedies )
{
Severity = severity;
Problem = problem;
Cause = cause;
ParameterLabel = parameterLabel;
SuggestedValue = suggestedValue;
if ( remedies is { Length: > 0 } )
Remedies.AddRange( remedies );
}
/// <summary>Problem plus cause, for a tooltip that has no room for the list.</summary>
public string Tooltip
{
get
{
if ( string.IsNullOrEmpty( Cause ) )
return Problem;
return string.IsNullOrEmpty( Problem ) ? Cause : $"{Problem}\n{Cause}";
}
}
}
/// <summary>Thrown by a feature that knows exactly why it cannot proceed.</summary>
public sealed class FeatureException : Exception
{
public readonly FeatureDiagnostic Diagnostic;
public FeatureException( FeatureDiagnostic diagnostic )
: base( diagnostic?.Problem ?? "Feature failed" )
{
Diagnostic = diagnostic ?? throw new ArgumentNullException( nameof( diagnostic ) );
}
}
/// <summary>What EdgeBlend did, including the silent degradations that used to vanish.</summary>
public sealed class BlendReport
{
public PolyMesh Mesh;
public FeatureDiagnostic Failure;
public readonly List<FeatureDiagnostic> Warnings = new();
public float SuggestedSize;
public int SelectedEdges;
public float SharpestDegrees;
public float OriginalVolume;
public float ResultVolume;
}