Reports.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using XYZ = System.Numerics.Vector3;
  5. using SharpGLTF.Schema2;
  6. using System.Linq;
  7. namespace SharpGLTF.Reporting
  8. {
  9. public class VisualReport
  10. {
  11. #region data
  12. public int NumVertices { get; internal set; }
  13. public int NumTriangles { get; internal set; }
  14. public int NumLines { get; internal set; }
  15. public int NumPoints { get; internal set; }
  16. public (XYZ Min, XYZ Max) Bounds { get; internal set; }
  17. public IEnumerable<string> VertexAttributes { get; internal set; }
  18. #endregion
  19. #region API
  20. protected virtual string DebuggerDisplay
  21. {
  22. get
  23. {
  24. var txt = string.Empty;
  25. if (!VertexAttributes.Contains("SCENE")) txt += " " + string.Join(" ", VertexAttributes);
  26. txt += " Vrts:" + NumVertices;
  27. txt += " Tris:" + NumTriangles;
  28. return txt;
  29. }
  30. }
  31. public void SetFrom(Schema2.Scene scene)
  32. {
  33. var tris = scene.EvaluateTriangles().ToList();
  34. this.NumTriangles = tris.Count;
  35. Bounds = tris
  36. .SelectMany(item => new[] { item.A, item.B, item.C })
  37. .Select(item => item.GetGeometry().GetPosition())
  38. .GetBounds();
  39. this.VertexAttributes = new[] { "SCENE" };
  40. }
  41. internal void SetFrom(IReadOnlyList<VisualReport> many)
  42. {
  43. NumVertices = many.Sum(item => item.NumVertices);
  44. NumTriangles = many.Sum(item => item.NumTriangles);
  45. NumLines = many.Sum(item => item.NumLines);
  46. NumPoints = many.Sum(item => item.NumPoints);
  47. var min = many.Select(item => item.Bounds.Min).GetMin();
  48. var max = many.Select(item => item.Bounds.Max).GetMax();
  49. Bounds = (min, max);
  50. VertexAttributes = many
  51. .SelectMany(item => item.VertexAttributes)
  52. .Distinct()
  53. .ToArray();
  54. }
  55. #endregion
  56. }
  57. [System.Diagnostics.DebuggerDisplay("{DebuggerDisplay,nq}")]
  58. public sealed class PrimitiveReport : VisualReport
  59. {
  60. internal PrimitiveReport(Schema2.MeshPrimitive prim)
  61. {
  62. var vertices = prim.GetVertexAccessor("POSITION").AsVector3Array();
  63. NumVertices = vertices.Count;
  64. NumPoints = prim.GetPointIndices().Count();
  65. NumLines = prim.GetLineIndices().Count();
  66. NumTriangles = prim.GetTriangleIndices().Count();
  67. Bounds = vertices.GetBounds();
  68. VertexAttributes = prim.VertexAccessors.Keys.ToArray();
  69. }
  70. public string MaterialName { get; private set; }
  71. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  72. protected override string DebuggerDisplay => "PRIM " + MaterialName + " " + base.DebuggerDisplay;
  73. }
  74. [System.Diagnostics.DebuggerDisplay("{DebuggerDisplay,nq}")]
  75. public class MeshReport : VisualReport
  76. {
  77. internal MeshReport(Schema2.Mesh mesh)
  78. {
  79. Name = mesh.Name;
  80. _Primitives = mesh.Primitives
  81. .Select(prim => new PrimitiveReport(prim))
  82. .ToArray();
  83. this.SetFrom(_Primitives);
  84. }
  85. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
  86. private readonly PrimitiveReport[] _Primitives;
  87. public String Name { get; private set; }
  88. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  89. protected override string DebuggerDisplay => "MESH " + Name + " " + base.DebuggerDisplay;
  90. }
  91. [System.Diagnostics.DebuggerDisplay("{DebuggerDisplay,nq}")]
  92. public class ModelReport : VisualReport
  93. {
  94. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
  95. private readonly List<MeshReport> _Meshes = new List<MeshReport>();
  96. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
  97. private readonly List<VisualReport> _Scenes = new List<VisualReport>();
  98. private readonly List<int> _VertexBuffers = new List<int>();
  99. private readonly List<int> _IndexBuffers = new List<int>();
  100. private readonly List<int> _DataBuffers = new List<int>();
  101. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  102. protected override string DebuggerDisplay => "MODEL" + base.DebuggerDisplay;
  103. public static ModelReport CreateReportFrom(Schema2.ModelRoot model)
  104. {
  105. var rrrr = new ModelReport();
  106. foreach (var vb in model.LogicalBufferViews.Where(item => item.IsVertexBuffer)) rrrr._VertexBuffers.Add(vb.Content.Count);
  107. foreach (var ib in model.LogicalBufferViews.Where(item => item.IsIndexBuffer)) rrrr._IndexBuffers.Add(ib.Content.Count);
  108. foreach (var db in model.LogicalBufferViews.Where(item => item.IsDataBuffer)) rrrr._DataBuffers.Add(db.Content.Count);
  109. foreach (var mesh in model.LogicalMeshes)
  110. {
  111. rrrr._Meshes.Add( new MeshReport(mesh) );
  112. }
  113. foreach (var scene in model.LogicalScenes)
  114. {
  115. var r = new VisualReport();
  116. r.SetFrom(scene);
  117. rrrr._Scenes.Add(r);
  118. }
  119. rrrr.SetFrom(rrrr._Scenes);
  120. return rrrr;
  121. }
  122. }
  123. }