Skip to content

Commit

Permalink
Simplified CesiumPrimitiveOutline API from PR #175
Browse files Browse the repository at this point in the history
  • Loading branch information
vpenades committed Mar 10, 2023
1 parent c099555 commit 70ee77b
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 161 deletions.
2 changes: 1 addition & 1 deletion build/SharpGLTF.CodeGen/Ext.CESIUM_primitive_outline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CesiumPrimitiveOutlineExtension : SchemaProcessor

public override void PrepareTypes(CSharpEmitter newEmitter, SchemaType.Context ctx)
{
newEmitter.SetRuntimeName("Ext.CESIUM_primitive_outline glTF extension", "CesiumPrimitiveOutline");
newEmitter.SetRuntimeName("CESIUM_primitive_outline glTF primitive extension", "CesiumPrimitiveOutline");
}

public override IEnumerable<(string TargetFileName, SchemaType.Context Schema)> Process()
Expand Down
112 changes: 56 additions & 56 deletions src/SharpGLTF.Core/Schema2/Generated/Ext.CESIUM_primitive_outline.g.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@
// <auto-generated/>

//------------------------------------------------------------------------------------------------
// This file has been programatically generated; DON´T EDIT!
//------------------------------------------------------------------------------------------------

#pragma warning disable SA1001
#pragma warning disable SA1027
#pragma warning disable SA1028
#pragma warning disable SA1121
#pragma warning disable SA1205
#pragma warning disable SA1309
#pragma warning disable SA1402
#pragma warning disable SA1505
#pragma warning disable SA1507
#pragma warning disable SA1508
#pragma warning disable SA1652

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Text.Json;

namespace SharpGLTF.Schema2
{
using Collections;

/// <summary>
/// glTF extension for indicating that some edges of a primitive's triangles should be outlined.
/// </summary>
partial class CESIUM_primitive_outlineglTFprimitiveextension : ExtraProperties
{

private Int32? _indices;


protected override void SerializeProperties(Utf8JsonWriter writer)
{
base.SerializeProperties(writer);
SerializeProperty(writer, "indices", _indices);
}

protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
{
switch (jsonPropertyName)
{
case "indices": _indices = DeserializePropertyValue<Int32?>(ref reader); break;
default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
}
}

}

}
// <auto-generated/>

//------------------------------------------------------------------------------------------------
// This file has been programatically generated; DON´T EDIT!
//------------------------------------------------------------------------------------------------

#pragma warning disable SA1001
#pragma warning disable SA1027
#pragma warning disable SA1028
#pragma warning disable SA1121
#pragma warning disable SA1205
#pragma warning disable SA1309
#pragma warning disable SA1402
#pragma warning disable SA1505
#pragma warning disable SA1507
#pragma warning disable SA1508
#pragma warning disable SA1652

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Numerics;
using System.Text.Json;

namespace SharpGLTF.Schema2
{
using Collections;

/// <summary>
/// glTF extension for indicating that some edges of a primitive's triangles should be outlined.
/// </summary>
partial class CesiumPrimitiveOutline : ExtraProperties
{

private Int32? _indices;


protected override void SerializeProperties(Utf8JsonWriter writer)
{
base.SerializeProperties(writer);
SerializeProperty(writer, "indices", _indices);
}

protected override void DeserializeProperty(string jsonPropertyName, ref Utf8JsonReader reader)
{
switch (jsonPropertyName)
{
case "indices": _indices = DeserializePropertyValue<Int32?>(ref reader); break;
default: base.DeserializeProperty(jsonPropertyName,ref reader); break;
}
}

}

}
2 changes: 1 addition & 1 deletion src/SharpGLTF.Core/Schema2/gltf.ExtensionsFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static ExtensionsFactory()
RegisterExtension<Node, AgiNodeArticulations>("AGI_articulations");
RegisterExtension<Node, AgiNodeStkMetadata>("AGI_stk_metadata");

RegisterExtension<MeshPrimitive, CESIUM_primitive_outlineglTFprimitiveextension>("CESIUM_primitive_outline");
RegisterExtension<MeshPrimitive, CesiumPrimitiveOutline>("CESIUM_primitive_outline");
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
@@ -1,98 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace SharpGLTF.Schema2
{
partial class CESIUM_primitive_outlineglTFprimitiveextension
{
private MeshPrimitive meshPrimitive;
internal CESIUM_primitive_outlineglTFprimitiveextension(MeshPrimitive meshPrimitive)
{
this.meshPrimitive = meshPrimitive;
}

public int? Indices
{
get => _indices;
set => _indices = value;
}

protected override void OnValidateContent(Validation.ValidationContext validate)
{
var outlineAccessor = meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[(int)_indices];
var isValid = CesiumToolkit.ValidateCesiumOutlineIndices(outlineAccessor, meshPrimitive);
validate.IsTrue(nameof(_indices), isValid, "Mismatch between accesor indices and MeshPrimitive indices");

base.OnValidateContent(validate);
}
}

partial class MeshPrimitive
{
public void SetCesiumOutline(Accessor accessor)
{
if (accessor == null) { RemoveExtensions<CESIUM_primitive_outlineglTFprimitiveextension>(); return; }

Guard.NotNull(accessor, nameof(accessor));
Guard.MustShareLogicalParent(LogicalParent.LogicalParent, "this", accessor, nameof(accessor));
Guard.IsTrue(accessor.Encoding == EncodingType.UNSIGNED_INT, nameof(accessor));
Guard.IsTrue(accessor.Dimensions == DimensionType.SCALAR, nameof(accessor));

var ext = UseExtension<CESIUM_primitive_outlineglTFprimitiveextension>();
ext.Indices = accessor.LogicalIndex;
}
}

public static class CesiumToolkit
{
/// <summary>
/// Creates an accessor to store Cesium outline vertex indices
/// </summary>
/// <param name="model"></param>
/// <param name="outlines"></param>
/// <returns></returns>
public static Accessor CreateCesiumOutlineAccessor(ModelRoot model, IReadOnlyList<uint> outlines, string name="Cesium outlines")
{
var outlineBytes = new List<byte>();

foreach (var bytes in from outline in outlines
let bytes = BitConverter.GetBytes(outline).ToList()
select bytes)
{
outlineBytes.AddRange(bytes);
}

var buffer = model.UseBufferView(outlineBytes.ToArray());
var accessor = model.CreateAccessor(name);
accessor.SetData(buffer, 0, outlineBytes.Count / 4, DimensionType.SCALAR, EncodingType.UNSIGNED_INT, false);
return accessor;
}

/// <summary>
/// Checks if all the indices of the Cesium outline accessor are within the range of in the MeshPrimitive indices
/// </summary>
/// <param name="accessor">Cesium outline accessor</param>
/// <param name="meshPrimitive">MeshPrimitive with the CESIUM_primitive_outline extension</param>
/// <returns>true all indices are available, false indices are missing </returns>
internal static bool ValidateCesiumOutlineIndices(Accessor accessor, MeshPrimitive meshPrimitive)
{
var cesiumOutlineExtension = meshPrimitive.GetExtension<CESIUM_primitive_outlineglTFprimitiveextension>();
if (cesiumOutlineExtension != null)
{
var accessorIndices = accessor.AsIndicesArray();
var meshPrimitiveIndices = meshPrimitive.GetIndices();
var maxIndice = meshPrimitiveIndices.Max();

foreach (var _ in from accessorIndice in accessorIndices
let contains = accessorIndice <= maxIndice
where !contains
select new { })
{
return false;
}
}
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;

using SharpGLTF.Validation;

namespace SharpGLTF.Schema2
{
partial class CesiumPrimitiveOutline
{
private MeshPrimitive meshPrimitive;
internal CesiumPrimitiveOutline(MeshPrimitive meshPrimitive)
{
this.meshPrimitive = meshPrimitive;
}

public Accessor Indices
{
get
{
return _indices.HasValue
? meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[_indices.Value]
: null;
}
set
{
if (value == null) { _indices = null; return; }

_ValidateAccessor(meshPrimitive.LogicalParent.LogicalParent, value);

_indices = value.LogicalIndex;
}
}

protected override void OnValidateReferences(ValidationContext validate)
{
validate.IsNullOrIndex(nameof(Indices), this._indices, meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors);

base.OnValidateReferences(validate);
}

protected override void OnValidateContent(Validation.ValidationContext validate)
{
var outlineAccessor = meshPrimitive.LogicalParent.LogicalParent.LogicalAccessors[(int)_indices];
var isValid = _ValidateCesiumOutlineIndices(outlineAccessor, meshPrimitive);
validate.IsTrue(nameof(_indices), isValid, "Mismatch between accesor indices and MeshPrimitive indices");

base.OnValidateContent(validate);
}

internal static void _ValidateAccessor(ModelRoot model, Accessor accessor)
{
Guard.NotNull(accessor, nameof(accessor));
Guard.MustShareLogicalParent(model, "this", accessor, nameof(accessor));
Guard.IsTrue(accessor.Encoding == EncodingType.UNSIGNED_INT, nameof(accessor));
Guard.IsTrue(accessor.Dimensions == DimensionType.SCALAR, nameof(accessor));
Guard.IsFalse(accessor.Normalized, nameof(accessor));
}

/// <summary>
/// Checks if all the indices of the Cesium outline accessor are within the range of in the MeshPrimitive indices
/// </summary>
/// <param name="accessor">Cesium outline accessor</param>
/// <param name="meshPrimitive">MeshPrimitive with the CESIUM_primitive_outline extension</param>
/// <returns>true all indices are available, false indices are missing </returns>
private static bool _ValidateCesiumOutlineIndices(Accessor accessor, MeshPrimitive meshPrimitive)
{
var cesiumOutlineExtension = meshPrimitive.GetExtension<CesiumPrimitiveOutline>();
if (cesiumOutlineExtension != null)
{
var accessorIndices = accessor.AsIndicesArray();
var meshPrimitiveIndices = meshPrimitive.GetIndices();
var maxIndex = meshPrimitiveIndices.Max();

foreach (var _ in from accessorIndice in accessorIndices
let contains = accessorIndice <= maxIndex
where !contains
select new { })
{
return false;
}
}
return true;
}
}

partial class MeshPrimitive
{
/// <summary>
/// Sets Cesium outline vertex indices
/// </summary>
/// <param name="outlines">the list of vertex indices.</param>
/// <param name="accessorName">the name of the accessor to be created.</param>
public void SetCesiumOutline(IReadOnlyList<uint> outlines, string accessorName = "Cesium outlines")
{
Guard.NotNull(outlines, nameof(outlines));

// create and fill data

var dstData = new Byte[outlines.Count * 4];
var dstArray = new Memory.IntegerArray(dstData, IndexEncodingType.UNSIGNED_INT);
for (int i = 0; i < outlines.Count; ++i) { dstArray[i] = outlines[i]; }

var model = this.LogicalParent.LogicalParent;

var bview = model.UseBufferView(dstData);
var accessor = model.CreateAccessor(accessorName);

accessor.SetData(bview, 0, dstArray.Count, DimensionType.SCALAR, EncodingType.UNSIGNED_INT, false);

SetCesiumOutline(accessor);
}

public void SetCesiumOutline(Accessor accessor)
{
if (accessor == null) { RemoveExtensions<CesiumPrimitiveOutline>(); return; }

CesiumPrimitiveOutline._ValidateAccessor(this.LogicalParent.LogicalParent, accessor);

var ext = UseExtension<CesiumPrimitiveOutline>();
ext.Indices = accessor;
}
}
}
11 changes: 6 additions & 5 deletions tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@ public void CreateCesiumOutlineTriangleScene()

var model = scene.ToGltf2();

var outlines = new ReadOnlyCollection<uint>(new List<uint> { 0, 1, 1, 2, 2, 0});
var accessor = CesiumToolkit.CreateCesiumOutlineAccessor(model, outlines);
model.LogicalMeshes[0].Primitives[0].SetCesiumOutline(accessor);
var outlines = new uint[] { 0, 1, 1, 2, 2, 0};
model.LogicalMeshes[0].Primitives[0].SetCesiumOutline(outlines);

var cesiumOutlineExtension = (CesiumPrimitiveOutline)model.LogicalMeshes[0].Primitives[0].Extensions.FirstOrDefault();
Assert.NotNull(cesiumOutlineExtension.Indices);
CollectionAssert.AreEqual(outlines, cesiumOutlineExtension.Indices.AsIndicesArray());

var cesiumOutlineExtension = (CESIUM_primitive_outlineglTFprimitiveextension)model.LogicalMeshes[0].Primitives[0].Extensions.FirstOrDefault();
Assert.True(cesiumOutlineExtension.Indices == accessor.LogicalIndex);
var ctx = new ValidationResult(model, ValidationMode.Strict, true);
model.ValidateContent(ctx.GetContext());

Expand Down

0 comments on commit 70ee77b

Please sign in to comment.