Browse Source

API cleanup

Vicente Penades 6 years ago
parent
commit
ff37ac520f
29 changed files with 256 additions and 233 deletions
  1. 2 2
      src/SharpGLTF.DOM/Debug/DebugViews.cs
  2. 5 5
      src/SharpGLTF.DOM/Geometry/MeshPrimitive.cs
  3. 1 3
      src/SharpGLTF.DOM/IO/ModelException.cs
  4. 12 12
      src/SharpGLTF.DOM/Memory/FloatingArrays.cs
  5. 2 2
      src/SharpGLTF.DOM/Memory/IntegerArrays.cs
  6. 1 1
      src/SharpGLTF.DOM/Schema2/glb.cs
  7. 5 5
      src/SharpGLTF.DOM/Schema2/gltf.AccessorSparse.cs
  8. 17 14
      src/SharpGLTF.DOM/Schema2/gltf.Accessors.cs
  9. 5 5
      src/SharpGLTF.DOM/Schema2/gltf.Animations.cs
  10. 6 4
      src/SharpGLTF.DOM/Schema2/gltf.Asset.cs
  11. 14 42
      src/SharpGLTF.DOM/Schema2/gltf.Buffer.cs
  12. 28 31
      src/SharpGLTF.DOM/Schema2/gltf.BufferView.cs
  13. 1 1
      src/SharpGLTF.DOM/Schema2/gltf.Camera.cs
  14. 9 3
      src/SharpGLTF.DOM/Schema2/gltf.Materials.cs
  15. 4 4
      src/SharpGLTF.DOM/Schema2/gltf.MaterialsFactory.cs
  16. 5 3
      src/SharpGLTF.DOM/Schema2/gltf.Mesh.cs
  17. 4 3
      src/SharpGLTF.DOM/Schema2/gltf.MeshPrimitive.cs
  18. 8 4
      src/SharpGLTF.DOM/Schema2/gltf.Root.cs
  19. 20 18
      src/SharpGLTF.DOM/Schema2/gltf.Scene.cs
  20. 3 3
      src/SharpGLTF.DOM/Schema2/gltf.Serialization.cs
  21. 2 2
      src/SharpGLTF.DOM/Schema2/gltf.Skin.cs
  22. 27 15
      src/SharpGLTF.DOM/Schema2/gltf.Textures.cs
  23. 1 1
      src/SharpGLTF.DOM/Transforms/AffineTransform.cs
  24. 1 1
      src/SharpGLTF.DOM/Transforms/BoundingBox.cs
  25. 2 2
      tests/SharpGLTF.Tests/Geometry/CreateMeshTests.cs
  26. 1 1
      tests/SharpGLTF.Tests/GltfUtils.cs
  27. 28 25
      tests/SharpGLTF.Tests/Schema2/CreateModelTests.cs
  28. 9 6
      tests/SharpGLTF.Tests/Schema2/LoadModelTests.cs
  29. 33 15
      tests/SharpGLTF.Tests/WavefrontWriter.cs

+ 2 - 2
src/SharpGLTF.DOM/Debug/DebugViews.cs

@@ -43,11 +43,11 @@ namespace SharpGLTF.Debug
 
         public int ByteStride => _Value.ByteStride;
 
-        public int ByteLength => _Value.Data.Count;
+        public int ByteLength => _Value.Content.Count;
 
         public Schema2.BufferMode? DeviceBufferTarget => _Value.DeviceBufferTarget;
 
         [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
-        public Schema2.Accessor[] Accessors => _Value.Accessors.ToArray();
+        public Schema2.Accessor[] Accessors => _Value.FindAccessors().ToArray();
     }
 }

+ 5 - 5
src/SharpGLTF.DOM/Geometry/MeshPrimitive.cs

@@ -6,7 +6,7 @@ using System.Text;
 
 namespace SharpGLTF.Geometry
 {
-    abstract class NamedObject
+    public abstract class NamedObject
     {
         public NamedObject() { }
 
@@ -20,7 +20,7 @@ namespace SharpGLTF.Geometry
     }
 
     [System.Diagnostics.DebuggerDisplay("{Name}.{_MemoryAccessor.Attribute.Name} {_MemoryAccessor.Attribute.ItemsCount}")]
-    class VertexAccessor : NamedObject
+    public class VertexAccessor : NamedObject
     {
         #region lifecycle
 
@@ -131,7 +131,7 @@ namespace SharpGLTF.Geometry
     }
 
     [System.Diagnostics.DebuggerDisplay("{Name}.{_MemoryAccessor.Attribute.Name} {_MemoryAccessor.Attribute.ItemsCount}")]
-    class IndicesAccessor : NamedObject
+    public class IndicesAccessor : NamedObject
     {
         #region lifecycle
 
@@ -191,7 +191,7 @@ namespace SharpGLTF.Geometry
         #endregion
     }
 
-    class MeshPrimitive
+    public class MeshPrimitive
     {
         #region lifecycle
 
@@ -284,7 +284,7 @@ namespace SharpGLTF.Geometry
     }
 
     [System.Diagnostics.DebuggerDisplay("Mesh {Name}")]
-    class Mesh : NamedObject
+    public class Mesh : NamedObject
     {
         #region lifecycle
 

+ 1 - 3
src/SharpGLTF.DOM/ModelException.cs → src/SharpGLTF.DOM/IO/ModelException.cs

@@ -3,10 +3,8 @@ using System.Collections.Generic;
 using System.Reflection;
 using System.Text;
 
-namespace SharpGLTF
+namespace SharpGLTF.IO
 {
-    using IO;
-
     /// <summary>
     /// Represents an exception produced by the serialization or validation of a gltf model
     /// </summary>

+ 12 - 12
src/SharpGLTF.DOM/Memory/FloatingArrays.cs

@@ -217,10 +217,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public ScalarArray(Byte[] data, int byteStride, ENCODING encoding, Boolean normalized)
+        public ScalarArray(Byte[] data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(new BYTES(data), 0, int.MaxValue, byteStride, encoding, normalized) { }
 
-        public ScalarArray(BYTES data, int byteStride, ENCODING encoding, Boolean normalized)
+        public ScalarArray(BYTES data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(data, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
         public ScalarArray(BYTES data, int byteOffset, int count, int byteStride, ENCODING encoding, Boolean normalized)
@@ -272,10 +272,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public Vector2Array(Byte[] data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Vector2Array(Byte[] data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(new BYTES(data), 0, int.MaxValue, byteStride, encoding, normalized) { }
 
-        public Vector2Array(BYTES data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Vector2Array(BYTES data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(data, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
         public Vector2Array(BYTES data, int byteOffset, int count, int byteStride, ENCODING encoding, Boolean normalized)
@@ -335,10 +335,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public Vector3Array(Byte[] data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Vector3Array(Byte[] data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(new BYTES(data), 0, int.MaxValue, byteStride, encoding, normalized) { }
 
-        public Vector3Array(BYTES data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Vector3Array(BYTES data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(data, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
         public Vector3Array(BYTES data, int byteOffset, int count, int byteStride, ENCODING encoding, Boolean normalized)
@@ -399,10 +399,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public Vector4Array(Byte[] data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Vector4Array(Byte[] data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(new BYTES(data), 0, int.MaxValue, byteStride, encoding, normalized) { }
 
-        public Vector4Array(BYTES data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Vector4Array(BYTES data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(data, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
         public Vector4Array(BYTES data, int byteOffset, int count, int byteStride, ENCODING encoding, Boolean normalized)
@@ -464,10 +464,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public QuaternionArray(Byte[] data, int byteStride, ENCODING encoding, Boolean normalized)
+        public QuaternionArray(Byte[] data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(new BYTES(data), 0, int.MaxValue, byteStride, encoding, normalized) { }
 
-        public QuaternionArray(BYTES data, int byteStride, ENCODING encoding, Boolean normalized)
+        public QuaternionArray(BYTES data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(data, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
         public QuaternionArray(BYTES data, int byteOffset, int count, int byteStride, ENCODING encoding, Boolean normalized)
@@ -529,10 +529,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public Matrix4x4Array(Byte[] data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Matrix4x4Array(Byte[] data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(new BYTES(data), 0, int.MaxValue, byteStride, encoding, normalized) { }
 
-        public Matrix4x4Array(BYTES data, int byteStride, ENCODING encoding, Boolean normalized)
+        public Matrix4x4Array(BYTES data, int byteStride = 0, ENCODING encoding = ENCODING.FLOAT, Boolean normalized = false)
             : this(data, 0, int.MaxValue, byteStride, encoding, normalized) { }
 
         public Matrix4x4Array(BYTES data, int byteOffset, int count, int byteStride, ENCODING encoding, Boolean normalized)

+ 2 - 2
src/SharpGLTF.DOM/Memory/IntegerArrays.cs

@@ -18,10 +18,10 @@ namespace SharpGLTF.Memory
     {
         #region constructors
 
-        public IntegerArray(Byte[] data, ENCODING encoding)
+        public IntegerArray(Byte[] data, ENCODING encoding = ENCODING.UNSIGNED_INT)
             : this(new BYTES(data), encoding) { }
 
-        public IntegerArray(BYTES data, ENCODING encoding)
+        public IntegerArray(BYTES data, ENCODING encoding = ENCODING.UNSIGNED_INT)
             : this(data, 0, int.MaxValue, encoding) { }
 
         public IntegerArray(BYTES data, int byteOffset, int itemsCount, ENCODING encoding)

+ 1 - 1
src/SharpGLTF.DOM/Schema2/glb.cs

@@ -137,7 +137,7 @@ namespace SharpGLTF.Schema2
             var jsonChunk = Encoding.UTF8.GetBytes(jsonText);
             var jsonPadding = jsonChunk.Length & 3; if (jsonPadding != 0) jsonPadding = 4 - jsonPadding;
 
-            var buffer = model.LogicalBuffers.Count > 0 ? model.LogicalBuffers[0]._Data : null;
+            var buffer = model.LogicalBuffers.Count > 0 ? model.LogicalBuffers[0]._Content : null;
             if (buffer != null && buffer.Length == 0) buffer = null;
 
             var binPadding = buffer == null ? 0 : buffer.Length & 3; if (binPadding != 0) binPadding = 4 - binPadding;

+ 5 - 5
src/SharpGLTF.DOM/Schema2/gltf.AccessorSparse.cs

@@ -19,7 +19,7 @@ namespace SharpGLTF.Schema2
 
     using ROOT = ModelRoot;
 
-    public partial class AccessorSparse
+    public sealed partial class AccessorSparse
     {
         internal AccessorSparse() { }
 
@@ -45,7 +45,7 @@ namespace SharpGLTF.Schema2
         }
     }
 
-    public partial class AccessorSparseIndices
+    public sealed partial class AccessorSparseIndices
     {
         internal AccessorSparseIndices() { }
 
@@ -62,11 +62,11 @@ namespace SharpGLTF.Schema2
         internal Memory.IntegerArray _GetIndicesArray(ROOT root, int count)
         {
             var srcBuffer = root.LogicalBufferViews[this._bufferView];
-            return srcBuffer.CreateIndicesArray(this._byteOffset ?? 0, count, this._componentType);
+            return new Memory.IntegerArray(srcBuffer.Content, this._byteOffset ?? 0, count, this._componentType);
         }
     }
 
-    public partial class AccessorSparseValues
+    public sealed partial class AccessorSparseValues
     {
         internal AccessorSparseValues() { }
 
@@ -83,7 +83,7 @@ namespace SharpGLTF.Schema2
         {
             var view = root.LogicalBufferViews[this._bufferView];
             var info = new Geometry.MemoryAccessInfo(null, this._byteOffset ?? 0, count, view.ByteStride, baseAccessor.Dimensions, baseAccessor.Encoding, baseAccessor.Normalized);
-            return new Geometry.MemoryAccessor(info, view.Data);
+            return new Geometry.MemoryAccessor(info, view.Content);
         }
     }
 }

+ 17 - 14
src/SharpGLTF.DOM/Schema2/gltf.Accessors.cs

@@ -6,12 +6,14 @@ using System.Text;
 
 namespace SharpGLTF.Schema2
 {
+    using EXCEPTION = IO.ModelException;
+
     using ROOT = ModelRoot;
 
     // https://github.com/KhronosGroup/glTF/issues/827#issuecomment-277537204
 
     [System.Diagnostics.DebuggerDisplay("Accessor[{LogicalIndex}] BufferView[{SourceBufferView.LogicalIndex}][{ByteOffset}...] => 0 => {Dimensions}x{Encoding}x{Normalized} => [{Count}]")]
-    public partial class Accessor
+    public sealed partial class Accessor
     {
         #region debug
 
@@ -54,14 +56,14 @@ namespace SharpGLTF.Schema2
 
         public int ItemByteSize                 => Encoding.ByteLength() * Dimensions.DimCount();
 
-        public BoundingBox3? LocalBounds3
+        public Transforms.BoundingBox3? LocalBounds3
         {
             get
             {
                 if (this._min.Count != 3) return null;
                 if (this._max.Count != 3) return null;
 
-                return new BoundingBox3(this._min, this._max);
+                return new Transforms.BoundingBox3(this._min, this._max);
             }
         }
 
@@ -73,7 +75,7 @@ namespace SharpGLTF.Schema2
         {
             var view = SourceBufferView;
             var info = new Geometry.MemoryAccessInfo(null, ByteOffset, Count, view.ByteStride, Dimensions, Encoding, Normalized);
-            return new Geometry.MemoryAccessor(info, view.Data);
+            return new Geometry.MemoryAccessor(info, view.Content);
         }
 
         internal KeyValuePair<Memory.IntegerArray, Geometry.MemoryAccessor>? _GetSparseMemoryAccessor()
@@ -147,7 +149,8 @@ namespace SharpGLTF.Schema2
         {
             Guard.IsFalse(this.IsSparse, nameof(IsSparse));
             Guard.IsTrue(this.Dimensions == ElementType.SCALAR, nameof(Dimensions));
-            return SourceBufferView.CreateIndicesArray(this.ByteOffset, this._count, this.Encoding.ToIndex());
+
+            return new Memory.IntegerArray(SourceBufferView.Content, this.ByteOffset, this._count, this.Encoding.ToIndex());
         }
 
         #endregion
@@ -228,7 +231,7 @@ namespace SharpGLTF.Schema2
             var byteStride = Math.Max(byteSize, SourceBufferView.ByteStride);
             var byteOffset = vertexIdx * byteStride;
 
-            return SourceBufferView.Data.Slice(this.ByteOffset + (vertexIdx * byteStride), byteSize);
+            return SourceBufferView.Content.Slice(this.ByteOffset + (vertexIdx * byteStride), byteSize);
         }
 
         internal void _UpdateBounds()
@@ -305,31 +308,31 @@ namespace SharpGLTF.Schema2
         {
             var exxx = base.Validate().ToList();
 
-            if (!_bufferView.HasValue) { exxx.Add(new ModelException(this, $"BufferView index missing")); return exxx; }
-            if (_bufferView < 0 || _bufferView >= LogicalParent.LogicalBufferViews.Count) exxx.Add(new ModelException(this, $"BufferView index out of range"));
+            if (!_bufferView.HasValue) { exxx.Add(new EXCEPTION(this, $"BufferView index missing")); return exxx; }
+            if (_bufferView < 0 || _bufferView >= LogicalParent.LogicalBufferViews.Count) exxx.Add(new EXCEPTION(this, $"BufferView index out of range"));
 
-            if (_count < 0) exxx.Add(new ModelException(this, $"Count is out of range"));
-            if (_byteOffset < 0) exxx.Add(new ModelException(this, $"ByteOffset is out of range"));
+            if (_count < 0) exxx.Add(new EXCEPTION(this, $"Count is out of range"));
+            if (_byteOffset < 0) exxx.Add(new EXCEPTION(this, $"ByteOffset is out of range"));
 
             if (SourceBufferView.DeviceBufferTarget == BufferMode.ARRAY_BUFFER)
             {
                 var len = Encoding.ByteLength() * Dimensions.DimCount();
-                if (len > 0 && (len & 3) != 0) exxx.Add(new ModelException(this, $"Expected length to be multiple of 4, found {len}"));
+                if (len > 0 && (len & 3) != 0) exxx.Add(new EXCEPTION(this, $"Expected length to be multiple of 4, found {len}"));
             }
 
             if (SourceBufferView.DeviceBufferTarget == BufferMode.ELEMENT_ARRAY_BUFFER)
             {
                 var len = Encoding.ByteLength() * Dimensions.DimCount();
-                if (len != 1 && len != 2 && len != 4) exxx.Add(new ModelException(this, $"Expected length to be 1, 2 or 4, found {len}"));
+                if (len != 1 && len != 2 && len != 4) exxx.Add(new EXCEPTION(this, $"Expected length to be 1, 2 or 4, found {len}"));
             }
 
             // validate bounds
 
-            if (_min.Count != _max.Count) { exxx.Add(new ModelException(this, "min and max length mismatch")); return exxx; }
+            if (_min.Count != _max.Count) { exxx.Add(new EXCEPTION(this, "min and max length mismatch")); return exxx; }
 
             for (int i = 0; i < _min.Count; ++i)
             {
-                if (_min[i] > _max[i]) exxx.Add(new ModelException(this, $"min[{i}] is larger than max[{i}]"));
+                if (_min[i] > _max[i]) exxx.Add(new EXCEPTION(this, $"min[{i}] is larger than max[{i}]"));
             }
 
             return exxx;

+ 5 - 5
src/SharpGLTF.DOM/Schema2/gltf.Animations.cs

@@ -8,7 +8,7 @@ namespace SharpGLTF.Schema2
     using Collections;
 
     [System.Diagnostics.DebuggerDisplay("Animation[{LogicalIndex}] {Name}")]
-    public partial class Animation
+    public sealed partial class Animation
     {
         #region lifecycle
 
@@ -85,7 +85,7 @@ namespace SharpGLTF.Schema2
         #endregion
     }
 
-    public partial class AnimationChannelTarget
+    public sealed partial class AnimationChannelTarget
     {
         #region lifecycle
 
@@ -108,7 +108,7 @@ namespace SharpGLTF.Schema2
         #endregion
     }
 
-    public partial class AnimationChannel : IChildOf<Animation>
+    public sealed partial class AnimationChannel : IChildOf<Animation>
     {
         #region lifecycle
 
@@ -160,7 +160,7 @@ namespace SharpGLTF.Schema2
         #endregion
     }
 
-    public partial class AnimationSampler : IChildOf<Animation>
+    public sealed partial class AnimationSampler : IChildOf<Animation>
     {
         #region lifecycle
 
@@ -192,7 +192,7 @@ namespace SharpGLTF.Schema2
         #endregion
     }
 
-    public partial class ModelRoot
+    public sealed partial class ModelRoot
     {
         public Animation CreateAnimation(string name = null)
         {

+ 6 - 4
src/SharpGLTF.DOM/Schema2/gltf.Asset.cs

@@ -4,8 +4,10 @@ using System.Linq;
 
 namespace SharpGLTF.Schema2
 {
+    using EXCEPTION = IO.ModelException;
+
     [System.Diagnostics.DebuggerDisplay("{Version} {MinVersion} {Generator} {Copyright}")]
-    public partial class Asset
+    public sealed partial class Asset
     {
         #region lifecycle
 
@@ -42,13 +44,13 @@ namespace SharpGLTF.Schema2
         {
             foreach (var ex in base.Validate()) yield return ex;
 
-            if (string.IsNullOrWhiteSpace(_version)) yield return new ModelException(this, "version number is missing");
+            if (string.IsNullOrWhiteSpace(_version)) yield return new EXCEPTION(this, "version number is missing");
 
             var curVer = this.Version;
             var minVer = this.MinVersion;
 
-            if (curVer < MINVERSION) yield return new ModelException(this, $"invalid version number {this.Version} expected {MINVERSION}");
-            if (curVer > MAXVERSION) yield return new ModelException(this, $"invalid version number {this.Version} expected {MAXVERSION}");
+            if (curVer < MINVERSION) yield return new EXCEPTION(this, $"invalid version number {this.Version} expected {MINVERSION}");
+            if (curVer > MAXVERSION) yield return new EXCEPTION(this, $"invalid version number {this.Version} expected {MAXVERSION}");
         }
 
         #endregion

+ 14 - 42
src/SharpGLTF.DOM/Schema2/gltf.Buffer.cs

@@ -8,7 +8,7 @@ using System.Text;
 namespace SharpGLTF.Schema2
 {
     [System.Diagnostics.DebuggerDisplay("Buffer[{LogicalIndex}] {Name} Bytes:{_Data.Length}")]
-    public partial class Buffer
+    public sealed partial class Buffer
     {
         #region lifecycle
 
@@ -21,7 +21,7 @@ namespace SharpGLTF.Schema2
         /// <summary>
         /// Immediately after deserialization, binary buffer is loaded/parsed and stored here
         /// </summary>
-        internal Byte[] _Data;
+        internal Byte[] _Content;
 
         #endregion
 
@@ -29,6 +29,8 @@ namespace SharpGLTF.Schema2
 
         public int LogicalIndex => this.LogicalParent.LogicalBuffers.IndexOfReference(this);
 
+        public Byte[] Content => _Content;
+
         #endregion
 
         #region binary read
@@ -38,7 +40,7 @@ namespace SharpGLTF.Schema2
 
         internal void _ResolveUri(AssetReader externalReferenceSolver)
         {
-            _Data = _LoadBinaryBufferUnchecked(_uri, externalReferenceSolver);
+            _Content = _LoadBinaryBufferUnchecked(_uri, externalReferenceSolver);
 
             _uri = null; // When _Data is not empty, clear URI
         }
@@ -57,15 +59,15 @@ namespace SharpGLTF.Schema2
         internal void _WriteToExternal(string uri, AssetWriter writer)
         {
             this._uri = uri;
-            this._byteLength = _Data.Length;
+            this._byteLength = _Content.Length;
 
-            writer(uri, _Data);
+            writer(uri, _Content);
         }
 
         internal void _WriteToInternal()
         {
             this._uri = null;
-            this._byteLength = _Data.Length;
+            this._byteLength = _Content.Length;
         }
 
         internal void _ClearAfterWrite()
@@ -87,7 +89,7 @@ namespace SharpGLTF.Schema2
         public Buffer CreateBuffer(int byteCount)
         {
             var buffer = new Buffer();
-            buffer._Data = new byte[byteCount];
+            buffer._Content = new byte[byteCount];
 
             _buffers.Add(buffer);
 
@@ -105,11 +107,11 @@ namespace SharpGLTF.Schema2
 
             foreach (var b in this.LogicalBuffers)
             {
-                if (b._Data == data) return b;
+                if (b._Content == data) return b;
             }
 
             var buffer = new Buffer();
-            buffer._Data = data;
+            buffer._Content = data;
 
             _buffers.Add(buffer);
 
@@ -121,43 +123,13 @@ namespace SharpGLTF.Schema2
             Guard.IsFalse(data.IsEmpty, nameof(data));
 
             var buffer = new Buffer();
-            buffer._Data = data.ToArray();
+            buffer._Content = data.ToArray();
 
             _buffers.Add(buffer);
 
             return buffer;
         }
 
-        [Obsolete("to be removed")]
-        public Buffer CreateIndexBuffer(params int[] indices)
-        {
-            var buffer = CreateBuffer(indices.Length * 4);
-
-            var accessor = new Memory.IntegerArray(buffer._Data, IndexType.UNSIGNED_INT);
-
-            for (int i = 0; i < indices.Length; ++i)
-            {
-                accessor[i] = (UInt32)indices[i];
-            }
-
-            return buffer;
-        }
-
-        [Obsolete("to be removed")]
-        public Buffer CreateVector3Buffer(params Vector3[] vectors)
-        {
-            var buffer = CreateBuffer(vectors.Length * 12);
-
-            var accessor = new Memory.Vector3Array(new ArraySegment<byte>(buffer._Data), 0, ComponentType.FLOAT, false);
-
-            for (int i = 0; i < vectors.Length; ++i)
-            {
-                accessor[i] = vectors[i];
-            }
-
-            return buffer;
-        }
-
         /// <summary>
         /// Merges all the Buffer objects into a single, big one.
         /// </summary>
@@ -169,7 +141,7 @@ namespace SharpGLTF.Schema2
             // retrieve all buffers and merge them into a single, big buffer
 
             var views = _bufferViews
-                .OrderByDescending(item => item.Data.Count)
+                .OrderByDescending(item => item.Content.Count)
                 .ToArray();
 
             if (views.Length <= 1) return; // nothing to do.
@@ -182,7 +154,7 @@ namespace SharpGLTF.Schema2
 
             var b = new Buffer
             {
-                _Data = sbbuilder.ToArray()
+                _Content = sbbuilder.ToArray()
             };
 
             this._buffers.Add(b);

+ 28 - 31
src/SharpGLTF.DOM/Schema2/gltf.BufferView.cs

@@ -11,7 +11,7 @@ namespace SharpGLTF.Schema2
     using ENCODING = ComponentType;
 
     [System.Diagnostics.DebuggerTypeProxy(typeof(Debug._BufferDebugView))]
-    public partial class BufferView
+    public sealed partial class BufferView
     {
         #region lifecycle
 
@@ -20,10 +20,10 @@ namespace SharpGLTF.Schema2
         internal BufferView(Buffer buffer, int? byteLength, int? byteOffset, int? byteStride, BufferMode? target)
         {
             Guard.NotNull(buffer, nameof(buffer));
-            Guard.NotNull(buffer._Data, nameof(buffer));
+            Guard.NotNull(buffer._Content, nameof(buffer));
             Guard.NotNull(buffer.LogicalParent, nameof(buffer));
 
-            byteLength = byteLength.AsValue(buffer._Data.Length - byteOffset.AsValue(0));
+            byteLength = byteLength.AsValue(buffer._Content.Length - byteOffset.AsValue(0));
 
             Guard.MustBeGreaterThanOrEqualTo(byteLength.AsValue(0), _byteLengthMinimum, nameof(byteLength));
             Guard.MustBeGreaterThanOrEqualTo(byteOffset.AsValue(0), _byteOffsetMinimum, nameof(byteOffset));
@@ -42,7 +42,7 @@ namespace SharpGLTF.Schema2
 
             this._buffer = buffer.LogicalIndex;
 
-            this._byteLength = byteLength.AsValue(buffer._Data.Length);
+            this._byteLength = byteLength.AsValue(buffer._Content.Length);
 
             this._byteOffset = byteOffset.AsValue(0).AsNullable(0);
             this._byteStride = byteStride.AsValue(0).AsNullable(0);
@@ -60,24 +60,12 @@ namespace SharpGLTF.Schema2
 
         public int ByteStride                   => this._byteStride.AsValue(0);
 
-        public BYTES Data
+        public BYTES Content
         {
             get
             {
                 var buffer = this.LogicalParent.LogicalBuffers[this._buffer];
-                return new BYTES(buffer._Data, this._byteOffset ?? 0, this._byteLength);
-            }
-        }
-
-        public IEnumerable<Accessor> Accessors
-        {
-            get
-            {
-                var idx = LogicalIndex;
-
-                return this.LogicalParent
-                    .LogicalAccessors
-                    .Where(accessor => accessor._LogicalBufferViewIndex == idx);
+                return new BYTES(buffer._Content, this._byteOffset ?? 0, this._byteLength);
             }
         }
 
@@ -85,10 +73,23 @@ namespace SharpGLTF.Schema2
 
         #region API
 
+        /// <summary>
+        /// Finds all the accessors using this BufferView
+        /// </summary>
+        /// <returns>A collection of accessors</returns>
+        public IEnumerable<Accessor> FindAccessors()
+        {
+            var idx = LogicalIndex;
+
+            return this.LogicalParent
+                .LogicalAccessors
+                .Where(accessor => accessor._LogicalBufferViewIndex == idx);
+        }
+
         internal void _ConvertToStaticBuffer(_StaticBufferBuilder targetBuffer)
         {
             // retrieve old buffer
-            var srcBuf = this.LogicalParent.LogicalBuffers[this._buffer]._Data;
+            var srcBuf = this.LogicalParent.LogicalBuffers[this._buffer]._Content;
             var data = new Byte[this._byteLength];
             Array.Copy(srcBuf, this._byteOffset ?? 0, data, 0, this._byteLength);
 
@@ -100,18 +101,14 @@ namespace SharpGLTF.Schema2
 
         private string _DebuggerDisplay_TryIdentifyContent()
         {
-            var accessors = this.Accessors.OrderBy(item => item.ByteOffset).ToArray();
+            var accessors = this
+                .FindAccessors()
+                .OrderBy(item => item.ByteOffset)
+                .ToList();
 
             return String.Join(" ", accessors.Select(item => item._DebuggerDisplay_TryIdentifyContent()));
         }
 
-        public Memory.IntegerArray CreateIndicesArray(int byteOffset, int count, IndexType encoding)
-        {
-            Guard.IsTrue(this.ByteStride == 0, null, "bytestride must be zero");
-
-            return new Memory.IntegerArray(this.Data, byteOffset, count, encoding);
-        }
-
         /// <summary>
         /// Checks if all the accessors use this buffer in interleaved arrangement
         /// </summary>
@@ -119,7 +116,7 @@ namespace SharpGLTF.Schema2
         /// <returns>true if the buffer is interleaved</returns>
         public bool IsInterleaved(IEnumerable<Accessor> accessors)
         {
-            Guard.NotNullOrEmpty(Accessors, nameof(accessors));
+            Guard.NotNullOrEmpty(accessors, nameof(accessors));
             Guard.IsTrue(accessors.All(item => item.SourceBufferView == this), nameof(accessors));
 
             return accessors
@@ -150,9 +147,9 @@ namespace SharpGLTF.Schema2
 
             foreach (var bv in this.LogicalBufferViews)
             {
-                if (bv.Data.Array != data.Array) continue;
-                if (bv.Data.Offset != data.Offset) continue;
-                if (bv.Data.Count != data.Count) continue;
+                if (bv.Content.Array != data.Array) continue;
+                if (bv.Content.Offset != data.Offset) continue;
+                if (bv.Content.Count != data.Count) continue;
                 if (bv.ByteStride != byteStride) continue;
                 if (bv.DeviceBufferTarget != mode) continue;
 

+ 1 - 1
src/SharpGLTF.DOM/Schema2/gltf.Camera.cs

@@ -5,7 +5,7 @@ using System.Text;
 namespace SharpGLTF.Schema2
 {
     [System.Diagnostics.DebuggerDisplay("Camera[{LogicalIndex}] {Name}")]
-    public partial class Camera
+    public sealed partial class Camera
     {
         #region lifecycle
 

+ 9 - 3
src/SharpGLTF.DOM/Schema2/gltf.Materials.cs

@@ -7,8 +7,14 @@ using System.Text;
 namespace SharpGLTF.Schema2
 {
     [System.Diagnostics.DebuggerDisplay("Material[{LogicalIndex}] {Name}")]
-    public partial class Material
+    public sealed partial class Material
     {
+        #region lifecycle
+
+        internal Material() { }
+
+        #endregion
+
         #region properties
 
         public int LogicalIndex => this.LogicalParent.LogicalMaterials.IndexOfReference(this);
@@ -131,8 +137,8 @@ namespace SharpGLTF.Schema2
         {
             if (texImg == null) return; // in theory, we should completely remove the TextureInfo
 
-            var sampler = _Material.LogicalParent.UseLogicalSampler(mag, min, ws, wt);
-            var texture = _Material.LogicalParent.UseLogicalTexture(texImg, sampler);
+            var sampler = _Material.LogicalParent.UseSampler(mag, min, ws, wt);
+            var texture = _Material.LogicalParent.UseTexture(texImg, sampler);
 
             SetTexture(texSet, texture);
         }

+ 4 - 4
src/SharpGLTF.DOM/Schema2/gltf.MaterialsFactory.cs

@@ -98,7 +98,7 @@ namespace SharpGLTF.Schema2
 
     public partial class ModelRoot
     {
-        public Material AddLogicalMaterial(string name = null)
+        public Material CreateMaterial(string name = null)
         {
             var mat = new Material();
             mat.Name = name;
@@ -109,7 +109,7 @@ namespace SharpGLTF.Schema2
         }
     }
 
-    internal partial class MaterialPBRMetallicRoughness
+    internal sealed partial class MaterialPBRMetallicRoughness
     {
         private TextureInfo _GetBaseTexture(bool create)
         {
@@ -154,7 +154,7 @@ namespace SharpGLTF.Schema2
         }
     }
 
-    internal partial class MaterialPBRSpecularGlossiness_KHR
+    internal sealed partial class MaterialPBRSpecularGlossiness_KHR
     {
 
         private TextureInfo _GetDiffuseTexture(bool create)
@@ -200,7 +200,7 @@ namespace SharpGLTF.Schema2
         }
     }
 
-    internal partial class MaterialUnlit_KHR
+    internal sealed partial class MaterialUnlit_KHR
     {
     }
 }

+ 5 - 3
src/SharpGLTF.DOM/Schema2/gltf.Mesh.cs

@@ -9,7 +9,7 @@ namespace SharpGLTF.Schema2
     using Collections;
 
     [System.Diagnostics.DebuggerDisplay("Mesh[{LogicalIndex}] {Name}")]
-    public partial class Mesh
+    public sealed partial class Mesh
     {
         #region lifecycle
 
@@ -31,7 +31,7 @@ namespace SharpGLTF.Schema2
 
         public IReadOnlyList<Single> MorphWeights => _weights.Select(item => (Single)item).ToArray();
 
-        public BoundingBox3? LocalBounds3 => BoundingBox3.UnionOf(Primitives.Select(item => item.LocalBounds3));
+        public Transforms.BoundingBox3? LocalBounds3 => Transforms.BoundingBox3.UnionOf(Primitives.Select(item => item.LocalBounds3));
 
         #endregion
 
@@ -63,9 +63,11 @@ namespace SharpGLTF.Schema2
 
     public partial class ModelRoot
     {
-        public Mesh CreateMesh()
+        public Mesh CreateMesh(string name = null)
         {
             var dstMesh = new Mesh();
+            dstMesh.Name = name;
+
             this._meshes.Add(dstMesh);
 
             return dstMesh;

+ 4 - 3
src/SharpGLTF.DOM/Schema2/gltf.MeshPrimitive.cs

@@ -8,10 +8,11 @@ namespace SharpGLTF.Schema2
 {
     using Collections;
 
+    using EXCEPTION = IO.ModelException;
     using ROOT = ModelRoot;
 
     [System.Diagnostics.DebuggerDisplay("MeshPrimitive[{LogicalIndex}] {_mode} {_DebuggerDisplay_TryIdentifyContent()}")]
-    public partial class MeshPrimitive : IChildOf<Mesh>
+    public sealed partial class MeshPrimitive : IChildOf<Mesh>
     {
         #region debug
 
@@ -59,7 +60,7 @@ namespace SharpGLTF.Schema2
 
         public int MorpthTargetsCount => _targets.Count;
 
-        public BoundingBox3? LocalBounds3 => VertexAccessors["POSITION"]?.LocalBounds3;
+        public Transforms.BoundingBox3? LocalBounds3 => VertexAccessors["POSITION"]?.LocalBounds3;
 
         public IReadOnlyDictionary<String, Accessor> VertexAccessors => new ReadOnlyLinqDictionary<String, int, Accessor>(_attributes, alidx => this.LogicalParent.LogicalParent.LogicalAccessors[alidx]);
 
@@ -203,7 +204,7 @@ namespace SharpGLTF.Schema2
                 switch (DrawPrimitiveType)
                 {
                     case PrimitiveType.TRIANGLES:
-                        if ((IndexAccessor.Count % 3) != 0) exx.Add(new ModelException(this, $"Indices count {IndexAccessor.Count} incompatible with Primitive.{DrawPrimitiveType}"));
+                        if ((IndexAccessor.Count % 3) != 0) exx.Add(new EXCEPTION(this, $"Indices count {IndexAccessor.Count} incompatible with Primitive.{DrawPrimitiveType}"));
                         break;
                 }
             }

+ 8 - 4
src/SharpGLTF.DOM/Schema2/gltf.Root.cs

@@ -7,11 +7,15 @@ namespace SharpGLTF.Schema2
     using Collections;
 
     [System.Diagnostics.DebuggerDisplay("Model Root")]
-    public partial class ModelRoot
+    public sealed partial class ModelRoot
     {
         #region lifecycle
 
-        public static ModelRoot CreateNew()
+        /// <summary>
+        /// Creates a new, empty model.
+        /// </summary>
+        /// <returns>A new model</returns>
+        public static ModelRoot CreateModel()
         {
             var root = new ModelRoot();
             root._asset = Asset.CreateDefault(string.Empty);
@@ -86,7 +90,7 @@ namespace SharpGLTF.Schema2
 
             // 1st check version number
 
-            if (Asset == null) exx.Add(new ModelException(this, "missing Asset object, can't check glTF version")); // fix: create a default Asset
+            if (Asset == null) exx.Add(new IO.ModelException(this, "missing Asset object, can't check glTF version")); // fix: create a default Asset
             else exx.AddRange(Asset.Validate());
 
             if (exx.Count > 0) return exx;
@@ -95,7 +99,7 @@ namespace SharpGLTF.Schema2
 
             foreach (var iex in this.IncompatibleExtensions)
             {
-                exx.Add(new UnsupportedExtensionException(this, iex)); // fix: attempt to remove given extension
+                exx.Add(new IO.UnsupportedExtensionException(this, iex)); // fix: attempt to remove given extension
             }
 
             if (exx.Count > 0) return exx;

+ 20 - 18
src/SharpGLTF.DOM/Schema2/gltf.Scene.cs

@@ -6,6 +6,8 @@ using System.Text;
 
 namespace SharpGLTF.Schema2
 {
+    using EXCEPTION = IO.ModelException;
+
     public interface IVisualNodeContainer
     {
         IEnumerable<Node> VisualChildren { get; }
@@ -16,11 +18,11 @@ namespace SharpGLTF.Schema2
     }
 
     [System.Diagnostics.DebuggerDisplay("Node[{LogicalIndex}] {Name} SkinJoint:{IsSkinJoint} T:{LocalTransform.Translation.X} {LocalTransform.Translation.Y} {LocalTransform.Translation.Z}")]
-    public partial class Node : IVisualNodeContainer
+    public sealed partial class Node : IVisualNodeContainer
     {
         #region lifecycle
 
-        public Node()
+        internal Node()
         {
             _children = new List<int>();
             _weights = new List<double>();
@@ -36,7 +38,7 @@ namespace SharpGLTF.Schema2
 
         public IEnumerable<Node> VisualChildren => GetVisualChildren();
 
-        public Boolean IsSkinJoint => Skin.GetSkinsUsing(this).Any();
+        public Boolean IsSkinJoint => Skin.FindSkinsUsing(this).Any();
 
         public Scene VisualScene
         {
@@ -62,7 +64,7 @@ namespace SharpGLTF.Schema2
 
         public Matrix4x4 LocalMatrix
         {
-            get => AffineTransform.Evaluate(_matrix, _scale, _rotation, _translation);
+            get => Transforms.AffineTransform.Evaluate(_matrix, _scale, _rotation, _translation);
             set
             {
                 if (value == System.Numerics.Matrix4x4.Identity) _matrix = null;
@@ -74,9 +76,9 @@ namespace SharpGLTF.Schema2
             }
         }
 
-        public AffineTransform LocalTransform
+        public Transforms.AffineTransform LocalTransform
         {
-            get => new AffineTransform(_matrix, _scale, _rotation, _translation);
+            get => new Transforms.AffineTransform(_matrix, _scale, _rotation, _translation);
             set
             {
                 _matrix = null;
@@ -91,12 +93,12 @@ namespace SharpGLTF.Schema2
             get
             {
                 var vs = VisualParent;
-                return vs == null ? LocalMatrix : AffineTransform.LocalToWorld(vs.WorldMatrix, LocalMatrix);
+                return vs == null ? LocalMatrix : Transforms.AffineTransform.LocalToWorld(vs.WorldMatrix, LocalMatrix);
             }
             set
             {
                 var vs = VisualParent;
-                LocalMatrix = vs == null ? value : AffineTransform.WorldToLocal(vs.WorldMatrix, value);
+                LocalMatrix = vs == null ? value : Transforms.AffineTransform.WorldToLocal(vs.WorldMatrix, value);
             }
         }
 
@@ -128,7 +130,7 @@ namespace SharpGLTF.Schema2
 
         public IReadOnlyList<float> MorphWeights => _weights == null ? Mesh?.MorphWeights : _weights.Select(item => (float)item).ToArray();
 
-        public BoundingBox3? WorldBounds3 => BoundingBox3.Create(this);
+        public Transforms.BoundingBox3? WorldBounds3 => Transforms.BoundingBox3.Create(this);
 
         #endregion
 
@@ -224,14 +226,14 @@ namespace SharpGLTF.Schema2
             // check out of range indices
             foreach (var idx in this._children)
             {
-                if (idx < 0 || idx >= this.LogicalParent.LogicalNodes.Count) yield return new ModelException(this, $"references invalid Node[{idx}]");
+                if (idx < 0 || idx >= this.LogicalParent.LogicalNodes.Count) yield return new EXCEPTION(this, $"references invalid Node[{idx}]");
             }
 
             // check duplicated indices
-            if (this._children.Distinct().Count() != this._children.Count) yield return new ModelException(this, "has duplicated node references");
+            if (this._children.Distinct().Count() != this._children.Count) yield return new EXCEPTION(this, "has duplicated node references");
 
             // check self references
-            if (this._children.Contains(this.LogicalIndex)) yield return new ModelException(this, "has self references");
+            if (this._children.Contains(this.LogicalIndex)) yield return new EXCEPTION(this, "has self references");
 
             // check circular references
             var p = this;
@@ -241,7 +243,7 @@ namespace SharpGLTF.Schema2
                 if (p == null) break;
                 if (p.LogicalIndex == this.LogicalIndex)
                 {
-                    yield return new ModelException(this, "has a circular reference");
+                    yield return new EXCEPTION(this, "has a circular reference");
                     break;
                 }
             }
@@ -255,11 +257,11 @@ namespace SharpGLTF.Schema2
     }
 
     [System.Diagnostics.DebuggerDisplay("Scene[{LogicalIndex}] {Name}")]
-    public partial class Scene : IVisualNodeContainer
+    public sealed partial class Scene : IVisualNodeContainer
     {
         #region lifecycle
 
-        public Scene()
+        internal Scene()
         {
             _nodes = new List<int>();
         }
@@ -274,7 +276,7 @@ namespace SharpGLTF.Schema2
 
         public IEnumerable<Node> VisualChildren => _nodes.Select(idx => LogicalParent.LogicalNodes[idx]);
 
-        public BoundingBox3? WorldBounds3 => BoundingBox3.Create(this);
+        public Transforms.BoundingBox3? WorldBounds3 => Transforms.BoundingBox3.Create(this);
 
         #endregion
 
@@ -316,11 +318,11 @@ namespace SharpGLTF.Schema2
             // check out of range indices
             foreach (var idx in this._nodes)
             {
-                if (idx < 0 || idx >= this.LogicalParent.LogicalNodes.Count) yield return new ModelException(this, $"references invalid Node[{idx}]");
+                if (idx < 0 || idx >= this.LogicalParent.LogicalNodes.Count) yield return new EXCEPTION(this, $"references invalid Node[{idx}]");
             }
 
             // check duplicated indices
-            if (this._nodes.Distinct().Count() != this._nodes.Count) yield return new ModelException(this, "has duplicated node references");
+            if (this._nodes.Distinct().Count() != this._nodes.Count) yield return new EXCEPTION(this, "has duplicated node references");
         }
 
         // TODO: AddVisualChild must return a "NodeBuilder"

+ 3 - 3
src/SharpGLTF.DOM/Schema2/gltf.Serialization.cs

@@ -133,7 +133,7 @@ namespace SharpGLTF.Schema2
                 content = streamReader.ReadToEnd();
             }
 
-            return Parse(content, settings);
+            return ParseGLTF(content, settings);
         }
 
         public static ROOT ReadGLB(Stream stream, ReadSettings settings)
@@ -150,10 +150,10 @@ namespace SharpGLTF.Schema2
                 settings.FileReader = key => string.IsNullOrEmpty(key) ? chunks[glb.CHUNKBIN] : settings.FileReader?.Invoke(key);
             }
 
-            return Parse(dom, settings);
+            return ParseGLTF(dom, settings);
         }
 
-        public static ROOT Parse(String jsonContent, ReadSettings settings)
+        public static ROOT ParseGLTF(String jsonContent, ReadSettings settings)
         {
             Guard.NotNullOrEmpty(jsonContent, nameof(jsonContent));
             Guard.NotNull(settings, nameof(settings));

+ 2 - 2
src/SharpGLTF.DOM/Schema2/gltf.Skin.cs

@@ -11,7 +11,7 @@ namespace SharpGLTF.Schema2
     using ROOT = ModelRoot;
 
     [System.Diagnostics.DebuggerDisplay("Skin[{LogicalIndex}] {Name}")]
-    public partial class Skin
+    public sealed partial class Skin
     {
         // https://github.com/KhronosGroup/glTF/issues/461
         // https://github.com/KhronosGroup/glTF/issues/100
@@ -53,7 +53,7 @@ namespace SharpGLTF.Schema2
 
         #region API
 
-        public static IEnumerable<Skin> GetSkinsUsing(Node n)
+        public static IEnumerable<Skin> FindSkinsUsing(Node n)
         {
             var idx = n.LogicalIndex;
 

+ 27 - 15
src/SharpGLTF.DOM/Schema2/gltf.Textures.cs

@@ -27,7 +27,7 @@ namespace SharpGLTF.Schema2
     }
 
     [System.Diagnostics.DebuggerDisplay("Normal Texture[{LogicalIndex}] {Name}")]
-    internal partial class MaterialNormalTextureInfo
+    internal sealed partial class MaterialNormalTextureInfo
     {
         #region properties
 
@@ -41,7 +41,7 @@ namespace SharpGLTF.Schema2
     }
 
     [System.Diagnostics.DebuggerDisplay("Occlusion Texture[{LogicalIndex}] {Name}")]
-    internal partial class MaterialOcclusionTextureInfo
+    internal sealed partial class MaterialOcclusionTextureInfo
     {
         #region properties
 
@@ -55,8 +55,14 @@ namespace SharpGLTF.Schema2
     }
 
     [System.Diagnostics.DebuggerDisplay("Texture[{LogicalIndex}] {Name}")]
-    public partial class Texture
+    public sealed partial class Texture
     {
+        #region lifecycle
+
+        internal Texture() { }
+
+        #endregion
+
         #region properties
 
         public int LogicalIndex => this.LogicalParent.LogicalTextures.IndexOfReference(this);
@@ -64,26 +70,26 @@ namespace SharpGLTF.Schema2
         public Sampler Sampler
         {
             get => _sampler.HasValue ? LogicalParent.LogicalSamplers[_sampler.Value] : null;
-            set => _sampler = value == null ? null : (int?)LogicalParent._UseLogicalSampler(value);
+            set => _sampler = value == null ? null : (int?)LogicalParent._UseSampler(value);
         }
 
         public Image Source
         {
             get => _source.HasValue ? LogicalParent.LogicalImages[_source.Value] : null;
-            set => _source = value == null ? null : (int?)LogicalParent._UseLogicalImage(value);
+            set => _source = value == null ? null : (int?)LogicalParent._UseImage(value);
         }
 
         #endregion
     }
 
     [System.Diagnostics.DebuggerDisplay("Sampler[{LogicalIndex}] {Name}")]
-    public partial class Sampler
+    public sealed partial class Sampler
     {
         #region lifecycle
 
         internal Sampler() { }
 
-        public Sampler(TextureInterpolationMode mag, TextureMipMapMode min, TextureWrapMode ws, TextureWrapMode wt)
+        internal Sampler(TextureInterpolationMode mag, TextureMipMapMode min, TextureWrapMode ws, TextureWrapMode wt)
         {
             _magFilter = mag;
             _minFilter = min;
@@ -109,7 +115,7 @@ namespace SharpGLTF.Schema2
     }
 
     [System.Diagnostics.DebuggerDisplay("Image[{LogicalIndex}] {Name}")]
-    public partial class Image
+    public sealed partial class Image
     {
         #region Base64 constants
 
@@ -123,6 +129,12 @@ namespace SharpGLTF.Schema2
 
         #endregion
 
+        #region lifecycle
+
+        internal Image() { }
+
+        #endregion
+
         #region data
 
         // this is the actual compressed image in PNG or JPEG, -NOT- the pixels data.
@@ -167,7 +179,7 @@ namespace SharpGLTF.Schema2
             {
                 var bv = this.LogicalParent.LogicalBufferViews[this._bufferView.Value];
 
-                return bv.Data;
+                return bv.Content;
             }
 
             throw new InvalidOperationException();
@@ -270,21 +282,21 @@ namespace SharpGLTF.Schema2
 
     public partial class ModelRoot
     {
-        internal int _UseLogicalImage(Image image)
+        internal int _UseImage(Image image)
         {
             Guard.NotNull(image, nameof(image));
 
             return _images.Use(image);
         }
 
-        internal int _UseLogicalSampler(Sampler sampler)
+        internal int _UseSampler(Sampler sampler)
         {
             Guard.NotNull(sampler, nameof(sampler));
 
             return _samplers.Use(sampler);
         }
 
-        internal Image _AddLogicalImage()
+        internal Image _AddImage()
         {
             var img = new Image();
 
@@ -293,7 +305,7 @@ namespace SharpGLTF.Schema2
             return img;
         }
 
-        public Sampler UseLogicalSampler(TextureInterpolationMode mag, TextureMipMapMode min, TextureWrapMode ws, TextureWrapMode wt)
+        public Sampler UseSampler(TextureInterpolationMode mag, TextureMipMapMode min, TextureWrapMode ws, TextureWrapMode wt)
         {
             foreach (var s in this._samplers)
             {
@@ -307,7 +319,7 @@ namespace SharpGLTF.Schema2
             return ss;
         }
 
-        public Texture UseLogicalTexture(Image image, Sampler sampler)
+        public Texture UseTexture(Image image, Sampler sampler)
         {
             if (image == null) return null;
 
@@ -329,7 +341,7 @@ namespace SharpGLTF.Schema2
         internal T UseTextureInfo<T>(Image image, Sampler sampler, int textureSet)
             where T : TextureInfo, new()
         {
-            var tex = UseLogicalTexture(image, sampler);
+            var tex = UseTexture(image, sampler);
             if (tex == null) return null;
 
             return new T

+ 1 - 1
src/SharpGLTF.DOM/Transforms/AffineTransform.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.Numerics;
 using System.Text;
 
-namespace SharpGLTF
+namespace SharpGLTF.Transforms
 {
     public struct AffineTransform
     {

+ 1 - 1
src/SharpGLTF.DOM/Transforms/BoundingBox.cs

@@ -4,7 +4,7 @@ using System.Linq;
 using System.Numerics;
 using System.Text;
 
-namespace SharpGLTF
+namespace SharpGLTF.Transforms
 {
     public struct BoundingBox3
     {

+ 2 - 2
tests/SharpGLTF.Tests/Geometry/CreateMeshTests.cs

@@ -56,11 +56,11 @@ namespace SharpGLTF.Geometry
 
             // Now we switch to the .Schema2 namespace and we create a new scene:
 
-            var root = Schema2.ModelRoot.CreateNew();                        
+            var root = Schema2.ModelRoot.CreateModel();                        
             var scene = root.UseScene("default");
             var node = scene.AddVisualNode("main scene");
 
-            var material = root.AddLogicalMaterial("DefaultMaterial")
+            var material = root.CreateMaterial("DefaultMaterial")
                 .InitializeDefault(new Vector4(1, 0, 0, 1));
             material.DoubleSided = true;            
 

+ 1 - 1
tests/SharpGLTF.Tests/GltfUtils.cs

@@ -20,7 +20,7 @@ namespace SharpGLTF
 
                 return ModelRoot.Load(filePath);
             }
-            catch (UnsupportedExtensionException eex)
+            catch (IO.UnsupportedExtensionException eex)
             {
                 TestContext.WriteLine($"{filePath} ERROR: {eex.Message}");
 

+ 28 - 25
tests/SharpGLTF.Tests/Schema2/CreateModelTests.cs

@@ -12,7 +12,7 @@ namespace SharpGLTF.Schema2
         [Test(Description = "Creates an empty model")]
         public void CreateEmptyScene()
         {
-            var root = ModelRoot.CreateNew();
+            var root = ModelRoot.CreateModel();
 
             var scene = root.UseScene("Empty Scene");
 
@@ -23,48 +23,51 @@ namespace SharpGLTF.Schema2
         [Test(Description ="Creates a model with a triangle mesh")]
         public void CreateTriangleScene()
         {
-            // Notice!! Although this is a valid way of creating a gltf mesh, it will be extremely GPU inefficient.
-
-            var root = ModelRoot.CreateNew();            
-
-            var mesh = root.CreateMesh();
-
-            var primitive = mesh.CreatePrimitive();
-            primitive.DrawPrimitiveType = PrimitiveType.TRIANGLES;            
-
-            var positions = root.CreateVector3Buffer
-                (
-                new System.Numerics.Vector3(0, 10, 0),
-                new System.Numerics.Vector3(-10, -10, 0),
-                new System.Numerics.Vector3(10, -10, 0)
-                );
-
-            var indices = root.CreateIndexBuffer( 0, 1, 2 );
-
-            var positionsView = root.CreateBufferView(positions,null,null,null, BufferMode.ARRAY_BUFFER);
-            var indicesView =   root.CreateBufferView(indices, null, null, null, BufferMode.ELEMENT_ARRAY_BUFFER);
-
+            TestContext.CurrentContext.AttachShowDirLink();
+
+            // Although this is a valid way of creating a gltf mesh, it will be extremely GPU inefficient.            
+
+            var root = ModelRoot.CreateModel();
+            
+            // create a vertex buffer with positions and fill it
+            var positionsView = root.CreateBufferView(root.CreateBuffer(12 * 3), null, null, null, BufferMode.ARRAY_BUFFER);
+            var positionsArray = new Memory.Vector3Array(positionsView.Content);
+            positionsArray[0] = new System.Numerics.Vector3(0, 10, 0);
+            positionsArray[1] = new System.Numerics.Vector3(-10, -10, 0);
+            positionsArray[2] = new System.Numerics.Vector3(10, -10, 0);
+
+            // create an index buffer and fill it
+            var indicesView = root.CreateBufferView(root.CreateBuffer(4 * 3), null, null, null, BufferMode.ELEMENT_ARRAY_BUFFER);
+            var indicesArray = new Memory.IntegerArray(indicesView.Content);
+            indicesArray[0] = 0;
+            indicesArray[1] = 1;
+            indicesArray[2] = 2;
+
+            // create a positions accessor
             var positionsAccessor = root.CreateAccessor();
             positionsAccessor.SetVertexData(positionsView, 0, ElementType.VEC3, ComponentType.FLOAT, false, 3);
 
+            // create an indices accessor
             var indicesAccessor = root.CreateAccessor();
             indicesAccessor.SetIndexData(indicesView, 0, IndexType.UNSIGNED_INT, 3);
 
+            // create a mesh and a mesh primitive
+            var mesh = root.CreateMesh();
+            var primitive = mesh.CreatePrimitive();
+            primitive.DrawPrimitiveType = PrimitiveType.TRIANGLES;
             primitive.SetVertexAccessor("POSITION", positionsAccessor);
             primitive.IndexAccessor = indicesAccessor;
 
             // create a scene
-
             var scene = root.UseScene("Empty Scene");
 
+            // create a node
             var node = scene.AddVisualNode("Triangle");
 
             // assign the mesh we previously created
-
             node.Mesh = mesh;
 
             // save
-
             root.AttachToCurrentTest("result.glb");
             root.AttachToCurrentTest("result.gltf");            
         }

+ 9 - 6
tests/SharpGLTF.Tests/Schema2/LoadModelTests.cs

@@ -26,14 +26,11 @@ namespace SharpGLTF.Schema2
         {
             foreach (var f in TestFiles.GetGeneratedFilePaths())
             {
-                TestContext.Progress.WriteLine($"Processing {f.ToShortDisplayPath()}...");
-
                 var model = GltfUtils.LoadModel(f);
 
                 Assert.NotNull(model);
             }
         }
-
         
         [TestCase(0)]        
         [TestCase(6)]
@@ -60,7 +57,7 @@ namespace SharpGLTF.Schema2
                 ModelRoot.Load(filePath);
                 Assert.Fail("Did not throw!");
             }
-            catch(ModelException ex)
+            catch(IO.ModelException ex)
             {
                 TestContext.WriteLine($"{filePath} threw {ex.Message}");
             }
@@ -100,9 +97,15 @@ namespace SharpGLTF.Schema2
         [Test(Description ="Example of traversing the visual tree all the way to individual vertices and indices")]
         public void TestLoadPolly()
         {
-            var model = GltfUtils.LoadModel(TestFiles.GetPollyFilePath());            
+            var path = TestFiles.GetPollyFilePath();
+
+            var polly = GltfUtils.LoadModel(path);
+
+            Assert.NotNull(polly);
+
+            TestContext.CurrentContext.AttachToCurrentTestAsWavefrontObject(System.IO.Path.GetFileName(path), polly);
 
-            var scene = model.DefaultScene;
+            var scene = polly.DefaultScene;
 
             var pollyNode = scene.FindVisualNode("Polly_Display");            
 

+ 33 - 15
tests/SharpGLTF.Tests/WavefrontWriter.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Numerics;
 using System.Text;
@@ -7,22 +8,22 @@ using static System.FormattableString;
 
 namespace SharpGLTF
 {
-    /// <summary>
-    /// Tiny wavefront object writer
-    /// </summary>
-    class WavefrontWriter
+
+    class VertexColumn<T> : IReadOnlyList<T>
+        where T:IEquatable<T>
     {
-        #region data
+        private readonly List<T> _Vertices = new List<T>();
+        private readonly Dictionary<T, int> _VertexCache = new Dictionary<T, int>();
 
-        private readonly List<Vector3> _Vertices = new List<Vector3>();
-        private readonly List<(int, int, int)> _Indices = new List<(int, int, int)>();
-        private readonly Dictionary<Vector3, int> _VertexCache = new Dictionary<Vector3, int>();
+        public T this[int index] => _Vertices[index];
 
-        #endregion
+        public int Count => _Vertices.Count;
+
+        public IEnumerator<T> GetEnumerator() { return _Vertices.GetEnumerator(); }
 
-        #region API
+        IEnumerator IEnumerable.GetEnumerator() { return _Vertices.GetEnumerator(); }
 
-        private int _UseVertex(Vector3 v)
+        public int Use(T v)
         {
             if (_VertexCache.TryGetValue(v, out int index)) return index;
 
@@ -33,12 +34,29 @@ namespace SharpGLTF
 
             return index;
         }
+    }
+
+    /// <summary>
+    /// Tiny wavefront object writer
+    /// </summary>
+    class WavefrontWriter
+    {
+        #region data
+
+        private readonly VertexColumn<Vector3> _Positions = new VertexColumn<Vector3>();
+        private readonly VertexColumn<Vector3> _Normals = new VertexColumn<Vector3>();
+
+        private readonly List<(int, int, int)> _Indices = new List<(int, int, int)>();        
+
+        #endregion
+
+        #region API        
 
         public void AddTriangle(Vector3 a, Vector3 b, Vector3 c)
         {
-            var aa = _UseVertex(a);
-            var bb = _UseVertex(b);
-            var cc = _UseVertex(c);
+            var aa = _Positions.Use(a);
+            var bb = _Positions.Use(b);
+            var cc = _Positions.Use(c);
 
             // check for degenerated triangles:
             if (aa == bb) return;
@@ -54,7 +72,7 @@ namespace SharpGLTF
 
             sb.AppendLine();
 
-            foreach (var v in _Vertices)
+            foreach (var v in _Positions)
             {
                 sb.AppendLine(Invariant($"v {v.X} {v.Y} {v.Z}"));
             }