Skip to content

Commit

Permalink
add validation and guards
Browse files Browse the repository at this point in the history
  • Loading branch information
bertt committed Nov 27, 2023
1 parent f16732d commit 8fbe607
Showing 1 changed file with 68 additions and 4 deletions.
72 changes: 68 additions & 4 deletions src/SharpGLTF.Cesium/Schema2/MeshExtInstanceFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace SharpGLTF.Schema2
{
public partial class MeshExtInstanceFeatures
{
private Node _node;
private Node _node;
internal MeshExtInstanceFeatures(Node node)
{
_node = node;
Expand Down Expand Up @@ -48,16 +48,80 @@ public MeshExtInstanceFeatureID(int featureCount, int? attribute = null, int? pr
_propertyTable = propertyTable;
_nullFeatureId = nullFeatureId;
}

/// <summary>
/// The number of unique features in the attribute
/// </summary>
public int FeatureCount { get => _featureCount; }

/// <summary>
/// An attribute containing feature IDs. When this is omitted, then the feature IDs are assigned to the GPU instances by their index.
/// </summary>
public int? Attribute { get => _attribute; }

/// <summary>
/// A label assigned to this feature ID set
/// </summary>
public string Label { get => _label; }

/// <summary>
/// The index of the property table containing per-feature property values. Only applicable when using the `EXT_structural_metadata` extension.
/// </summary>
public int? PropertyTable { get => _propertyTable; }

/// <summary>
/// A value that indicates that no feature is associated with this instance
/// </summary>
public int? NullFeatureId { get => _nullFeatureId; }
}

public static class ExtInstanceFeatures
{
public static void SetFeatureIds(this Node node, List<MeshExtInstanceFeatureID> list)
/// <summary>
/// Set the instance feature ids for this node.
/// </summary>
/// <param name="node"></param>
/// <param name="instanceFeatureIds"></param>
public static void SetFeatureIds(this Node node, List<MeshExtInstanceFeatureID> instanceFeatureIds)
{
if (list == null) { node.RemoveExtensions<MeshExtInstanceFeatures>(); return; }
if (instanceFeatureIds == null) { node.RemoveExtensions<MeshExtInstanceFeatures>(); return; }

Guard.NotNullOrEmpty(instanceFeatureIds, nameof(instanceFeatureIds));

foreach (var instanceFeatureId in instanceFeatureIds)
{
ValidateInstanceFeatureId(node, instanceFeatureId);
};

var ext = node.UseExtension<MeshExtInstanceFeatures>();
ext.FeatureIds = list;
ext.FeatureIds = instanceFeatureIds;
}

private static void ValidateInstanceFeatureId(Node node, MeshExtInstanceFeatureID item)
{
Guard.MustBeGreaterThanOrEqualTo((int)item.FeatureCount, 1, nameof(item.FeatureCount));

if (item.NullFeatureId.HasValue)
{
Guard.MustBeGreaterThanOrEqualTo((int)item.NullFeatureId, 0, nameof(item.NullFeatureId));
}
if (item.Label != null)
{
var regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
Guard.IsTrue(System.Text.RegularExpressions.Regex.IsMatch(item.Label, regex), nameof(item.Label));
}
if (item.Attribute.HasValue)
{
Guard.MustBeGreaterThanOrEqualTo((int)item.Attribute, 0, nameof(item.Attribute));
// todo: check attribute
// Guard that the custom vertex attribute (_FEATURE_ID_{attribute}) exists when FeatureID has attribute set
// var expectedVertexAttribute = $"_FEATURE_ID_{item.Attribute}";
// Guard.NotNull(primitive.GetVertexAccessor(expectedVertexAttribute), expectedVertexAttribute);
}
if (item.PropertyTable.HasValue)
{
Guard.MustBeGreaterThanOrEqualTo((int)item.PropertyTable, 0, nameof(item.PropertyTable));
}
}
}
}

0 comments on commit 8fbe607

Please sign in to comment.