diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml
index 2694cdc8..b6981896 100644
--- a/.github/workflows/build-and-test.yaml
+++ b/.github/workflows/build-and-test.yaml
@@ -47,7 +47,7 @@ jobs:
uses: ./.github/workflows/merge-and-run.yaml
with:
run-codegen: true
- run: dotnet build ./src/cs/vim-format.sln -c Release
+ run: dotnet build ./src/cs/vim-format.slnx -c Release
test_cs_merged:
if: ${{ success() }}
@@ -56,7 +56,7 @@ jobs:
with:
lfs: true
run-codegen: true
- run: dotnet test ./src/cs/vim-format.sln
+ run: dotnet test ./src/cs/vim-format.slnx
##############
##### TS #####
diff --git a/data/RoomTestModified.vim b/data/RoomTestModified.vim
new file mode 100644
index 00000000..6d414543
--- /dev/null
+++ b/data/RoomTestModified.vim
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2eac8e80283f005c52845b85ec520ded4e739db99cd35a1b9520977b1b9dfde2
+size 720000
diff --git a/docs/g3d.md b/docs/g3d.md
deleted file mode 100644
index c22373e3..00000000
--- a/docs/g3d.md
+++ /dev/null
@@ -1,135 +0,0 @@
-# G3D
-
-[
](https://www.nuget.org/packages/Vim.G3d)
-
-G3D is a simple, efficient, generic binary format for storing and transmitting geometry. The G3D format
-is designed to be used either as a serialization format or as an in-memory data structure.
-
-G3D can represent triangular meshes, quadrilateral meshes, polygonal meshes, point clouds, and line segments.
-It can be easily and efficiently deserialized and rendered in different languages and on different platforms.
-
-The G3D format can contain a superset of geometry attributes found in most common geometry formats,
-including formats such as FBX, glTF, OBJ, PLY, and in memory data structures used in popular 3D APIs, like
-Unity, Three.JS, Assimp, and 3dsMax.
-
-G3D is maintained by [VIMaec LLC](https://vimaec.com) and is licensed under the terms of the MIT License.
-
-# Repository Structure and Projects
-
-On this Github repository we have the following projects:
-
-* `src/cs/g3d/Vim.G3d` - C# .NET Standard 2.0 Library for reading/writing G3D buffers
-* `src/cs/g3d/Vim.G3d.AssimpAdapter` - C# library for converting from Assimp meshes to G3D data structures
-* `src/cs/g3d/Vim.G3d.Tests` - C# project with NUnit tests
-
-# Format
-
-## BFAST Container
-
-The underlying binary layout of a G3D file conforms to the [BFAST serialization format](./bfast.md), which is a simple and efficient binary format for serializing collections of byte arrays. BFAST provides an interface that allows named arrays of binary data to be serialized and deserialized quickly and easily.
-
-## Meta-Information
-
-The first buffer in a g3d, named "meta", is an 8 byte header composed of the following data:
-
-```
-byte1=0x63 // magic number part "A"
-byte2=0xD0 // magic number part "B"
-byte3=0x66 // first character in the unit (0x66 is the character code for 'f' in 'ft' for feet)
-byte4=0x74 // second character in the unit (0x77 is the character code for 't' in 'ft' for feet)
-byte5=0x02 // up axis (0x00: x axis, 0x01: y axis, 0x02: z axis)
-byte6=0x00 // forward vector (0x00: x axis, 0x01: y axis, 0x02: z axis, 0x03: -x axis, 0x04: -y axis, 0x05: -z axis)
-byte7=0x00 // axis handedness (0x00: left-handed, 0x01: right-handed)
-byte8=0x00 // zero-padding
-```
-
-## Attributes
-
-### Attribute Descriptor String
-
-Every attribute descriptor has a one to one mapping to a string representation similar to a URN:
-
- `g3d:::::`
-
-This attribute descriptor string is the name of the buffer.
-
-### Association
-
-G3D is organized as a collection of attribute buffers. Each attributes describe what part of the incoming geometry they are associated with:
-
-* vertex // vertex data
-* corner // face-vertex data
-* face // per polygon data
-* edge // per half-edge data
-* mesh // A continuous group of submeshes
-* submesh // polygonal group - assumes a contiguous sequence of indices in the index buffer
-* instance // objects which may have a related mesh, matrix and more.
-* all // whole object data - for example face-size of 4 with whole object indicates a quad mesh
-
-### Semantic
-
-Attributes also have a "semantic" which is used to identify what role the attribute has when parsing. These map roughly to FBX layer elements, or Three.JS buffer attributes. There are a number of predefined semantic values with reserved names, but applications are free to define custom semantic values. The only required semantic in a G3D file is "position". Here is a list of some of the predefined semantics:
-
-* unknown, // no known attribute type
-* position, // vertex buffer
-* index, // index buffer
-* indexoffset, // an offset into the index buffer (used with groups and with faces)
-* vertexoffset, // the offset into the vertex buffer (used only with groups, and must have offset.)
-* normal, // computed normal information (per face, group, corner, or vertex)
-* binormal, // computed binormal information
-* tangent, // computed tangent information
-* materialid, // material id
-* visibility, // visibility data
-* size, // number of indices per face or group
-* uv, // UV (sometimes more than 1, e.g. Unity supports up to 8)
-* color, // usually vertex color, but could be edge color as well
-* smoothing, // identifies smoothing groups (e.g. ala 3ds Max and OBJ files)
-* weight, // in 3ds Max this is called selection
-* mapchannel, // 3ds Max map channel (assoc of none => map verts, assoc of corner => map faces)
-* id, // used to identify what object each face part came from
-* joint, // used to identify what a joint a skin is associated with
-* boxes, // used to identify bounding boxes
-* spheres, // used to identify bounding spheres
-* user, // identifies user specific data (in 3ds Max this could be "per-vertex-data")
-
-### Index
-
-Attributes use indices to distinguish when multiple attributes share the same name (e.g. uv:0 ... uv:8)
-
-### Data Type
-
-Attributes are stored in 512-byte aligned data-buffers arranged as arrays of scalars or fixed width vectors. The individual data values can be integers, or floating point values of various widths from 1 to 8 bytes. The data-types are:
-
-* int8
-* int16
-* int32
-* int64
-* uint8
-* uint16
-* uint32
-* uint64
-* float32
-* float64
-
-### Arity
-
-The number of primitives per data element is called the "arity" and can be any integer value greater than zero.
-
-## Encoding Strings
-
-While there is no explicit string type, one could encode string data by using a data-type uint8 with an arity of a fixed value (say 255) to store short strings.
-
-# Recommended reading:
-
-* [VIM AEC blog post about using G3D with Unity](https://www.vimaec.com/the-g3d-geometry-exchange-format/)
-* [Hackernoon article about BFast](https://hackernoon.com/bfast-a-data-format-for-serializing-named-binary-buffers-243p130uw)
-* http://assimp.sourceforge.net/lib_html/structai_mesh.html
-* http://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_5EDC0280_E000_4B0B_88DF_5D215A589D5E_htm
-* https://help.autodesk.com/cloudhelp/2017/ENU/Max-SDK/cpp_ref/class_mesh.html
-* https://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=__files_GUID_CBBA20AD_F7D5_46BC_9F5E_5EDA109F9CF4_htm
-* http://paulbourke.net/dataformats/
-* http://paulbourke.net/dataformats/obj/
-* http://paulbourke.net/dataformats/ply/
-* http://paulbourke.net/dataformats/3ds/
-* https://github.com/KhronosGroup/gltf
-* http://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_layer_element_html
diff --git a/docs/linqarray.md b/docs/linqarray.md
deleted file mode 100644
index fd5b23c8..00000000
--- a/docs/linqarray.md
+++ /dev/null
@@ -1,65 +0,0 @@
-# LinqArray
-
-**LinqArray** is a pure functional .NET library from **[Ara 3D](https://ara3d.com)** that provides LINQ functionality for
-immutable (read only) arrays, rather than streams, while preserving `O(1)` complexity when retrieving the count or items by index.
-It is performant, memory efficient, cross-platform, safe, and easy to use.
-
-## Overview
-
-LinqArray is a set of extension methods build on the `System.IReadonlyList` interface which effectively is:
-
-```
-interface IReadonlyList {
- int Count { get; }
- T this[int n] { get; }
-}
-```
-
-Because the interface does not mutate objects it is safe to use in a multithreaded context. Furthermore, as with regular LINQ for `IEnumerable`,
-evaluation of many of the operations can be performed on demand (aka lazily).
-
-## Motivation
-
-There are two key characteristics of an array data type which are important to maintain in some problem domains:
-1. Retrieving size of collection in `O(1)`
-2. Retrieving any item in collection by index in `O(1)`
-
-LINQ provides a large library of extremely useful and powerful algorithms that work on any data type that can be enumerated.
-However most LINQ methods return an `IEnumerable` interface which has `O(N)` time for retrieving the size of a collection, or `O(N)` time
-for retrieving an element in the collection at a given index.
-
-### Note about Big O Complexity
-
-The notation `O(1)` is called Big-O notation and describes the average running time of an operation in terms of the size of the input set.
-The `O(1)` means that the running time of the operation is a fixed constant independent of the size of the collection.
-
-### Why use Interfaces versus Types
-
-Using concrete types like `List` or `Array` versus an interface leadas to code that is more verbose and harder to maintain because it
-commit library authors and consumers to uses a specific implementation of an abstract data type. Library functions then have to be written
-for each type. This is why interfaces like `IEnumerable` are so prevalent: using extension methods we can easily write libraries that work
-on any conforming type. The closest thing to an array
-
-## Extension Methods
-
-LinqArray provides many of the same extension methods for `IReadOnlyList` as LINQ does for objects implementing the `IEnumerable` interface. Some examples include:
-
-* `Aggregate`
-* `Select`
-* `Zip`
-* `Take`
-* `Skip`
-* `Reverse`
-* `All`
-* `Any`
-* `Count`
-
-## Status
-
-The project is under heavy development but the core functionality is fixed.
-
-## Similar Work
-
-This library is based on an article on CodeProject.com called [LINQ for Immutable Arrays](https://www.codeproject.com/Articles/517728/LINQ-for-Immutable-Arrays). While I worked at Autodesk we used a library based on this article in Autodesk 3ds Max 2016 and later, which shows that
-
-Unlike [LinqFaster](https://github.com/jackmott/LinqFaster) by Jack Mott evaluations of functions happen lazily, and have no side effects. This means that this library can be easily used in a multi-threaded context without inccurring the overhead and complexity of synchronization.
\ No newline at end of file
diff --git a/docs/vim.md b/docs/vim.md
index 67903d3f..bfc9c9b3 100644
--- a/docs/vim.md
+++ b/docs/vim.md
@@ -1,4 +1,5 @@
# VIM v1.0.0
+
The VIM format is a modern and efficient open 3D data interchange format designed for BIM and manufacturing data optimized for efficient loading and rendering on low-power devices.
Characteristics of the VIM format:
@@ -21,10 +22,12 @@ This is the specification for version 1.0.0 of the VIM data format. It is divide
5. FAQ
# 1. VIM Format Binary Specification
+
At the top level, a VIM document conforms to the [BFAST (Binary Format for Array Serialization and Transmission) binary data format](./bfast.md).
A BFAST is conceptually similar to a ZIP or TAR archive without compression, just an array of named data buffers. Physically it is laid out as a header, an array of range structures (each containing offsets to the beginning and end of a buffer), and then the data section. The following structures assume 64-bit or smaller alignment.
## Header
+
The first structure in the VIM file (or any BFAST) is a 32-byte header.
```
@@ -63,9 +66,11 @@ The range structs are expected to satisfy the following criteria:
* There are no more than 64 bytes of padding between each buffer.
## Names Buffer
+
The first data buffer in a VIM file contains the names of the others buffers as NUL character delimited UTF-8 encoded strings. The number of strings should always be equal to the number of data buffers specified in the header minus one.
## VIM Data Buffers
+
There are five expected top-level buffers in the VIM file with the following names. Their order is not essential, and only the header is optional. Additional buffers are allowed for custom purposes but will not be parsed by most readers.
* `header`
* `assets`
@@ -74,6 +79,7 @@ There are five expected top-level buffers in the VIM file with the following nam
* `geometry`
## Header Buffer
+
The header section contains the VIM file version and additional meta data as a sequence of newline (`\n`) terminated sets of key/value pairs denoted by `=`.
The following is an example:
@@ -99,31 +105,21 @@ The `generator` field contains the name of the program used to generate or edit
The `schema` field contains the version of the VIM Object Model.
## Assets Buffer
+
The assets section of a BIM is also a BFAST container. It may contain any number of buffers with any names. Buffers prefixed with the name `texture/` are assumed to be texture files. By convention buffers prefixed with the name `render/` contain image files. The asset buffer `render/main.png` is used as the PNG thumbnail of the VIM file.
## Geometry Buffer
-The geometry section of a VIM contains the merged geometry and basic scene graph information for an entire VIM document using the [G3D format](./g3d.md).
-
-### About G3D
-The [G3D format](./g3d.md) is a binary format for 3D geometry that encodes data in an array of attribute buffers.
-
-G3D is based on the BFAST binary layout and uses a naming convention to identify the layout of each attribute buffer and how it is used.
-Each attribute buffer is associated with a component of a geometry:
-* vertex
-* corner
-* submesh
-* mesh
-* instance
-* shape
+The geometry section of a VIM contains the merged geometry and basic scene graph information for an entire VIM document.
-G3D attributes have names to identify them (e.g., position or UV) and uses indices to distinguish when multiple attributes share the same name (e.g., uv:0 ... uv:8).
+### About G3D
-They can be of one of the following core data datatypes: float32, float64, int8, int16, int32, int64.
+The G3D is a binary format for 3D geometry that encodes data in an array of attribute buffers.
-More information on G3D is available on its [page](./g3d.md).
+G3D is based on the BFAST binary layout and uses a naming convention to identify the layout of each attribute buffer and how it is used.
### VIM Geometry Attributes
+
The geometry in a VIM contains the following attributes:
* `g3d:vertex:position:0:float32:3`
@@ -254,8 +250,8 @@ rowCount(Vim.Shape) == itemCount(g3d:shape:color:0:float32:4)
rowCount(Vim.Shape) == itemCount(g3d:shape:width:0:float32:1)
```
-
## Strings Buffer
+
The strings buffer contains a sequence of strings of zero or more length, with no duplicates, delimited by the "NUL" character. There may or may not be a trailing "NUL" character. The zero-based index of each string is used by the string columns of entity tables.
# 2. VIM Version
@@ -290,4 +286,4 @@ Additional tables and columns can be added as desired, and all software supporti
# Copyright
-This documentation is [Copyright 2023 VIMaec LLC.](https://www.vimaec.com/copyright).
+This documentation is [Copyright 2026 VIMaec LLC.](https://www.vimaec.com/copyright).
diff --git a/src/cs/bfast/Vim.BFast/BFastStructs.cs b/src/cs/bfast/Vim.BFast/BFastStructs.cs
index 46cb0dde..65f297dd 100644
--- a/src/cs/bfast/Vim.BFast/BFastStructs.cs
+++ b/src/cs/bfast/Vim.BFast/BFastStructs.cs
@@ -12,7 +12,6 @@ Usage licensed under terms of MIT License
is required for transmitting data to/from disk, between processes, or over a network.
*/
-using System.Linq;
using System.Runtime.InteropServices;
namespace Vim.BFast
@@ -25,15 +24,6 @@ public class BFastHeader
public BFastPreamble Preamble = new BFastPreamble();
public BFastRange[] Ranges;
public string[] Names;
-
- public override bool Equals(object o)
- => o is BFastHeader other && Equals(other);
-
- public bool Equals(BFastHeader other)
- => Preamble.Equals(other.Preamble) &&
- Ranges.Length == other.Ranges.Length &&
- Ranges.Zip(other.Ranges, (x, y) => x.Equals(y)).All(x => x) &&
- Names.Zip(other.Names, (x, y) => x.Equals(y)).All(x => x);
}
///
@@ -68,12 +58,6 @@ public struct BFastRange
public long Count => End - Begin;
public static long Size = 16;
-
- public override bool Equals(object x)
- => x is BFastRange other && Equals(other);
-
- public bool Equals(BFastRange other)
- => Begin == other.Begin && End == other.End;
}
///
@@ -103,11 +87,5 @@ public struct BFastPreamble
/// Returns true if the producer of the BFast file has the same endianness as the current library
///
public bool SameEndian => Magic == Constants.SameEndian;
-
- public override bool Equals(object x)
- => x is BFastPreamble other && Equals(other);
-
- public bool Equals(BFastPreamble other)
- => Magic == other.Magic && DataStart == other.DataStart && DataEnd == other.DataEnd && NumArrays == other.NumArrays;
};
}
diff --git a/src/cs/g3d/G3d.Build.props b/src/cs/g3d/G3d.Build.props
deleted file mode 100644
index 5f31fa50..00000000
--- a/src/cs/g3d/G3d.Build.props
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
- 1.6.1
- 1.5.0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/cs/g3d/Vim.G3d.AssimpWrapper/AssimpExtensions.cs b/src/cs/g3d/Vim.G3d.AssimpWrapper/AssimpExtensions.cs
deleted file mode 100644
index 80e26239..00000000
--- a/src/cs/g3d/Vim.G3d.AssimpWrapper/AssimpExtensions.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using System;
-using System.Linq;
-using Assimp;
-using Vim.LinqArray;
-using Vim.Math3d;
-
-namespace Vim.G3d.AssimpWrapper
-{
- public static class AssimpExtensions
- {
- public static Vector2 ToMath3D(this Vector2D v)
- => new Vector2(v.X, v.Y);
-
- public static Vector3 ToMath3D(this Vector3D v)
- => new Vector3(v.X, v.Y, v.Z);
-
- public static Vector3 ToMath3D(this Color3D v)
- => new Vector3(v.R, v.G, v.B);
-
- public static Vector4 ToMath3D(this Color4D v)
- => new Vector4(v.R, v.G, v.B, v.A);
-
- public static Math3d.Matrix4x4 ToMath3D(this Assimp.Matrix4x4 m)
- => new Math3d.Matrix4x4(
- m.A1, m.A2, m.A3, m.A4,
- m.B1, m.B2, m.B3, m.B4,
- m.C1, m.C2, m.C3, m.C4,
- m.D1, m.D2, m.D3, m.D4);
-
- public static bool IsTriangular(this Mesh mesh)
- => mesh.Faces.All(f => f.IndexCount == 3);
-
- public static G3D ToG3d(this Scene scene)
- {
- var meshes = scene.Meshes.Select(m => m.ToG3D()).ToIArray();
- var nodes = scene.GetNodes().ToIArray();
- if (nodes.Count == 0 || nodes.Count == 1)
- return meshes.Count > 0 ? meshes[0] : G3D.Empty;
-
- var mergedAttributes = meshes.Merge().Attributes.ToList();
-
- var subGeoTransforms = nodes.Select(n => n.Transform.ToMath3D()).ToInstanceTransformAttribute();
- mergedAttributes.Add(subGeoTransforms);
-
- var meshIndices = nodes.Select(n => n.MeshIndex).ToInstanceMeshAttribute();
- mergedAttributes.Add(meshIndices);
-
- return mergedAttributes.ToG3d();
- }
-
- public static G3D ToG3D(this Mesh mesh)
- {
- // The Assimp mesh must be triangulated
- if (mesh.FaceCount == 0)
- return G3D.Empty;
-
- var bldr = new G3DBuilder();
-
- // Note: should be at most 3 for meses, but could 2 for lines, or 1 for point clouds
- var numCornersPerFace = mesh.Faces[0].IndexCount;
- if (numCornersPerFace > 3)
- throw new Exception("The Assimp mesh must be triangulated as a post-process");
- if (numCornersPerFace <= 0)
- throw new Exception("The Assimp mesh has faces without indices");
- foreach (var f in mesh.Faces)
- {
- if (f.IndexCount != numCornersPerFace)
- throw new Exception($"Each face of the assimp mesh must have {numCornersPerFace} corners, but found one with {f.IndexCount}");
- }
- bldr.SetObjectFaceSize(numCornersPerFace);
-
- var indices = mesh.GetIndices();
- if (indices.Length % numCornersPerFace != 0)
- throw new Exception($"The mesh index buffer length {indices.Length} is not divisible by {numCornersPerFace}");
-
- bldr.AddVertices(mesh.Vertices.ToIArray().Select(ToMath3D));
- bldr.AddIndices(indices);
-
- if (mesh.HasTangentBasis)
- bldr.Add(mesh.BiTangents.ToIArray().Select(ToMath3D).ToVertexBitangentAttribute());
-
- if (mesh.HasTangentBasis)
- bldr.Add(mesh.Tangents.ToIArray().Select(x => ToMath3D(x).ToVector4()).ToVertexTangentAttribute());
-
- if (mesh.HasNormals)
- bldr.Add(mesh.Normals.ToIArray().Select(ToMath3D).ToVertexNormalAttribute());
-
- for (var i = 0; i < mesh.TextureCoordinateChannelCount; ++i)
- {
- var uvChannel = mesh.TextureCoordinateChannels[i];
- bldr.Add(uvChannel.ToIArray().Select(ToMath3D).ToVertexUvwAttribute(i));
- }
-
- for (var i = 0; i < mesh.VertexColorChannelCount; ++i)
- {
- var vcChannel = mesh.VertexColorChannels[i];
- bldr.Add(vcChannel.ToIArray().Select(ToMath3D).ToVertexColorAttribute(i));
- }
-
- return bldr.ToG3D();
- }
- }
-}
diff --git a/src/cs/g3d/Vim.G3d.AssimpWrapper/AssimpLoader.cs b/src/cs/g3d/Vim.G3d.AssimpWrapper/AssimpLoader.cs
deleted file mode 100644
index bb0387be..00000000
--- a/src/cs/g3d/Vim.G3d.AssimpWrapper/AssimpLoader.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using Assimp;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Vim.LinqArray;
-
-namespace Vim.G3d.AssimpWrapper
-{
- public static class AssimpLoader
- {
- public static AssimpContext Context = new AssimpContext();
-
- public class AssimpNode
- {
- public int MeshIndex { get; }
- public Matrix4x4 Transform { get; }
- public AssimpNode(int index, Matrix4x4 transform)
- => (MeshIndex, Transform) = (index, transform);
- }
-
- public static IEnumerable GetNodes(this Scene scene)
- => scene == null || scene.RootNode == null
- ? Enumerable.Empty()
- : GetNodes(scene, scene.RootNode, scene.RootNode.Transform);
-
- public static IEnumerable GetNodes(this Scene scene, Node node, Matrix4x4 transform)
- => node.MeshIndices.Select(idx => new AssimpNode(idx, node.Transform))
- .Concat(node.Children.SelectMany(c => GetNodes(scene, c, transform * c.Transform)));
-
- public static Scene Load(string filePath, bool triangulate = true)
- => Context.ImportFile(filePath, triangulate ? PostProcessSteps.Triangulate : PostProcessSteps.None);
-
- public static bool CanLoad(string filePath)
- => Context.IsImportFormatSupported(Path.GetExtension(filePath));
- }
-}
diff --git a/src/cs/g3d/Vim.G3d.AssimpWrapper/Vim.G3d.AssimpWrapper.csproj b/src/cs/g3d/Vim.G3d.AssimpWrapper/Vim.G3d.AssimpWrapper.csproj
deleted file mode 100644
index afd6d77d..00000000
--- a/src/cs/g3d/Vim.G3d.AssimpWrapper/Vim.G3d.AssimpWrapper.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- netstandard2.0
- Vim.G3d.AssimpWrapper
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/cs/g3d/Vim.G3d.Tests/G3dTestUtils.cs b/src/cs/g3d/Vim.G3d.Tests/G3dTestUtils.cs
deleted file mode 100644
index 0a28e014..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/G3dTestUtils.cs
+++ /dev/null
@@ -1,137 +0,0 @@
-using Assimp;
-using NUnit.Framework;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using Vim.G3d.AssimpWrapper;
-using Vim.LinqArray;
-
-namespace Vim.G3d.Tests
-{
- public static class G3dTestUtils
- {
- public static void OutputSceneStats(Scene scene)
- => Console.WriteLine(
-$@" #animations = {scene.AnimationCount}
- #cameras = {scene.CameraCount}
- #lights = {scene.LightCount}
- #materials = {scene.MaterialCount}
- #meshes = {scene.MeshCount}
- #nodes = {scene.GetNodes().Count()}
- #textures = {scene.TextureCount}");
-
- // TODO: merge all of the meshes using the transform.
-
- public static void OutputMeshStats(Mesh mesh)
- => Console.WriteLine(
- $@"
- mesh {mesh.Name}
- #faces = {mesh.FaceCount}
- #vertices = {mesh.VertexCount}
- #normals = {mesh.Normals?.Count ?? 0}
- #texture coordinate chanels = {mesh.TextureCoordinateChannelCount}
- #vertex color chanels = {mesh.VertexColorChannelCount}
- #bones = {mesh.BoneCount}
- #tangents = {mesh.Tangents?.Count}
- #bitangents = {mesh.BiTangents?.Count}");
-
- public static T TimeLoadingFile(string fileName, Func func)
- {
- var sw = new Stopwatch();
- sw.Start();
- try
- {
- return func(fileName);
- }
- finally
- {
- Console.WriteLine($"Time to open {Path.GetFileName(fileName)} is {sw.ElapsedMilliseconds}msec");
- }
- }
-
- public static void OutputStats(G3D g)
- {
- //Console.WriteLine("Header");
-
- Console.WriteLine($"# corners per faces {g.NumCornersPerFace} ");
- Console.WriteLine($"# vertices = {g.NumVertices}");
- Console.WriteLine($"# faces = {g.NumFaces}");
- Console.WriteLine($"# subgeos = {g.NumMeshes}");
- Console.WriteLine($"# indices (corners/edges0 = {g.NumCorners}");
- Console.WriteLine($"# instances = {g.NumInstances}");
- Console.WriteLine($"Number of attributes = {g.Attributes.Count}");
-
- foreach (var attr in g.Attributes.ToEnumerable())
- Console.WriteLine($"{attr.Name} #items={attr.ElementCount}");
- }
-
- public static void AssertSame(G3D g1, G3D g2)
- {
- Assert.AreEqual(g1.NumCornersPerFace, g2.NumCornersPerFace);
- Assert.AreEqual(g1.NumFaces, g2.NumFaces);
- Assert.AreEqual(g1.NumCorners, g2.NumCorners);
- Assert.AreEqual(g1.NumVertices, g2.NumVertices);
- Assert.AreEqual(g1.NumInstances, g2.NumInstances);
- Assert.AreEqual(g1.NumMeshes, g2.NumMeshes);
- Assert.AreEqual(g1.Attributes.Count, g2.Attributes.Count);
- for (var i = 0; i < g1.Attributes.Count; ++i)
- {
- var attr1 = g1.Attributes[i];
- var attr2 = g2.Attributes[i];
- Assert.AreEqual(attr1.Name, attr2.Name);
- Assert.AreEqual(attr1.GetByteSize(), attr2.GetByteSize());
- Assert.AreEqual(attr1.ElementCount, attr2.ElementCount);
- }
- }
-
- public static void AssertSame(Mesh m, G3D g)
- {
- Assert.AreEqual(m.FaceCount, g.NumFaces);
- Assert.AreEqual(m.GetIndices(), g.Indices.ToArray());
- Assert.AreEqual(m.VertexCount, g.NumVertices);
- }
-
- public static G3D CompareTiming(string fileName, string outputFolder)
- {
- using (var context = new AssimpContext())
- {
- var scene = TimeLoadingFile(fileName, context.ImportFile);
- var m = scene.Meshes[0];
- var g3d = m.ToG3D();
- AssertSame(m, g3d);
- var outputFile = Path.Combine(outputFolder, Path.GetFileName(fileName) + ".g3d");
- g3d.Write(outputFile);
- var r = TimeLoadingFile(outputFile, G3D.Read);
- //OutputG3DStats(g3d);
- AssertSame(g3d, r);
- return r;
- }
- }
-
- public static string[] TestFiles =
- {
- @"models-nonbsd\3DS\jeep1.3ds",
- @"models-nonbsd\3DS\mar_rifle.3ds",
- @"models-nonbsd\dxf\rifle.dxf",
- @"models-nonbsd\FBX\2013_ASCII\duck.fbx",
- @"models-nonbsd\FBX\2013_ASCII\jeep1.fbx",
- // Binary fails assimp import
- //@"models-nonbsd\FBX\2013_BINARY\duck.fbx",
- //@"models-nonbsd\FBX\2013_BINARY\jeep1.fbx",
- // OBJ files were not checked in to the repo.
- //@"models-nonbsd\OBJ\rifle.obj",
- //@"models-nonbsd\OBJ\segment.obj",
- @"models-nonbsd\PLY\ant-half.ply",
- @"models\IFC\AC14-FZK-Haus.ifc",
- @"models\PLY\Wuson.ply",
- @"models\STL\Wuson.stl",
- @"models\STL\Spider_ascii.stl",
- @"models\STL\Spider_binary.stl",
- @"models\glTF\CesiumMilkTruck\CesiumMilkTruck.gltf",
- @"models\glTF2\2CylinderEngine-glTF-Binary\2CylinderEngine.glb",
- @"models\DXF\wuson.dxf",
- @"models\Collada\duck.dae",
- };
- }
-}
diff --git a/src/cs/g3d/Vim.G3d.Tests/G3dTests.cs b/src/cs/g3d/Vim.G3d.Tests/G3dTests.cs
deleted file mode 100644
index 363a020d..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/G3dTests.cs
+++ /dev/null
@@ -1,377 +0,0 @@
-using Assimp;
-using NUnit.Framework;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Vim.G3d.AssimpWrapper;
-using Vim.LinqArray;
-using Vim.Math3d;
-
-namespace Vim.G3d.Tests
-{
- [TestFixture, Ignore("Ignored until the new version is ready")]
- public static class G3dTests
- {
- public class FileLoadData
- {
- public FileLoadData(string filePath)
- => SourceFile = new FileInfo(filePath);
-
- public string ShortName => Path.GetFileName(SourceFile.FullName);
- public int NumMeshes => Scene?.MeshCount ?? 0;
- public FileInfo SourceFile;
- public FileInfo G3DFile;
- public long MSecToOpen;
- public long MSecToSaveG3d;
- public long MSecToOpenG3d;
- public long MSecToConvert;
- public long MemoryConsumption;
- public long MemoryConsumptionG3d;
- public Exception Error;
- public Scene Scene;
- public G3D G3d;
- }
-
- public static readonly string ProjectFolder = new DirectoryInfo(Properties.Resources.ProjDir.Trim()).FullName;
- public static string RootFolder = Path.Combine(ProjectFolder, "..", "..", "..", "..");
- public static string TestInputFolder = Path.Combine(RootFolder, "data", "g3d-test-data", "models");
- public static string TestOutputFolder = Path.Combine(RootFolder, "data", "g3d-test-data", "output");
-
- public static IEnumerable GetInputFiles()
- => Directory.GetFiles(TestInputFolder, "*.*", SearchOption.AllDirectories);
-
- public static void ValidateSame(Object a, Object b, string name = "")
- {
- if (!a.Equals(b))
- throw new Exception($"Values {a} and {b} are different {name}");
- }
-
- public static void ValidateSameG3D(G3D g1, G3D g2)
- {
- ValidateSame(g1.NumCornersPerFace, g2.NumCornersPerFace, "NumCornersPerFace");
- ValidateSame(g1.NumFaces, g2.NumFaces, "NumFaces");
- ValidateSame(g1.NumCorners, g2.NumCorners, "NumCorners");
- ValidateSame(g1.NumVertices, g2.NumVertices, "NumVertices");
- ValidateSame(g1.NumInstances, g2.NumInstances, "NumInstances");
- ValidateSame(g1.NumMeshes, g2.NumMeshes, "NumMeshes");
- ValidateSame(g1.Attributes.Count, g2.Attributes.Count, "NumAttributes");
- for (var i = 0; i < g1.Attributes.Count; ++i)
- {
- var attr1 = g1.Attributes[i];
- var attr2 = g2.Attributes[i];
- ValidateSame(attr1.Name, attr2.Name, $"Attribute[{i}].Name");
- ValidateSame(attr1.GetByteSize(), attr2.GetByteSize(), $"Attribute[{i}].ByteSize");
- ValidateSame(attr1.ElementCount, attr2.ElementCount, $"Attribute[{i}].ElementCount");
- }
- }
-
- [Test, Explicit("Use during debugging")]
- public static void ReadG3DFiles()
- {
- foreach (var f in Directory.GetFiles(TestOutputFolder))
- {
- var g3d = G3D.Read(f);
- G3dTestUtils.OutputStats(g3d);
- }
- }
-
- [Test]
- [Platform(Exclude = "Linux,Unix", Reason = "AssimpNet is failing to load its dependency on 'libdl.so'.")]
- public static void OpenAndConvertAssimpFiles()
- {
- var files = GetInputFiles()
- .Where(AssimpLoader.CanLoad)
- .Select(f => new FileLoadData(f))
- .ToArray();
-
- // Load all the files
- foreach (var f in files)
- {
- try
- {
- (f.MemoryConsumption, f.MSecToOpen) =
- Util.GetMemoryConsumptionAndMSecElapsed(() =>
- f.Scene = AssimpLoader.Load(f.SourceFile.FullName));
- }
- catch (Exception e)
- {
- f.Error = e;
- }
- }
-
- // Convert all the Assimp scenes to G3D
- foreach (var f in files)
- {
- if (f.Scene == null) continue;
-
- try
- {
- f.MSecToConvert = Util.GetMSecElapsed(() =>
- f.G3d = f.Scene.ToG3d());
- }
- catch (Exception e)
- {
- f.Error = e;
- }
- }
-
- // Save all the G3D scenes
- Util.CreateAndClearDirectory(TestOutputFolder);
- foreach (var f in files)
- {
- if (f.G3d == null) continue;
-
- try
- {
- var outputFilePath = Path.Combine(TestOutputFolder, f.ShortName + ".g3d");
- f.G3DFile = new FileInfo(outputFilePath);
-
- f.MSecToSaveG3d = Util.GetMSecElapsed(() =>
- f.G3d.Write(outputFilePath));
- }
- catch (Exception e)
- {
- f.Error = e;
- }
- }
-
- // Try reading back in all of the G3D scenes, measure load times and the memory consumption
- foreach (var f in files)
- {
- if (f.G3DFile == null) continue;
-
- try
- {
- G3D localG3d = null;
-
- (f.MemoryConsumptionG3d, f.MSecToOpenG3d) =
- Util.GetMemoryConsumptionAndMSecElapsed(() =>
- localG3d = G3D.Read(f.G3DFile.FullName));
-
- ValidateSameG3D(f.G3d, localG3d);
- }
- catch (Exception e)
- {
- f.Error = e;
- }
- }
-
- // Output the header for data
- Console.WriteLine(
- "Importer," +
- "Extension," +
- "File Name," +
- "File Size(KB)," +
- "Load Time(s)," +
- "Memory(KB)," +
- "# Meshes," +
- "Time to Convert," +
- "Time to Write G3D," +
- "G3D File Size(KB)," +
- "G3D Memory(KB)",
- "G3D Load Time(s)",
- "Error");
-
- // Output the data rows
- foreach (var f in files)
- {
- Console.WriteLine(
- "Assimp," +
- $"{Path.GetExtension(f.ShortName)}," +
- $"{f.ShortName}," +
- $"{f.SourceFile?.Length / 1000}," +
- $"{f.MSecToOpen / 100f}," +
- $"{f.MemoryConsumption / 1000}," +
- $"{f.NumMeshes}," +
- $"{f.MSecToConvert / 100f}," +
- $"{f.MSecToSaveG3d / 100f}," +
- $"{f.G3DFile?.Length / 1000}," +
- $"{f.MemoryConsumptionG3d / 1000}," +
- $"{f.MSecToOpenG3d / 100f}," +
- $"{f.Error}");
- }
-
- Assert.AreEqual(0, files.Count(f => f.Error != null), "Errors occurred");
- }
-
- [Test]
- public static void TriangleTest()
- {
- // Serialize a triangle g3d as bytes and read it back.
- var vertices = new[]
- {
- new Vector3(0, 0, 0),
- new Vector3(0, 1, 0),
- new Vector3(0, 1, 1)
- };
-
- var indices = new[] { 0, 1, 2 };
- var materialIndices = new[] { 5 };
-
- var g3d = new G3DBuilder()
- .AddVertices(vertices.ToIArray())
- .AddIndices(indices.ToIArray())
- .Add(materialIndices.ToIArray().ToFaceMaterialAttribute())
- .ToG3D();
-
- var bytes = g3d.WriteToBytes();
- var g = G3D.Read(bytes);
-
- Assert.IsNotNull(g);
-
- Assert.AreEqual(3, g.NumVertices);
- Assert.AreEqual(3, g.NumCorners);
- Assert.AreEqual(1, g.NumFaces);
- Assert.AreEqual(3, g.NumCornersPerFace);
- Assert.AreEqual(0, g.NumMeshes);
- Assert.AreEqual(0, g.NumInstances);
-
- Assert.AreEqual(vertices, g.Vertices.ToArray());
- Assert.AreEqual(indices, g.Indices.ToArray());
- Assert.AreEqual(materialIndices, g.FaceMaterials.ToArray());
- }
-
- [Test]
- public static void QuadAndCopyTest()
- {
- // Serialize a triangle g3d as bytes and read it back.
- var vertices = new[]
- {
- new Vector3(0, 0, 0),
- new Vector3(0, 1, 0),
- new Vector3(0, 1, 1),
- new Vector3(1, 1, 1)
- };
-
- var indices = new[] { 0, 1, 2, 3 };
- var materialIndices = new[] { 5 };
-
- var g3d = new G3DBuilder()
- .AddVertices(vertices.ToIArray())
- .AddIndices(indices.ToIArray())
- .Add(materialIndices.ToIArray().ToFaceMaterialAttribute())
- .ToG3D();
-
- var bytes = g3d.WriteToBytes();
- var g = G3D.Read(bytes);
-
- Assert.IsNotNull(g);
-
- Assert.AreEqual(4, g.NumCornersPerFace);
- Assert.AreEqual(4, g.NumVertices);
- Assert.AreEqual(4, g.NumCorners);
- Assert.AreEqual(1, g.NumFaces);
- Assert.AreEqual(0, g.NumMeshes);
- Assert.AreEqual(0, g.NumInstances);
-
- Assert.AreEqual(vertices, g.Vertices.ToArray());
- Assert.AreEqual(indices, g.Indices.ToArray());
- Assert.AreEqual(materialIndices, g.FaceMaterials.ToArray());
-
- var g2 = g.TriangulateQuadMesh();
-
- Assert.AreEqual(3, g2.NumCornersPerFace);
- Assert.AreEqual(4, g2.NumVertices);
- Assert.AreEqual(6, g2.NumCorners);
- Assert.AreEqual(2, g2.NumFaces);
- Assert.AreEqual(0, g2.NumMeshes);
- Assert.AreEqual(0, g2.NumInstances);
-
- Assert.AreEqual(vertices, g2.GetAttributeDataPosition().ToArray());
- Assert.AreEqual(new[] { 0, 1, 2, 0, 2, 3 }, g2.GetAttributeDataIndex().ToArray());
- Assert.AreEqual(new[] { 5, 5 }, g2.GetAttributeDataFaceMaterial().ToArray());
-
- g2 = g2.CopyFaces(1, 1);
-
- Assert.AreEqual(3, g2.NumCornersPerFace);
- Assert.AreEqual(4, g2.NumVertices);
- Assert.AreEqual(3, g2.NumCorners);
- Assert.AreEqual(1, g2.NumFaces);
-
- Assert.AreEqual(vertices, g2.GetAttributeDataPosition().ToArray());
- Assert.AreEqual(new[] { 0, 2, 3 }, g2.GetAttributeDataIndex().ToArray());
- Assert.AreEqual(new[] { 5 }, g2.GetAttributeDataFaceMaterial().ToArray());
- }
-
- [Test]
- public static void UnexpectedAttributeTest()
- {
- // This test validates that unrecognized g3d attributes are simply ignored in the deserialization process.
- //
- // "unexpected.g3d" was generated using the following code snippet. Note that the code was temporarily modified such
- // that UNKNOWN mapped to a ulong data type value (8 bits):
- //
- // var g3d = new G3DBuilder()
- // .Add(new GeometryAttribute(new int[] { 5 }.ToIArray(), AttributeDescriptor.Parse("g3d:instance:potato:0:int32:1")))
- // .Add(new GeometryAttribute(new ulong[] { 42 }.ToIArray(), AttributeDescriptor.Parse("g3d:instance:beep:0:UNKNOWN:1")))
- // .ToG3D();
-
- var g = G3D.Read(Path.Combine(TestInputFolder, "unexpected.g3d"));
-
- var parsedInstanceAttrs = g.Attributes.Where(ga => ga.Descriptor.Association == Association.assoc_instance).ToArray();
- Assert.AreEqual(1, parsedInstanceAttrs.Length); // NOTE: we only expect one attribute (the one with the "potato" semantic) because UNKNOWN is currently ignored as a datatype.
- var parsedPotatoAttr = parsedInstanceAttrs.Single(ga => ga.Descriptor.Semantic == "potato");
- Assert.AreEqual(new [] { 5 }, parsedPotatoAttr.AsType().Data.ToArray());
- }
-
- public static G3D LoadAssimpFile(string filePath)
- {
- using (var context = new AssimpContext())
- {
- var scene = context.ImportFile(filePath);
- Assert.AreEqual(1, scene.Meshes.Count);
- return scene.Meshes[0].ToG3D();
- }
- }
-
- // NOTE: can't be run as part of NUnit because it requires the GC
- public static void BigFileTest()
- {
- var nVerts = (300 * 1000 * 1000); // 300 * 12 = 3.6 GB
- var vertices = nVerts.Select(i => new Vector3(i, i, i));
- var bldr = new G3DBuilder();
- bldr.AddVertices(vertices);
- var g3d = bldr.ToG3D();
- Assert.AreEqual(nVerts, g3d.NumVertices);
- var tempFile = Path.Combine(Path.GetTempPath(), "bigfile.g3d");
- g3d.Write(tempFile);
- var tmp = G3D.Read(tempFile);
- ValidateSameG3D(g3d, tmp);
- }
-
- [Test]
- [Platform(Exclude = "Linux,Unix", Reason = "AssimpNet is failing to load its dependency on 'libdl.so'.")]
- public static void TestWriters()
- {
- var fileName = Path.Combine(TestInputFolder, "PLY", "Wuson.ply");
-
- var outputFileName = @"test";
- outputFileName = Path.Combine(TestOutputFolder, outputFileName);
-
- var g3d = LoadAssimpFile(fileName);
-
- g3d.WritePly(outputFileName + ".ply");
- g3d.WriteObj(outputFileName + ".obj");
-
- // TODO compare the PLY, the OBJ and the original file.
-
- var g3dFromPly = LoadAssimpFile(outputFileName + ".ply");
- //var g3dFromObj = LoadAssimpFile(outputFileName + ".obj");
-
- {
- var g1 = g3d;
- var g2 = g3dFromPly;
- Assert.AreEqual(g1.NumCornersPerFace, g2.NumCornersPerFace);
- Assert.AreEqual(g1.NumFaces, g2.NumFaces);
- Assert.AreEqual(g1.NumCorners, g2.NumCorners);
- Assert.AreEqual(g1.NumVertices, g2.NumVertices);
- Assert.AreEqual(g1.NumInstances, g2.NumInstances);
- Assert.AreEqual(g1.NumMeshes, g2.NumMeshes);
- }
-
- // BUG: Assimp ignores the OBJ index buffer. God knows why.
- //CompareG3D(g3d, g3dFromObj);
- }
- }
-}
diff --git a/src/cs/g3d/Vim.G3d.Tests/Properties/Resources.Designer.cs b/src/cs/g3d/Vim.G3d.Tests/Properties/Resources.Designer.cs
deleted file mode 100644
index 2f5f4dfd..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace Vim.G3d.Tests.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Vim.G3d.Tests.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to C:\DEV\g3d\csharp\Vim.G3d.Tests\
- ///.
- ///
- internal static string ProjDir {
- get {
- return ResourceManager.GetString("ProjDir", resourceCulture);
- }
- }
- }
-}
diff --git a/src/cs/g3d/Vim.G3d.Tests/Properties/Resources.resx b/src/cs/g3d/Vim.G3d.Tests/Properties/Resources.resx
deleted file mode 100644
index 579dd3b6..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/Properties/Resources.resx
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
-
- ..\Resources\ProjDir.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252
-
-
\ No newline at end of file
diff --git a/src/cs/g3d/Vim.G3d.Tests/Resources/.gitignore b/src/cs/g3d/Vim.G3d.Tests/Resources/.gitignore
deleted file mode 100644
index d8fff56a..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/Resources/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-ProjDir.txt
\ No newline at end of file
diff --git a/src/cs/g3d/Vim.G3d.Tests/Util.cs b/src/cs/g3d/Vim.G3d.Tests/Util.cs
deleted file mode 100644
index 2ff62684..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/Util.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-
-namespace Vim.G3d.Tests
-{
- public static class Util
- {
- public static (long, long) GetMemoryConsumptionAndMSecElapsed(Action action)
- {
- var time = 0L;
- var mem = GetMemoryConsumption(
- () => time = GetMSecElapsed(action));
- return (mem, time);
- }
-
- public static long GetMSecElapsed(Action action)
- {
- var sw = Stopwatch.StartNew();
- action();
- return sw.ElapsedMilliseconds;
- }
-
- ///
- /// Creates a directory if needed, or clears all of its contents otherwise
- ///
- public static string CreateAndClearDirectory(string dirPath)
- {
- if (!Directory.Exists(dirPath))
- Directory.CreateDirectory(dirPath);
- else
- DeleteFolderContents(dirPath);
- return dirPath;
- }
-
- ///
- /// Deletes all contents in a folder
- ///
- ///
- /// https://stackoverflow.com/questions/1288718/how-to-delete-all-files-and-folders-in-a-directory
- ///
- private static void DeleteFolderContents(string folderPath)
- {
- var di = new DirectoryInfo(folderPath);
- foreach (var dir in di.EnumerateDirectories().AsParallel())
- DeleteFolderAndAllContents(dir.FullName);
- foreach (var file in di.EnumerateFiles().AsParallel())
- file.Delete();
- }
-
- ///
- /// Deletes everything in a folder and then the folder.
- ///
- private static void DeleteFolderAndAllContents(string folderPath)
- {
- if (!Directory.Exists(folderPath))
- return;
-
- DeleteFolderContents(folderPath);
- Directory.Delete(folderPath);
- }
-
- // NOTE: Calling a function generates additional memory
- private static long GetMemoryConsumption(Action action)
- {
- GC.Collect();
- GC.WaitForPendingFinalizers();
- var memBefore = GC.GetTotalMemory(true);
- action();
- GC.Collect();
- GC.WaitForPendingFinalizers();
- return GC.GetTotalMemory(true) - memBefore;
- }
- }
-}
\ No newline at end of file
diff --git a/src/cs/g3d/Vim.G3d.Tests/Vim.G3d.Tests.csproj b/src/cs/g3d/Vim.G3d.Tests/Vim.G3d.Tests.csproj
deleted file mode 100644
index 65b5a383..00000000
--- a/src/cs/g3d/Vim.G3d.Tests/Vim.G3d.Tests.csproj
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
- net8.0
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
-
-
diff --git a/src/cs/g3d/Vim.G3d/AttributeDescriptor.cs b/src/cs/g3d/Vim.G3d/AttributeDescriptor.cs
deleted file mode 100644
index a2f48840..00000000
--- a/src/cs/g3d/Vim.G3d/AttributeDescriptor.cs
+++ /dev/null
@@ -1,158 +0,0 @@
-using System;
-
-namespace Vim.G3d
-{
- ///
- /// Provides information about identifying the role and parsing the data within an attribute data buffer.
- /// This is encoded using a string in a particular URN form.
- ///
- public class AttributeDescriptor
- {
- public Association Association { get; }
- public string Semantic { get; }
- public DataType DataType { get; }
- public int DataArity { get; }
- public int Index { get; }
-
- public int DataElementSize { get; }
- public int DataTypeSize { get; }
- public string Name { get; }
-
- public AttributeDescriptor(Association association, string semantic, DataType dataType, int dataArity, int index = 0)
- {
- Association = association;
- if (semantic.Contains(":"))
- throw new Exception("The semantic must not contain a semicolon");
- Semantic = semantic;
- DataType = dataType;
- DataArity = dataArity;
- Index = index;
- DataTypeSize = GetDataTypeSize(DataType);
- DataElementSize = DataTypeSize * DataArity;
- Name = $"g3d:{AssociationString}:{Semantic}:{Index}:{DataTypeString}:{DataArity}";
- }
-
- ///
- /// Generates a URN representation of the attribute descriptor
- ///
- public override string ToString()
- => Name;
-
- ///
- /// Returns true if the attribute descriptor has been successfully parsed.
- ///
- public static bool TryParse(string urn, out AttributeDescriptor attributeDescriptor)
- {
- attributeDescriptor = null;
- try
- {
- attributeDescriptor = Parse(urn);
- }
- catch
- {
- // do nothing.
- }
-
- return attributeDescriptor != null;
- }
-
- ///
- /// Parses a URN representation of the attribute descriptor to generate an actual attribute descriptor
- ///
- public static AttributeDescriptor Parse(string urn)
- {
- var vals = urn.Split(':');
- if (vals.Length != 6) throw new Exception("Expected 6 parts to the attribute descriptor URN");
- if (vals[0] != "g3d") throw new Exception("First part of URN must be g3d");
- return new AttributeDescriptor(
- ParseAssociation(vals[1]),
- vals[2],
- ParseDataType(vals[4]),
- int.Parse(vals[5]),
- int.Parse(vals[3])
- );
- }
-
- public bool Validate()
- {
- var urn = ToString();
- var tmp = Parse(urn);
- if (!Equals(tmp))
- throw new Exception("Invalid attribute descriptor (or internal error in the parsing/string conversion");
- return true;
- }
-
- public bool Equals(AttributeDescriptor other)
- => ToString() == other.ToString();
-
- public static int GetDataTypeSize(DataType dt)
- {
- switch (dt)
- {
- case DataType.dt_uint8:
- case DataType.dt_int8:
- return 1;
- case DataType.dt_uint16:
- case DataType.dt_int16:
- return 2;
- case DataType.dt_uint32:
- case DataType.dt_int32:
- return 4;
- case DataType.dt_uint64:
- case DataType.dt_int64:
- return 8;
- case DataType.dt_float32:
- return 4;
- case DataType.dt_float64:
- return 8;
- default:
- throw new ArgumentOutOfRangeException(nameof(dt), dt, null);
- }
- }
-
- public string AssociationString
- => Association.ToString().Substring("assoc_".Length);
-
- public static Association ParseAssociation(string s)
- {
- switch (s)
- {
- case "all":
- return Association.assoc_all;
- case "corner":
- return Association.assoc_corner;
- case "edge":
- return Association.assoc_edge;
- case "face":
- return Association.assoc_face;
- case "instance":
- return Association.assoc_instance;
- case "vertex":
- return Association.assoc_vertex;
- case "shapevertex":
- return Association.assoc_shapevertex;
- case "shape":
- return Association.assoc_shape;
- case "material":
- return Association.assoc_material;
- case "mesh":
- return Association.assoc_mesh;
- case "submesh":
- return Association.assoc_submesh;
-
- // Anything else we just treat as unknown
- default:
- return Association.assoc_none;
- }
- }
-
- public string DataTypeString
- => DataType.ToString()?.Substring("dt_".Length) ?? null;
-
- public static DataType ParseDataType(string s)
- => (DataType)Enum.Parse(typeof(DataType), "dt_" + s);
-
- public AttributeDescriptor SetIndex(int index)
- => new AttributeDescriptor(Association, Semantic, DataType, DataArity, index);
- }
-}
diff --git a/src/cs/g3d/Vim.G3d/AttributeExtensions.cs b/src/cs/g3d/Vim.G3d/AttributeExtensions.cs
deleted file mode 100644
index 98fb02fa..00000000
--- a/src/cs/g3d/Vim.G3d/AttributeExtensions.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using Vim.LinqArray;
-using Vim.Math3d;
-
-namespace Vim.G3d
-{
- public static class AttributeExtensions
- {
- public static GeometryAttribute CheckArity(this GeometryAttribute self, int arity) where T : unmanaged
- => self?.Descriptor?.DataArity == arity ? self : null;
-
- public static GeometryAttribute CheckAssociation(this GeometryAttribute self, Association assoc) where T : unmanaged
- => self?.Descriptor?.Association == assoc ? self : null;
-
- public static GeometryAttribute CheckArityAndAssociation(this GeometryAttribute self, int arity, Association assoc) where T : unmanaged
- => self?.CheckArity(arity)?.CheckAssociation(assoc);
-
- public static GeometryAttribute ToAttribute(this IList self, string desc) where T : unmanaged
- => self.ToIArray().ToAttribute(desc);
-
- public static GeometryAttribute ToAttribute(this IList self, AttributeDescriptor desc) where T : unmanaged
- => self.ToIArray().ToAttribute(desc);
-
- public static GeometryAttribute ToAttribute(this IArray self, AttributeDescriptor desc) where T : unmanaged
- => new GeometryAttribute(self, desc);
-
- public static GeometryAttribute ToAttribute(this IArray self, string desc) where T : unmanaged
- => self.ToAttribute(AttributeDescriptor.Parse(desc));
-
- public static GeometryAttribute ToAttribute(this IArray self, string desc, int index) where T : unmanaged
- => self.ToAttribute(AttributeDescriptor.Parse(desc).SetIndex(index));
-
- public static IArray AttributeToColors(this GeometryAttribute attr)
- {
- var desc = attr.Descriptor;
- if (desc.DataType == DataType.dt_float32)
- {
- if (desc.DataArity == 4)
- return attr.AsType().Data;
- if (desc.DataArity == 3)
- return attr.AsType().Data.Select(vc => new Vector4(vc, 1f));
- if (desc.DataArity == 2)
- return attr.AsType().Data.Select(vc => new Vector4(vc.X, vc.Y, 0, 1f));
- if (desc.DataArity == 1)
- return attr.AsType().Data.Select(vc => new Vector4(vc, vc, vc, 1f));
- }
- if (desc.DataType == DataType.dt_int8)
- {
- if (desc.DataArity == 4)
- return attr.AsType().Data.Select(b => new Vector4(b.X / 255f, b.Y / 255f, b.Z / 255f, b.W / 255f));
- if (desc.DataArity == 3)
- return attr.AsType().Data.Select(b => new Vector4(b.X / 255f, b.Y / 255f, b.Z / 255f, 1f));
- if (desc.DataArity == 2)
- return attr.AsType().Data.Select(b => new Vector4(b.X / 255f, b.Y / 255f, 0f, 1f));
- if (desc.DataArity == 1)
- return attr.AsType().Data.Select(b => new Vector4(b / 255f, b / 255f, b / 255f, 1f));
- }
- Debug.WriteLine($"Failed to recongize color format {attr.Descriptor}");
- return null;
- }
-
- public static GeometryAttribute ToDefaultAttribute(this AttributeDescriptor desc, int count)
- {
- switch (desc.DataType)
- {
- // TODO: TECH DEBT - Add unsigned tuple objects to Math3d
- case DataType.dt_uint8:
- if (desc.DataArity == 1)
- return default(byte).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_int8:
- if (desc.DataArity == 1)
- return default(byte).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 2)
- return default(Byte2).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 3)
- return default(Byte3).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 4)
- return default(Byte4).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_uint16:
- if (desc.DataArity == 1)
- return default(ushort).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_int16:
- if (desc.DataArity == 1)
- return default(short).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_uint32:
- if (desc.DataArity == 1)
- return default(uint).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_int32:
- if (desc.DataArity == 1)
- return default(int).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 2)
- return default(Int2).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 3)
- return default(Int3).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 4)
- return default(Int4).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_uint64:
- if (desc.DataArity == 1)
- return default(ulong).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_int64:
- if (desc.DataArity == 1)
- return default(long).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_float32:
- if (desc.DataArity == 1)
- return default(float).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 2)
- return default(Vector2).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 3)
- return default(Vector3).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 4)
- return default(Vector4).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 16)
- return default(Matrix4x4).Repeat(count).ToAttribute(desc);
- break;
- case DataType.dt_float64:
- if (desc.DataArity == 1)
- return default(double).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 2)
- return default(DVector2).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 3)
- return default(DVector3).Repeat(count).ToAttribute(desc);
- if (desc.DataArity == 4)
- return default(DVector4).Repeat(count).ToAttribute(desc);
- break;
- }
-
- throw new Exception($"Could not create a default attribute for {desc}");
- }
-
- public static long GetByteSize(this GeometryAttribute attribute)
- => (long)attribute.ElementCount * attribute.Descriptor.DataElementSize;
-
- public static GeometryAttribute Merge(this IEnumerable attributes)
- => attributes.FirstOrDefault()?.Merge(attributes.Skip(1));
-
- public static GeometryAttribute Merge(this IArray attributes)
- => attributes.ToEnumerable().Merge();
- }
-}
diff --git a/src/cs/g3d/Vim.G3d/CommonAttributes.cs b/src/cs/g3d/Vim.G3d/CommonAttributes.cs
deleted file mode 100644
index da835913..00000000
--- a/src/cs/g3d/Vim.G3d/CommonAttributes.cs
+++ /dev/null
@@ -1,231 +0,0 @@
-
-// AUTOGENERATED FILE: DO NOT EDIT
-// This file is generated from CommonAttributeExtensions.tt
-
-
-using Vim.LinqArray;
-using Vim.Math3d;
-
-namespace Vim.G3d
-{
- public static class CommonAttributes
- {
-
- public const string ObjectFaceSize = "g3d:all:facesize:0:int32:1";
- public const string Index = "g3d:corner:index:0:int32:1";
- public const string Position = "g3d:vertex:position:0:float32:3";
- public const string VertexUv = "g3d:vertex:uv:0:float32:2";
- public const string VertexUvw = "g3d:vertex:uv:0:float32:3";
- public const string VertexNormal = "g3d:vertex:normal:0:float32:3";
- public const string VertexColor = "g3d:vertex:color:0:float32:4";
- public const string VertexColor8Bit = "g3d:vertex:color:0:int8:4";
- public const string VertexBitangent = "g3d:vertex:bitangent:0:float32:3";
- public const string VertexTangent = "g3d:vertex:tangent:0:float32:4";
- public const string VertexSelectionWeight = "g3d:vertex:weight:0:float32:1";
- public const string FaceColor = "g3d:face:color:0:float32:4";
- public const string FaceMaterial = "g3d:face:material:0:int32:1";
- public const string FaceNormal = "g3d:face:normal:0:float32:3";
- public const string MeshSubmeshOffset = "g3d:mesh:submeshoffset:0:int32:1";
- public const string InstanceTransform = "g3d:instance:transform:0:float32:16";
- public const string InstanceParent = "g3d:instance:parent:0:int32:1";
- public const string InstanceMesh = "g3d:instance:mesh:0:int32:1";
- public const string InstanceFlags = "g3d:instance:flags:0:uint16:1";
- public const string LineTangentIn = "g3d:vertex:tangent:0:float32:3";
- public const string LineTangentOut = "g3d:vertex:tangent:1:float32:3";
- public const string ShapeVertex = "g3d:shapevertex:position:0:float32:3";
- public const string ShapeVertexOffset = "g3d:shape:vertexoffset:0:int32:1";
- public const string ShapeColor = "g3d:shape:color:0:float32:4";
- public const string ShapeWidth = "g3d:shape:width:0:float32:1";
- public const string MaterialColor = "g3d:material:color:0:float32:4";
- public const string MaterialGlossiness = "g3d:material:glossiness:0:float32:1";
- public const string MaterialSmoothness = "g3d:material:smoothness:0:float32:1";
- public const string SubmeshIndexOffset = "g3d:submesh:indexoffset:0:int32:1";
- public const string SubmeshMaterial = "g3d:submesh:material:0:int32:1";
- }
-
- public static class CommonAttributeExtensions
- {
-
- public static GeometryAttribute ToObjectFaceSizeAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.ObjectFaceSize, index);
- public static GeometryAttribute ToObjectFaceSizeAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.ObjectFaceSize);
- public static GeometryAttribute ToObjectFaceSizeAttribute(this int[] xs, int index) => xs.ToIArray().ToObjectFaceSizeAttribute(index);
- public static GeometryAttribute ToObjectFaceSizeAttribute(this int[] xs) => xs.ToIArray().ToObjectFaceSizeAttribute();
- public static GeometryAttribute GetAttributeObjectFaceSize(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.ObjectFaceSize);
- public static IArray GetAttributeDataObjectFaceSize(this IGeometryAttributes self) => self.GetAttributeObjectFaceSize()?.Data;
- public static GeometryAttribute ToIndexAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.Index, index);
- public static GeometryAttribute ToIndexAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.Index);
- public static GeometryAttribute ToIndexAttribute(this int[] xs, int index) => xs.ToIArray().ToIndexAttribute(index);
- public static GeometryAttribute ToIndexAttribute(this int[] xs) => xs.ToIArray().ToIndexAttribute();
- public static GeometryAttribute GetAttributeIndex(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.Index);
- public static IArray GetAttributeDataIndex(this IGeometryAttributes self) => self.GetAttributeIndex()?.Data;
- public static GeometryAttribute ToPositionAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.Position, index);
- public static GeometryAttribute ToPositionAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.Position);
- public static GeometryAttribute ToPositionAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToPositionAttribute(index);
- public static GeometryAttribute ToPositionAttribute(this Vector3[] xs) => xs.ToIArray().ToPositionAttribute();
- public static GeometryAttribute GetAttributePosition(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.Position);
- public static IArray GetAttributeDataPosition(this IGeometryAttributes self) => self.GetAttributePosition()?.Data;
- public static GeometryAttribute ToVertexUvAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexUv, index);
- public static GeometryAttribute ToVertexUvAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexUv);
- public static GeometryAttribute ToVertexUvAttribute(this Vector2[] xs, int index) => xs.ToIArray().ToVertexUvAttribute(index);
- public static GeometryAttribute ToVertexUvAttribute(this Vector2[] xs) => xs.ToIArray().ToVertexUvAttribute();
- public static GeometryAttribute GetAttributeVertexUv(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexUv);
- public static IArray GetAttributeDataVertexUv(this IGeometryAttributes self) => self.GetAttributeVertexUv()?.Data;
- public static GeometryAttribute ToVertexUvwAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexUvw, index);
- public static GeometryAttribute ToVertexUvwAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexUvw);
- public static GeometryAttribute ToVertexUvwAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToVertexUvwAttribute(index);
- public static GeometryAttribute ToVertexUvwAttribute(this Vector3[] xs) => xs.ToIArray().ToVertexUvwAttribute();
- public static GeometryAttribute GetAttributeVertexUvw(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexUvw);
- public static IArray GetAttributeDataVertexUvw(this IGeometryAttributes self) => self.GetAttributeVertexUvw()?.Data;
- public static GeometryAttribute ToVertexNormalAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexNormal, index);
- public static GeometryAttribute ToVertexNormalAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexNormal);
- public static GeometryAttribute ToVertexNormalAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToVertexNormalAttribute(index);
- public static GeometryAttribute ToVertexNormalAttribute(this Vector3[] xs) => xs.ToIArray().ToVertexNormalAttribute();
- public static GeometryAttribute GetAttributeVertexNormal(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexNormal);
- public static IArray GetAttributeDataVertexNormal(this IGeometryAttributes self) => self.GetAttributeVertexNormal()?.Data;
- public static GeometryAttribute ToVertexColorAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexColor, index);
- public static GeometryAttribute ToVertexColorAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexColor);
- public static GeometryAttribute ToVertexColorAttribute(this Vector4[] xs, int index) => xs.ToIArray().ToVertexColorAttribute(index);
- public static GeometryAttribute ToVertexColorAttribute(this Vector4[] xs) => xs.ToIArray().ToVertexColorAttribute();
- public static GeometryAttribute GetAttributeVertexColor(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexColor);
- public static IArray GetAttributeDataVertexColor(this IGeometryAttributes self) => self.GetAttributeVertexColor()?.Data;
- public static GeometryAttribute ToVertexColor8BitAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexColor8Bit, index);
- public static GeometryAttribute ToVertexColor8BitAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexColor8Bit);
- public static GeometryAttribute ToVertexColor8BitAttribute(this Byte4[] xs, int index) => xs.ToIArray().ToVertexColor8BitAttribute(index);
- public static GeometryAttribute ToVertexColor8BitAttribute(this Byte4[] xs) => xs.ToIArray().ToVertexColor8BitAttribute();
- public static GeometryAttribute GetAttributeVertexColor8Bit(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexColor8Bit);
- public static IArray GetAttributeDataVertexColor8Bit(this IGeometryAttributes self) => self.GetAttributeVertexColor8Bit()?.Data;
- public static GeometryAttribute ToVertexBitangentAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexBitangent, index);
- public static GeometryAttribute ToVertexBitangentAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexBitangent);
- public static GeometryAttribute ToVertexBitangentAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToVertexBitangentAttribute(index);
- public static GeometryAttribute ToVertexBitangentAttribute(this Vector3[] xs) => xs.ToIArray().ToVertexBitangentAttribute();
- public static GeometryAttribute GetAttributeVertexBitangent(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexBitangent);
- public static IArray GetAttributeDataVertexBitangent(this IGeometryAttributes self) => self.GetAttributeVertexBitangent()?.Data;
- public static GeometryAttribute ToVertexTangentAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexTangent, index);
- public static GeometryAttribute ToVertexTangentAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexTangent);
- public static GeometryAttribute ToVertexTangentAttribute(this Vector4[] xs, int index) => xs.ToIArray().ToVertexTangentAttribute(index);
- public static GeometryAttribute ToVertexTangentAttribute(this Vector4[] xs) => xs.ToIArray().ToVertexTangentAttribute();
- public static GeometryAttribute GetAttributeVertexTangent(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexTangent);
- public static IArray GetAttributeDataVertexTangent(this IGeometryAttributes self) => self.GetAttributeVertexTangent()?.Data;
- public static GeometryAttribute ToVertexSelectionWeightAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.VertexSelectionWeight, index);
- public static GeometryAttribute ToVertexSelectionWeightAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.VertexSelectionWeight);
- public static GeometryAttribute ToVertexSelectionWeightAttribute(this float[] xs, int index) => xs.ToIArray().ToVertexSelectionWeightAttribute(index);
- public static GeometryAttribute ToVertexSelectionWeightAttribute(this float[] xs) => xs.ToIArray().ToVertexSelectionWeightAttribute();
- public static GeometryAttribute GetAttributeVertexSelectionWeight(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.VertexSelectionWeight);
- public static IArray GetAttributeDataVertexSelectionWeight(this IGeometryAttributes self) => self.GetAttributeVertexSelectionWeight()?.Data;
- public static GeometryAttribute ToFaceColorAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.FaceColor, index);
- public static GeometryAttribute ToFaceColorAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.FaceColor);
- public static GeometryAttribute ToFaceColorAttribute(this Vector4[] xs, int index) => xs.ToIArray().ToFaceColorAttribute(index);
- public static GeometryAttribute ToFaceColorAttribute(this Vector4[] xs) => xs.ToIArray().ToFaceColorAttribute();
- public static GeometryAttribute GetAttributeFaceColor(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.FaceColor);
- public static IArray GetAttributeDataFaceColor(this IGeometryAttributes self) => self.GetAttributeFaceColor()?.Data;
- public static GeometryAttribute ToFaceMaterialAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.FaceMaterial, index);
- public static GeometryAttribute ToFaceMaterialAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.FaceMaterial);
- public static GeometryAttribute ToFaceMaterialAttribute(this int[] xs, int index) => xs.ToIArray().ToFaceMaterialAttribute(index);
- public static GeometryAttribute ToFaceMaterialAttribute(this int[] xs) => xs.ToIArray().ToFaceMaterialAttribute();
- public static GeometryAttribute GetAttributeFaceMaterial(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.FaceMaterial);
- public static IArray GetAttributeDataFaceMaterial(this IGeometryAttributes self) => self.GetAttributeFaceMaterial()?.Data;
- public static GeometryAttribute ToFaceNormalAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.FaceNormal, index);
- public static GeometryAttribute ToFaceNormalAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.FaceNormal);
- public static GeometryAttribute ToFaceNormalAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToFaceNormalAttribute(index);
- public static GeometryAttribute ToFaceNormalAttribute(this Vector3[] xs) => xs.ToIArray().ToFaceNormalAttribute();
- public static GeometryAttribute GetAttributeFaceNormal(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.FaceNormal);
- public static IArray GetAttributeDataFaceNormal(this IGeometryAttributes self) => self.GetAttributeFaceNormal()?.Data;
- public static GeometryAttribute ToMeshSubmeshOffsetAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.MeshSubmeshOffset, index);
- public static GeometryAttribute ToMeshSubmeshOffsetAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.MeshSubmeshOffset);
- public static GeometryAttribute ToMeshSubmeshOffsetAttribute(this int[] xs, int index) => xs.ToIArray().ToMeshSubmeshOffsetAttribute(index);
- public static GeometryAttribute ToMeshSubmeshOffsetAttribute(this int[] xs) => xs.ToIArray().ToMeshSubmeshOffsetAttribute();
- public static GeometryAttribute GetAttributeMeshSubmeshOffset(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.MeshSubmeshOffset);
- public static IArray GetAttributeDataMeshSubmeshOffset(this IGeometryAttributes self) => self.GetAttributeMeshSubmeshOffset()?.Data;
- public static GeometryAttribute ToInstanceTransformAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.InstanceTransform, index);
- public static GeometryAttribute ToInstanceTransformAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.InstanceTransform);
- public static GeometryAttribute ToInstanceTransformAttribute(this Matrix4x4[] xs, int index) => xs.ToIArray().ToInstanceTransformAttribute(index);
- public static GeometryAttribute ToInstanceTransformAttribute(this Matrix4x4[] xs) => xs.ToIArray().ToInstanceTransformAttribute();
- public static GeometryAttribute GetAttributeInstanceTransform(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.InstanceTransform);
- public static IArray GetAttributeDataInstanceTransform(this IGeometryAttributes self) => self.GetAttributeInstanceTransform()?.Data;
- public static GeometryAttribute ToInstanceParentAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.InstanceParent, index);
- public static GeometryAttribute ToInstanceParentAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.InstanceParent);
- public static GeometryAttribute ToInstanceParentAttribute(this int[] xs, int index) => xs.ToIArray().ToInstanceParentAttribute(index);
- public static GeometryAttribute ToInstanceParentAttribute(this int[] xs) => xs.ToIArray().ToInstanceParentAttribute();
- public static GeometryAttribute GetAttributeInstanceParent(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.InstanceParent);
- public static IArray GetAttributeDataInstanceParent(this IGeometryAttributes self) => self.GetAttributeInstanceParent()?.Data;
- public static GeometryAttribute ToInstanceMeshAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.InstanceMesh, index);
- public static GeometryAttribute ToInstanceMeshAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.InstanceMesh);
- public static GeometryAttribute ToInstanceMeshAttribute(this int[] xs, int index) => xs.ToIArray().ToInstanceMeshAttribute(index);
- public static GeometryAttribute ToInstanceMeshAttribute(this int[] xs) => xs.ToIArray().ToInstanceMeshAttribute();
- public static GeometryAttribute GetAttributeInstanceMesh(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.InstanceMesh);
- public static IArray GetAttributeDataInstanceMesh(this IGeometryAttributes self) => self.GetAttributeInstanceMesh()?.Data;
- public static GeometryAttribute ToInstanceFlagsAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.InstanceFlags, index);
- public static GeometryAttribute ToInstanceFlagsAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.InstanceFlags);
- public static GeometryAttribute ToInstanceFlagsAttribute(this ushort[] xs, int index) => xs.ToIArray().ToInstanceFlagsAttribute(index);
- public static GeometryAttribute ToInstanceFlagsAttribute(this ushort[] xs) => xs.ToIArray().ToInstanceFlagsAttribute();
- public static GeometryAttribute GetAttributeInstanceFlags(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.InstanceFlags);
- public static IArray GetAttributeDataInstanceFlags(this IGeometryAttributes self) => self.GetAttributeInstanceFlags()?.Data;
- public static GeometryAttribute ToLineTangentInAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.LineTangentIn, index);
- public static GeometryAttribute ToLineTangentInAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.LineTangentIn);
- public static GeometryAttribute ToLineTangentInAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToLineTangentInAttribute(index);
- public static GeometryAttribute ToLineTangentInAttribute(this Vector3[] xs) => xs.ToIArray().ToLineTangentInAttribute();
- public static GeometryAttribute GetAttributeLineTangentIn(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.LineTangentIn);
- public static IArray GetAttributeDataLineTangentIn(this IGeometryAttributes self) => self.GetAttributeLineTangentIn()?.Data;
- public static GeometryAttribute ToLineTangentOutAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.LineTangentOut, index);
- public static GeometryAttribute ToLineTangentOutAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.LineTangentOut);
- public static GeometryAttribute ToLineTangentOutAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToLineTangentOutAttribute(index);
- public static GeometryAttribute ToLineTangentOutAttribute(this Vector3[] xs) => xs.ToIArray().ToLineTangentOutAttribute();
- public static GeometryAttribute GetAttributeLineTangentOut(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.LineTangentOut);
- public static IArray GetAttributeDataLineTangentOut(this IGeometryAttributes self) => self.GetAttributeLineTangentOut()?.Data;
- public static GeometryAttribute ToShapeVertexAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.ShapeVertex, index);
- public static GeometryAttribute ToShapeVertexAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.ShapeVertex);
- public static GeometryAttribute ToShapeVertexAttribute(this Vector3[] xs, int index) => xs.ToIArray().ToShapeVertexAttribute(index);
- public static GeometryAttribute ToShapeVertexAttribute(this Vector3[] xs) => xs.ToIArray().ToShapeVertexAttribute();
- public static GeometryAttribute GetAttributeShapeVertex(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.ShapeVertex);
- public static IArray GetAttributeDataShapeVertex(this IGeometryAttributes self) => self.GetAttributeShapeVertex()?.Data;
- public static GeometryAttribute ToShapeVertexOffsetAttribute(this IArray