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 xs, int index) => xs.ToAttribute(CommonAttributes.ShapeVertexOffset, index); - public static GeometryAttribute ToShapeVertexOffsetAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.ShapeVertexOffset); - public static GeometryAttribute ToShapeVertexOffsetAttribute(this int[] xs, int index) => xs.ToIArray().ToShapeVertexOffsetAttribute(index); - public static GeometryAttribute ToShapeVertexOffsetAttribute(this int[] xs) => xs.ToIArray().ToShapeVertexOffsetAttribute(); - public static GeometryAttribute GetAttributeShapeVertexOffset(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.ShapeVertexOffset); - public static IArray GetAttributeDataShapeVertexOffset(this IGeometryAttributes self) => self.GetAttributeShapeVertexOffset()?.Data; - public static GeometryAttribute ToShapeColorAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.ShapeColor, index); - public static GeometryAttribute ToShapeColorAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.ShapeColor); - public static GeometryAttribute ToShapeColorAttribute(this Vector4[] xs, int index) => xs.ToIArray().ToShapeColorAttribute(index); - public static GeometryAttribute ToShapeColorAttribute(this Vector4[] xs) => xs.ToIArray().ToShapeColorAttribute(); - public static GeometryAttribute GetAttributeShapeColor(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.ShapeColor); - public static IArray GetAttributeDataShapeColor(this IGeometryAttributes self) => self.GetAttributeShapeColor()?.Data; - public static GeometryAttribute ToShapeWidthAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.ShapeWidth, index); - public static GeometryAttribute ToShapeWidthAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.ShapeWidth); - public static GeometryAttribute ToShapeWidthAttribute(this float[] xs, int index) => xs.ToIArray().ToShapeWidthAttribute(index); - public static GeometryAttribute ToShapeWidthAttribute(this float[] xs) => xs.ToIArray().ToShapeWidthAttribute(); - public static GeometryAttribute GetAttributeShapeWidth(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.ShapeWidth); - public static IArray GetAttributeDataShapeWidth(this IGeometryAttributes self) => self.GetAttributeShapeWidth()?.Data; - public static GeometryAttribute ToMaterialColorAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.MaterialColor, index); - public static GeometryAttribute ToMaterialColorAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.MaterialColor); - public static GeometryAttribute ToMaterialColorAttribute(this Vector4[] xs, int index) => xs.ToIArray().ToMaterialColorAttribute(index); - public static GeometryAttribute ToMaterialColorAttribute(this Vector4[] xs) => xs.ToIArray().ToMaterialColorAttribute(); - public static GeometryAttribute GetAttributeMaterialColor(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.MaterialColor); - public static IArray GetAttributeDataMaterialColor(this IGeometryAttributes self) => self.GetAttributeMaterialColor()?.Data; - public static GeometryAttribute ToMaterialGlossinessAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.MaterialGlossiness, index); - public static GeometryAttribute ToMaterialGlossinessAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.MaterialGlossiness); - public static GeometryAttribute ToMaterialGlossinessAttribute(this float[] xs, int index) => xs.ToIArray().ToMaterialGlossinessAttribute(index); - public static GeometryAttribute ToMaterialGlossinessAttribute(this float[] xs) => xs.ToIArray().ToMaterialGlossinessAttribute(); - public static GeometryAttribute GetAttributeMaterialGlossiness(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.MaterialGlossiness); - public static IArray GetAttributeDataMaterialGlossiness(this IGeometryAttributes self) => self.GetAttributeMaterialGlossiness()?.Data; - public static GeometryAttribute ToMaterialSmoothnessAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.MaterialSmoothness, index); - public static GeometryAttribute ToMaterialSmoothnessAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.MaterialSmoothness); - public static GeometryAttribute ToMaterialSmoothnessAttribute(this float[] xs, int index) => xs.ToIArray().ToMaterialSmoothnessAttribute(index); - public static GeometryAttribute ToMaterialSmoothnessAttribute(this float[] xs) => xs.ToIArray().ToMaterialSmoothnessAttribute(); - public static GeometryAttribute GetAttributeMaterialSmoothness(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.MaterialSmoothness); - public static IArray GetAttributeDataMaterialSmoothness(this IGeometryAttributes self) => self.GetAttributeMaterialSmoothness()?.Data; - public static GeometryAttribute ToSubmeshIndexOffsetAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.SubmeshIndexOffset, index); - public static GeometryAttribute ToSubmeshIndexOffsetAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.SubmeshIndexOffset); - public static GeometryAttribute ToSubmeshIndexOffsetAttribute(this int[] xs, int index) => xs.ToIArray().ToSubmeshIndexOffsetAttribute(index); - public static GeometryAttribute ToSubmeshIndexOffsetAttribute(this int[] xs) => xs.ToIArray().ToSubmeshIndexOffsetAttribute(); - public static GeometryAttribute GetAttributeSubmeshIndexOffset(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.SubmeshIndexOffset); - public static IArray GetAttributeDataSubmeshIndexOffset(this IGeometryAttributes self) => self.GetAttributeSubmeshIndexOffset()?.Data; - public static GeometryAttribute ToSubmeshMaterialAttribute(this IArray xs, int index) => xs.ToAttribute(CommonAttributes.SubmeshMaterial, index); - public static GeometryAttribute ToSubmeshMaterialAttribute(this IArray xs) => xs.ToAttribute(CommonAttributes.SubmeshMaterial); - public static GeometryAttribute ToSubmeshMaterialAttribute(this int[] xs, int index) => xs.ToIArray().ToSubmeshMaterialAttribute(index); - public static GeometryAttribute ToSubmeshMaterialAttribute(this int[] xs) => xs.ToIArray().ToSubmeshMaterialAttribute(); - public static GeometryAttribute GetAttributeSubmeshMaterial(this IGeometryAttributes self) => self.GetAttribute(CommonAttributes.SubmeshMaterial); - public static IArray GetAttributeDataSubmeshMaterial(this IGeometryAttributes self) => self.GetAttributeSubmeshMaterial()?.Data; - - } -} diff --git a/src/cs/g3d/Vim.G3d/CommonAttributes.tt b/src/cs/g3d/Vim.G3d/CommonAttributes.tt deleted file mode 100644 index fad9970c..00000000 --- a/src/cs/g3d/Vim.G3d/CommonAttributes.tt +++ /dev/null @@ -1,95 +0,0 @@ -<#@ template language="C#" #> -<#@ output extension=".cs" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> - -// AUTOGENERATED FILE: DO NOT EDIT -// This file is generated from CommonAttributeExtensions.tt - -<# -string[] namesDescriptorAndTypes = { - "ObjectFaceSize", "g3d:all:facesize:0:int32:1","int", - "Index", "g3d:corner:index:0:int32:1","int", - "Position", "g3d:vertex:position:0:float32:3","Vector3", - "VertexUv", "g3d:vertex:uv:0:float32:2","Vector2", - "VertexUvw", "g3d:vertex:uv:0:float32:3","Vector3", - "VertexNormal", "g3d:vertex:normal:0:float32:3","Vector3", - "VertexColor", "g3d:vertex:color:0:float32:4","Vector4", - "VertexColor8Bit", "g3d:vertex:color:0:int8:4","Byte4", - "VertexBitangent", "g3d:vertex:bitangent:0:float32:3","Vector3", - "VertexTangent", "g3d:vertex:tangent:0:float32:4","Vector4", - "VertexSelectionWeight", "g3d:vertex:weight:0:float32:1","float", - "FaceColor", "g3d:face:color:0:float32:4","Vector4", - "FaceMaterial", "g3d:face:material:0:int32:1","int", - "FaceNormal", "g3d:face:normal:0:float32:3","Vector3", - - "MeshSubmeshOffset", "g3d:mesh:submeshoffset:0:int32:1", "int", - - "InstanceTransform", "g3d:instance:transform:0:float32:16", "Matrix4x4", - "InstanceParent", "g3d:instance:parent:0:int32:1", "int", - "InstanceMesh", "g3d:instance:mesh:0:int32:1", "int", - "InstanceFlags", "g3d:instance:flags:0:uint16:1", "ushort", - - "LineTangentIn", "g3d:vertex:tangent:0:float32:3","Vector3", - "LineTangentOut", "g3d:vertex:tangent:1:float32:3","Vector3", - "ShapeVertex", "g3d:shapevertex:position:0:float32:3", "Vector3", // We're using a distinct "shapevertex" association here because the "vertex" association is coupled to mesh geometry (there is a lot of logic related to face remapping and merging). - "ShapeVertexOffset", "g3d:shape:vertexoffset:0:int32:1", "int", - "ShapeColor", "g3d:shape:color:0:float32:4", "Vector4", - "ShapeWidth", "g3d:shape:width:0:float32:1", "float", - - "MaterialColor", "g3d:material:color:0:float32:4","Vector4", - "MaterialGlossiness", "g3d:material:glossiness:0:float32:1","float", - "MaterialSmoothness", "g3d:material:smoothness:0:float32:1","float", - - "SubmeshIndexOffset", "g3d:submesh:indexoffset:0:int32:1","int", - "SubmeshMaterial", "g3d:submesh:material:0:int32:1","int", - -}; -#> - -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - public static class CommonAttributes - { - -<# - for (var i=0; i < namesDescriptorAndTypes.Length; i += 3) - { - var name = namesDescriptorAndTypes[i]; - var desc = namesDescriptorAndTypes[i + 1]; - var type = namesDescriptorAndTypes[i + 2]; -#> - public const string <#= name #> = "<#= desc #>"; -<# - } -#> - } - - public static class CommonAttributeExtensions - { - -<# - for (var i=0; i < namesDescriptorAndTypes.Length; i += 3) - { - var name = namesDescriptorAndTypes[i]; - var desc = namesDescriptorAndTypes[i + 1]; - var type = namesDescriptorAndTypes[i + 2]; - var codeName = "CommonAttributes." + name; -#> - public static GeometryAttribute<<#= type #>> To<#= name #>Attribute(this IArray<<#= type #>> xs, int index) => xs.ToAttribute(<#= codeName #>, index); - public static GeometryAttribute<<#= type #>> To<#= name #>Attribute(this IArray<<#= type #>> xs) => xs.ToAttribute(<#= codeName #>); - public static GeometryAttribute<<#= type #>> To<#= name #>Attribute(this <#= type #>[] xs, int index) => xs.ToIArray().To<#= name #>Attribute(index); - public static GeometryAttribute<<#= type #>> To<#= name #>Attribute(this <#= type #>[] xs) => xs.ToIArray().To<#= name #>Attribute(); - public static GeometryAttribute<<#= type #>> GetAttribute<#= name #>(this IGeometryAttributes self) => self.GetAttribute<<#= type #>>(<#= codeName #>); - public static IArray<<#= type #>> GetAttributeData<#= name #>(this IGeometryAttributes self) => self.GetAttribute<#= name #>()?.Data; -<# - } -#> - - } -} diff --git a/src/cs/g3d/Vim.G3d/Enums.cs b/src/cs/g3d/Vim.G3d/Enums.cs deleted file mode 100644 index a3e1db1f..00000000 --- a/src/cs/g3d/Vim.G3d/Enums.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; - -namespace Vim.G3d -{ - /// - /// The different types of data types that can be used as elements. - /// - public enum DataType - { - dt_uint8, - dt_int8, - dt_uint16, - dt_int16, - dt_uint32, - dt_int32, - dt_uint64, - dt_int64, - dt_float32, - dt_float64, - dt_string, - }; - - /// - /// What element or component of a mesh each attribute is associated with. - /// - public enum Association - { - assoc_all, // associated with all data in G3d - assoc_none, // no association - assoc_vertex, // vertex or point data - assoc_face, // face associated data - assoc_corner, // corner (aka face-vertex) data. A corner is associated with one vertex, but a vertex may be shared between multiple corners - assoc_edge, // half-edge data. Each face consists of n half-edges, one per corner. A half-edge, is a directed edge - assoc_instance, // instance information - assoc_shapevertex, // flattened shape vertex collection. - assoc_shape, // shape instance - assoc_material, // material properties - assoc_mesh, - assoc_submesh - } - - [Flags] - public enum InstanceFlags - { - /// - /// Default - no instance options defined. - /// - None = 0, - - /// - /// When enabled, indicates that the renderer (or the consuming application) should hide - /// the instance by default. - /// - Hidden = 1, - } - - /// - /// Common semantic names. - /// - public static class Semantic - { - public const string Position = "position"; - public const string Index = "index"; - public const string FaceSize = "facesize"; - public const string Uv = "uv"; - public const string Normal = "normal"; - public const string Color = "color"; - public const string Bitangent = "bitangent"; - public const string Tangent = "tangent"; - public const string Weight = "weight"; - public const string Width = "width"; - - // Usually associated with face. - public const string Material = "material"; - - // Usually associated with material. - public const string Glossiness = "glossiness"; - - public const string Smoothness = "smoothness"; - - // Usually associated with meshes and submeshes - public const string IndexOffset = "indexoffset"; - public const string VertexOffset = "vertexoffset"; - - // Usually associated with instances - public const string Subgeometry = "subgeometry"; - public const string Mesh = "mesh"; - public const string Parent = "parent"; - public const string Transform = "transform"; - public const string Flags = "flags"; - - public const string TangentInt = "tangentin"; - public const string TangentOut = "tangentout"; - - public const string SubMeshOffset = "submeshoffset"; - - } -} diff --git a/src/cs/g3d/Vim.G3d/G3D.cs b/src/cs/g3d/Vim.G3d/G3D.cs deleted file mode 100644 index 98aed23b..00000000 --- a/src/cs/g3d/Vim.G3d/G3D.cs +++ /dev/null @@ -1,314 +0,0 @@ -/* - G3D Geometry Format Library - Copyright 2019, VIMaec LLC. - Copyright 2018, Ara 3D Inc. - Usage licensed under terms of MIT License -*/ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - /// - /// Represents a basic single-precision G3D in memory, with access to common attributes. - /// The G3D format can be double precision, but this data structure won't provide access to all of the attributes. - /// In the case of G3D formats that are non-conformant to the expected semantics you can use GeometryAttributes. - /// This class is inspired heavily by the structure of FBX and Assimp. - /// - public class G3D : GeometryAttributes - { - public new static G3D Empty = Create(); - - public G3dHeader Header { get; } - - // These are the values of the most common attributes. Some are retrieved directly from data, others are computed on demand, or coerced. - - // Vertex buffer. Usually present. - public IArray Vertices { get; } - - // Index buffer (one index per corner, and per half-edge). Computed if absent. - public IArray Indices { get; } - - // Vertex associated data, provided or null - public List> AllVertexUvs { get; } = new List>(); - public List> AllVertexColors { get; } = new List>(); - public IArray VertexUvs => AllVertexUvs?.ElementAtOrDefault(0); - public IArray VertexColors => AllVertexColors?.ElementAtOrDefault(0); - public IArray VertexNormals { get; } - public IArray VertexTangents { get; } - - // Faces - public IArray FaceMaterials { get; } // Material indices per face, - public IArray FaceNormals { get; } // If not provided, are computed dynamically as the average of all vertex normals, - - // Meshes - public IArray MeshIndexOffsets { get; } // Offset into the index buffer for each Mesh - public IArray MeshVertexOffsets { get; } // Offset into the vertex buffer for each Mesh - public IArray MeshIndexCounts { get; } // Computed - public IArray MeshVertexCounts { get; } // Computed - public IArray MeshSubmeshOffset { get; } - public IArray MeshSubmeshCount { get; } // Computed - public IArray Meshes { get; } - - // Instances - public IArray InstanceParents { get; } // Index of the parent transform - public IArray InstanceTransforms { get; } // A 4x4 matrix in row-column order defining the transormed - public IArray InstanceMeshes { get; } // The SubGeometry associated with the index - public IArray InstanceFlags { get; } // The instance flags associated with the index. - - // Shapes - public IArray ShapeVertices { get; } - public IArray ShapeVertexOffsets { get; } - public IArray ShapeColors { get; } - public IArray ShapeWidths { get; } - public IArray ShapeVertexCounts { get; } // Computed - public IArray Shapes { get; } // Computed - - // Materials - public IArray MaterialColors { get; } // RGBA with transparency. - public IArray MaterialGlossiness { get; } - public IArray MaterialSmoothness { get; } - public IArray Materials { get; } - - - // Submeshes - public IArray SubmeshIndexOffsets { get; } - public IArray SubmeshIndexCount { get; } - public IArray SubmeshMaterials { get; } - - public G3D(IEnumerable attributes, G3dHeader? header = null, int numCornersPerFaceOverride = -1) - : base(attributes, numCornersPerFaceOverride) - { - Header = header ?? new G3dHeader(); - - foreach (var attr in Attributes.ToEnumerable()) - { - var desc = attr.Descriptor; - switch (desc.Semantic) - { - case Semantic.Index: - if (attr.IsTypeAndAssociation(Association.assoc_corner)) - Indices = Indices ?? attr.AsType().Data; - if (attr.IsTypeAndAssociation(Association.assoc_corner)) - Indices = Indices ?? attr.AsType().Data.Select(x => (int)x); - break; - - case Semantic.Position: - if (attr.IsTypeAndAssociation(Association.assoc_vertex)) - Vertices = Vertices ?? attr.AsType().Data; - if (attr.IsTypeAndAssociation(Association.assoc_corner)) - Vertices = Vertices ?? attr.AsType().Data; // TODO: is this used? - if (attr.IsTypeAndAssociation(Association.assoc_shapevertex)) - ShapeVertices = ShapeVertices ?? attr.AsType().Data; - break; - - case Semantic.Tangent: - if (attr.IsTypeAndAssociation(Association.assoc_vertex)) - VertexTangents = VertexTangents ?? attr.AsType().Data.Select(v => v.ToVector4()); - if (attr.IsTypeAndAssociation(Association.assoc_vertex)) - VertexTangents = VertexTangents ?? attr.AsType().Data; - break; - - case Semantic.Uv: - if (attr.IsTypeAndAssociation(Association.assoc_vertex)) - AllVertexUvs.Add(attr.AsType().Data.Select(uv => uv.ToVector2())); - if (attr.IsTypeAndAssociation(Association.assoc_vertex)) - AllVertexUvs.Add(attr.AsType().Data); - break; - - case Semantic.Color: - if (desc.Association == Association.assoc_vertex) - AllVertexColors.Add(attr.AttributeToColors()); - if (desc.Association == Association.assoc_shape) - ShapeColors = ShapeColors ?? attr.AttributeToColors(); - if (desc.Association == Association.assoc_material) - MaterialColors = MaterialColors ?? attr.AttributeToColors(); - break; - - case Semantic.VertexOffset: - if (attr.IsTypeAndAssociation(Association.assoc_mesh)) - MeshVertexOffsets = MeshVertexOffsets ?? attr.AsType().Data; - if (attr.IsTypeAndAssociation(Association.assoc_shape)) - ShapeVertexOffsets = ShapeVertexOffsets ?? attr.AsType().Data; - break; - - case Semantic.IndexOffset: - if (attr.IsTypeAndAssociation(Association.assoc_mesh)) - MeshIndexOffsets = MeshIndexOffsets ?? attr.AsType().Data; - if (attr.IsTypeAndAssociation(Association.assoc_submesh)) - SubmeshIndexOffsets = SubmeshIndexOffsets ?? attr.AsType().Data; - break; - - case Semantic.Normal: - if (attr.IsTypeAndAssociation(Association.assoc_face)) - FaceNormals = FaceNormals ?? attr.AsType().Data; - if (attr.IsTypeAndAssociation(Association.assoc_vertex)) - VertexNormals = VertexNormals ?? attr.AsType().Data; - break; - - case Semantic.Material: - if (attr.IsTypeAndAssociation(Association.assoc_face)) - FaceMaterials = FaceMaterials ?? attr.AsType().Data; - if (attr.IsTypeAndAssociation(Association.assoc_submesh)) - SubmeshMaterials = SubmeshMaterials ?? attr.AsType().Data; - break; - - case Semantic.Parent: - if (attr.IsTypeAndAssociation(Association.assoc_instance)) - InstanceParents = InstanceParents ?? attr.AsType().Data; - break; - - case Semantic.Mesh: - if (attr.IsTypeAndAssociation(Association.assoc_instance)) - InstanceMeshes = InstanceMeshes ?? attr.AsType().Data; - break; - - case Semantic.Transform: - if (attr.IsTypeAndAssociation(Association.assoc_instance)) - InstanceTransforms = InstanceTransforms ?? attr.AsType().Data; - break; - - case Semantic.Width: - if (attr.IsTypeAndAssociation(Association.assoc_shape)) - ShapeWidths = ShapeWidths ?? attr.AsType().Data; - break; - - case Semantic.Glossiness: - if (attr.IsTypeAndAssociation(Association.assoc_material)) - MaterialGlossiness = attr.AsType().Data; - break; - - case Semantic.Smoothness: - if (attr.IsTypeAndAssociation(Association.assoc_material)) - MaterialSmoothness = attr.AsType().Data; - break; - - case Semantic.SubMeshOffset: - if (attr.IsTypeAndAssociation(Association.assoc_mesh)) - MeshSubmeshOffset = attr.AsType().Data; - break; - - case Semantic.Flags: - if (attr.IsTypeAndAssociation(Association.assoc_instance)) - InstanceFlags = attr.AsType().Data; - break; - } - } - - // If no vertices are provided, we are going to generate a list of zero vertices. - if (Vertices == null) - Vertices = Vector3.Zero.Repeat(0); - - // If no indices are provided then we are going to have to treat the index buffer as indices - if (Indices == null) - Indices = Vertices.Indices(); - - // Compute face normals if possible - if (FaceNormals == null && VertexNormals != null) - FaceNormals = NumFaces.Select(ComputeFaceNormal); - - if (NumMeshes > 0) - { - // Mesh offset is the same as the offset of its first submesh. - if(MeshSubmeshOffset != null) - { - MeshIndexOffsets = MeshSubmeshOffset.Select(submesh => SubmeshIndexOffsets[submesh]); - MeshSubmeshCount = GetSubArrayCounts(MeshSubmeshOffset.Count, MeshSubmeshOffset, NumSubmeshes).Evaluate(); - } - - if(MeshIndexOffsets != null) - { - MeshIndexCounts = GetSubArrayCounts(NumMeshes, MeshIndexOffsets, NumCorners); - MeshVertexOffsets = MeshIndexOffsets - .Zip(MeshIndexCounts, (start, count) => (start, count)) - .Select(range => Indices.SubArray(range.start, range.count).Min()); - } - - if (MeshVertexOffsets != null) - MeshVertexCounts = GetSubArrayCounts(NumMeshes, MeshVertexOffsets, NumVertices); - } - else - { - MeshSubmeshCount = Array.Empty().ToIArray(); - } - - if (SubmeshIndexOffsets != null) - SubmeshIndexCount = GetSubArrayCounts(SubmeshIndexOffsets.Count, SubmeshIndexOffsets, NumCorners).Evaluate(); - - // Compute all meshes - Meshes = NumMeshes.Select(i => new G3dMesh(this, i)); - - if (MaterialColors != null) - Materials = MaterialColors.Count.Select(i => new G3dMaterial(this, i)); - - // Process the shape data - if (ShapeVertices == null) - ShapeVertices = Vector3.Zero.Repeat(0); - - if (ShapeVertexOffsets == null) - ShapeVertexOffsets = Array.Empty().ToIArray(); - - if (ShapeColors == null) - ShapeColors = Vector4.Zero.Repeat(0); - - if (ShapeWidths == null) - ShapeWidths = Array.Empty().ToIArray(); - - // Update the instance options - if (InstanceFlags == null) - InstanceFlags = ((ushort) 0).Repeat(NumInstances); - - ShapeVertexCounts = GetSubArrayCounts(NumShapes, ShapeVertexOffsets, ShapeVertices.Count); - ValidateSubArrayCounts(ShapeVertexCounts, nameof(ShapeVertexCounts)); - - Shapes = NumShapes.Select(i => new G3dShape(this, i)); - } - - private static IArray GetSubArrayCounts(int numItems, IArray offsets, int totalCount) - => numItems.Select(i => i < (numItems - 1) - ? offsets[i + 1] - offsets[i] - : totalCount - offsets[i]); - - private static void ValidateSubArrayCounts(IArray subArrayCounts, string memberName) - { - for (var i = 0; i < subArrayCounts.Count; ++i) - { - if (subArrayCounts[i] < 0) - throw new Exception($"{memberName}[{i}] is a negative sub array count."); - } - } - - public static Vector3 Average(IArray xs) - => xs.Aggregate(Vector3.Zero, (a, b) => a + b) / xs.Count; - - public Vector3 ComputeFaceNormal(int nFace) - => Average(NumCornersPerFace.Select(c => VertexNormals[nFace * NumCornersPerFace + c])); - - public static G3D Read(string filePath) - { - using (var stream = File.OpenRead(filePath)) - return stream.ReadG3d(); - } - - public static G3D Read(Stream stream) - => stream.ReadG3d(); - - public static G3D Read(byte[] bytes) - { - using (var stream = new MemoryStream(bytes)) - return stream.ReadG3d(); - } - - public static G3D Create(params GeometryAttribute[] attributes) - => new G3D(attributes); - - public static G3D Create(G3dHeader header, params GeometryAttribute[] attributes) - => new G3D(attributes, header); - } -} diff --git a/src/cs/g3d/Vim.G3d/G3DBuilder.cs b/src/cs/g3d/Vim.G3d/G3DBuilder.cs deleted file mode 100644 index 6d68cb99..00000000 --- a/src/cs/g3d/Vim.G3d/G3DBuilder.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - /// - /// This is a helper class for constructing a G3D from individual attributes - /// - public class G3DBuilder - { - public readonly List Attributes = new List(); - - public G3D ToG3D(G3dHeader? header = null) - => new G3D(Attributes, header ?? G3dHeader.Default); - - public G3DBuilder Add(GeometryAttribute attr) - { - Attributes.Add(attr); - return this; - } - - public G3DBuilder AddIndices(int[] indices) - => Add(indices.ToIndexAttribute()); - - public G3DBuilder AddIndices(IArray indices) - => Add(indices.ToIndexAttribute()); - - public G3DBuilder SetObjectFaceSize(int objectFaceSize) - => Add(new[] { objectFaceSize }.ToIArray().ToObjectFaceSizeAttribute()); - - public G3DBuilder AddVertices(IArray vertices) - => Add(vertices.ToPositionAttribute()); - - public IGeometryAttributes ToIGeometryAttributes() - => new GeometryAttributes(Attributes); - } -} - diff --git a/src/cs/g3d/Vim.G3d/G3dMaterial.cs b/src/cs/g3d/Vim.G3d/G3dMaterial.cs deleted file mode 100644 index 9dc3b5bf..00000000 --- a/src/cs/g3d/Vim.G3d/G3dMaterial.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Vim.Math3d; - -namespace Vim.G3d -{ - public class G3dMaterial - { - public readonly G3D G3d; - public readonly int Index; - - public G3dMaterial(G3D g3D, int index) - { - G3d = g3D; - Index = index; - } - - public Vector4 Color => G3d.MaterialColors[Index]; - public float Glossiness => G3d?.MaterialGlossiness[Index] ?? 0f; - public float Smoothness => G3d?.MaterialSmoothness[Index] ?? 0f; - } -} diff --git a/src/cs/g3d/Vim.G3d/G3dMesh.cs b/src/cs/g3d/Vim.G3d/G3dMesh.cs deleted file mode 100644 index 689122c5..00000000 --- a/src/cs/g3d/Vim.G3d/G3dMesh.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Generic; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - /// - /// A G3dMesh is a section of the G3D data that defines a mesh. - /// This does not implement IGeometryAttributes for performance reasons. - /// - public class G3dMesh - { - public G3D G3D { get; } - public int Index { get; } - - public int VertexOffset => G3D.MeshVertexOffsets[Index]; - public int NumVertices => G3D.MeshVertexCounts[Index]; - public int IndexOffset => G3D.MeshIndexOffsets[Index]; - public int NumCorners => G3D.MeshIndexCounts[Index]; - public int FaceOffset => IndexOffset / NumCornersPerFace; - public int NumFaces => NumCorners / NumCornersPerFace; - public int NumCornersPerFace => G3D.NumCornersPerFace; - - public G3dMesh(G3D parent, int index) - { - (G3D, Index) = (parent, index); - Vertices = G3D.Vertices?.SubArray(VertexOffset, NumVertices); - var offset = VertexOffset; - Indices = G3D.Indices?.SubArray(IndexOffset, NumCorners).Select(i => i - offset); - VertexUvs = G3D.VertexUvs?.SubArray(VertexOffset, NumVertices); - VertexNormals = G3D.VertexNormals?.SubArray(VertexOffset, NumVertices); - VertexColors = G3D.VertexColors?.SubArray(VertexOffset, NumVertices); - VertexTangents = G3D.VertexTangents?.SubArray(VertexOffset, NumVertices); - FaceNormals = G3D.FaceNormals?.SubArray(FaceOffset, NumFaces); - - // TODO: Remove need for this. - var submeshArray = (G3D.SubmeshIndexOffsets as ArrayAdapter).Array; - var submeshIndex = Array.BinarySearch(submeshArray, IndexOffset); - var submeshCount = 0; - for(var i = submeshIndex; i < submeshArray.Length; i++) - { - var indexOffset = submeshArray[i]; - if (indexOffset - IndexOffset >= NumCorners) - break; - submeshCount++; - } - SubmeshMaterials = G3D.SubmeshMaterials?.SubArray(submeshIndex, submeshCount); - SubmeshIndexOffsets = G3D.SubmeshIndexOffsets?.SubArray(submeshIndex, submeshCount).Select(i => i-IndexOffset); - MeshSubmeshOffset = new List() {0}.ToIArray(); - } - - // Vertex buffer. Usually present. - public IArray Vertices { get; } - - // Index buffer (one index per corner, and per half-edge) - public IArray Indices { get; } - - // Vertex associated data - public IArray VertexUvs { get; } - public IArray VertexNormals { get; } - public IArray VertexColors { get; } - public IArray VertexTangents { get; } - - // Face associated data. - public IArray FaceNormals { get; } - - public IArray SubmeshMaterials { get; } - public IArray SubmeshIndexOffsets { get; } - public IArray MeshSubmeshOffset { get; } - } -} diff --git a/src/cs/g3d/Vim.G3d/G3dSerialization.cs b/src/cs/g3d/Vim.G3d/G3dSerialization.cs deleted file mode 100644 index ba7e59a7..00000000 --- a/src/cs/g3d/Vim.G3d/G3dSerialization.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Vim.BFast; - -namespace Vim.G3d -{ - public static partial class G3DExtension - { - public static void WriteAttribute(Stream stream, GeometryAttribute attribute, string name, long size) - { - var buffer = attribute.ToBuffer(); - if (buffer.NumBytes() != size) - throw new Exception($"Internal error while writing attribute, expected number of bytes was {size} but instead was {buffer.NumBytes()}"); - if (buffer.Name != name) - throw new Exception($"Internal error while writing attribute, expected name was {name} but instead was {buffer.Name}"); - stream.Write(buffer); - } - - public static G3dWriter ToG3DWriter(this IGeometryAttributes self, G3dHeader? header = null) - => new G3dWriter(self, header); - - public static void Write(this IGeometryAttributes self, Stream stream, G3dHeader? header = null) - => self.ToG3DWriter(header).Write(stream); - - public static void Write(this IGeometryAttributes self, string filePath, G3dHeader? header = null) - { - using (var stream = File.OpenWrite(filePath)) - self.Write(stream, header); - } - - public static byte[] WriteToBytes(this IGeometryAttributes self) - { - using (var memoryStream = new MemoryStream()) - { - self.Write(memoryStream); - return memoryStream.ToArray(); - } - } - - public static bool TryReadHeader(Stream stream, long size, out G3dHeader outHeader) - { - var buffer = stream.ReadArray((int)size); - - if (buffer[0] == G3dHeader.MagicA && buffer[1] == G3dHeader.MagicB) - { - outHeader = G3dHeader.FromBytes(buffer); - return true; - } - else - { - outHeader = default; - return false; - } - } - - public static bool TryReadGeometryAttribute(Stream stream, string name, long size, out GeometryAttribute geometryAttribute) - { - geometryAttribute = null; - - bool ReadFailure() - { - // Update the seek head to consume the stream and return false. - stream.Seek((int)size, SeekOrigin.Current); - return false; - } - - if (!AttributeDescriptor.TryParse(name, out var attributeDescriptor)) - { - // Skip unknown attribute descriptors. - return ReadFailure(); - } - - // Populate a default attribute with the parsed attribute descriptor. - GeometryAttribute defaultAttribute; - try - { - defaultAttribute = attributeDescriptor.ToDefaultAttribute(0); - } - catch - { - // Eat the exception and return. - return ReadFailure(); - } - - // Success; consume the stream. - geometryAttribute = defaultAttribute.Read(stream, size); - return true; - } - - public static G3D ReadG3d(this Stream stream, Func renameFunc = null) - { - var header = G3dHeader.Default; - - GeometryAttribute ReadG3dSegment(Stream s2, string name, long size) - { - name = renameFunc?.Invoke(name) ?? name; - - // Check for the G3dHeader - if (name == "meta" && size == 8) - { - if (TryReadHeader(s2, size, out var outHeader)) - { - // Assign to the header variable in the closure. - header = outHeader; - } - - return null; - } - else - { - return TryReadGeometryAttribute(s2, name, size, out var geometryAttribute) - ? geometryAttribute - : null; - } - - } - - var results = stream.ReadBFast(ReadG3dSegment).Select(r => r.Item2); - return new G3D(results.Where(x => x != null), header); - } - } -} diff --git a/src/cs/g3d/Vim.G3d/G3dShape.cs b/src/cs/g3d/Vim.G3d/G3dShape.cs deleted file mode 100644 index 9cd220ad..00000000 --- a/src/cs/g3d/Vim.G3d/G3dShape.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - public class G3dShape - { - public readonly G3D G3D; - public readonly int Index; - public readonly IArray Vertices; - - public int ShapeVertexOffset => G3D.ShapeVertexOffsets[Index]; - public int NumVertices => G3D.ShapeVertexCounts[Index]; - public Vector4 Color => G3D.ShapeColors[Index]; - public float Width => G3D.ShapeWidths[Index]; - - public G3dShape(G3D parent, int index) - { - (G3D, Index) = (parent, index); - Vertices = G3D.ShapeVertices?.SubArray(ShapeVertexOffset, NumVertices); - } - } -} diff --git a/src/cs/g3d/Vim.G3d/G3dWriter.cs b/src/cs/g3d/Vim.G3d/G3dWriter.cs deleted file mode 100644 index 0d3a9ca8..00000000 --- a/src/cs/g3d/Vim.G3d/G3dWriter.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.IO; -using System.Linq; -using Vim.BFast; -using Vim.LinqArray; - -namespace Vim.G3d -{ - public static partial class G3DExtension - { - /// - /// This is a helper class for writing G3Ds - /// - public class G3dWriter : IBFastComponent - { - public INamedBuffer Meta { get; } - public string[] Names { get; } - public long[] Sizes { get; } - BFastHeader Header { get; } - IGeometryAttributes Attributes { get; } - - public G3dWriter(IGeometryAttributes g, G3dHeader? header = null) - { - Attributes = g; - Meta = (header ?? G3dHeader.Default).ToBytes().ToNamedBuffer("meta"); - Names = new[] { Meta.Name }.Concat(g.Attributes.ToEnumerable().Select(attr => attr.Name)).ToArray(); - Sizes = new[] { Meta.NumBytes() }.Concat(g.Attributes.ToEnumerable().Select(attr => attr.GetByteSize())).ToArray(); - Header = BFast.BFast.CreateBFastHeader(Sizes, Names); - } - - public long GetSize() - => Header.Preamble.DataEnd; - - public void Write(Stream stream) - { - stream.WriteBFastHeader(Header); - stream.WriteBFastBody(Header, Names, Sizes, (_stream, index, name, size) => - { - if (index == 0) - _stream.Write(Meta); - else - WriteAttribute(_stream, Attributes.Attributes[index - 1], name, size); - return size; - }); - } - } - } -} diff --git a/src/cs/g3d/Vim.G3d/GeometryAttribute.cs b/src/cs/g3d/Vim.G3d/GeometryAttribute.cs deleted file mode 100644 index 221a576e..00000000 --- a/src/cs/g3d/Vim.G3d/GeometryAttribute.cs +++ /dev/null @@ -1,226 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Vim.BFast; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - /// - /// A mesh attribute is an array of data associated with some component of a mesh. - /// It could be vertices, corners, faces, face groups, sub-meshes, instances or the entire mesh. - /// This is the base class of a typed MeshAttribute. - /// It provides two core operations we are the foundation for mesh manipulation: - /// 1. concatenation with like-typed attributes - /// 2. remapping - /// - public abstract class GeometryAttribute - { - /// - /// The descriptor contains information about the data contained in the attribute: - /// * the primitive data type - /// * the arity - /// * the association - /// * the semantic - /// - public AttributeDescriptor Descriptor { get; } - - /// - /// A "name" is a string encoding of the attribute descriptor. - /// - public string Name - => Descriptor.Name; - - /// - /// This is the number of data elements in the attribute. This is equal to - /// the number of primitives times the arity. All mesh attributes associated - /// with the same mesh component (e.g. vertices) must have the same element count. - /// - public int ElementCount { get; } - - /// - /// Constructor. - /// - protected GeometryAttribute(AttributeDescriptor descriptor, int count) - => (Descriptor, ElementCount) = (descriptor, count); - - /// - /// Multiple mesh attributes can be merged together if they have the same - /// underlying descriptor and data type. - /// - public abstract GeometryAttribute Merge(IEnumerable others); - - /// - /// A mesh attribute can be remapped, using the given indices. - /// - public abstract GeometryAttribute Remap(IArray indices); - - /// - /// Converted to an INamedBuffer which consists of a name and an array of unmanaged types. - /// - public abstract INamedBuffer ToBuffer(); - - /// - /// Convenience function to check if this object is a mesh attribute of the given type. - /// - public bool IsType() where T : unmanaged - => this is GeometryAttribute; - - /// - /// Convenience function to check if this object is a mesh attribute of the given type, and the association matches. - /// - public bool IsTypeAndAssociation(Association assoc) where T : unmanaged - => Descriptor.Association == assoc && this is GeometryAttribute; - - /// - /// Convenience function to cast this object into a mesh attribute of the given type, throwing an exception if not possible, - /// - public GeometryAttribute AsType() where T : unmanaged - => this as GeometryAttribute ?? throw new Exception($"The type of the attribute is {GetType()} not MeshAttribute<{typeof(T)}>"); - - /// - /// Loads the correct typed data from a Stream. - /// - public abstract GeometryAttribute Read(Stream stream, long byteCount); - - /// - /// Creates a new GeometryAttribute with the same data, but with a different index. Useful when constructing attributes - /// - public abstract GeometryAttribute SetIndex(int index); - } - - /// - /// This is a typed attribute associated with some part of the mesh. - /// The underlying data is an IArray which means that it can be - /// computed on demand. - /// - public class GeometryAttribute : GeometryAttribute where T : unmanaged - { - public IArray Data; - - public GeometryAttribute(IArray data, AttributeDescriptor descriptor) - : base(descriptor, data.Count) - { - Data = data; - int arity; - DataType dataType; - // TODO: TECH DEBT - Support unsigned tuples in Math3d - if (typeof(T) == typeof(byte)) - (arity, dataType) = (1, DataType.dt_uint8); - else if (typeof(T) == typeof(sbyte)) - (arity, dataType) = (1, DataType.dt_int8); - else if (typeof(T) == typeof(Byte2)) - (arity, dataType) = (2, DataType.dt_int8); - else if (typeof(T) == typeof(Byte3)) - (arity, dataType) = (3, DataType.dt_int8); - else if (typeof(T) == typeof(Byte4)) - (arity, dataType) = (4, DataType.dt_int8); - else if (typeof(T) == typeof(ushort)) - (arity, dataType) = (1, DataType.dt_uint16); - else if (typeof(T) == typeof(short)) - (arity, dataType) = (1, DataType.dt_int16); - else if (typeof(T) == typeof(uint)) - (arity, dataType) = (1, DataType.dt_uint32); - else if (typeof(T) == typeof(int)) - (arity, dataType) = (1, DataType.dt_int32); - else if (typeof(T) == typeof(Int2)) - (arity, dataType) = (2, DataType.dt_int32); - else if (typeof(T) == typeof(Int3)) - (arity, dataType) = (3, DataType.dt_int32); - else if (typeof(T) == typeof(Int4)) - (arity, dataType) = (4, DataType.dt_int32); - else if (typeof(T) == typeof(ulong)) - (arity, dataType) = (1, DataType.dt_uint64); - else if (typeof(T) == typeof(long)) - (arity, dataType) = (1, DataType.dt_int64); - else if (typeof(T) == typeof(float)) - (arity, dataType) = (1, DataType.dt_float32); - else if (typeof(T) == typeof(Vector2)) - (arity, dataType) = (2, DataType.dt_float32); - else if (typeof(T) == typeof(Vector3)) - (arity, dataType) = (3, DataType.dt_float32); - else if (typeof(T) == typeof(Vector4)) - (arity, dataType) = (4, DataType.dt_float32); - else if (typeof(T) == typeof(Matrix4x4)) - (arity, dataType) = (16, DataType.dt_float32); - else if (typeof(T) == typeof(double)) - (arity, dataType) = (1, DataType.dt_float64); - else if (typeof(T) == typeof(DVector2)) - (arity, dataType) = (2, DataType.dt_float64); - else if (typeof(T) == typeof(DVector3)) - (arity, dataType) = (3, DataType.dt_float64); - else if (typeof(T) == typeof(DVector4)) - (arity, dataType) = (4, DataType.dt_float64); - else - throw new Exception($"Unsupported data type {typeof(T)}"); - - // Check that the computed data type is consistent with the descriptor - if (dataType != Descriptor.DataType) - throw new Exception($"DataType was {dataType} but expected {Descriptor.DataType}"); - - // Check that the computed data arity is consistent with the descriptor - if (arity != Descriptor.DataArity) - throw new Exception($"DatArity was {arity} but expected {Descriptor.DataArity}"); - } - - public override GeometryAttribute Merge(IEnumerable others) - { - if (!others.Any()) - return this; - - // Check that all attributes have the same descriptor - if (!others.All(ma => ma.Descriptor.Equals(Descriptor))) - throw new Exception($"All attributes have to have same descriptor {Descriptor} to be concatenated"); - - // Check that all attributes have the same type - if (!others.All(ma => ma is GeometryAttribute)) - throw new Exception($"All attributes have to have the same type {typeof(T)} to be concatenated"); - - // Given multiple attributes associated with "all" or with "nothing", the first one takes precedence - if (Descriptor.Association == Association.assoc_all || Descriptor.Association == Association.assoc_none) - return this; - - // Sub-geometry attributes can't be merged - if (Descriptor.Association == Association.assoc_mesh) - throw new Exception("Can't merge sub-geometry attributes"); - - // Instance attributes can't be merged - if (Descriptor.Association == Association.assoc_instance) - throw new Exception("Can't merge instance attributes"); - - // Index attributes can't be merged - if (Descriptor.Semantic == Semantic.Index) - throw new Exception("Can't merge index attributes"); - - return others - .Select(ma => ma as GeometryAttribute) - .Prepend(this) - .ToIArray() - .Select(attr => attr.Data) - .Flatten() - .ToAttribute(Descriptor); - } - - public override GeometryAttribute Remap(IArray indices) - => Data.SelectByIndex(indices).ToAttribute(Descriptor); - - public override INamedBuffer ToBuffer() - => Data.ToArray().ToNamedBuffer(Name); - - public override GeometryAttribute Read(Stream stream, long byteCount) - { - if (byteCount % Descriptor.DataElementSize != 0) - throw new Exception($"The number of bytes to read {byteCount} does not divide cleanly by the size of the elements {Descriptor.DataElementSize}"); - var nElements = byteCount / Descriptor.DataElementSize; - if (nElements > int.MaxValue) - throw new Exception($"Trying to read {nElements} which is more than the maximum number of elements in a C# array"); - var data = stream.ReadArray((int)nElements); - return new GeometryAttribute(data.ToIArray(), Descriptor); - } - - public override GeometryAttribute SetIndex(int index) - => index == Descriptor.Index ? this : new GeometryAttribute(Data, Descriptor.SetIndex(index)); - } -} diff --git a/src/cs/g3d/Vim.G3d/GeometryAttributes.cs b/src/cs/g3d/Vim.G3d/GeometryAttributes.cs deleted file mode 100644 index ac799c07..00000000 --- a/src/cs/g3d/Vim.G3d/GeometryAttributes.cs +++ /dev/null @@ -1,164 +0,0 @@ -/* - G3D Geometry Format Library - Copyright 2019, VIMaec LLC. - Copyright 2018, Ara 3D Inc. - Usage licensed under terms of MIT License -*/ - -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.LinqArray; - -namespace Vim.G3d -{ - /// - /// This is the most generic representation of a G3D, which is a bag of attributes, and the observed size of each component. - /// - public class GeometryAttributes : IGeometryAttributes - { - public int NumCornersPerFace { get; } = -1; - - public int NumVertices { get; } = -1; - public int NumFaces { get; } = -1; - public int NumCorners { get; } = -1; - public int NumMeshes { get; } = -1; - public int NumInstances { get; } = -1; - public int NumMaterials { get; } = -1; - public int NumSubmeshes { get; } = -1; - - public int NumShapeVertices { get; } = -1; - public int NumShapes { get; } = -1; - - public IArray Attributes { get; } - - public GeometryAttribute GetAttribute(string name) - => Lookup.TryGetValue(name, out var val) ? val : null; - - public Dictionary Lookup - = new Dictionary(); - - public int ValidateAttribute(GeometryAttribute attr, int expectedCount) - { - if (expectedCount >= 0 && attr.ElementCount != expectedCount) - throw new Exception($"Attribute {attr.Descriptor.Name} size {attr.ElementCount} not match the expected size {expectedCount}"); - return attr.ElementCount; - } - - public GeometryAttributes(IEnumerable attributes, int numCornersPerFaceOverride = -1) - { - foreach (var attr in attributes) - { - if (attr != null && !Lookup.ContainsKey(attr.Name)) - Lookup.Add(attr.Name, attr); - } - - foreach (var attr in Lookup.Values) - { - var desc = attr.Descriptor; - - switch (desc.Association) - { - case Association.assoc_none: - break; - case Association.assoc_vertex: - NumVertices = ValidateAttribute(attr, NumVertices); - break; - case Association.assoc_edge: - case Association.assoc_corner: - NumCorners = ValidateAttribute(attr, NumCorners); - break; - case Association.assoc_face: - NumFaces = ValidateAttribute(attr, NumFaces); - break; - case Association.assoc_instance: - NumInstances = ValidateAttribute(attr, NumInstances); - break; - case Association.assoc_submesh: - NumSubmeshes = ValidateAttribute(attr, NumSubmeshes); - break; - case Association.assoc_material: - NumMaterials = ValidateAttribute(attr, NumMaterials); - break; - case Association.assoc_mesh: - NumMeshes = ValidateAttribute(attr, NumMeshes); - break; - case Association.assoc_shapevertex: - NumShapeVertices = ValidateAttribute(attr, NumShapeVertices); - break; - case Association.assoc_shape: - NumShapes = ValidateAttribute(attr, NumShapes); - break; - } - - if (desc.Semantic == Semantic.FaceSize) - { - if (desc.Association != Association.assoc_all) - throw new Exception($"The face size semantic has to be associated with entire geometry set, not {desc.Association}"); - if (desc.DataArity != 1) - throw new Exception($"The face size semantic has to have arity of 1, not {desc.DataArity}"); - - if (desc.DataType == DataType.dt_int8) - NumCornersPerFace = attr.AsType().Data[0]; - else if (desc.DataType == DataType.dt_int16) - NumCornersPerFace = attr.AsType().Data[0]; - else if (desc.DataType == DataType.dt_int32) - NumCornersPerFace = attr.AsType().Data[0]; - else - throw new Exception($"The face size semantic has to be an int8, int16, or int32"); - } - } - - if (NumVertices < 0) NumVertices = 0; - - // If the index attribute is missing we will have to add it. - if (!Lookup.ContainsKey(CommonAttributes.Index)) - { - if (NumCorners < 0) NumCorners = NumVertices; - Lookup.Add(CommonAttributes.Index, NumCorners.Range().ToIndexAttribute()); - } - - // Now we create the public ordered list of attributes - Attributes = Lookup.Values.OrderBy(attr => attr.Name).ToIArray(); - - - // If the number of corner and faces are observed, one has to be a multiple of the other - if (NumCorners > 0 && NumFaces > 0) - { - if (NumCorners % NumFaces != 0) - throw new Exception($"The number of corners {NumCorners} to be divisible by the number of faces {NumFaces}"); - } - - // Try to compute the number of corners per face - if (NumCornersPerFace < 0) - { - if (NumCorners > 0 && NumFaces > 0) - { - // We compute the number of corners per face by dividing the observed number of faces by the observed number of corners - NumCornersPerFace = NumCorners / NumFaces; - } - else - { - // By default we assume a triangular mesh - NumCornersPerFace = 3; - } - } - - if (numCornersPerFaceOverride >= 0) - { - NumCornersPerFace = numCornersPerFaceOverride; - } - - if (NumCorners < 0) NumCorners = NumVertices; - if (NumInstances < 0) NumInstances = 0; - if (NumMeshes < 0) NumMeshes = 0; - if (NumFaces < 0) NumFaces = NumCorners / NumCornersPerFace; - - if (NumShapeVertices < 0) NumShapeVertices = 0; - if (NumShapes < 0) NumShapes = 0; - } - - public static GeometryAttributes Empty - => new GeometryAttributes(new GeometryAttribute[] { }); - } -} diff --git a/src/cs/g3d/Vim.G3d/GeometryAttributesExtensions.cs b/src/cs/g3d/Vim.G3d/GeometryAttributesExtensions.cs deleted file mode 100644 index ba7c1cfa..00000000 --- a/src/cs/g3d/Vim.G3d/GeometryAttributesExtensions.cs +++ /dev/null @@ -1,520 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.G3d -{ - public static class GeometryAttributesExtensions - { - public static int ExpectedElementCount(this IGeometryAttributes self, AttributeDescriptor desc) - { - switch (desc.Association) - { - case Association.assoc_all: - return 1; - case Association.assoc_none: - return 0; - case Association.assoc_vertex: - return self.NumVertices; - case Association.assoc_face: - return self.NumFaces; - case Association.assoc_corner: - return self.NumCorners; - case Association.assoc_edge: - return self.NumCorners; - case Association.assoc_mesh: - return self.NumMeshes; - case Association.assoc_instance: - return self.NumInstances; - case Association.assoc_shapevertex: - return self.NumShapeVertices; - case Association.assoc_shape: - return self.NumShapes; - } - return -1; - } - - public static IArray AttributeNames(this IGeometryAttributes g) - => g.Attributes.Select(attr => attr.Name); - - public static GeometryAttribute GetAttribute(this IGeometryAttributes g, string attributeName) where T : unmanaged - => g.GetAttribute(attributeName)?.AsType(); - - public static GeometryAttribute DefaultAttribute(this IGeometryAttributes self, string name) - => self.DefaultAttribute(AttributeDescriptor.Parse(name)); - - public static GeometryAttribute DefaultAttribute(this IGeometryAttributes self, AttributeDescriptor desc) - => desc.ToDefaultAttribute(self.ExpectedElementCount(desc)); - - public static GeometryAttribute GetOrDefaultAttribute(this IGeometryAttributes self, AttributeDescriptor desc) - => self.GetAttribute(desc.ToString()) ?? desc.ToDefaultAttribute(self.ExpectedElementCount(desc)); - - public static IEnumerable NoneAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_none); - - public static IEnumerable CornerAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_corner); - - public static IEnumerable EdgeAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_edge); - - public static IEnumerable FaceAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_face); - - public static IEnumerable VertexAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_vertex); - - public static IEnumerable InstanceAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_instance); - - public static IEnumerable MeshAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_mesh); - - public static IEnumerable SubMeshAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_submesh); - - public static IEnumerable WholeGeometryAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_all); - - public static IEnumerable ShapeVertexAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_shapevertex); - - public static IEnumerable ShapeAttributes(this IGeometryAttributes g) - => g.Attributes.Where(a => a.Descriptor.Association == Association.assoc_shape); - - public static bool HasSameAttributes(this IGeometryAttributes g1, IGeometryAttributes g2) - => g1.Attributes.Count == g2.Attributes.Count && g1.Attributes.Indices().All(i => g1.Attributes[i].Name == g2.Attributes[i].Name); - - public static int FaceToCorner(this IGeometryAttributes g, int f) - => f * g.NumCornersPerFace; - - /// - /// Given a set of face indices, creates an array of corner indices - /// - public static IArray FaceIndicesToCornerIndices(this IGeometryAttributes g, IArray faceIndices) - => (faceIndices.Count * g.NumCornersPerFace) - .Select(i => g.FaceToCorner(faceIndices[i / g.NumCornersPerFace]) + i % g.NumCornersPerFace); - - /// - /// Given a set of face indices, creates an array of indices of the first corner in each face - /// - public static IArray FaceIndicesToFirstCornerIndices(this IGeometryAttributes g, IArray faceIndices) - => faceIndices.Select(f => f * g.NumCornersPerFace); - - public static int CornerToFace(this IGeometryAttributes g, int c) - => c / g.NumCornersPerFace; - - public static IArray CornersToFaces(this IGeometryAttributes g) - => g.NumCorners.Select(g.CornerToFace); - - public static int CornerNumber(this IGeometryAttributes g, int c) - => c % g.NumCornersPerFace; - - public static IGeometryAttributes ToGeometryAttributes(this IEnumerable attributes) - => new GeometryAttributes(attributes); - - public static IGeometryAttributes ToGeometryAttributes(this IArray attributes) - => attributes.ToEnumerable().ToGeometryAttributes(); - - public static IGeometryAttributes AddAttributes(this IGeometryAttributes attributes, params GeometryAttribute[] newAttributes) - => attributes.Attributes.ToEnumerable().Concat(newAttributes).ToGeometryAttributes(); - - public static GeometryAttribute GetAttributeOrDefault(this IGeometryAttributes g, string name) - => g.GetAttribute(name) ?? g.DefaultAttribute(name); - - public static IGeometryAttributes Merge(this IArray gs) - => gs.Select(x => (IGeometryAttributes)x).Merge(); - - public static IGeometryAttributes Merge(this IGeometryAttributes self, params IGeometryAttributes[] gs) - => gs.ToIArray().Prepend(self).Merge(); - - public static IGeometryAttributes Merge(this IArray geometryAttributesArray) - { - if (geometryAttributesArray.Count == 0) - return GeometryAttributes.Empty; - - var first = geometryAttributesArray[0]; - - if (geometryAttributesArray.Count == 1) - return first; - var corners = first.NumCornersPerFace; - if (!geometryAttributesArray.All(g => g.NumCornersPerFace == corners)) - throw new Exception("Cannot merge meshes with different numbers of corners per faces"); - - // Merge all of the attributes of the different geometries - // Except: indices, group indexes, subgeo, and instance attributes - var attributes = first.VertexAttributes() - .Concat(first.CornerAttributes()) - .Concat(first.EdgeAttributes()) - .Concat(first.NoneAttributes()) - .Concat(first.FaceAttributes()) - .Append(first.GetAttributeSubmeshMaterial()) - // Skip the index semantic because things get re-ordered - .Where(attr => attr != null && attr.Descriptor.Semantic != Semantic.Index) - .ToArray(); - - // Merge the non-indexed attributes - var others = geometryAttributesArray.Skip(1).ToEnumerable(); - var attributeList = attributes.Select( - attr => attr.Merge(others.Select(g => g.GetAttributeOrDefault(attr.Name)))).ToList(); - - // Merge the index attribute - // numVertices: [X], [Y], [Z], ... - // valueOffsets: [0], [X], [X+Y], ... - // indices: [A, B, C], [D, E, F], [G, H, I], ... - // mergedIndices: [A, B, C], [X+D, X+E, X+F], [X+Y+G, X+Y+H, X+Y+I], ... - var mergedIndexAttribute = geometryAttributesArray.MergeIndexedAttribute( - ga => ga.GetAttributeIndex(), - ga => ga.NumVertices) - ?.ToIndexAttribute(); - - if (mergedIndexAttribute != null) - attributeList.Add(mergedIndexAttribute); - - // Merge the submesh index offset attribute - // numCorners: [X], [Y], [Z], ... - // valueOffsets: [0] [X], [X+Y], ... - // submeshIndexOffsets: [0, A, B], [0, C, D], [0, E, F], ... - // mergedSubmeshIndexOffsets: [0, A, B], [X, X+C, X+D], [X+Y, X+Y+E, X+Y+F], ... - var mergedSubmeshIndexOffsetAttribute = geometryAttributesArray.MergeIndexedAttribute( - ga => ga.GetAttributeSubmeshIndexOffset(), - ga => ga.NumCorners) - ?.ToSubmeshIndexOffsetAttribute(); - - if (mergedSubmeshIndexOffsetAttribute != null) - attributeList.Add(mergedSubmeshIndexOffsetAttribute); - - return attributeList.ToGeometryAttributes(); - } - - /// - /// Merges the indexed attributes based on the given transformations and returns an array of integers - /// representing the merged and offset values. - /// - public static int[] MergeIndexedAttribute( - this IArray geometryAttributesArray, - Func> getIndexedAttributeFunc, - Func getValueOffsetFunc, - int initialValueOffset = 0) - { - var first = geometryAttributesArray.FirstOrDefault(); - if (first == null) - return null; - - var firstAttribute = getIndexedAttributeFunc(first); - if (firstAttribute == null) - return null; - - return geometryAttributesArray.MergeAttributes( - getIndexedAttributeFunc, - tuples => - { - var valueOffset = initialValueOffset; - var mergedCount = 0; - - var merged = new int[tuples.Sum(t => t.Attribute.Data.Count)]; - - foreach (var (parent, attr) in tuples) - { - var attrData = attr.Data; - var attrDataCount = attr.Data.Count; - - for (var i = 0; i < attrDataCount; ++i) - merged[mergedCount + i] = attrData[i] + valueOffset; - - mergedCount += attrDataCount; - valueOffset += getValueOffsetFunc(parent); - } - - return merged; - }); - } - - /// - /// Merges the attributes based on the given transformations and returns an array of merged values. - /// - public static T[] MergeAttributes( - this IArray geometryAttributesArray, - Func> getAttributeFunc, - Func<(IGeometryAttributes Parent, GeometryAttribute Attribute)[], T[]> mergeFunc) where T : unmanaged - { - var tuples = geometryAttributesArray - .Select(ga => (Parent: ga, GeometryAttribute: getAttributeFunc(ga))) - .Where(tuple => tuple.GeometryAttribute != null) - .ToArray(); - - if (tuples.Length != geometryAttributesArray.Count) - throw new Exception("The geometry attributes array do not all contain the same attribute"); - - return mergeFunc(tuples); - } - - /// - /// Applies a transformation function to position attributes and another to normal attributes. When deforming, we may want to - /// apply a similar deformation to the normals. For example a matrix can change the position, rotation, and scale of a geometry, - /// but the only changes should be to the direction of the normal, not the length. - /// - public static IGeometryAttributes Deform(this IGeometryAttributes g, Func positionTransform, Func normalTransform) - => g.Attributes.Select( - a => - (a.Descriptor.Semantic == Semantic.Position && a is GeometryAttribute p) ? p.Data.Select(positionTransform).ToAttribute(a.Descriptor) : - (a.Descriptor.Semantic == Semantic.Normal && a is GeometryAttribute n) ? n.Data.Select(normalTransform).ToAttribute(a.Descriptor) : - a) - .ToGeometryAttributes(); - - /// - /// Applies a deformation to points, without changing the normals. For some transformation functions this can result in incorrect normals. - /// - public static IGeometryAttributes Deform(this IGeometryAttributes g, Func positionTransform) - => g.Attributes.Select( - a => - (a.Descriptor.Semantic == Semantic.Position && a is GeometryAttribute p) ? p.Data.Select(positionTransform).ToAttribute(a.Descriptor) : - a) - .ToGeometryAttributes(); - - /// - /// Applies a transformation matrix - /// - public static IGeometryAttributes Transform(this IGeometryAttributes g, Matrix4x4 matrix) - => g.Deform(v => v.Transform(matrix), v => v.TransformNormal(matrix)); - - public static IGeometryAttributes SetPosition(this IGeometryAttributes g, IArray points) - => g.SetAttribute(points.ToPositionAttribute()); - - public static IGeometryAttributes SetAttribute(this IGeometryAttributes self, GeometryAttribute attr) - => self.Attributes.Where(a => !a.Descriptor.Equals(attr.Descriptor)).Append(attr).ToGeometryAttributes(); - - public static IGeometryAttributes SetAttribute(this IGeometryAttributes self, IArray values, AttributeDescriptor desc) where ValueT : unmanaged - => self.SetAttribute(values.ToAttribute(desc)); - - /// - /// Leaves the vertex buffer intact and creates a new geometry that remaps all of the group, corner, and face data. - /// The newFaces array is a list of indices into the old face array. - /// Note: meshes are lost. - /// - public static IGeometryAttributes RemapFaces(this IGeometryAttributes g, IArray faceRemap) - => g.RemapFacesAndCorners(faceRemap, g.FaceIndicesToCornerIndices(faceRemap)); - - public static IEnumerable SetFaceSizeAttribute(this IEnumerable attributes, int numCornersPerFaces) - => (numCornersPerFaces <= 0) - ? attributes - : attributes - .Where(attr => attr.Descriptor.Semantic != Semantic.FaceSize) - .Append(new[] { numCornersPerFaces }.ToObjectFaceSizeAttribute()); - - /// - /// Low-level remap function. Maps faces and corners at the same time. - /// In some cases, this is important (e.g. triangulating quads). - /// Note: meshes are lost. - /// - public static IGeometryAttributes RemapFacesAndCorners(this IGeometryAttributes g, IArray faceRemap, IArray cornerRemap, int numCornersPerFace = -1) - => g.VertexAttributes() - .Concat(g.NoneAttributes()) - .Concat(g.FaceAttributes().Select(attr => attr.Remap(faceRemap))) - .Concat(g.EdgeAttributes().Select(attr => attr.Remap(cornerRemap))) - .Concat(g.CornerAttributes().Select(attr => attr.Remap(cornerRemap))) - .Concat(g.WholeGeometryAttributes()) - .SetFaceSizeAttribute(numCornersPerFace) - .ToGeometryAttributes(); - - /// - /// Converts a quadrilateral mesh into a triangular mesh carrying over all attributes. - /// - public static IGeometryAttributes TriangulateQuadMesh(this IGeometryAttributes g) - { - if (g.NumCornersPerFace != 4) throw new Exception("Not a quad mesh"); - - var cornerRemap = new int[g.NumFaces * 6]; - var faceRemap = new int[g.NumFaces * 2]; - var cur = 0; - for (var i = 0; i < g.NumFaces; ++i) - { - cornerRemap[cur++] = i * 4 + 0; - cornerRemap[cur++] = i * 4 + 1; - cornerRemap[cur++] = i * 4 + 2; - cornerRemap[cur++] = i * 4 + 0; - cornerRemap[cur++] = i * 4 + 2; - cornerRemap[cur++] = i * 4 + 3; - - faceRemap[i * 2 + 0] = i; - faceRemap[i * 2 + 1] = i; - } - - return g.RemapFacesAndCorners(faceRemap.ToIArray(), cornerRemap.ToIArray(), 3); - } - - public static IGeometryAttributes CopyFaces(this IGeometryAttributes g, IArray keep) - => g.CopyFaces(i => keep[i]); - - public static IGeometryAttributes CopyFaces(this IGeometryAttributes g, IArray keep) - => g.RemapFaces(keep); - - public static IGeometryAttributes CopyFaces(this IGeometryAttributes self, Func predicate) - => self.RemapFaces(self.NumFaces.Select(i => i).IndicesWhere(predicate).ToIArray()); - - public static IGeometryAttributes DeleteFaces(this IGeometryAttributes g, Func predicate) - => g.CopyFaces(i => !predicate(i)); - - public static IGeometryAttributes CopyFaces(this IGeometryAttributes g, int from, int count) - => g.CopyFaces(i => i >= from && i < from + count); - - /// - /// Updates the vertex buffer (e.g. after identifying unwanted faces) and the index - /// buffer. Vertices are either re-ordered, removed, or deleted. Does not affect any other - /// - public static IGeometryAttributes RemapVertices(this IGeometryAttributes g, IArray newVertices, IArray newIndices) - => (new[] { newIndices.ToIndexAttribute() } - .Concat( - g.VertexAttributes() - .Select(attr => attr.Remap(newVertices))) - .Concat(g.NoneAttributes()) - .Concat(g.FaceAttributes()) - .Concat(g.EdgeAttributes()) - .Concat(g.CornerAttributes()) - .Concat(g.WholeGeometryAttributes()) - ) - .ToGeometryAttributes(); - - /// - /// The vertRemap is a list of vertices in the new vertex buffer, and where they came from. - /// This could be a reordering of the original vertex buffer, it could even be a repetition. - /// It could also be some vertices were deleted, BUT if those vertices are still referenced - /// then this will throw an exception. - /// The values in the index buffer will change, but it will stay the same length. - /// - public static IGeometryAttributes RemapVertices(this IGeometryAttributes g, IArray vertRemap) - { - var vertLookup = (-1).Repeat(g.NumVertices).ToArray(); - for (var i = 0; i < vertRemap.Count; ++i) - { - var oldVert = vertRemap[i]; - vertLookup[oldVert] = i; - } - - var oldIndices = g.GetAttributeIndex()?.Data ?? g.NumVertices.Range(); - var newIndices = oldIndices.Select(i => vertLookup[i]).Evaluate(); - - if (newIndices.Any(x => x == -1)) - throw new Exception("At least one of the indices references a vertex that no longer exists"); - - return g.RemapVertices(vertRemap, newIndices); - } - - /// - /// For mesh g, create a new mesh from the passed selected faces, - /// discarding un-referenced data and generating new index, vertex & face buffers. - /// - public static IGeometryAttributes SelectFaces(this IGeometryAttributes g, IArray faces) - { - // Early exit, if all selected no need to do anything - if (g.NumFaces == faces.Count) - return g; - - // Early exit, if none selected no need to do anything - if (faces.Count == 0) - return null; - - // First, get all the indices for this array of faces - var oldIndices = g.GetAttributeIndex(); - var oldSelIndices = new int[faces.Count * g.NumCornersPerFace]; - // var oldIndices = faces.SelectMany(f => f.Indices()); - for (var i = 0; i < faces.Count; i++) - { - for (var t = 0; t < 3; t++) - oldSelIndices[i * 3 + t] = oldIndices.Data[faces[i] * g.NumCornersPerFace + t]; - } - - // We need to create list of newIndices, and remapping - // of oldVertices to newVertices - var newIndices = (-1).Repeat(oldSelIndices.Length).ToArray(); - // Each index could potentially be in the new mesh - var indexLookup = (-1).Repeat(oldIndices.ElementCount).ToArray(); - - // Build mapping. For each index, if the vertex it has - // already been referred to has been mapped, use the - // mapped index. Otherwise, remember that we need this vertex - var numUsedVertices = 0; - // remapping from old vert array => new vert array - // Cache built of the old indices of vertices that are used - // should be equivalent to indexLookup.Where(i => i != -1) - var oldVertices = g.GetAttributePosition(); - var usedVertices = (-1).Repeat(oldVertices.ElementCount).ToArray(); - for (var i = 0; i < oldSelIndices.Length; ++i) - { - var oldIndex = oldSelIndices[i]; - var newIndex = indexLookup[oldIndex]; - if (newIndex < 0) - { - // remapping from old vert array => new vert array - usedVertices[numUsedVertices] = oldIndex; - newIndex = indexLookup[oldIndex] = numUsedVertices++; - } - newIndices[i] = newIndex; - } - - //var faceRemapping = faces.Select(f => f.Index); - var vertRemapping = usedVertices.Take(numUsedVertices).ToIArray(); - var cornerRemapping = g.FaceIndicesToCornerIndices(faces); - - return g.VertexAttributes() - .Select(attr => attr.Remap(vertRemapping)) - .Concat(g.NoneAttributes()) - .Concat(g.FaceAttributes().Select(attr => attr.Remap(faces))) - .Concat(g.EdgeAttributes().Select(attr => attr.Remap(cornerRemapping))) - .Concat(g.CornerAttributes().Select(attr => attr.Remap(cornerRemapping))) - .Concat(g.WholeGeometryAttributes()) - .ToGeometryAttributes() - .SetAttribute(newIndices.ToIndexAttribute()); - } - - public static G3D ToG3d(this IEnumerable attributes, G3dHeader? header = null) - => new G3D(attributes, header); - - public static G3D ToG3d(this IArray attributes, G3dHeader? header = null) - => attributes.ToEnumerable().ToG3d(header); - - public static IArray IndexFlippedRemapping(this IGeometryAttributes g) - => g.NumCorners.Select(c => ((c / g.NumCornersPerFace) + 1) * g.NumCornersPerFace - 1 - c % g.NumCornersPerFace); - - public static bool IsNormalAttribute(this GeometryAttribute attr) - => attr.IsType() && attr.Descriptor.Semantic == "normal"; - - public static IEnumerable FlipNormalAttributes(this IEnumerable self) - => self.Select(attr => attr.IsNormalAttribute() - ? attr.AsType().Data.Select(v => v.Inverse()).ToAttribute(attr.Descriptor) - : attr); - - public static IGeometryAttributes FlipWindingOrder(this IGeometryAttributes g) - => g.VertexAttributes() - .Concat(g.NoneAttributes()) - .Concat(g.FaceAttributes()) - .Concat(g.EdgeAttributes().Select(attr => attr.Remap(g.IndexFlippedRemapping()))) - .Concat(g.CornerAttributes().Select(attr => attr.Remap(g.IndexFlippedRemapping()))) - .Concat(g.WholeGeometryAttributes()) - .FlipNormalAttributes() - .ToGeometryAttributes(); - - public static IGeometryAttributes DoubleSided(this IGeometryAttributes g) - => g.Merge(g.FlipWindingOrder()); - - public static IArray DefaultMaterials(this IGeometryAttributes self) - => (-1).Repeat(self.NumFaces); - - public static IArray DefaultColors(this IGeometryAttributes self) - => Vector4.Zero.Repeat(self.NumVertices); - - public static IArray DefaultUvs(this IGeometryAttributes self) - => Vector2.Zero.Repeat(self.NumVertices); - - public static IGeometryAttributes Replace(this IGeometryAttributes self, Func selector, GeometryAttribute attribute) - => self.Attributes.Where(a => !selector(a.Descriptor)).Append(attribute).ToGeometryAttributes(); - - public static IGeometryAttributes Remove(this IGeometryAttributes self, Func selector) - => self.Attributes.Where(a => !selector(a.Descriptor)).ToGeometryAttributes(); - - public static G3D ToG3d(this IGeometryAttributes self) - => G3D.Create(self.Attributes.ToArray()); - } -} diff --git a/src/cs/g3d/Vim.G3d/Header.cs b/src/cs/g3d/Vim.G3d/Header.cs deleted file mode 100644 index c37140ce..00000000 --- a/src/cs/g3d/Vim.G3d/Header.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Text; - -namespace Vim.G3d -{ - // http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=files/GUID-CC93340E-C4A1-49EE-B048-E898F856CFBF.htm,topicNumber=d30e8478 - // https://twitter.com/FreyaHolmer/status/644881436982575104 - // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#coordinate-system-and-units - - // The header is 7 bytes + 1 bytes padding. - public struct G3dHeader - { - public const byte MagicA = 0x63; - public const byte MagicB = 0xD0; - - public byte magicA; // 0x63 - public byte magicB; // 0xD0 - public byte unitA; // with unitB could be: 'ft', 'yd', 'mi', 'km', 'mm', 'in', 'cm', 'm', - public byte unitB; - public byte upAxis; // e.g. 1=y or 2=z (could be 0=x, if you hate people) - public byte forwardVector; // e.g. 0=x, 1=y, 2=z, 3=-x, 4=-y, 5=-z - public byte handedness; // 0=left-handed, 1=right-handed - public byte padding; // 0 - - public string Unit => Encoding.ASCII.GetString(new byte[] { unitA, unitB }); - - public byte[] ToBytes() - => new[] { magicA, magicB, unitA, unitB, upAxis, forwardVector, handedness, padding }; - - public static G3dHeader FromBytes(byte[] bytes) - => new G3dHeader - { - magicA = bytes[0], - magicB = bytes[1], - unitA = bytes[2], - unitB = bytes[3], - upAxis = bytes[4], - forwardVector = bytes[5], - handedness = bytes[6], - } - .Validate(); - - public static G3dHeader Default - = new G3dHeader - { - magicA = 0x63, - magicB = 0xD0, - unitA = (byte)'m', - unitB = 0, - upAxis = 2, - forwardVector = 0, - handedness = 0, - padding = 0 - }; - - public static readonly string[] SupportedUnits = { "mm", "cm", "m\0", "km", "in", "ft", "yd", "mi" }; - - public G3dHeader Validate() - { - if (magicA != 0x63) throw new Exception($"First magic number must be 0x63 not {magicA}"); - if (magicB != 0xD0) throw new Exception($"Second magic number must be 0xD0 not {magicB}"); - if (Array.IndexOf(SupportedUnits, Unit) < 0) throw new Exception($"Unit {Unit} is not a supported unit: {string.Join(", ", SupportedUnits)}"); - if (upAxis < 0 || upAxis > 2) throw new Exception("Up axis must be 0(x), 1(y), or 2(z)"); - if (forwardVector < 0 || forwardVector > 5) throw new Exception("Front vector must be 0 (x), 1(y), 2(z), 3(-x), 4(-y), or 5(-z)"); - if (handedness < 0 || handedness > 1) throw new Exception("Handedness must be 0 (left) or 1 (right"); - return this; - } - } -} diff --git a/src/cs/g3d/Vim.G3d/IGeometryAttributes.cs b/src/cs/g3d/Vim.G3d/IGeometryAttributes.cs deleted file mode 100644 index e25da638..00000000 --- a/src/cs/g3d/Vim.G3d/IGeometryAttributes.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Vim.LinqArray; - -namespace Vim.G3d -{ - /// - /// This is a read-only collection of G3D attributes. - /// - public interface IGeometryAttributes - { - int NumCornersPerFace { get; } - int NumVertices { get; } - int NumCorners { get; } - int NumFaces { get; } - int NumInstances { get; } - int NumMeshes { get; } - int NumShapeVertices { get; } - int NumShapes { get; } - - IArray Attributes { get; } - GeometryAttribute GetAttribute(string name); - } -} diff --git a/src/cs/g3d/Vim.G3d/ObjExporter.cs b/src/cs/g3d/Vim.G3d/ObjExporter.cs deleted file mode 100644 index b76184dd..00000000 --- a/src/cs/g3d/Vim.G3d/ObjExporter.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using System.IO; -using Vim.LinqArray; - -namespace Vim.G3d -{ - /// - /// This is a simple ObjExporter for the purposes of testing. - /// - public static class ObjExporter - { - public static IEnumerable ObjLines(G3D g3d) - { - // Write the vertices - var vertices = g3d.Vertices; - var uvs = g3d.VertexUvs; - foreach (var v in vertices.ToEnumerable()) - yield return ($"v {v.X} {v.Y} {v.Z}"); - if (uvs != null) - { - for (var v = 0; v < uvs.Count; v++) - yield return ($"vt {uvs[v].X} {uvs[v].Y}"); - } - - var indices = g3d.Indices; - var sb = new StringBuilder(); - var i = 0; - var faceSize = g3d.NumCornersPerFace; - while (i < indices.Count) - { - sb.Append("f"); - - if (uvs == null) - { - for (var j = 0; j < faceSize; ++j) - { - var index = g3d.Indices[i++] + 1; - sb.Append(" ").Append(index); - } - } - else - { - for (var j = 0; j < faceSize; ++j) - { - var index = g3d.Indices[i++] + 1; - sb.Append(" ").Append(index).Append("/").Append(index); - } - } - - yield return sb.ToString(); - sb.Clear(); - } - } - - public static void WriteObj(this G3D g3d, string filePath) - => File.WriteAllLines(filePath, ObjLines(g3d)); - } -} diff --git a/src/cs/g3d/Vim.G3d/PlyExporter.cs b/src/cs/g3d/Vim.G3d/PlyExporter.cs deleted file mode 100644 index 1b2f3425..00000000 --- a/src/cs/g3d/Vim.G3d/PlyExporter.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using System.IO; -using Vim.Math3d; - -namespace Vim.G3d -{ - /// - /// A very simple .ply file exporter - /// - public static class PlyExporter - { - public static void WritePly(this G3D g, string filePath) - => File.WriteAllLines(filePath, PlyStrings(g)); - - public static IEnumerable PlyStrings(G3D g) - { - var vertices = g.Vertices; - var indices = g.Indices; - var colors = g.VertexColors; - - //Write the header - yield return "ply"; - yield return "format ascii 1.0"; - yield return "element vertex " + vertices.Count + ""; - yield return "property float x"; - yield return "property float y"; - yield return "property float z"; - if (colors != null) - { - yield return "property uint8 red"; - yield return "property uint8 green"; - yield return "property uint8 blue"; - } - yield return "element face " + g.NumFaces; - yield return "property list uint8 int32 vertex_index"; - yield return "end_header"; - - // Write the vertices - if (colors != null) - { - for (var i = 0; i < vertices.Count; i++) - { - var v = vertices[i]; - var c = (colors[i] * 255f).Clamp(Vector4.Zero, new Vector4(255, 255, 255, 255)); - - yield return - $"{v.X} {v.Y} {v.Z} {(byte)c.X} {(byte)c.Y} {(byte)c.Z}"; - } - } - else - { - for (var i = 0; i < vertices.Count; i++) - { - var v = vertices[i]; - yield return - $"{v.X} {v.Y} {v.Z}"; - } - } - - // Write the face indices - var index = 0; - var sb = new StringBuilder(); - var faceSize = g.NumCornersPerFace; - for (var i = 0; i < g.NumFaces; i++) - { - sb.Append(faceSize); - for (var j = 0; j < faceSize; j++) - { - sb.Append(" ").Append(indices[index++]); - } - - yield return sb.ToString(); - sb.Clear(); - } - } - } -} diff --git a/src/cs/g3d/Vim.G3d/README.md b/src/cs/g3d/Vim.G3d/README.md deleted file mode 100644 index fd8f0ebe..00000000 --- a/src/cs/g3d/Vim.G3d/README.md +++ /dev/null @@ -1,109 +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. - -BFAST is maintained by [VIMaec LLC](https://vimaec.com) and is licensed under the terms of the MIT License. - -# Format - -## BFAST Container - -The underlying binary layout of a G3D file conforms to the [BFAST serialization format](https://github.com/vimaec/bfast), 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. - -The first named buffer in the BFAST container is reserved for meta-information about the file encoded in JSON format. It has the name "meta". -Each subsequent buffer uses the attribute descriptor string as a name. - -## Meta-Information - -The first buffer of a G3D file is named "meta" and is represented by the G3D - -## Attributes - -G3D is organized as a collection of attribute buffers. Each attributes describe what part of the incoming geometry they are associated with: - -* point // vertex data -* corner // face-vertex data -* face // per polygon data -* edge // per half-edge data -* group // face group. Face groups are identified by a face data buffer -* SubGeometry // a contiguous section of the vertex-buffer, and index-buffer -* material // data associated with a material, materials are usually associated with groups, a -* instance // instance data, usually an instance has an index to a SubGeometry -* all // whole object data - for example face-size of 4 with whole object indicates a quad mesh -* none // no association - -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 Subgeometries) -* vertexoffset, // the offset into the vertex buffer (used only with Subgeometries) -* normal, // computed normal information (per face, group, corner, or vertex) -* binormal, // computed binormal information -* tangent, // computed tangent information -* material, // material index -* visibility, // visibility data (e.g. -* 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") - -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 -* float32 -* float64 - -The number of primitives per data element is called the "arity" and can be any integer value greater than zero. For example UV might have an arity of 2, while position data -frequently has an arity of 3. - -## 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. - -## 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. - -# 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/src/cs/g3d/Vim.G3d/Validation.cs b/src/cs/g3d/Vim.G3d/Validation.cs deleted file mode 100644 index b1fde949..00000000 --- a/src/cs/g3d/Vim.G3d/Validation.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System.Collections.Generic; -using Vim.LinqArray; - -namespace Vim.G3d -{ - public enum G3dErrors - { - NodesCountMismatch, - MaterialsCountMismatch, - IndicesInvalidCount, - IndicesOutOfRange, - - //Submeshes - SubmeshesCountMismatch, - SubmeshesIndesxOffsetInvalidIndex, - SubmeshesIndexOffsetOutOfRange, - SubmeshesNonPositive, - SubmeshesMaterialOutOfRange, - - //Meshes - MeshesSubmeshOffsetOutOfRange, - MeshesSubmeshCountNonPositive, - - // Instances - InstancesCountMismatch, - InstancesParentOutOfRange, - InstancesMeshOutOfRange, - } - - public static class Validation - { - public static IEnumerable Validate(G3D g3d) - { - var errors = new List(); - - void Validate(bool value, G3dErrors error) - { - if (!value) errors.Add(error); - } - - //Indices - Validate(g3d.Indices.Count % 3 == 0, G3dErrors.IndicesInvalidCount); - Validate(g3d.Indices.All(i => i >= 0 && i < g3d.NumVertices), G3dErrors.IndicesOutOfRange); - //Triangle should have 3 distinct vertices - //Assert.That(g3d.Indices.SubArrays(3).Select(face => face.ToEnumerable().Distinct().Count()).All(c => c == 3)); - - //Submeshes - Validate(g3d.NumSubmeshes >= g3d.NumMeshes, G3dErrors.SubmeshesCountMismatch); - Validate(g3d.NumSubmeshes == g3d.SubmeshMaterials.Count, G3dErrors.SubmeshesCountMismatch); - Validate(g3d.NumSubmeshes == g3d.SubmeshIndexOffsets.Count, G3dErrors.SubmeshesCountMismatch); - Validate(g3d.SubmeshIndexOffsets.All(i => i % 3 == 0), G3dErrors.SubmeshesIndesxOffsetInvalidIndex); - Validate(g3d.SubmeshIndexOffsets.All(i => i >= 0 && i < g3d.NumCorners), G3dErrors.SubmeshesIndexOffsetOutOfRange); - Validate(g3d.SubmeshIndexCount.All(i => i > 0), G3dErrors.SubmeshesNonPositive); - Validate(g3d.SubmeshMaterials.All(m => m < g3d.NumMaterials), G3dErrors.SubmeshesMaterialOutOfRange); - - //Mesh - Validate(g3d.MeshSubmeshOffset.All(i => i >= 0 && i < g3d.NumSubmeshes), G3dErrors.MeshesSubmeshOffsetOutOfRange); - Validate(g3d.MeshSubmeshCount.All(i => i > 0), G3dErrors.MeshesSubmeshCountNonPositive); - - //Instances - Validate(g3d.NumInstances == g3d.InstanceParents.Count, G3dErrors.InstancesCountMismatch); - Validate(g3d.NumInstances == g3d.InstanceMeshes.Count, G3dErrors.InstancesCountMismatch); - Validate(g3d.NumInstances == g3d.InstanceTransforms.Count, G3dErrors.InstancesCountMismatch); - Validate(g3d.NumInstances == g3d.InstanceFlags.Count, G3dErrors.InstancesCountMismatch); - Validate(g3d.InstanceParents.All(i => i < g3d.NumInstances), G3dErrors.InstancesParentOutOfRange); - Validate(g3d.InstanceMeshes.All(i => i < g3d.NumMeshes), G3dErrors.InstancesMeshOutOfRange); - - //Materials - Validate(g3d.NumMaterials == g3d.MaterialColors.Count, G3dErrors.MaterialsCountMismatch); - Validate(g3d.NumMaterials == g3d.MaterialGlossiness.Count, G3dErrors.MaterialsCountMismatch); - Validate(g3d.NumMaterials == g3d.MaterialSmoothness.Count, G3dErrors.MaterialsCountMismatch); - - return errors; - } - } -} diff --git a/src/cs/g3d/Vim.G3d/Vim.G3d.csproj b/src/cs/g3d/Vim.G3d/Vim.G3d.csproj deleted file mode 100644 index 7f4cdcb4..00000000 --- a/src/cs/g3d/Vim.G3d/Vim.G3d.csproj +++ /dev/null @@ -1,56 +0,0 @@ - - - - netstandard2.0 - true - 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. - true - true - snupkg - - - - true - - - - true - - - - - True - - - - - - - - - - - - - - CommonAttributes.tt - True - True - - - - - - CommonAttributes.cs - TextTemplatingFileGenerator - - - - - - - - - - diff --git a/src/cs/linqarray/Vim.LinqArray.Tests/LinqArrayTests.cs b/src/cs/linqarray/Vim.LinqArray.Tests/LinqArrayTests.cs deleted file mode 100644 index 4f85ca04..00000000 --- a/src/cs/linqarray/Vim.LinqArray.Tests/LinqArrayTests.cs +++ /dev/null @@ -1,72 +0,0 @@ -using NUnit.Framework; -using System; - -namespace Vim.LinqArray.Tests -{ - public class LinqArrayTests - { - public static int[] ArrayToTen = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - public static IArray RangeToTen = 10.Range(); - public static IArray BuildToTen = LinqArray.Build(0, x => x + 1, x => x < 10); - - public static object[] TensData = { ArrayToTen.ToIArray(), RangeToTen, BuildToTen }; - - [TestCaseSource(nameof(TensData))] - public void CheckTens(IArray tens) - { - Assert.IsTrue(tens.SequenceEquals(ArrayToTen.ToIArray())); - Assert.AreEqual(0, tens.First()); - Assert.AreEqual(9, tens.Last()); - Assert.AreEqual(45, tens.Aggregate(0, (a, b) => a + b)); - Assert.AreEqual(10, tens.Count); - Assert.AreEqual(5, tens[5]); - Assert.AreEqual(5, tens.ElementAt(5)); - - var ones = 1.Repeat(9); - var diffs = tens.ZipEachWithNext((x, y) => y - x); - Assert.IsTrue(ones.SequenceEquals(diffs)); - Assert.IsFalse(ones.SequenceEquals(tens)); - - var indices = tens.Indices(); - Assert.IsTrue(tens.SequenceEquals(indices)); - Assert.IsTrue(tens.SequenceEquals(tens.SelectByIndex(indices))); - Assert.IsTrue(tens.Reverse().SequenceEquals(tens.SelectByIndex(indices.Reverse()))); - - var sum = 0; - foreach (var x in tens.ToEnumerable()) - { - sum += x; - } - foreach (var x in tens.ToEnumerable()) - { - Console.WriteLine(x.ToString()); - } - Assert.AreEqual(45, sum); - Assert.AreEqual(0, tens.First()); - Assert.True(tens.All(x => x < 10)); - Assert.True(tens.Any(x => x < 5)); - Assert.AreEqual(5, tens.CountWhere(x => x % 2 == 0)); - Assert.AreEqual(0, tens.Reverse().Last()); - Assert.AreEqual(0, tens.Reverse().Reverse().First()); - var split = tens.Split(LinqArray.Create(3, 6)); - Assert.AreEqual(3, split.Count); - - var batch = tens.SubArrays(3); - Assert.AreEqual(4, batch.Count); - Assert.True(batch[0].SequenceEquals(LinqArray.Create(0, 1, 2))); - Assert.True(batch[3].SequenceEquals(LinqArray.Create(9))); - - var batch2 = tens.Take(9).SubArrays(3); - Assert.AreEqual(3, batch2.Count); - - var counts = split.Select(x => x.Count); - Assert.True(counts.SequenceEquals(LinqArray.Create(3, 3, 4))); - var indices2 = counts.Accumulate((x, y) => x + y); - Assert.True(indices2.SequenceEquals(LinqArray.Create(3, 6, 10))); - var indices3 = counts.PostAccumulate((x, y) => x + y); - Assert.True(indices3.SequenceEquals(LinqArray.Create(0, 3, 6, 10))); - var flattened = split.Flatten(); - Assert.True(flattened.SequenceEquals(tens)); - } - } -} diff --git a/src/cs/linqarray/Vim.LinqArray.Tests/Vim.LinqArray.Tests.csproj b/src/cs/linqarray/Vim.LinqArray.Tests/Vim.LinqArray.Tests.csproj deleted file mode 100644 index 015c702d..00000000 --- a/src/cs/linqarray/Vim.LinqArray.Tests/Vim.LinqArray.Tests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net8.0 - false - - - - - - - - - - - - - diff --git a/src/cs/linqarray/Vim.LinqArray/ILookup.cs b/src/cs/linqarray/Vim.LinqArray/ILookup.cs deleted file mode 100644 index 4bf6dc81..00000000 --- a/src/cs/linqarray/Vim.LinqArray/ILookup.cs +++ /dev/null @@ -1,78 +0,0 @@ -// MIT License - Copyright 2019 (C) VIMaec, LLC. -// MIT License - Copyright 2018 (C) Ara 3D, Inc. -// This file is subject to the terms and conditions defined in -// file 'LICENSE.txt', which is part of this source code package. - -using System.Collections.Generic; -using System.Linq; - -namespace Vim.LinqArray -{ - /// - /// Lookup table: mapping from a key to some value. - /// - public interface ILookup - { - IArray Keys { get; } - IArray Values { get; } - bool Contains(TKey key); - TValue this[TKey key] { get; } - } - - public class EmptyLookup : ILookup - { - public IArray Keys => LinqArray.Empty(); - public IArray Values => LinqArray.Empty(); - public bool Contains(TKey key) => false; - public TValue this[TKey key] => default; - } - - public class LookupFromDictionary : ILookup - { - public IDictionary Dictionary; - private TValue _default; - - public LookupFromDictionary(IDictionary d = null, TValue defaultValue = default) - { - Dictionary = d ?? new Dictionary(); - // TODO: sort? - _default = defaultValue; - Keys = d.Keys.ToIArray(); - Values = d.Values.ToIArray(); - } - - public IArray Keys { get; } - public IArray Values { get; } - public TValue this[TKey key] => Contains(key) ? Dictionary[key] : _default; - public bool Contains(TKey key) => Dictionary.ContainsKey(key); - } - - public class LookupFromArray : ILookup - { - private IArray array; - - public LookupFromArray(IArray xs) - { - array = xs; - Keys = array.Indices(); - Values = array; - } - - public IArray Keys { get; } - public IArray Values { get; } - public TValue this[int key] => array[key]; - public bool Contains(int key) => key >= 0 && key <= array.Count; - } - - public static class LookupExtensions - { - public static ILookup ToLookup(this IDictionary d, TValue defaultValue = default) - => new LookupFromDictionary(d, defaultValue); - - public static TValue GetOrDefault(this ILookup lookup, TKey key) - => lookup.Contains(key) ? lookup[key] : default; - - public static IEnumerable GetValues(this ILookup lookup) - => lookup.Keys.ToEnumerable().Select(k => lookup[k]); - } -} diff --git a/src/cs/linqarray/Vim.LinqArray/LinqArray.cs b/src/cs/linqarray/Vim.LinqArray/LinqArray.cs deleted file mode 100644 index 92cc3b45..00000000 --- a/src/cs/linqarray/Vim.LinqArray/LinqArray.cs +++ /dev/null @@ -1,1016 +0,0 @@ -// MIT License - Copyright 2019 (C) VIMaec, LLC. -// MIT License - Copyright (C) Ara 3D, Inc. -// This file is subject to the terms and conditions defined in -// file 'LICENSE.txt', which is part of this source code package. -// -// LinqArray.cs -// A library for working with pure functional arrays, using LINQ style extension functions. -// Based on code that originally appeared in https://www.codeproject.com/Articles/140138/Immutable-Array-for-NET - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Vim.LinqArray -{ - /// - /// Represents an immutable array with expected O(1) complexity when - /// retrieving the number of items. - /// - public interface IArray - { - int Count { get; } - } - - /// - /// Represents an immutable array with expected O(1) complexity when - /// retrieving the number of items and random element access. - /// - public interface IArray : IArray - { - T this[int n] { get; } - } - - /// - /// Implements an IArray via a function and a count. - /// - public class FunctionalArray : IArray - { - public readonly Func Function; - - public int Count - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - } - - public T this[int n] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Function(n); - } - public FunctionalArray(int count, Func function) - => (Count, Function) = (count, function); - } - - /// - /// Implements an IArray from a System.Array. - /// - public class ArrayAdapter : IArray - { - public readonly T[] Array; - - public int Count - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - } - - public T this[int n] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Array[n]; - } - public ArrayAdapter(T[] xs) { Count = xs.Length; Array = xs; } - } - - /// - /// Extension functions for working on any object implementing IArray. This overrides - /// many of the Linq functions providing better performance. - /// - public static class LinqArray - { - /// - /// Helper function for creating an IArray from the arguments. - /// - public static IArray Create(params T[] self) - => self.ToIArray(); - - /// - /// A helper function to enable IArray to support IEnumerable - /// - public static IEnumerable ToEnumerable(this IArray self) - => Enumerable.Range(0, self.Count).Select(self.ElementAt); - - public static IArray ForEach(this IArray xs, Action f) - { - for (var i = 0; i < xs.Count; ++i) - f(xs[i]); - return xs; - } - - /// - /// Creates an IArray with the given number of items, - /// and uses the function to return items. - /// - public static IArray Select(this int count, Func f) - => new FunctionalArray(count, f); - - /// - /// Converts any implementation of IList (e.g. Array/List) to an IArray. - /// - public static IArray ToIArray(this IList self) - => self.Count.Select(i => self[i]); - - /// - /// Converts any implementation of IList (e.g. Array/List) to an IArray. - /// - public static IArray ToIArray(this T[] self) - => new ArrayAdapter(self); - - /// - /// Converts any implementation of IEnumerable to an IArray - /// - public static IArray ToIArray(this IEnumerable self) - => self is IList xs ? xs.ToIArray() : self.ToArray().ToIArray(); - - /// - /// Creates an IArray by repeating the given item a number of times. - /// - public static IArray Repeat(this T self, int count) - => Select(count, i => self); - - /// - /// Creates an IArray by repeating each item in the source a number of times. - /// - public static IArray RepeatElements(this IArray self, int count) - => Select(count, i => self[i / count]); - - /// - /// Creates an IArray starting with a seed value, and applying a function - /// to each individual member of the array. This is eagerly evaluated. - /// - public static IArray Generate(this T init, int count, Func f) - { - var r = new T[count]; - for (var i = 0; i < count; ++i) - { - r[i] = init; - init = f(init); - } - return r.ToIArray(); - } - - /// - /// Creates an IArray of integers from zero up to one less than the given number. - /// - public static IArray Range(this int self) - => Select(self, i => i); - - /// - /// Returns the first item in the array. - /// - public static T First(this IArray self, T @default = default) - => self.IsEmpty() ? @default : self[0]; - - /// - /// Returns the last item in the array - /// - public static T Last(this IArray self, T @default = default) - => self.IsEmpty() ? @default : self[self.Count - 1]; - - /// - /// Returns true if and only if the argument is a valid index into the array. - /// - public static bool InRange(this IArray self, int n) - => n >= 0 && n < self.Count; - - /// - /// A mnemonic for "Any()" that returns false if the count is greater than zero - /// - public static bool IsEmpty(this IArray self) - => !self.Any(); - - /// - /// Returns true if there are any elements in the array. - /// - public static bool Any(this IArray self) - => self.Count != 0; - - /// - /// Converts the IArray into a system array. - /// - public static T[] ToArray(this IArray self) - => self.CopyTo(new T[self.Count]); - - /// - /// Converts the IArray into a system List. - /// - public static List ToList(this IArray self) - => self.ToEnumerable().ToList(); - - /// - /// Converts the array into a function that returns values from an integer, returning a default value if out of range. - /// - public static Func ToFunction(this IArray self, T def = default) - => i => self.InRange(i) ? self[i] : def; - - /// - /// Converts the array into a predicate (a function that returns true or false) based on the truth of the given value. - /// - public static Func ToPredicate(this IArray self) - => self.ToFunction(); - - /// - /// Adds all elements of the array to the target collection. - /// - public static U AddTo(this IArray self, U other) where U : ICollection - { - self.ForEach(other.Add); - return other; - } - - /// - /// Copies all elements of the array to the target list or array, starting at the provided index. - /// - public static U CopyTo(this IArray self, U other, int destIndex = 0) where U : IList - { - for (var i = 0; i < self.Count; ++i) - other[i + destIndex] = self[i]; - return other; - } - - /// - /// Returns an array generated by applying a function to each element. - /// - public static IArray Select(this IArray self, Func f) - => Select(self.Count, i => f(self[i])); - - /// - /// Returns an array generated by applying a function to each element. - /// - public static IArray Select(this IArray self, Func f) - => Select(self.Count, i => f(self[i], i)); - - /// - /// Returns an array generated by applying a function to each element. - /// - public static IArray SelectIndices(this IArray self, Func f) - => self.Count.Select(f); - - /// - /// Converts an array of array into a flattened array. Each array is assumed to be of size n. - /// - public static IArray Flatten(this IArray> self, int n) - => Select(self.Count * n, i => self[i / n][i % n]); - - /// - /// Converts an array of array into a flattened array. - /// - public static IArray Flatten(this IArray> self) - { - var counts = self.Select(x => x.Count).PostAccumulate((x, y) => x + y); - var r = new T[counts.Last()]; - var i = 0; - foreach (var xs in self.ToEnumerable()) - xs.CopyTo(r, counts[i++]); - return r.ToIArray(); - } - - /// - /// Returns an array of tuple where each element of the initial array is paired with its index. - /// - public static IArray<(T value, int index)> ZipWithIndex(this IArray self) - => self.Select((v, i) => (v, i)); - - /// - /// Returns an array from an array of arrays, where the number of sub-elements is the same for reach array and is known. - /// - public static IArray SelectMany(this IArray> self, int count) - => Select(self.Count, i => self[i / count][i % count]); - - /// - /// Returns an array given a function that generates an IArray from each member. Eager evaluation. - /// - public static IArray SelectMany(this IArray self, Func> func) - { - var xs = new List(); - for (var i = 0; i < self.Count; ++i) - func(self[i]).AddTo(xs); - return xs.ToIArray(); - } - - /// - /// Returns an array given a function that generates an IArray from each member. Eager evaluation. - /// - public static IArray SelectMany(this IArray self, Func> func) - { - var xs = new List(); - for (var i = 0; i < self.Count; ++i) - func(self[i], i).AddTo(xs); - return xs.ToIArray(); - } - - /// - /// Returns an array given a function that generates a tuple from each member. Eager evaluation. - /// - public static IArray SelectMany(this IArray self, Func> func) - { - var r = new U[self.Count * 2]; - for (var i = 0; i < self.Count; ++i) - { - var tmp = func(self[i]); - r[i * 2] = tmp.Item1; - r[i * 2 + 1] = tmp.Item2; - } - - return r.ToIArray(); - } - - /// - /// Returns an array given a function that generates a tuple from each member. Eager evaluation. - /// - public static IArray SelectMany(this IArray self, Func> func) - { - var r = new U[self.Count * 3]; - for (var i = 0; i < self.Count; ++i) - { - var tmp = func(self[i]); - r[i * 3] = tmp.Item1; - r[i * 3 + 1] = tmp.Item2; - r[i * 3 + 2] = tmp.Item3; - } - return r.ToIArray(); - } - - /// - /// Returns an array given a function that generates a tuple from each member. Eager evaluation. - /// - public static IArray SelectMany(this IArray self, Func> func) - { - var r = new U[self.Count * 4]; - for (var i = 0; i < self.Count; ++i) - { - var tmp = func(self[i]); - r[i * 4] = tmp.Item1; - r[i * 4 + 1] = tmp.Item2; - r[i * 4 + 2] = tmp.Item3; - r[i * 4 + 3] = tmp.Item4; - } - return r.ToIArray(); - } - - /// - /// Returns an array generated by applying a function to corresponding pairs of elements in both arrays. - /// - public static IArray Zip(this IArray self, IArray other, Func f) - => Select(Math.Min(self.Count, other.Count), i => f(self[i], other[i])); - - /// - /// Returns an array generated by applying a function to corresponding pairs of elements in both arrays. - /// - public static IArray Zip(this IArray self, IArray other, Func f) - => Select(Math.Min(self.Count, other.Count), i => f(self[i], other[i], i)); - - /// - /// Returns an array generated by applying a function to corresponding pairs of elements in both arrays. - /// - public static IArray Zip(this IArray self, IArray other, IArray other2, Func f) - => Select(Math.Min(Math.Min(self.Count, other.Count), other2.Count), i => f(self[i], other[i], other2[i])); - - /// - /// Returns an array generated by applying a function to corresponding pairs of elements in both arrays. - /// - public static IArray Zip(this IArray self, IArray other, IArray other2, Func f) - => Select(Math.Min(Math.Min(self.Count, other.Count), other2.Count), i => f(self[i], other[i], other2[i], i)); - - /// - /// Returns an array generated by applying a function to corresponding pairs of elements in both arrays. - /// - public static IArray Zip(this IArray self, IArray other, IArray other2, IArray other3, Func f) - => Select(Math.Min(Math.Min(self.Count, other.Count), Math.Min(other2.Count, other3.Count)), i => f(self[i], other[i], other2[i], other3[i])); - - /// - /// Returns an array generated by applying a function to corresponding pairs of elements in both arrays. - /// - public static IArray Zip(this IArray self, IArray other, IArray other2, IArray other3, Func f) - => Select(Math.Min(Math.Min(self.Count, other.Count), Math.Min(other2.Count, other3.Count)), i => f(self[i], other[i], other2[i], other3[i], i)); - - /// - /// Applies a function to each element in the list paired with the next one. - /// Used to implement adjacent differences for example. - /// - public static IArray ZipEachWithNext(this IArray self, Func f) - => self.Zip(self.Skip(), f); - - /// - /// Returns an IEnumerable containing only elements of the array for which the function returns true on the index. - /// An IArray is not created automatically because it is an expensive operation that is potentially unneeded. - /// - public static IEnumerable WhereIndices(this IArray self, Func f) - => self.Where((x, i) => f(i)); - - /// - /// Returns an IEnumerable containing only elements of the array for which the corresponding mask is true. - /// An IArray is not created automatically because it is an expensive operation that is potentially unneeded. - /// - public static IEnumerable Where(this IArray self, IArray mask) - => self.WhereIndices(mask.ToPredicate()); - - /// - /// Returns an IEnumerable containing only elements of the array for which the corresponding predicate is true. - /// - public static IEnumerable Where(this IArray self, Func predicate) - => self.ToEnumerable().Where(predicate); - - /// - /// Returns an IEnumerable containing only elements of the array for which the corresponding predicate is true. - /// - public static IEnumerable Where(this IArray self, Func predicate) - => self.ToEnumerable().Where(predicate); - - /// - /// Returns an IEnumerable containing only indices of the array for which the function satisfies a specific predicate. - /// An IArray is not created automatically because it is an expensive operation that is potentially unneeded. - /// - public static IEnumerable IndicesWhere(this IArray self, Func f) - => self.Indices().Where(i => f(self[i])); - - /// - /// Returns an IEnumerable containing only indices of the array for which the function satisfies a specific predicate. - /// An IArray is not created automatically because it is an expensive operation that is potentially unneeded. - /// - public static IEnumerable IndicesWhere(this IArray self, Func f) - => self.IndicesWhere(i => f(self[i], i)); - - /// - /// Returns an IEnumerable containing only indices of the array for which the function satisfies a specific predicate. - /// An IArray is not created automatically because it is an expensive operation that is potentially unneeded. - /// - public static IEnumerable IndicesWhere(this IArray self, Func f) - => self.Indices().Where(i => f(i)); - - /// - /// Returns an IEnumerable containing only indices of the array for which booleans in the mask are true. - /// An IArray is not created automatically because it is an expensive operation that is potentially unneeded. - /// - public static IEnumerable IndicesWhere(this IArray self, IArray mask) - => self.IndicesWhere(mask.ToPredicate()); - - /// - /// Shortcut for ToEnumerable.Aggregate() - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static U Aggregate(this IArray self, U init, Func func) - { - for (var i = 0; i < self.Count; ++i) - init = func(init, self[i]); - return init; - } - - /// - /// Shortcut for ToEnumerable.Aggregate() - /// - public static U Aggregate(this IArray self, Func func) - => Aggregate(self, default, func); - - /// - /// Shortcut for ToEnumerable.Aggregate() - /// - public static U Aggregate(this IArray self, U init, Func func) - { - for (var i = 0; i < self.Count; ++i) - init = func(init, self[i], i); - return init; - } - - /// - /// Shortcut for ToEnumerable.Aggregate() - /// - public static U Aggregate(this IArray self, Func func) - => Aggregate(self, default, func); - - /// - /// Returns a new array containing the elements in the range of from to to. - /// - public static IArray Slice(this IArray self, int from, int to) - => Select(to - from, i => self[i + from]); - - /// - /// Returns an array of SubArrays of size "size" - /// the last items that cannot fill an arrat if size "size" will be ignored - /// - public static IArray> SubArraysFixed(this IArray self, int size) - => (self.Count / size).Select(i => self.SubArray(i, size)); - - - /// Returns an array of SubArrays of size "size" plus extras - /// The extra array is of size count % size if present - public static IArray> SubArrays(this IArray self, int size) - => self.Count % size == 0 - ? self.SubArraysFixed(size) - : self.SubArraysFixed(size).Append(self.TakeLast(self.Count % size)); - - /// - /// Returns n elements of the list starting from a given index. - /// - public static IArray SubArray(this IArray self, int from, int count) - => self.Slice(from, count + from); - - /// - /// Returns elements of the array between from and skipping every stride element. - /// - public static IArray Slice(this IArray self, int from, int to, int stride) - => Select(to - from / stride, i => self[i * stride + from]); - - /// - /// Returns a new array containing the elements by taking every nth item. - /// - public static IArray Stride(this IArray self, int n) - => Select(self.Count / n, i => self[i * n % self.Count]); - - /// - /// Returns a new array containing just the first n items. - /// - public static IArray Take(this IArray self, int n) - => self.Slice(0, n); - - /// - /// Returns a new array containing just at most n items. - /// - public static IArray TakeAtMost(this IArray self, int n) - => self.Count > n ? self.Slice(0, n) : self; - - /// - /// Returns a new array containing the elements after the first n elements. - /// - public static IArray Skip(this IArray self, int n = 1) - => self.Slice(n, self.Count); - - /// - /// Returns a new array containing the last n elements. - /// - public static IArray TakeLast(this IArray self, int n = 1) - => self.Skip(self.Count - n); - - /// - /// Returns a new array containing all elements excluding the last n elements. - /// - public static IArray DropLast(this IArray self, int n = 1) - => self.Count > n ? self.Take(self.Count - n) : self.Empty(); - - /// - /// Returns a new array by remapping indices - /// - public static IArray MapIndices(this IArray self, Func f) - => self.Count.Select(i => self[f(i)]); - - /// - /// Returns a new array that reverses the order of elements - /// - public static IArray Reverse(this IArray self) - => self.MapIndices(i => self.Count - 1 - i); - - /// - /// Uses the provided indices to select elements from the array. - /// - public static IArray SelectByIndex(this IArray self, IArray indices) - => indices.Select(i => self[i]); - - /// - /// Uses the array as indices to select elements from the other array. - /// - public static IArray Choose(this IArray indices, IArray values) - => values.SelectByIndex(indices); - - /// - /// Given indices of sub-arrays groups, this will convert it to arrays of indices (e.g. [0, 2] with a group size of 3 becomes [0, 1, 2, 6, 7, 8]) - /// - public static IArray GroupIndicesToIndices(this IArray indices, int groupSize) - => groupSize == 1 - ? indices : (indices.Count * groupSize).Select(i => indices[i / groupSize] * groupSize + i % groupSize); - - /// - /// Return the array separated into a series of groups (similar to DictionaryOfLists) - /// based on keys created by the given keySelector - /// - public static IEnumerable> GroupBy(this IArray self, Func keySelector) - => self.ToEnumerable().GroupBy(keySelector); - - /// - /// Return the array separated into a series of groups (similar to DictionaryOfLists) - /// based on keys created by the given keySelector and elements chosen by the element selector - /// - public static IEnumerable> GroupBy(this IArray self, Func keySelector, Func elementSelector) - => self.ToEnumerable().GroupBy(keySelector, elementSelector); - - /// - /// Uses the provided indices to select groups of contiguous elements from the array. - /// This is equivalent to self.SubArrays(groupSize).SelectByIndex(indices).SelectMany(); - /// - public static IArray SelectGroupsByIndex(this IArray self, int groupSize, IArray indices) - => self.SelectByIndex(indices.GroupIndicesToIndices(groupSize)); - - /// - /// Similar to take, if count is less than the number of items in the array, otherwise uses a modulo operation. - /// - public static IArray Resize(this IArray self, int count) - => Select(count, i => self[i % self.Count]); - - /// - /// Returns an array of the same type with no elements. - /// - public static IArray Empty(this IArray self) - => self.Take(0); - - /// - /// Returns an array of the same type with no elements. - /// - public static IArray Empty() - => default(T).Repeat(0); - - /// - /// Returns a sequence of integers from 0 to 1 less than the number of items in the array, representing indicies of the array. - /// - public static IArray Indices(this IArray self) - => self.Count.Range(); - - /// - /// Converts an array of elements into a string representation - /// - public static string Join(this IArray self, string sep = " ") - => self.Aggregate(new StringBuilder(), (sb, x) => sb.Append(x).Append(sep)).ToString(); - - /// - /// Concatenates the contents of one array with another. - /// - public static IArray Concatenate(this IArray self, IArray other) - => Select(self.Count + other.Count, i => i < self.Count ? self[i] : other[i - self.Count]); - - /// - /// Returns the index of the first element matching the given item. - /// - public static int IndexOf(this IArray self, T item) where T : IEquatable - => self.IndexOf(x => x.Equals(item)); - - /// - /// Returns the index of the first element matching the given item. - /// - public static int IndexOf(this IArray self, Func predicate) - { - for (var i = 0; i < self.Count; ++i) - { - if (predicate(self[i])) - return i; - } - - return -1; - } - - /// - /// Returns the index of the last element matching the given item. - /// - public static int LastIndexOf(this IArray self, T item) where T : IEquatable - { - var n = self.Reverse().IndexOf(item); - return n < 0 ? n : self.Count - 1 - n; - } - - /// - /// Returns an array that is one element shorter that subtracts each element from its previous one. - /// - public static IArray AdjacentDifferences(this IArray self) - => self.ZipEachWithNext((a, b) => b - a); - - /// - /// Creates a new array that concatenates a unit item list of one item after it. - /// Repeatedly calling Append would result in significant performance degradation. - /// - public static IArray Append(this IArray self, T x) - => (self.Count + 1).Select(i => i < self.Count ? self[i] : x); - - /// - /// Creates a new array that concatenates the given items to itself. - /// - public static IArray Append(this IArray self, params T[] x) - => self.Concatenate(x.ToIArray()); - - /// - /// Creates a new array that concatenates a unit item list of one item before it - /// Repeatedly calling Prepend would result in significant performance degradation. - /// - public static IArray Prepend(this IArray self, T x) - => (self.Count + 1).Select(i => i == 0 ? x : self[i - 1]); - - /// - /// Returns the element at the nth position, where n is modulo the number of items in the arrays. - /// - public static T ElementAt(this IArray self, int n) - => self[n]; - - /// - /// Returns the element at the nth position, where n is modulo the number of items in the arrays. - /// - public static T ElementAtModulo(this IArray self, int n) - => self.ElementAt(n % self.Count); - - /// - /// Returns the Nth element of the array, or a default value if out of range/ - /// - public static T ElementAtOrDefault(this IArray xs, int n, T defaultValue = default) - => xs != null && n >= 0 && n < xs.Count ? xs[n] : defaultValue; - - /// - /// Counts all elements in an array that satisfy a predicate - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountWhere(this IArray self, Func p) - => self.Aggregate(0, (n, x) => n + (p(x) ? 1 : 0)); - - /// - /// Counts all elements in an array that are equal to true - /// - public static int CountWhere(this IArray self) - => self.CountWhere(x => x); - - /// - /// Counts all elements in an array that are equal to a value - /// - public static int CountWhere(this IArray self, T val) where T : IEquatable - => self.CountWhere(x => x.Equals(val)); - - /// - /// Returns the minimum element in the list - /// - public static T Min(this IArray self) where T : IComparable - { - if (self.Count == 0) throw new ArgumentOutOfRangeException(); - return self.Aggregate(self[0], (a, b) => a.CompareTo(b) < 0 ? a : b); - } - - /// - /// Returns the maximum element in the list - /// - public static T Max(this IArray self) where T : IComparable - { - if (self.Count == 0) throw new ArgumentOutOfRangeException(); - return self.Aggregate(self[0], (a, b) => a.CompareTo(b) > 0 ? a : b); - } - - /// - /// Applies a function (like "+") to each element in the series to create an effect similar to partial sums. - /// - public static IArray Accumulate(this IArray self, Func f) - { - var n = self.Count; - var r = new T[n]; - if (n == 0) return r.ToIArray(); - var prev = r[0] = self[0]; - for (var i = 1; i < n; ++i) - { - prev = r[i] = f(prev, self[i]); - } - return r.ToIArray(); - } - - /// - /// Applies a function (like "+") to each element in the series to create an effect similar to partial sums. - /// The first value in the array will be zero. - /// - public static IArray PostAccumulate(this IArray self, Func f, T init = default) - { - var n = self.Count; - var r = new T[n + 1]; - var prev = r[0] = init; - if (n == 0) return r.ToIArray(); - for (var i = 0; i < n; ++i) - { - prev = r[i + 1] = f(prev, self[i]); - } - return r.ToIArray(); - } - - /// - /// Returns true if the two lists are the same length, and the elements are the same. - /// - public static bool SequenceEquals(this IArray self, IArray other) where T : IEquatable - => self == other || (self.Count == other.Count && self.Zip(other, (x, y) => x?.Equals(y) ?? y == null).All(x => x)); - - /// - /// Creates a readonly array from a seed value, by applying a function - /// - public static IArray Build(T init, Func next, Func hasNext) - { - var r = new List(); - while (hasNext(init)) - { - r.Add(init); - init = next(init); - } - return r.ToIArray(); - } - - /// - /// Creates a readonly array from a seed value, by applying a function - /// - public static IArray Build(T init, Func next, Func hasNext) - { - var i = 0; - var r = new List(); - while (hasNext(init, i)) - { - r.Add(init); - init = next(init, ++i); - } - return r.ToIArray(); - } - - /// - /// Creates an array of arrays, split at the given indices - /// - public static IArray> Split(this IArray self, IArray indices) - => indices.Prepend(0).Zip(indices.Append(self.Count), (x, y) => self.Slice(x, y)); - - /// - /// Creates an array of arrays, split at the given index. - /// - public static IArray> Split(this IArray self, int index) - => Create(self.Take(index), self.Skip(index)); - - /// - /// Splits an array of tuples into a tuple of array - /// - public static (IArray, IArray) Unzip(this IArray<(T1, T2)> self) - => (self.Select(pair => pair.Item1), self.Select(pair => pair.Item2)); - - - /// - /// Returns true if the predicate is true for all of the elements in the array - /// - public static bool All(this IArray self, Func predicate) - => self.ToEnumerable().All(predicate); - - /// - /// Returns true if the predicate is true for any of the elements in the array - /// - public static bool Any(this IArray self, Func predicate) - => self.ToEnumerable().Any(predicate); - - /// - /// Sums items in an array using a selector function that returns integers. - /// - public static long Sum(this IArray self, Func func) - => self.Aggregate(0L, (init, x) => init + func(x)); - - /// - /// Sums items in an array using a selector function that returns doubles. - /// - public static double Sum(this IArray self, Func func) - => self.Aggregate(0.0, (init, x) => init + func(x)); - - /// - /// Forces evaluation (aka reification) of the array by creating a copy in memory. - /// This is useful as a performance optimization, or to force the objects to exist permanently. - /// - public static IArray Evaluate(this IArray x) - => (x is ArrayAdapter) ? x : x.ToArray().ToIArray(); - - /// - /// Forces evaluation (aka reification) of the array in parallel. - /// - public static IArray EvaluateInParallel(this IArray x) - => (x is ArrayAdapter) ? x : x.ToArrayInParallel().ToIArray(); - - /// - /// Converts to a regular array in paralle; - /// - /// - /// - /// - public static T[] ToArrayInParallel(this IArray xs) - { - if (xs.Count == 0) - return Array.Empty(); - - if (xs.Count < Environment.ProcessorCount) - return xs.ToArray(); - - var r = new T[xs.Count]; - var partitioner = Partitioner.Create(0, xs.Count, xs.Count / Environment.ProcessorCount); - - Parallel.ForEach(partitioner, (range, state) => - { - for (var i = range.Item1; i < range.Item2; ++i) - r[i] = xs[i]; - }); - return r; - } - - /// - /// Maps pairs of elements to a new array. - /// - public static IArray SelectPairs(this IArray xs, Func f) - => (xs.Count / 2).Select(i => f(xs[i * 2], xs[i * 2 + 1])); - - /// - /// Maps every 3 elements to a new array. - /// - public static IArray SelectTriplets(this IArray xs, Func f) - => (xs.Count / 3).Select(i => f(xs[i * 3], xs[i * 3 + 1], xs[i * 3 + 2])); - - /// - /// Maps every 4 elements to a new array. - /// - public static IArray SelectQuartets(this IArray xs, Func f) - => (xs.Count / 4).Select(i => f(xs[i * 4], xs[i * 4 + 1], xs[i * 4 + 2], xs[i * 4 + 3])); - - /// - /// Returns the number of unique instances of elements in the array. - /// - public static int CountUnique(this IArray xs) - => xs.ToEnumerable().Distinct().Count(); - - /// - /// Returns elements in order. - /// - public static IArray Sort(this IArray xs) where T : IComparable - => xs.ToEnumerable().OrderBy(x => x).ToIArray(); - - /// - /// Given an array of elements of type T casts them to a U - /// - public static IArray Cast(this IArray xs) where T : U - => xs.Select(x => (U)x); - - /// - /// Returns true if the value is present in the array. - /// - public static bool Contains(this IArray xs, T value) - => xs.Any(x => x.Equals(value)); - - public static ILookup ToLookup(this IEnumerable input, Func keyFunc, Func valueFunc) - => input.ToDictionary(keyFunc, valueFunc).ToLookup(); - - public static ILookup ToLookup(this IArray input, Func keyFunc, Func valueFunc) - => input.ToEnumerable().ToLookup(keyFunc, valueFunc); - - public static ILookup ToLookup(this IEnumerable input, Func keyFunc) - => input.ToDictionary(keyFunc, x => x).ToLookup(); - - public static ILookup ToLookup(this IArray input, Func keyFunc) - => input.ToEnumerable().ToLookup(keyFunc, x => x); - - public static T FirstOrDefault(this IArray xs) - => xs.Count > 0 ? xs[0] : default; - - public static T FirstOrDefault(this IArray xs, T @default) - => xs.Count > 0 ? xs[0] : @default; - - public static T FirstOrDefault(this IArray xs, Func predicate) - => xs.Where(predicate).FirstOrDefault(); - - public static IArray ToLongs(this IArray xs) - => xs.Select(x => (long)x); - - public static IArray PrefixSums(this IArray self) - => self.ToLongs().PrefixSums(); - - public static IArray PrefixSums(this IArray self) - => self.Scan(0f, (a, b) => a + b); - - public static IArray PrefixSums(this IArray self) - => self.Scan(0.0, (a, b) => a + b); - - public static IArray Scan(this IArray self, U init, Func scanFunc) - { - if (self.Count == 0) - return Empty(); - var r = new U[self.Count]; - for (var i = 0; i < self.Count; ++i) - init = r[i] = scanFunc(init, self[i]); - return r.ToIArray(); - } - - public static IArray PrefixSums(this IArray counts) - => counts.Scan(0L, (a, b) => a + b); - - // Similar to prefix sums, but starts at zero. - // r[i] = Sum(count[0 to i]) - public static IArray CountsToOffsets(this IArray counts) - { - var r = new int[counts.Count]; - for (var i = 1; i < counts.Count; ++i) - r[i] = r[i - 1] + counts[i - 1]; - return r.ToIArray(); - } - - public static IArray OffsetsToCounts(this IArray offsets, int last) - => offsets.Indices().Select(i => i < offsets.Count - 1 ? offsets[i + 1] - offsets[i] : last - offsets[i]); - - public static IArray SetElementAt(this IArray self, int index, T value) - => self.SelectIndices(i => i == index ? value : self[i]); - - public static IArray SetFirstElementWhere(this IArray self, Func predicate, T value) - { - var index = self.IndexOf(predicate); - if (index < 0) - return self; - return self.SetElementAt(index, value); - } - } -} diff --git a/src/cs/linqarray/Vim.LinqArray/README.md b/src/cs/linqarray/Vim.LinqArray/README.md deleted file mode 100644 index b698f3b8..00000000 --- a/src/cs/linqarray/Vim.LinqArray/README.md +++ /dev/null @@ -1,51 +0,0 @@ -# LinqArray - -**LinqArray** is a pure functional .NET library from **[VIM AEC](https://vimaec.com)** that provides LINQ functionality for -immutable (read only) arrays, rather than `IEnumerable` (which is effectively a stream), -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 `IArray` interface: - -``` -interface IArray { - 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). - -This allows for algorithms to be constructed that do not load large data sets into memory. - -## 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 -and `O(N)` time for retrieving an element in the collection at a given index. - -Using the `IArray` extension methods in `LinqArray`, all of the properties of the array can be maintained through a number -of operations, include `Select`, `Take`, `Reverse`, and more, as well as various useful array specific operations like -`Slice`. - -### 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. - -## 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). - -Unlike [LinqFaster](https://github.com/jackmott/LinqFaster) by Jack Mott, the evaluation of functions in -`LinqArray` happen on demand (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/src/cs/linqarray/Vim.LinqArray/Vim.LinqArray.csproj b/src/cs/linqarray/Vim.LinqArray/Vim.LinqArray.csproj deleted file mode 100644 index 110fabe9..00000000 --- a/src/cs/linqarray/Vim.LinqArray/Vim.LinqArray.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - netstandard2.0 - true - Vim.LinqArray - LinqArray is a library of efficient LINQ-style operation on immutable arrays. - - https://github.com/vimaec/linqarray - https://github.com/vimaec/linqarray - GitHub - true - license.txt - 1.1.3 - true - true - true - snupkg - - - - - - - - true - - - - - True - - - - - - \ No newline at end of file diff --git a/src/cs/math3d/Vim.Math3D/LinqUtil.cs b/src/cs/math3d/Vim.Math3D/LinqUtil.cs index c105f6e4..cbe95914 100644 --- a/src/cs/math3d/Vim.Math3D/LinqUtil.cs +++ b/src/cs/math3d/Vim.Math3D/LinqUtil.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Collections.Generic; namespace Vim.Math3d { diff --git a/src/cs/math3d/Vim.Math3D/Matrix4x4.cs b/src/cs/math3d/Vim.Math3D/Matrix4x4.cs index a7e93474..f6a5c0be 100644 --- a/src/cs/math3d/Vim.Math3D/Matrix4x4.cs +++ b/src/cs/math3d/Vim.Math3D/Matrix4x4.cs @@ -7,7 +7,6 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/cs/math3d/Vim.Math3D/StructsPartial.cs b/src/cs/math3d/Vim.Math3D/StructsPartial.cs index a30b4aef..773b1ca4 100644 --- a/src/cs/math3d/Vim.Math3D/StructsPartial.cs +++ b/src/cs/math3d/Vim.Math3D/StructsPartial.cs @@ -5,7 +5,6 @@ using System; using System.Runtime.CompilerServices; -using System.Runtime.Serialization; namespace Vim.Math3d { diff --git a/src/cs/samples/Vim.Gltf.Converter.Tests/TestVimGltfConverter.cs b/src/cs/samples/Vim.Gltf.Converter.Tests/TestVimGltfConverter.cs index 86acc9de..1c8c27e8 100644 --- a/src/cs/samples/Vim.Gltf.Converter.Tests/TestVimGltfConverter.cs +++ b/src/cs/samples/Vim.Gltf.Converter.Tests/TestVimGltfConverter.cs @@ -1,6 +1,6 @@ using NUnit.Framework; using System.IO; -using Vim.Format.SceneBuilder; +using Vim.Format; using Vim.Util.Tests; namespace Vim.Gltf.Converter.Tests; @@ -26,7 +26,7 @@ public static void VimGltfConverterWritesVimFile(string gltfFileName, float scal Assert.IsTrue(File.Exists(vimFilePath), $"Output VIM file not found: {vimFilePath}"); - var vim = VimScene.LoadVim(vimFilePath); + var vim = VIM.Open(vimFilePath); vim.Validate(); } diff --git a/src/cs/samples/Vim.Gltf.Converter/GltfToVimStore.cs b/src/cs/samples/Vim.Gltf.Converter/GltfToVimStore.cs index 7112b16a..dc51e0e8 100644 --- a/src/cs/samples/Vim.Gltf.Converter/GltfToVimStore.cs +++ b/src/cs/samples/Vim.Gltf.Converter/GltfToVimStore.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using Vim.Format; -using Vim.Format.ObjectModel; using Vim.Math3d; using Vim.Util; @@ -14,7 +13,7 @@ namespace Vim.Gltf.Converter /// /// A bare-bones example of converting a GLTF into a VIM file. /// - public class GltfToVimStore : ObjectModelStore + public class GltfToVimStore : VimBuilder { // ASSEMBLY VERSION INFO private static readonly Version AssemblyVersion = typeof(GltfToVimStore).Assembly.GetName().Version; @@ -31,7 +30,7 @@ public static void Convert(string gltfFilePath, string vimFilePath, float scale { var store = new GltfToVimStore(gltfFilePath, scale); store.VisitGltf(); - store.WriteVim(vimFilePath); + store.Write(vimFilePath); } private readonly float _scale; @@ -44,6 +43,7 @@ public static void Convert(string gltfFilePath, string vimFilePath, float scale /// Private constructor. Please use the static function ConvertGltfToVim to convert a GLTF file into a VIM file. /// private GltfToVimStore(string gltfFilePath, float scale = MetersToFeet) + : base(nameof(GltfToVimStore), SchemaVersion.Current, "0.0.0") { _gltfFilePath = gltfFilePath; _scale = scale; @@ -74,16 +74,16 @@ private void VisitGltf() /// Stores a default empty display unit entity. /// private DisplayUnit StoreDefaultDisplayUnit() - => ObjectModelBuilder.DisplayUnitBuilder.Add(DisplayUnit.Empty).Entity; + => DisplayUnitBuilder.Add(DisplayUnit.Empty).Entity; /// /// Since GLTF does not contain Category information, we will store a single default Category /// entity which will be applied to all elements. /// private Category StoreDefaultCategory() - => ObjectModelBuilder.CategoryBuilder.Add(new Category + => CategoryBuilder.Add(new Category { - Id = VimConstants.SyntheticCategoryId, + Id = VimEntityTableConstants.SyntheticCategoryId, BuiltInCategory = "GLTF_CATEGORY", Name = "GLTF Object", CategoryType = "GLTF", @@ -97,15 +97,15 @@ private Family StoreDefaultFamily( BimDocument bimDocument, Category category) { - var familyElement = ObjectModelBuilder.ElementBuilder.Add(new Element + var familyElement = ElementBuilder.Add(new Element { - Id = VimConstants.SyntheticElementId, + Id = VimEntityTableConstants.SyntheticElementId, Name = "GLTF Family", _BimDocument = { Index = bimDocument.Index }, _Category = { Index = category.Index } }).Entity; - return ObjectModelBuilder.FamilyBuilder.Add(new Family + return FamilyBuilder.Add(new Family { _Element = { Index = familyElement.Index }, }).Entity; @@ -120,15 +120,15 @@ private FamilyType StoreDefaultFamilyType( Category category, Family family) { - var familyTypeElement = ObjectModelBuilder.ElementBuilder.Add(new Element + var familyTypeElement = ElementBuilder.Add(new Element { - Id = VimConstants.SyntheticElementId, + Id = VimEntityTableConstants.SyntheticElementId, Name = "GLTF Family Type", _BimDocument = { Index = bimDocument.Index }, _Category = { Index = category.Index } }).Entity; - return ObjectModelBuilder.FamilyTypeBuilder.Add(new FamilyType + return FamilyTypeBuilder.Add(new FamilyType { _Element = { Index = familyTypeElement.Index }, _Family = { Index = family.Index } @@ -141,7 +141,7 @@ private FamilyType StoreDefaultFamilyType( private BimDocument StoreGltfModel(string gltfFilePath, SharpGLTF.Schema2.ModelRoot gltfModel, Category category) { // Create a BIM document representing the GLTF model. - var bimDocument = ObjectModelBuilder.BimDocumentBuilder.Add(new BimDocument + var bimDocument = BimDocumentBuilder.Add(new BimDocument { Title = Path.GetFileNameWithoutExtension(gltfFilePath), Name = Path.GetFileName(gltfFilePath), @@ -149,7 +149,7 @@ private BimDocument StoreGltfModel(string gltfFilePath, SharpGLTF.Schema2.ModelR }).Entity; // Create an element to hold the BIM document's parameters. - var elementEntity = ObjectModelBuilder.ElementBuilder.Add(bimDocument.CreateParameterHolderElement()).Entity; + var elementEntity = ElementBuilder.Add(bimDocument.CreateParameterHolderElement()).Entity; elementEntity._Category.Index = category.Index; elementEntity._BimDocument.Index = bimDocument.Index; bimDocument._Element.Index = elementEntity.Index; @@ -168,14 +168,14 @@ private BimDocument StoreGltfModel(string gltfFilePath, SharpGLTF.Schema2.ModelR private void StoreParameter(Element elementEntity, string name, string value) { // Get (or add) the cached parameter descriptor associated with the name. - var parameterDescriptor = ObjectModelBuilder.ParameterDescriptorBuilder.GetOrAdd(name, _ => new ParameterDescriptor() + var parameterDescriptor = ParameterDescriptorBuilder.GetOrAdd(name, _ => new ParameterDescriptor() { Name = name, _DisplayUnit = { Index = _defaultDisplayUnit.Index }, }).Entity; // Store the parameter value. We use AddUntracked because it doesn't waste time doing a cache lookup. - ObjectModelBuilder.ParameterBuilder.AddUntracked(new Parameter + ParameterBuilder.AddUntracked(new Parameter { Values = (value, value), _ParameterDescriptor = { Index = parameterDescriptor.Index }, @@ -192,7 +192,7 @@ private void StoreGltfScene( Category category) { // For illustrative purposes, we'll convert a GLTF scene into a Site entity. - var siteElement = ObjectModelBuilder.ElementBuilder.Add(new Element() + var siteElement = ElementBuilder.Add(new Element() { Id = gltfScene.LogicalIndex, Name = gltfScene.Name, @@ -200,7 +200,7 @@ private void StoreGltfScene( _Category = { Index = category.Index }, }).Entity; - ObjectModelBuilder.SiteBuilder.Add(new Site + SiteBuilder.Add(new Site { _Element = { Index = siteElement.Index } }); @@ -233,7 +233,7 @@ private void StoreGltfNode( FamilyType familyType) { // Create the element associated to the node. - var familyInstanceElement = ObjectModelBuilder.ElementBuilder.Add(new Element + var familyInstanceElement = ElementBuilder.Add(new Element { Id = gltfNode.LogicalIndex, Name = gltfNode.Name, @@ -247,7 +247,7 @@ private void StoreGltfNode( StoreParameter(familyInstanceElement, nameof(gltfNode.IsTransformAnimated), gltfNode.IsTransformAnimated.ToString()); // Create a family instance pointing to the element and family type. - ObjectModelBuilder.FamilyInstanceBuilder.Add(new FamilyInstance + FamilyInstanceBuilder.Add(new FamilyInstance { _Element = { Index = familyInstanceElement.Index }, _FamilyType = { Index = familyType.Index } @@ -260,7 +260,7 @@ private void StoreGltfNode( : StoreGltfMesh(gltfNode.Mesh, bimDocument, category); // Store the GLTF node's transform as a VIM instance - var vimInstance = new DocumentBuilder.Instance + var vimInstance = new VimInstance { Transform = ConvertToVimMatrix(gltfNode.WorldMatrix, _scale), MeshIndex = vimMeshIndex, @@ -269,7 +269,7 @@ private void StoreGltfNode( // Store the node associated to the geometric instance. // This ordered 1:1 relationship connects the entities with the geometric instances. - ObjectModelBuilder.NodeBuilder.Add(new Vim.Format.ObjectModel.Node + NodeBuilder.Add(new Vim.Format.Node { _Element = { Index = familyInstanceElement.Index }, }); @@ -351,7 +351,7 @@ private int StoreGltfMesh( } var meshIndex = Meshes.Count; - var vimMesh = new DocumentBuilder.Mesh( + var vimMesh = new VimSubdividedMesh( vertices, indices, faceMaterials @@ -369,17 +369,17 @@ private int StoreGltfMaterial( BimDocument bimDocument, Category category) { - var getOrAddResult = ObjectModelBuilder.MaterialBuilder.GetOrAdd( + var getOrAddResult = MaterialBuilder.GetOrAdd( gltfMaterial.LogicalIndex, () => { var maybeChannel = gltfMaterial.FindChannel("BaseColor") ?? gltfMaterial.FindChannel("Diffuse"); if (maybeChannel == null) - return new Format.ObjectModel.Material { Color_X = 0.5d, Color_Y = 0.5d, Color_Z = 0.5d }; // default material + return new Format.Material { Color_X = 0.5d, Color_Y = 0.5d, Color_Z = 0.5d }; // default material var color = maybeChannel.Value.Color; - return new Format.ObjectModel.Material { Color_X = color.X, Color_Y = color.Y, Color_Z = color.Z, Transparency = 1 - color.W }; + return new Format.Material { Color_X = color.X, Color_Y = color.Y, Color_Z = color.Z, Transparency = 1 - color.W }; }); var material = getOrAddResult.Entity; @@ -389,9 +389,9 @@ private int StoreGltfMaterial( return materialIndex; // If the GetOrAdd operation already contained the material, then return early. // The material entity was just added so apply an Element to it. - var materialElement = ObjectModelBuilder.ElementBuilder.Add(new Element() + var materialElement = ElementBuilder.Add(new Element() { - Id = VimConstants.SyntheticElementId, + Id = VimEntityTableConstants.SyntheticElementId, Name = gltfMaterial.Name, _BimDocument = { Index = bimDocument.Index }, _Category = { Index = category.Index }, @@ -407,13 +407,10 @@ private int StoreGltfMaterial( StoreParameter(materialElement, nameof(gltfMaterial.IndexOfRefraction), gltfMaterial.IndexOfRefraction.ToString(CultureInfo.InvariantCulture)); StoreParameter(materialElement, nameof(gltfMaterial.Unlit), gltfMaterial.Unlit.ToString()); - return materialIndex; - } + // Add the renderable VIM material. + Materials.Add(material.ToVimMaterial()); - private void WriteVim(string vimFilePath) - { - var vimDocumentBuilder = ToDocumentBuilder(GeneratorString, VersionString); - vimDocumentBuilder.Write(vimFilePath); + return materialIndex; } } } diff --git a/src/cs/samples/Vim.Gltf.Converter/VimToGltfStore.cs b/src/cs/samples/Vim.Gltf.Converter/VimToGltfStore.cs index 24ad224e..04b90f07 100644 --- a/src/cs/samples/Vim.Gltf.Converter/VimToGltfStore.cs +++ b/src/cs/samples/Vim.Gltf.Converter/VimToGltfStore.cs @@ -3,9 +3,8 @@ using System.Diagnostics; using System.Linq; using System.Numerics; +using Vim.Format; using Vim.BFast; -using Vim.G3d; -using Vim.LinqArray; namespace Vim.Gltf.Converter { @@ -14,20 +13,22 @@ namespace Vim.Gltf.Converter /// public class VimToGltfStore { - - /// /// Converts the given VIM file into a GLTF (.glb) file. /// public static void Convert(string vimFilePath, string gltfFilePath, float scale = (float) Util.Units.FeetToMetersRatio, bool validateGltf = true) { - var vim = VimScene.LoadVim(vimFilePath); + var vim = VIM.Open(vimFilePath); + var gd = vim.GeometryData; var gltfModel = ModelRoot.CreateModel(); var gltfScene = gltfModel.UseScene(0); - foreach (var vimMaterial in vim.Materials.ToEnumerable()) + // foreach (var vimMaterial in vim.Materials.ToEnumerable()) + for (var i = 0; i < vim.GeometryData.MaterialCount; ++i) { + var vimMaterialColor = gd.MaterialColors[i]; + var gltfMaterial = gltfModel.CreateMaterial(); gltfMaterial.InitializePBRMetallicRoughness(); @@ -39,29 +40,27 @@ public static void Convert(string vimFilePath, string gltfFilePath, float scale } var colorChannel = maybeColorChannel.Value; - colorChannel.Color = new System.Numerics.Vector4(vimMaterial.Color.X, vimMaterial.Color.Y, vimMaterial.Color.Z, vimMaterial.Color.W); + colorChannel.Color = new System.Numerics.Vector4(vimMaterialColor.X, vimMaterialColor.Y, vimMaterialColor.Z, vimMaterialColor.W); - if (vimMaterial.Color.W < 1) + if (vimMaterialColor.W < 1) { gltfMaterial.Alpha = AlphaMode.BLEND; } } - var g3d = vim._SerializableDocument.Geometry; - // Initialize a flat vertex buffer. - var vimVertexBufferBytes = g3d.Vertices.ToArray().SelectMany(v => new [] { v.X, v.Y, v.Z }).ToArray().ToBytes(); + var vimVertexBufferBytes = gd.Vertices.SelectMany(v => new [] { v.X, v.Y, v.Z }).ToArray().ToBytes(); var gltfVertexBufferView = gltfModel.UseBufferView(vimVertexBufferBytes); var gltfVertexAccessor = gltfModel.CreateAccessor("VERTEX_ACCESSOR"); - gltfVertexAccessor.SetVertexData(gltfVertexBufferView, 0, g3d.Vertices.Count); + gltfVertexAccessor.SetVertexData(gltfVertexBufferView, 0, gd.VertexCount); // Initialize a flat index buffer. - var vimIndexBufferBytes = g3d.Indices.ToEnumerable().Select(i => (uint)i).ToArray().ToBytes(); + var vimIndexBufferBytes = gd.Indices.Select(i => (uint)i).ToArray().ToBytes(); var gltfIndexBufferView = gltfModel.UseBufferView(vimIndexBufferBytes); // Create the meshes and their primitives (submeshes) - var meshSubmeshCounts = g3d.MeshSubmeshCount.ToArray(); - var meshSubmeshOffsets = g3d.MeshSubmeshOffset.ToArray(); + var meshSubmeshCounts = gd.MeshSubmeshCount; + var meshSubmeshOffsets = gd.MeshSubmeshOffsets; for (var meshIndex = 0; meshIndex < meshSubmeshCounts.Length; ++meshIndex) { var meshSubmeshCount = meshSubmeshCounts[meshIndex]; @@ -74,9 +73,9 @@ public static void Convert(string vimFilePath, string gltfFilePath, float scale for (var submeshIndex = meshSubmeshOffset; submeshIndex < meshSubmeshOffset + meshSubmeshCount; ++submeshIndex) { - var submeshIndexOffset = g3d.SubmeshIndexOffsets[submeshIndex]; - var submeshIndexCount = g3d.SubmeshIndexCount[submeshIndex]; - var submeshMaterialIndex = g3d.SubmeshMaterials[submeshIndex]; + var submeshIndexOffset = gd.SubmeshIndexOffsets[submeshIndex]; + var submeshIndexCount = gd.SubmeshIndexCount[submeshIndex]; + var submeshMaterialIndex = gd.SubmeshMaterials[submeshIndex]; var gltfPrimitive = gltfMesh.CreatePrimitive(); gltfPrimitive.SetVertexAccessor("POSITION", gltfVertexAccessor); @@ -91,9 +90,9 @@ public static void Convert(string vimFilePath, string gltfFilePath, float scale } // Create the nodes and their transforms. - var instanceTransforms = g3d.InstanceTransforms.Select(t => ConvertToGltfMatrix(t, scale)).ToArray(); - var instanceMeshIndices = g3d.InstanceMeshes.ToArray(); - var instanceFlags = g3d.InstanceFlags.ToArray(); + var instanceTransforms = gd.InstanceTransforms.Select(t => ConvertToGltfMatrix(t, scale)).ToArray(); + var instanceMeshIndices = gd.InstanceMeshes; + var instanceFlags = gd.InstanceFlags; for (var i = 0; i < instanceTransforms.Length; ++i) { diff --git a/src/cs/samples/Vim.JsonDigest.AzureFunction/GetVimJsonDigest.cs b/src/cs/samples/Vim.JsonDigest.AzureFunction/GetVimJsonDigest.cs index 7c196486..35d0cc03 100644 --- a/src/cs/samples/Vim.JsonDigest.AzureFunction/GetVimJsonDigest.cs +++ b/src/cs/samples/Vim.JsonDigest.AzureFunction/GetVimJsonDigest.cs @@ -56,7 +56,7 @@ public async Task Run([HttpTrigger(AuthorizationLevel.Anonymou // Create a VIM json digest from the memory stream. _logger.LogTrace("Preparing to read VIM file"); - var vimJsonDigest = new VimJsonDigest(memoryStream); + var vimJsonDigest = new VimJsonDigest(memoryStream, ""); _logger.LogTrace("Created VIM json digest"); diff --git a/src/cs/samples/Vim.JsonDigest.Tests/TestVimJsonDigest.cs b/src/cs/samples/Vim.JsonDigest.Tests/TestVimJsonDigest.cs index d484ad0d..36a6a982 100644 --- a/src/cs/samples/Vim.JsonDigest.Tests/TestVimJsonDigest.cs +++ b/src/cs/samples/Vim.JsonDigest.Tests/TestVimJsonDigest.cs @@ -29,7 +29,7 @@ public static async Task Test_VimJsonDigest(string url) } // Create a VIM json digest from the memory stream. - var vimJsonDigest = new VimJsonDigest(memoryStream); + var vimJsonDigest = new VimJsonDigest(memoryStream, ""); // Assert the contained collections are not empty. Assert.IsNotEmpty(vimJsonDigest.BimDocumentDigestCollection, "BimDocument digest collection is empty."); diff --git a/src/cs/samples/Vim.JsonDigest/AreaDigest.cs b/src/cs/samples/Vim.JsonDigest/AreaDigest.cs index ea7fa455..ecc3c4e6 100644 --- a/src/cs/samples/Vim.JsonDigest/AreaDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/AreaDigest.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using System.Collections.Generic; -using Vim.LinqArray; +using System.Linq; +using Vim.Format; namespace Vim.JsonDigest { @@ -69,8 +70,8 @@ public AreaDigest() { } /// Returns the collection of area digests for each area in the given VIM scene. Note that areas only /// exist in 2d views. /// - public static IEnumerable GetAreaDigestCollection(VimScene vimScene) - => vimScene.DocumentModel.AreaList.Select(a => + public static IEnumerable GetAreaDigestCollection(VIM vim) + => vim.GetEntityTableSet().AreaTable.Select(a => { var areaElement = a.Element; @@ -87,6 +88,6 @@ public static IEnumerable GetAreaDigestCollection(VimScene vimScene) Perimeter = a.Perimeter, IsGrossInterior = a.IsGrossInterior }; - }).ToEnumerable(); + }); } } diff --git a/src/cs/samples/Vim.JsonDigest/BimDocumentDigest.cs b/src/cs/samples/Vim.JsonDigest/BimDocumentDigest.cs index 9ff103ec..d9f3f3a2 100644 --- a/src/cs/samples/Vim.JsonDigest/BimDocumentDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/BimDocumentDigest.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; -using Vim.LinqArray; +using System.Linq; +using Vim.Format; namespace Vim.JsonDigest { @@ -158,8 +159,8 @@ public class BimDocumentDigest /// /// Returns a collection of BIM document digests for each BIM document in the given VIM scene /// - public static IEnumerable GetBimDocumentDigestCollection(VimScene vimScene) - => vimScene.DocumentModel.BimDocumentList.Select(b => + public static IEnumerable GetBimDocumentDigestCollection(VIM vim) + => vim.GetEntityTableSet().BimDocumentTable.Select(b => { var bimDocumentElement = b.Element; @@ -196,6 +197,6 @@ public static IEnumerable GetBimDocumentDigestCollection(VimS User = b.User, Ref_ElementDigest_VimIndex = bimDocumentElement.Index, }; - }).ToEnumerable(); + }); } } diff --git a/src/cs/samples/Vim.JsonDigest/ElementDigest.cs b/src/cs/samples/Vim.JsonDigest/ElementDigest.cs index 3033c1a5..7caf9d52 100644 --- a/src/cs/samples/Vim.JsonDigest/ElementDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/ElementDigest.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; -using Vim.Format.ObjectModel; +using Vim.Format; namespace Vim.JsonDigest { @@ -114,53 +114,61 @@ public ElementDigest() {} /// /// Returns a collection of element digests for each element in the given VIM scene. /// - public static IEnumerable GetElementDigestCollection(VimScene vimScene) + public static IEnumerable GetElementDigestCollection(VIM vim) { var result = new List(); - for (var elementIndex = 0; elementIndex < vimScene.DocumentModel.NumElement; ++elementIndex) + var tableSet = vim.GetEntityTableSet(); + + var elementTable = tableSet.ElementTable; + var bimDocumentTable = tableSet.BimDocumentTable; + var categoryTable = tableSet.CategoryTable; + + for (var elementIndex = 0; elementIndex < elementTable.RowCount; ++elementIndex) { - var elementInfo = vimScene.DocumentModel.GetElementInfo(elementIndex); - + var bimDocumentIndex = elementTable.GetBimDocumentIndex(elementIndex); + var categoryIndex = elementTable.GetCategoryIndex(elementIndex); + var elementDigest = new ElementDigest { - VimIndex = elementInfo.ElementIndex, - ElementId = elementInfo.ElementId, - ElementUniqueId = elementInfo.ElementUniqueId, - Name = elementInfo.ElementName, - BimDocumentName = elementInfo.BimDocument.Name, - CategoryName = elementInfo.CategoryName, - BuiltInCategoryName = elementInfo.CategoryBuiltInName, - FamilyName = elementInfo.FamilyName, - FamilyTypeName = elementInfo.FamilyTypeName, - IsFamilyInstance = elementInfo.IsFamilyInstance, - IsFamilyType = elementInfo.IsFamilyType, - IsFamily = elementInfo.IsFamily, - IsSystem = elementInfo.IsSystem, - Ref_BimDocumentDigest_VimIndex = elementInfo.BimDocumentIndex, - Ref_LevelDigest_VimIndex = elementInfo.LevelIndex, - Ref_RoomDigest_VimIndex = elementInfo.RoomIndex, + VimIndex = elementIndex, + ElementId = elementTable.GetId(elementIndex), + ElementUniqueId = elementTable.GetUniqueId(elementIndex), + Name = elementTable.GetName(elementIndex), + BimDocumentName = bimDocumentTable.GetName(bimDocumentIndex), + CategoryName = categoryTable.GetName(categoryIndex), + BuiltInCategoryName = categoryTable.GetBuiltInCategory(categoryIndex), + FamilyName = elementTable.GetFamilyNameEx(elementIndex), + FamilyTypeName = elementTable.GetFamilyTypeName(elementIndex), + IsFamilyInstance = elementTable.IsFamilyInstance(elementIndex), + IsFamilyType = elementTable.IsFamilyType(elementIndex), + IsFamily = elementTable.IsFamily(elementIndex), + IsSystem = elementTable.IsSystem(elementIndex), + Ref_BimDocumentDigest_VimIndex = bimDocumentIndex, + Ref_LevelDigest_VimIndex = elementTable.GetLevelIndex(elementIndex), + Ref_RoomDigest_VimIndex = elementTable.GetRoomIndex(elementIndex), }; // Add the parameters to the element. NOTE: this generates a lot of duplicated strings. - var parameters = elementInfo.GetScopedParameters(); - if (parameters.TryGetValue(ElementInfo.ParameterScope.FamilyInstance, out var familyInstanceParameters)) + var parameterTable = tableSet.ParameterTable; + + var familyInstanceParameterIndices = elementTable.GetFamilyInstanceParameterIndices(elementIndex); + foreach (var pi in familyInstanceParameterIndices) { - elementDigest.FamilyInstanceParameters.AddRange( - familyInstanceParameters.Select(ParameterDigest.CreateFromParameter)); + elementDigest.FamilyInstanceParameters.Add(ParameterDigest.CreateFromParameter(parameterTable.Get(pi))); } - if (parameters.TryGetValue(ElementInfo.ParameterScope.FamilyType, out var familyTypeParameters)) + var familyTypeParameterIndices = elementTable.GetFamilyTypeParameterIndices(elementIndex); + foreach (var pi in familyTypeParameterIndices) { - elementDigest.FamilyTypeParameters.AddRange( - familyTypeParameters.Select(ParameterDigest.CreateFromParameter)); + elementDigest.FamilyTypeParameters.Add(ParameterDigest.CreateFromParameter(parameterTable.Get(pi))); } - if (parameters.TryGetValue(ElementInfo.ParameterScope.Family, out var familyParameters)) + var familyParameterIndices = elementTable.GetFamilyParameterIndices(elementIndex); + foreach (var pi in familyParameterIndices) { - elementDigest.FamilyParameters.AddRange( - familyParameters.Select(ParameterDigest.CreateFromParameter)); + elementDigest.FamilyParameters.Add(ParameterDigest.CreateFromParameter(parameterTable.Get(pi))); } result.Add(elementDigest); diff --git a/src/cs/samples/Vim.JsonDigest/LevelDigest.cs b/src/cs/samples/Vim.JsonDigest/LevelDigest.cs index f90ff2ae..63ce1789 100644 --- a/src/cs/samples/Vim.JsonDigest/LevelDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/LevelDigest.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using System.Collections.Generic; -using Vim.LinqArray; +using System.Linq; +using Vim.Format; namespace Vim.JsonDigest { @@ -55,8 +56,8 @@ public LevelDigest() { } /// /// Returns a collection of level digests for each level in the given VIM scene. /// - public static IEnumerable GetLevelDigestCollection(VimScene vimScene) - => vimScene.DocumentModel.LevelList.Select(l => + public static IEnumerable GetLevelDigestCollection(VIM vim) + => vim.GetEntityTableSet().LevelTable.Select(l => { var levelElement = l.Element; @@ -71,6 +72,6 @@ public static IEnumerable GetLevelDigestCollection(VimScene vimScen Elevation = l.Elevation, ProjectElevation = l.ProjectElevation, }; - }).ToEnumerable(); + }); } } diff --git a/src/cs/samples/Vim.JsonDigest/MaterialDigest.cs b/src/cs/samples/Vim.JsonDigest/MaterialDigest.cs index 31279545..ca23f91f 100644 --- a/src/cs/samples/Vim.JsonDigest/MaterialDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/MaterialDigest.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using System.Collections.Generic; using System.Linq; -using Vim.LinqArray; +using Vim.Format; namespace Vim.JsonDigest { @@ -64,10 +64,12 @@ public MaterialDigest() { } /// /// Returns the collection of material digests for each material in the given VIM scene. /// - public static IEnumerable GetMaterialDigestCollection(VimScene vimScene) + public static IEnumerable GetMaterialDigestCollection(VIM vim) { + var tableSet = vim.GetEntityTableSet(); + // First, we initialize the collection of MaterialInfo instances based on each material in the VIM scene. - var materialDigests = vimScene.DocumentModel.MaterialList.Select(m => + var materialDigests = tableSet.MaterialTable.Select(m => new MaterialDigest() { VimIndex = m.Index, @@ -82,7 +84,7 @@ public static IEnumerable GetMaterialDigestCollection(VimScene v }).ToArray(); // Next, we iterate over all the MaterialInElement associative objects and update the MaterialInfos we created above. - foreach (var materialInElement in vimScene.DocumentModel.MaterialInElementList.ToEnumerable()) + foreach (var materialInElement in tableSet.MaterialInElementTable) { var material = materialInElement.Material; var element = materialInElement.Element; diff --git a/src/cs/samples/Vim.JsonDigest/RoomDigest.cs b/src/cs/samples/Vim.JsonDigest/RoomDigest.cs index 114eaff0..2f4b67f0 100644 --- a/src/cs/samples/Vim.JsonDigest/RoomDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/RoomDigest.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using System.Collections.Generic; -using Vim.LinqArray; +using System.Linq; +using Vim.Format; namespace Vim.JsonDigest { @@ -68,8 +69,8 @@ public RoomDigest() { } /// /// Returns a collection of room digests for each room in the given VIM scene. /// - public static IEnumerable GetRoomDigestCollection(VimScene vimScene) - => vimScene.DocumentModel.RoomList.Select(r => + public static IEnumerable GetRoomDigestCollection(VIM vim) + => vim.GetEntityTableSet().RoomTable.Select(r => { var roomElement = r.Element; @@ -87,6 +88,6 @@ public static IEnumerable GetRoomDigestCollection(VimScene vimScene) Volume = r.Volume, Perimeter = r.Perimeter }; - }).ToEnumerable(); + }); } } diff --git a/src/cs/samples/Vim.JsonDigest/VimJsonDigest.cs b/src/cs/samples/Vim.JsonDigest/VimJsonDigest.cs index 969afb31..2bac6b98 100644 --- a/src/cs/samples/Vim.JsonDigest/VimJsonDigest.cs +++ b/src/cs/samples/Vim.JsonDigest/VimJsonDigest.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using Vim.Format; namespace Vim.JsonDigest { @@ -39,21 +40,21 @@ public VimJsonDigest() { } /// /// VIM scene constructor used for serialization. /// - public VimJsonDigest(VimScene vimScene) + public VimJsonDigest(VIM vim) { - BimDocumentDigestCollection = BimDocumentDigest.GetBimDocumentDigestCollection(vimScene).ToList(); - ElementDigestCollection = ElementDigest.GetElementDigestCollection(vimScene).ToList(); - LevelDigestCollection = LevelDigest.GetLevelDigestCollection(vimScene).ToList(); - RoomDigestCollection = RoomDigest.GetRoomDigestCollection(vimScene).ToList(); - AreaDigestCollection = AreaDigest.GetAreaDigestCollection(vimScene).ToList(); - MaterialDigestCollection = MaterialDigest.GetMaterialDigestCollection(vimScene).ToList(); + BimDocumentDigestCollection = BimDocumentDigest.GetBimDocumentDigestCollection(vim).ToList(); + ElementDigestCollection = ElementDigest.GetElementDigestCollection(vim).ToList(); + LevelDigestCollection = LevelDigest.GetLevelDigestCollection(vim).ToList(); + RoomDigestCollection = RoomDigest.GetRoomDigestCollection(vim).ToList(); + AreaDigestCollection = AreaDigest.GetAreaDigestCollection(vim).ToList(); + MaterialDigestCollection = MaterialDigest.GetMaterialDigestCollection(vim).ToList(); } /// /// Stream constructor used for serialization. Note: this stream must be seekable. /// - public VimJsonDigest(Stream stream) - : this(VimScene.LoadVim(stream)) + public VimJsonDigest(Stream stream, string vimFilePath) + : this(VIM.Open(stream, vimFilePath)) { } public JObject ToJObject() diff --git a/src/cs/util/Vim.Util.Tests/PipeSeparatedStringsTests.cs b/src/cs/util/Vim.Util.Tests/PipeSeparatedStringsTests.cs index dc896e50..83d70ea0 100644 --- a/src/cs/util/Vim.Util.Tests/PipeSeparatedStringsTests.cs +++ b/src/cs/util/Vim.Util.Tests/PipeSeparatedStringsTests.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Vim.Util.Tests { diff --git a/src/cs/util/Vim.Util/FractionConverter.cs b/src/cs/util/Vim.Util/FractionConverter.cs index ee530baf..f1aac957 100644 --- a/src/cs/util/Vim.Util/FractionConverter.cs +++ b/src/cs/util/Vim.Util/FractionConverter.cs @@ -132,7 +132,7 @@ public static double ParseFraction(string value) result = dWhole + result; // add whole number // and fractional part and we're done. } - catch (Exception e) + catch (Exception) { result = 0; } @@ -144,7 +144,7 @@ public static double ParseFraction(string value) { result = Convert.ToDouble(whole + dec); } - catch (Exception e) + catch (Exception) { // bad input so return 0. result = 0; diff --git a/src/cs/util/Vim.Util/HashCodeNetStandard_2_0.cs b/src/cs/util/Vim.Util/HashCodeNetStandard_2_0.cs index f8bd01d2..100a575d 100644 --- a/src/cs/util/Vim.Util/HashCodeNetStandard_2_0.cs +++ b/src/cs/util/Vim.Util/HashCodeNetStandard_2_0.cs @@ -377,5 +377,15 @@ public int ToHashCode() hash = MixFinal(hash); return (int)hash; } + + public static int GetSequenceHash(int[] values) + { + var hashStruct = new HashCodeStd2(); + foreach (var item in values) + { + hashStruct.Add(item); + } + return hashStruct.ToHashCode(); + } } } diff --git a/src/cs/util/Vim.Util/IO.cs b/src/cs/util/Vim.Util/IO.cs index 4f9574f1..a4a9d287 100644 --- a/src/cs/util/Vim.Util/IO.cs +++ b/src/cs/util/Vim.Util/IO.cs @@ -355,5 +355,17 @@ public static bool OpenUri(string uri) Process.Start(new ProcessStartInfo(uri) { UseShellExecute = true }); return true; } + + public static void ThrowIfNotSeekable(this Stream stream, string errorPreamble) + { + if (!stream.CanSeek) + throw new InvalidOperationException($"{errorPreamble}. Stream must be seekable."); + } + + public static void ThrowIfNotExists(this FileInfo fileInfo, string errorPreamble) + { + if (!fileInfo.Exists) + throw new FileNotFoundException(errorPreamble, fileInfo.FullName); + } } } diff --git a/src/cs/util/Vim.Util/IndexedSet.cs b/src/cs/util/Vim.Util/IndexedSet.cs index 3dc6c296..64f1026a 100644 --- a/src/cs/util/Vim.Util/IndexedSet.cs +++ b/src/cs/util/Vim.Util/IndexedSet.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections; +using System.Collections; using System.Collections.Generic; using System.Linq; diff --git a/src/cs/util/Vim.Util/LinqExtensions.cs b/src/cs/util/Vim.Util/LinqExtensions.cs index 3513b5a0..9f886c1c 100644 --- a/src/cs/util/Vim.Util/LinqExtensions.cs +++ b/src/cs/util/Vim.Util/LinqExtensions.cs @@ -105,12 +105,24 @@ public static bool TryAdd(this IDictionary self, K key, V value) public static V GetOrDefault(this IDictionary self, K key) => self.GetOrDefault(key, default); + /// + /// Returns a value if found in the dictionary, or default if not present. + /// + public static V GetOrDefaultReadOnly(this IReadOnlyDictionary self, K key) + => self.GetOrDefaultReadOnly(key, default); + /// /// Returns a value if found in the dictionary, or default if not present. /// public static V GetOrDefault(this IDictionary self, K key, V defaultValue) => self.ContainsKey(key) ? self[key] : defaultValue; + /// + /// Returns a value if found in the dictionary, or default if not present. + /// + public static V GetOrDefaultReadOnly(this IReadOnlyDictionary self, K key, V defaultValue) + => self.ContainsKey(key) ? self[key] : defaultValue; + /// /// Given a dictionary looks up the key, or uses the function to add to the dictionary, and returns that result. /// @@ -128,6 +140,12 @@ public static V GetOrCompute(this IDictionary self, K key, Func public static V GetOrDefaultAllowNulls(this IDictionary self, K key, V defaultValue) where K : class + => key != null && self.ContainsKey(key) ? self[key] : defaultValue; + + /// + /// Returns a value if found in the dictionary, or default if not present. + /// + public static V GetOrDefaultReadOnlyAllowNulls(this IReadOnlyDictionary self, K key, V defaultValue) where K : class => key != null && self.ContainsKey(key) ? self[key] : defaultValue; /// @@ -136,6 +154,12 @@ public static V GetOrDefaultAllowNulls(this IDictionary self, K key, public static V GetOrDefaultAllowNulls(this IDictionary self, K key) where K : class => self.GetOrDefaultAllowNulls(key, default); + /// + /// Returns a value if found in the dictionary, or default if not present. + /// + public static V GetOrDefaultReadOnlyAllowNulls(this IReadOnlyDictionary self, K key) where K : class + => self.GetOrDefaultReadOnlyAllowNulls(key, default); + public static IEnumerable WhereNotNull(this IEnumerable self) => self.Where(x => x != null); @@ -168,5 +192,24 @@ public static T Maximize(this IEnumerable xs, U init, Func func) return r; } + + public static IEnumerable IndicesWhere(this IReadOnlyList list, Func filter) + { + for(var i = 0; i < list.Count; ++i) + { + if (filter(list[i])) + { + yield return i; + } + } + } + + public static IEnumerable Reversed(this IReadOnlyList list) + { + for (var i = list.Count-1; i >= 0; --i) + { + yield return list[i]; + } + } } } diff --git a/src/cs/util/Vim.Util/Logging/IndentLogger.cs b/src/cs/util/Vim.Util/Logging/IndentLogger.cs index 438124fc..66a4795d 100644 --- a/src/cs/util/Vim.Util/Logging/IndentLogger.cs +++ b/src/cs/util/Vim.Util/Logging/IndentLogger.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace Vim.Util.Logging { diff --git a/src/cs/util/Vim.Util/Util.cs b/src/cs/util/Vim.Util/Util.cs index d4c2175b..4171c15b 100644 --- a/src/cs/util/Vim.Util/Util.cs +++ b/src/cs/util/Vim.Util/Util.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; namespace Vim.Util { diff --git a/src/cs/vim-format.sln b/src/cs/vim-format.sln deleted file mode 100644 index fb20d3c7..00000000 --- a/src/cs/vim-format.sln +++ /dev/null @@ -1,196 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bfast", "bfast", "{F3260C54-834F-4C74-A3B7-EAB622AFA492}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.BFast", "bfast\Vim.BFast\Vim.BFast.csproj", "{1059A7DE-95FA-4F54-85E3-84049E1872D5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.BFast.Tests", "bfast\Vim.BFast.Tests\Vim.BFast.Tests.csproj", "{000ED0CF-EC9C-488C-BE85-14B95FFDF104}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "linqarray", "linqarray", "{CF54EDFD-51AB-4B0D-B084-2DF42918BA51}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.LinqArray", "linqarray\Vim.LinqArray\Vim.LinqArray.csproj", "{07CA1F46-21DA-4C22-A8CB-52D526D51C94}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.LinqArray.Tests", "linqarray\Vim.LinqArray.Tests\Vim.LinqArray.Tests.csproj", "{461788B0-072C-485F-82C0-F83CCC86F95D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "math3d", "math3d", "{9BD3CC85-97FD-4093-AA11-58FE405B0F65}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Math3D", "math3d\Vim.Math3D\Vim.Math3D.csproj", "{1086F24E-32C8-4261-9B06-A364EEE71DEF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Math3D.Tests", "math3d\Vim.Math3D.Tests\Vim.Math3D.Tests.csproj", "{1CC20AA4-11F1-4548-9285-FD24D42190FB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "vim", "vim", "{D639C635-01D1-48C4-89B5-1FD70F1AFEE9}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Format", "vim\Vim.Format\Vim.Format.csproj", "{22278D91-27D7-4A84-8170-5FFB77A70C1F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "g3d", "g3d", "{705B8FB2-D707-4527-91FC-0AADEDBA4D80}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.G3d.Tests", "g3d\Vim.G3d.Tests\Vim.G3d.Tests.csproj", "{DFC8DC5E-377D-4CCC-A498-5894D891A471}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.G3d", "g3d\Vim.G3d\Vim.G3d.csproj", "{F1EC1E94-C74C-4C37-961C-305CAE7C4707}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.G3d.AssimpWrapper", "g3d\Vim.G3d.AssimpWrapper\Vim.G3d.AssimpWrapper.csproj", "{16DBF49F-3E0C-4CD3-BB6C-1BBAF0D89AC6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Format.CodeGen", "vim\Vim.Format.CodeGen\Vim.Format.CodeGen.csproj", "{762E8B1A-9182-4C5D-A25C-0C0F6219BA4E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Format.Tests", "vim\Vim.Format.Tests\Vim.Format.Tests.csproj", "{2CB4CF73-0CA8-4595-910C-EDA244EA5983}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Format.Core", "vim\Vim.Format.Core\Vim.Format.Core.csproj", "{2C798994-518D-4EA5-8F8A-3EAA30269F9E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Util", "util\Vim.Util\Vim.Util.csproj", "{EC00B2EC-3CF0-43C3-A071-320AD3C355CF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Util.Tests", "util\Vim.Util.Tests\Vim.Util.Tests.csproj", "{F7091670-1059-4F4F-AC3A-0B1DE4A724B5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "util", "util", "{A279C2F9-3418-484B-A36E-D1D1C67A0B2D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Util.Logging.Serilog", "util\Vim.Util.Logging.Serilog\Vim.Util.Logging.Serilog.csproj", "{6B9E6432-A7BB-4487-905A-0C3117398140}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E2EBD5E0-81EC-4720-833C-05ECE1BA84A1}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.JsonDigest", "samples\Vim.JsonDigest\Vim.JsonDigest.csproj", "{A315C6D7-BEFF-4BD6-9786-88959E579F5D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.JsonDigest.Tests", "samples\Vim.JsonDigest.Tests\Vim.JsonDigest.Tests.csproj", "{E09ADC19-3E9F-4DD5-AB74-A9EB765ED894}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.JsonDigest.AzureFunction", "samples\Vim.JsonDigest.AzureFunction\Vim.JsonDigest.AzureFunction.csproj", "{A0FA4646-67AC-4310-9BA5-53D2D7CF218F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Gltf.Converter", "samples\Vim.Gltf.Converter\Vim.Gltf.Converter.csproj", "{8C81050A-951C-418F-BBA8-76EE0353863C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vim.Gltf.Converter.Tests", "samples\Vim.Gltf.Converter.Tests\Vim.Gltf.Converter.Tests.csproj", "{902CF0A5-3433-4CF4-AEFB-E1E0E7A5A3F3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vim.Format.ILMerge", "vim\Vim.Format.ILMerge\Vim.Format.ILMerge.csproj", "{3EA06057-7FF8-C92D-16EE-28A0AFE3AEEF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vim.Format.ILMerge.Tests", "vim\Vim.Format.ILMerge.Tests\Vim.Format.ILMerge.Tests.csproj", "{26C02A1E-168B-2945-8AD2-7E7C30114F91}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1059A7DE-95FA-4F54-85E3-84049E1872D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1059A7DE-95FA-4F54-85E3-84049E1872D5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1059A7DE-95FA-4F54-85E3-84049E1872D5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1059A7DE-95FA-4F54-85E3-84049E1872D5}.Release|Any CPU.Build.0 = Release|Any CPU - {000ED0CF-EC9C-488C-BE85-14B95FFDF104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {000ED0CF-EC9C-488C-BE85-14B95FFDF104}.Debug|Any CPU.Build.0 = Debug|Any CPU - {000ED0CF-EC9C-488C-BE85-14B95FFDF104}.Release|Any CPU.ActiveCfg = Release|Any CPU - {000ED0CF-EC9C-488C-BE85-14B95FFDF104}.Release|Any CPU.Build.0 = Release|Any CPU - {07CA1F46-21DA-4C22-A8CB-52D526D51C94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {07CA1F46-21DA-4C22-A8CB-52D526D51C94}.Debug|Any CPU.Build.0 = Debug|Any CPU - {07CA1F46-21DA-4C22-A8CB-52D526D51C94}.Release|Any CPU.ActiveCfg = Release|Any CPU - {07CA1F46-21DA-4C22-A8CB-52D526D51C94}.Release|Any CPU.Build.0 = Release|Any CPU - {461788B0-072C-485F-82C0-F83CCC86F95D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {461788B0-072C-485F-82C0-F83CCC86F95D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {461788B0-072C-485F-82C0-F83CCC86F95D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {461788B0-072C-485F-82C0-F83CCC86F95D}.Release|Any CPU.Build.0 = Release|Any CPU - {1086F24E-32C8-4261-9B06-A364EEE71DEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1086F24E-32C8-4261-9B06-A364EEE71DEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1086F24E-32C8-4261-9B06-A364EEE71DEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1086F24E-32C8-4261-9B06-A364EEE71DEF}.Release|Any CPU.Build.0 = Release|Any CPU - {1CC20AA4-11F1-4548-9285-FD24D42190FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CC20AA4-11F1-4548-9285-FD24D42190FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CC20AA4-11F1-4548-9285-FD24D42190FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CC20AA4-11F1-4548-9285-FD24D42190FB}.Release|Any CPU.Build.0 = Release|Any CPU - {22278D91-27D7-4A84-8170-5FFB77A70C1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {22278D91-27D7-4A84-8170-5FFB77A70C1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {22278D91-27D7-4A84-8170-5FFB77A70C1F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {22278D91-27D7-4A84-8170-5FFB77A70C1F}.Release|Any CPU.Build.0 = Release|Any CPU - {DFC8DC5E-377D-4CCC-A498-5894D891A471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DFC8DC5E-377D-4CCC-A498-5894D891A471}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DFC8DC5E-377D-4CCC-A498-5894D891A471}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DFC8DC5E-377D-4CCC-A498-5894D891A471}.Release|Any CPU.Build.0 = Release|Any CPU - {F1EC1E94-C74C-4C37-961C-305CAE7C4707}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1EC1E94-C74C-4C37-961C-305CAE7C4707}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1EC1E94-C74C-4C37-961C-305CAE7C4707}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1EC1E94-C74C-4C37-961C-305CAE7C4707}.Release|Any CPU.Build.0 = Release|Any CPU - {16DBF49F-3E0C-4CD3-BB6C-1BBAF0D89AC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {16DBF49F-3E0C-4CD3-BB6C-1BBAF0D89AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {16DBF49F-3E0C-4CD3-BB6C-1BBAF0D89AC6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {16DBF49F-3E0C-4CD3-BB6C-1BBAF0D89AC6}.Release|Any CPU.Build.0 = Release|Any CPU - {762E8B1A-9182-4C5D-A25C-0C0F6219BA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {762E8B1A-9182-4C5D-A25C-0C0F6219BA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {762E8B1A-9182-4C5D-A25C-0C0F6219BA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {762E8B1A-9182-4C5D-A25C-0C0F6219BA4E}.Release|Any CPU.Build.0 = Release|Any CPU - {2CB4CF73-0CA8-4595-910C-EDA244EA5983}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2CB4CF73-0CA8-4595-910C-EDA244EA5983}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2CB4CF73-0CA8-4595-910C-EDA244EA5983}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2CB4CF73-0CA8-4595-910C-EDA244EA5983}.Release|Any CPU.Build.0 = Release|Any CPU - {2C798994-518D-4EA5-8F8A-3EAA30269F9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2C798994-518D-4EA5-8F8A-3EAA30269F9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2C798994-518D-4EA5-8F8A-3EAA30269F9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2C798994-518D-4EA5-8F8A-3EAA30269F9E}.Release|Any CPU.Build.0 = Release|Any CPU - {EC00B2EC-3CF0-43C3-A071-320AD3C355CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EC00B2EC-3CF0-43C3-A071-320AD3C355CF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EC00B2EC-3CF0-43C3-A071-320AD3C355CF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EC00B2EC-3CF0-43C3-A071-320AD3C355CF}.Release|Any CPU.Build.0 = Release|Any CPU - {F7091670-1059-4F4F-AC3A-0B1DE4A724B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7091670-1059-4F4F-AC3A-0B1DE4A724B5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7091670-1059-4F4F-AC3A-0B1DE4A724B5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7091670-1059-4F4F-AC3A-0B1DE4A724B5}.Release|Any CPU.Build.0 = Release|Any CPU - {6B9E6432-A7BB-4487-905A-0C3117398140}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B9E6432-A7BB-4487-905A-0C3117398140}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B9E6432-A7BB-4487-905A-0C3117398140}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B9E6432-A7BB-4487-905A-0C3117398140}.Release|Any CPU.Build.0 = Release|Any CPU - {A315C6D7-BEFF-4BD6-9786-88959E579F5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A315C6D7-BEFF-4BD6-9786-88959E579F5D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A315C6D7-BEFF-4BD6-9786-88959E579F5D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A315C6D7-BEFF-4BD6-9786-88959E579F5D}.Release|Any CPU.Build.0 = Release|Any CPU - {E09ADC19-3E9F-4DD5-AB74-A9EB765ED894}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E09ADC19-3E9F-4DD5-AB74-A9EB765ED894}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E09ADC19-3E9F-4DD5-AB74-A9EB765ED894}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E09ADC19-3E9F-4DD5-AB74-A9EB765ED894}.Release|Any CPU.Build.0 = Release|Any CPU - {A0FA4646-67AC-4310-9BA5-53D2D7CF218F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A0FA4646-67AC-4310-9BA5-53D2D7CF218F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A0FA4646-67AC-4310-9BA5-53D2D7CF218F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A0FA4646-67AC-4310-9BA5-53D2D7CF218F}.Release|Any CPU.Build.0 = Release|Any CPU - {8C81050A-951C-418F-BBA8-76EE0353863C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C81050A-951C-418F-BBA8-76EE0353863C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C81050A-951C-418F-BBA8-76EE0353863C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C81050A-951C-418F-BBA8-76EE0353863C}.Release|Any CPU.Build.0 = Release|Any CPU - {902CF0A5-3433-4CF4-AEFB-E1E0E7A5A3F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {902CF0A5-3433-4CF4-AEFB-E1E0E7A5A3F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {902CF0A5-3433-4CF4-AEFB-E1E0E7A5A3F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {902CF0A5-3433-4CF4-AEFB-E1E0E7A5A3F3}.Release|Any CPU.Build.0 = Release|Any CPU - {3EA06057-7FF8-C92D-16EE-28A0AFE3AEEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3EA06057-7FF8-C92D-16EE-28A0AFE3AEEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3EA06057-7FF8-C92D-16EE-28A0AFE3AEEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3EA06057-7FF8-C92D-16EE-28A0AFE3AEEF}.Release|Any CPU.Build.0 = Release|Any CPU - {26C02A1E-168B-2945-8AD2-7E7C30114F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {26C02A1E-168B-2945-8AD2-7E7C30114F91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {26C02A1E-168B-2945-8AD2-7E7C30114F91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {26C02A1E-168B-2945-8AD2-7E7C30114F91}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1059A7DE-95FA-4F54-85E3-84049E1872D5} = {F3260C54-834F-4C74-A3B7-EAB622AFA492} - {000ED0CF-EC9C-488C-BE85-14B95FFDF104} = {F3260C54-834F-4C74-A3B7-EAB622AFA492} - {07CA1F46-21DA-4C22-A8CB-52D526D51C94} = {CF54EDFD-51AB-4B0D-B084-2DF42918BA51} - {461788B0-072C-485F-82C0-F83CCC86F95D} = {CF54EDFD-51AB-4B0D-B084-2DF42918BA51} - {1086F24E-32C8-4261-9B06-A364EEE71DEF} = {9BD3CC85-97FD-4093-AA11-58FE405B0F65} - {1CC20AA4-11F1-4548-9285-FD24D42190FB} = {9BD3CC85-97FD-4093-AA11-58FE405B0F65} - {22278D91-27D7-4A84-8170-5FFB77A70C1F} = {D639C635-01D1-48C4-89B5-1FD70F1AFEE9} - {DFC8DC5E-377D-4CCC-A498-5894D891A471} = {705B8FB2-D707-4527-91FC-0AADEDBA4D80} - {F1EC1E94-C74C-4C37-961C-305CAE7C4707} = {705B8FB2-D707-4527-91FC-0AADEDBA4D80} - {16DBF49F-3E0C-4CD3-BB6C-1BBAF0D89AC6} = {705B8FB2-D707-4527-91FC-0AADEDBA4D80} - {762E8B1A-9182-4C5D-A25C-0C0F6219BA4E} = {D639C635-01D1-48C4-89B5-1FD70F1AFEE9} - {2CB4CF73-0CA8-4595-910C-EDA244EA5983} = {D639C635-01D1-48C4-89B5-1FD70F1AFEE9} - {2C798994-518D-4EA5-8F8A-3EAA30269F9E} = {D639C635-01D1-48C4-89B5-1FD70F1AFEE9} - {EC00B2EC-3CF0-43C3-A071-320AD3C355CF} = {A279C2F9-3418-484B-A36E-D1D1C67A0B2D} - {F7091670-1059-4F4F-AC3A-0B1DE4A724B5} = {A279C2F9-3418-484B-A36E-D1D1C67A0B2D} - {6B9E6432-A7BB-4487-905A-0C3117398140} = {A279C2F9-3418-484B-A36E-D1D1C67A0B2D} - {A315C6D7-BEFF-4BD6-9786-88959E579F5D} = {E2EBD5E0-81EC-4720-833C-05ECE1BA84A1} - {E09ADC19-3E9F-4DD5-AB74-A9EB765ED894} = {E2EBD5E0-81EC-4720-833C-05ECE1BA84A1} - {A0FA4646-67AC-4310-9BA5-53D2D7CF218F} = {E2EBD5E0-81EC-4720-833C-05ECE1BA84A1} - {8C81050A-951C-418F-BBA8-76EE0353863C} = {E2EBD5E0-81EC-4720-833C-05ECE1BA84A1} - {902CF0A5-3433-4CF4-AEFB-E1E0E7A5A3F3} = {E2EBD5E0-81EC-4720-833C-05ECE1BA84A1} - {3EA06057-7FF8-C92D-16EE-28A0AFE3AEEF} = {D639C635-01D1-48C4-89B5-1FD70F1AFEE9} - {26C02A1E-168B-2945-8AD2-7E7C30114F91} = {D639C635-01D1-48C4-89B5-1FD70F1AFEE9} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {7D1BF641-26E8-4809-B638-029241C51BE2} - EndGlobalSection -EndGlobal diff --git a/src/cs/vim-format.slnx b/src/cs/vim-format.slnx new file mode 100644 index 00000000..6a23ed80 --- /dev/null +++ b/src/cs/vim-format.slnx @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs b/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs index f34cddda..eb57c3a1 100644 --- a/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs +++ b/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Reflection; -using Vim.Format.ObjectModel; using Vim.Util; namespace Vim.Format.CodeGen; diff --git a/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs b/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs deleted file mode 100644 index d1d762e3..00000000 --- a/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs +++ /dev/null @@ -1,616 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using Vim.Format.ObjectModel; -using Vim.Util; - -namespace Vim.Format.CodeGen; - -public static class ObjectModelGenerator -{ - public static string GetEntityTableGetterFunctionName(this ValueSerializationStrategy strategy, Type type) - { - return strategy switch - { - ValueSerializationStrategy.SerializeAsStringColumn - => nameof(EntityTable.GetStringColumnValues), - ValueSerializationStrategy.SerializeAsDataColumn - => $"{nameof(EntityTable.GetDataColumnValues)}<{type.Name}>", - _ => throw new Exception($"{nameof(GetEntityTableGetterFunctionName)} error - unknown strategy {strategy:G}") - }; - } - - public static string GetEntityTable_v2GetterFunctionName(this ValueSerializationStrategy strategy, Type type) - { - return strategy switch - { - ValueSerializationStrategy.SerializeAsStringColumn - => nameof(EntityTable_v2.GetStringColumnValues), - ValueSerializationStrategy.SerializeAsDataColumn - => $"{nameof(EntityTable_v2.GetDataColumnValues)}<{type.Name}>", - _ => throw new Exception($"{nameof(GetEntityTable_v2GetterFunctionName)} error - unknown strategy {strategy:G}") - }; - } - - private static string GetEntityTableBuilderAddFunctionName(this ValueSerializationStrategy strategy, Type typeName) - { - return strategy switch - { - ValueSerializationStrategy.SerializeAsStringColumn - => nameof(EntityTableBuilder.AddStringColumn), - ValueSerializationStrategy.SerializeAsDataColumn - => $"{nameof(EntityTableBuilder.AddDataColumn)}", - _ => throw new Exception($"{nameof(GetEntityTableBuilderAddFunctionName)} error - unknown strategy {strategy:G}") - }; - } - - private class EntityFields - { - public readonly List TableInitializers = new(); - public readonly List ArraysInitializers = new(); - public readonly List RelationalColumns = new(); - } - - private static CodeBuilder WriteDocumentEntityData(Type t, CodeBuilder cb, EntityFields constructor) - { - cb.AppendLine(""); - cb.AppendLine($"// {t.Name}"); - cb.AppendLine(""); - - var relationFields = t.GetRelationFields().ToArray(); - var entityFields = t.GetEntityFields().ToArray(); - - // EntityTables - cb.AppendLine($"public EntityTable {t.Name}EntityTable {{ get; }}"); - constructor.TableInitializers.Add($"{t.Name}EntityTable = Document.GetTable(\"{t.GetEntityTableName()}\");"); - cb.AppendLine(""); - - // Get each non-relational columns for each element - foreach (var fieldInfo in entityFields) - { - var fieldName = fieldInfo.Name; - var fieldType = fieldInfo.FieldType; - var fieldTypeName = fieldInfo.FieldType.Name; - - var loadingInfos = fieldInfo.GetEntityColumnLoadingInfo(); - - var baseStrategy = loadingInfos[0].Strategy; // Invariant: there is always at least one entityColumnInfo (the default one) - - var dataColumnGetters = loadingInfos.Select(eci => - { - var functionName = eci.Strategy.GetEntityTableGetterFunctionName(eci.EntityColumnAttribute.SerializedType); - var dataColumnGetter = $"{t.Name}EntityTable?.{functionName}(\"{eci.SerializedValueColumnName}\")"; - if (eci.EntityColumnAttribute.SerializedType != fieldType) - { - dataColumnGetter += $"?.Select(v => ({fieldTypeName}) v)"; - } - return dataColumnGetter; - }).ToArray(); - - var dataColumnGetterString = dataColumnGetters.Length > 1 - ? $"({string.Join(" ?? ", dataColumnGetters)})" - : dataColumnGetters[0]; - - cb.AppendLine($"public IArray<{fieldTypeName}> {t.Name}{fieldName} {{ get; }}"); - constructor.ArraysInitializers - .Add($"{t.Name}{fieldName} = {dataColumnGetterString} ?? Array.Empty<{fieldTypeName}>().ToIArray();"); - - // Safe accessor. - var defaultValue = baseStrategy == ValueSerializationStrategy.SerializeAsStringColumn ? "\"\"" : "default"; - cb.AppendLine($"public {fieldTypeName} Get{t.Name}{fieldName}(int index, {fieldTypeName} defaultValue = {defaultValue}) => {t.Name}{fieldName}?.ElementAtOrDefault(index, defaultValue) ?? defaultValue;"); - } - - // Get each relational column - foreach (var fieldInfo in relationFields) - { - var (indexColumnName, localFieldName) = fieldInfo.GetIndexColumnInfo(); - - cb.AppendLine($"public IArray {t.Name}{localFieldName}Index {{ get; }}"); - constructor.RelationalColumns - .Add($"{t.Name}{localFieldName}Index = {t.Name}EntityTable?.GetIndexColumnValues(\"{indexColumnName}\") ?? Array.Empty().ToIArray();"); - - cb.AppendLine($"public int Get{t.Name}{localFieldName}Index(int index) => {t.Name}{localFieldName}Index?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None;"); - } - - // Num Count - cb.AppendLine($"public int Num{t.Name} => {t.Name}EntityTable?.NumRows ?? 0;"); - - // Entity lists - cb.AppendLine($"public IArray<{t.Name}> {t.Name}List {{ get; }}"); - - // Element getter function - cb.AppendLine($"public {t.Name} Get{t.Name}(int n)"); - cb.AppendLine("{"); - - // Get the entity retrieval function - cb.AppendLine("if (n < 0) return null;"); - cb.AppendLine($"var r = new {t.Name}();"); - cb.AppendLine("r.Document = Document;"); - cb.AppendLine("r.Index = n;"); - foreach (var fieldInfo in entityFields) - { - cb.AppendLine($"r.{fieldInfo.Name} = {t.Name}{fieldInfo.Name}.ElementAtOrDefault(n);"); - } - - foreach (var fieldInfo in relationFields) - { - var relType = fieldInfo.FieldType.RelationTypeParameter(); - cb.AppendLine($"r.{fieldInfo.Name} = new Relation<{relType}>(Get{t.Name}{fieldInfo.Name.Substring(1)}Index(n), Get{relType.Name});"); - } - - cb.AppendLine("return r;"); - cb.AppendLine("}"); - cb.AppendLine(); - - return cb; - } - - private static CodeBuilder WriteEntityClass(Type t, CodeBuilder cb = null) - { - var relationFields = t.GetRelationFields().ToArray(); - - cb ??= new CodeBuilder(); - cb.AppendLine("// AUTO-GENERATED"); - cb.AppendLine($"public partial class {t.Name}").AppendLine("{"); - foreach (var fieldInfo in relationFields) - { - var relationFieldName = fieldInfo.Name.Substring(1); - cb.AppendLine($"public {fieldInfo.FieldType.RelationTypeParameter()} {relationFieldName} => {fieldInfo.Name}?.Value;"); - cb.AppendLine($"public int {relationFieldName}Index => {fieldInfo.Name}?.Index ?? EntityRelation.None;"); - } - - cb.AppendLine($"public {t.Name}()"); - cb.AppendLine("{"); - foreach (var fieldInfo in relationFields) - { - cb.AppendLine($"{fieldInfo.Name} = new Relation<{fieldInfo.FieldType.RelationTypeParameter()}>();"); - } - - cb.AppendLine("}"); - cb.AppendLine(); - - cb.AppendLine("public override bool FieldsAreEqual(object obj)"); - cb.AppendLine("{"); - - cb.WriteFieldsAreEqualsType(t); - - cb.AppendLine("return false;"); - cb.AppendLine("}"); - cb.AppendLine(); - - cb.AppendLine("} // end of class"); - cb.AppendLine(); - return cb; - } - - private static CodeBuilder WriteFieldsAreEqualsType(this CodeBuilder cb, Type t, - (string @namespace, string variable)? modifier = null) - { - var entityFields = t.GetEntityFields().ToArray(); - var relationFields = t.GetRelationFields().ToArray(); - - var type = (modifier?.@namespace ?? string.Empty) + t.Name; - var variable = (modifier?.variable ?? string.Empty) + "other"; - - cb.AppendLine($"if ((obj is {type} {variable}))"); - cb.AppendLine("{"); - cb.AppendLine("var fieldsAreEqual ="); - - IEnumerable GetEquatableFields(FieldInfo[] fis) - => fis.Where(fi => !fi.GetCustomAttributes().Any(a => a is IgnoreInEquality)); - - var entityFieldComparisons = GetEquatableFields(entityFields).Select(f => $"({f.Name} == {variable}.{f.Name})") - .Prepend($"(Index == {variable}.Index)"); - var relationFieldComparisons = GetEquatableFields(relationFields) - .Select(f => $"({f.Name}?.Index == {variable}.{f.Name}?.Index)"); - - var comparisons = entityFieldComparisons.Concat(relationFieldComparisons).ToArray(); - for (var i = 0; i < comparisons.Length; ++i) - { - var comparison = comparisons[i]; - cb.AppendLine($" {comparison}{(i == comparisons.Length - 1 ? ";" : " &&")}"); - } - - cb.AppendLine("if (!fieldsAreEqual)"); - cb.AppendLine("{"); - cb.AppendLine("return false;"); - cb.AppendLine("}"); - cb.AppendLine(); - - cb.AppendLine("return true;"); - cb.AppendLine("}"); - - return cb; - } - - private static CodeBuilder WriteDocument(CodeBuilder cb) - { - var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); - - foreach (var et in entityTypes) - WriteEntityClass(et, cb); - - cb.AppendLine("public partial class DocumentModel"); - cb.AppendLine("{"); - - cb.AppendLine("public ElementIndexMaps ElementIndexMaps { get; }"); - - var entityFields = new EntityFields(); - foreach (var et in entityTypes) - WriteDocumentEntityData(et, cb, entityFields); - - cb.AppendLine("// All entity collections"); - cb.AppendLine("public Dictionary> AllEntities => new Dictionary>() {"); - foreach (var t in entityTypes) - cb.AppendLine($"{{\"{t.GetEntityTableName()}\", {t.Name}List.ToEnumerable()}},"); - cb.AppendLine("};"); - cb.AppendLine(); - - cb.AppendLine("// Entity types from table names"); - cb.AppendLine("public Dictionary EntityTypes => new Dictionary() {"); - foreach (var t in entityTypes) - cb.AppendLine($"{{\"{t.GetEntityTableName()}\", typeof({t.Name})}},"); - cb.AppendLine("};"); - - // Write the constructor - cb.AppendLine("public DocumentModel(Document d, bool inParallel = true)"); - cb.AppendLine("{"); - cb.AppendLine("Document = d;"); - cb.AppendLine(); - - cb.AppendLine("// Initialize entity tables"); - foreach (var line in entityFields.TableInitializers) - cb.AppendLine(line); - cb.AppendLine(""); - - cb.AppendLine("// Initialize entity arrays"); - foreach (var line in entityFields.ArraysInitializers) - cb.AppendLine(line); - cb.AppendLine(""); - - cb.AppendLine("// Initialize entity relational columns"); - foreach (var line in entityFields.RelationalColumns) - cb.AppendLine(line); - cb.AppendLine(""); - - - cb.AppendLine("// Initialize entity collections"); - foreach (var t in entityTypes) - cb.AppendLine($"{t.Name}List = Num{t.Name}.Select(i => Get{t.Name}(i));"); - cb.AppendLine(); - - cb.AppendLine("// Initialize element index maps"); - cb.AppendLine("ElementIndexMaps = new ElementIndexMaps(this, inParallel);"); - - cb.AppendLine("}"); - cb.AppendLine("} // Document class"); - cb.AppendLine(); - return cb; - } - - private static void WriteEntityTableSet(CodeBuilder cb) - { - var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); - - cb.AppendLine("public partial class EntityTableSet"); - cb.AppendLine("{"); - cb.AppendLine("public string[] StringTable { get; }"); - cb.AppendLine(); - cb.AppendLine("public Dictionary RawTableMap { get; } = new Dictionary();"); - cb.AppendLine(); - cb.AppendLine("public Dictionary Tables { get; } = new Dictionary();"); - cb.AppendLine(); - cb.AppendLine("public SerializableEntityTable GetSerializableTableOrEmpty(string tableName)"); - cb.AppendLine(" => RawTableMap.TryGetValue(tableName, out var result) ? result : new SerializableEntityTable { Name = tableName };"); - cb.AppendLine(); - cb.AppendLine("public ElementIndexMaps ElementIndexMaps { get; }"); - cb.AppendLine(); - - cb.AppendLine("public EntityTableSet(SerializableEntityTable[] rawTables, string[] stringTable, bool inParallel = true)"); - cb.AppendLine("{"); - cb.AppendLine("StringTable = stringTable;"); - cb.AppendLine(); - cb.AppendLine("foreach (var rawTable in rawTables)"); - cb.AppendLine(" RawTableMap[rawTable.Name] = rawTable;"); - cb.AppendLine(); - cb.AppendLine("// Populate the entity tables."); - foreach (var t in entityTypes) - { - cb.AppendLine($"Tables[TableNames.{t.Name}] = {t.Name}Table = new {t.Name}Table(GetSerializableTableOrEmpty(TableNames.{t.Name}), stringTable, this);"); - } - cb.AppendLine(); - cb.AppendLine("// Initialize element index maps"); - cb.AppendLine("ElementIndexMaps = new ElementIndexMaps(this, inParallel);"); - cb.AppendLine(); - cb.AppendLine("} // EntityTableSet constructor"); - - cb.AppendLine(); - foreach (var t in entityTypes) - { - cb.AppendLine($"public {t.Name}Table {t.Name}Table {{ get; }} // can be null"); - cb.AppendLine($"public {t.Name} Get{t.Name}(int index) => {t.Name}Table?.Get(index);"); - } - - var elementKindEntityTypes = entityTypes - .Select(t => (t, t.GetElementKind())) - .Where(tuple => tuple.Item2 != ElementKind.Unknown) - .ToArray(); - cb.AppendLine(); - cb.AppendLine("public static HashSet GetElementKindTableNames()"); - cb.AppendLine(" => new HashSet()"); - cb.AppendLine(" {"); - foreach (var (t, _) in elementKindEntityTypes) - { - cb.AppendLine( $"TableNames.{t.Name},"); - } - cb.AppendLine(" };"); - - cb.AppendLine(); - cb.AppendLine("// Returns an array defining a 1:1 association of Element to its ElementKind"); - cb.AppendLine("public ElementKind[] GetElementKinds()"); - cb.AppendLine("{"); - cb.AppendLine("var elementKinds = new ElementKind[ElementTable?.RowCount ?? 0];"); - cb.AppendLine(); - cb.AppendLine("if (elementKinds.Length == 0) return elementKinds;"); - cb.AppendLine(); - cb.AppendLine("// Initialize all element kinds to unknown"); - cb.AppendLine("for (var i = 0; i < elementKinds.Length; ++i) { elementKinds[i] = ElementKind.Unknown; }"); - cb.AppendLine(); - cb.AppendLine("// Populate the element kinds from the relevant entity tables"); - foreach (var (t, elementKind) in elementKindEntityTypes) - { - var etPropertyName = $"{t.Name}Table"; - cb.AppendLine($"for (var i = 0; i < ({etPropertyName}?.RowCount ?? 0); ++i)"); - cb.AppendLine("{"); - cb.AppendLine($"var elementIndex = {etPropertyName}?.Column_ElementIndex[i] ?? EntityRelation.None;"); - cb.AppendLine("if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue;"); - cb.AppendLine(); - cb.AppendLine("var currentElementKind = elementKinds[elementIndex];"); - cb.AppendLine($"var candidateElementKind = ElementKind.{elementKind:G};"); - cb.AppendLine(); - // NOTE: In some cases, a Group entity shares the same element as a FamilyInstance entity. - // Likewise, sometimes a System entity shares the same element as a FamilyInstance entity. - // In these cases, the ElementKind.FamilyInstance takes priority because of the comparison between the currentElementKind and the candidateElementKind. - cb.AppendLine("// Only update the element kind if it is unknown or if it is less than the current kind."); - cb.AppendLine("if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue;"); - cb.AppendLine(); - cb.AppendLine("elementKinds[elementIndex] = candidateElementKind;"); - cb.AppendLine("}"); - cb.AppendLine(); - } - cb.AppendLine("return elementKinds;"); - cb.AppendLine("} // GetElementKinds()"); - - cb.AppendLine("} // class EntityTableSet"); - cb.AppendLine(); - - foreach (var t in entityTypes) - WriteEntityTable(cb, t); - } - - private static void WriteEntityTable(CodeBuilder cb, Type t) - { - var entityFields = t.GetEntityFields().ToArray(); - var relationFields = t.GetRelationFields().ToArray(); - - var elementKind = t.GetElementKind(); - - cb.AppendLine($"public partial class {t.Name}Table : EntityTable_v2, IEnumerable<{t.Name}>{(elementKind != ElementKind.Unknown ? " , IElementKindTable" : "")}"); - cb.AppendLine("{"); - cb.AppendLine(); - cb.AppendLine($"public const string TableName = TableNames.{t.Name};"); - cb.AppendLine(); - cb.AppendLine("public EntityTableSet ParentTableSet { get; } // can be null"); - cb.AppendLine(); - cb.AppendLine($"public {t.Name}Table(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable)"); - cb.AppendLine("{"); - cb.AppendLine("ParentTableSet = parentTableSet;"); - foreach (var f in entityFields) - { - var fieldName = f.Name; - var fieldType = f.FieldType; - var fieldTypeName = f.FieldType.Name; - var loadingInfos = f.GetEntityColumnLoadingInfo(); - - var dataColumnGetters = loadingInfos.Select(eci => - { - var functionName = eci.Strategy.GetEntityTable_v2GetterFunctionName(eci.EntityColumnAttribute.SerializedType); - var dataColumnGetter = $"{functionName}(\"{eci.SerializedValueColumnName}\")"; - if (eci.EntityColumnAttribute.SerializedType != fieldType) - { - dataColumnGetter += $"?.Select(v => ({fieldTypeName}) v).ToArray()"; - } - return dataColumnGetter; - }).ToArray(); - - var dataColumnGetterString = dataColumnGetters.Length > 1 - ? $"({string.Join(" ?? ", dataColumnGetters)})" - : dataColumnGetters[0]; - - cb.AppendLine($"Column_{fieldName} = {dataColumnGetterString} ?? Array.Empty<{fieldTypeName}>();"); - } - foreach (var f in relationFields) - { - var (indexColumnName, localFieldName) = f.GetIndexColumnInfo(); - cb.AppendLine($"Column_{localFieldName}Index = GetIndexColumnValues(\"{indexColumnName}\") ?? Array.Empty();"); - } - cb.AppendLine("}"); - cb.AppendLine(); - - foreach (var f in entityFields) - { - var fieldName = f.Name; - var fieldTypeName = f.FieldType.Name; - var loadingInfos = f.GetEntityColumnLoadingInfo(); - var baseStrategy = loadingInfos[0].Strategy; // Invariant: there is always at least one entityColumnInfo (the default one) - var defaultValue = baseStrategy == ValueSerializationStrategy.SerializeAsStringColumn ? "\"\"" : "default"; - - cb.AppendLine($"public {fieldTypeName}[] Column_{fieldName} {{ get; }}"); - cb.AppendLine($"public {fieldTypeName} Get{fieldName}(int index, {fieldTypeName} @default = {defaultValue}) => Column_{fieldName}.ElementAtOrDefault(index, @default);"); - } - foreach (var f in relationFields) - { - var (_, localFieldName) = f.GetIndexColumnInfo(); - var relType = f.FieldType.RelationTypeParameter(); - cb.AppendLine($"public int[] Column_{localFieldName}Index {{ get; }}"); - cb.AppendLine($"public int Get{localFieldName}Index(int index) => Column_{localFieldName}Index.ElementAtOrDefault(index, EntityRelation.None);"); - cb.AppendLine($"public {relType.Name} Get{localFieldName}(int index) => _GetReferenced{localFieldName}(Get{localFieldName}Index(index));"); - cb.AppendLine($"private {relType.Name} _GetReferenced{localFieldName}(int referencedIndex) => ParentTableSet.Get{relType.Name}(referencedIndex);"); - } - - cb.AppendLine("// Object Getter"); - cb.AppendLine($"public {t.Name} Get(int index)"); - cb.AppendLine("{"); - cb.AppendLine("if (index < 0) return null;"); - cb.AppendLine($"var r = new {t.Name}();"); - cb.AppendLine("r.Index = index;"); - foreach (var f in entityFields) - { - cb.AppendLine($"r.{f.Name} = Get{f.Name}(index);"); - } - foreach (var f in relationFields) - { - var (_, localFieldName) = f.GetIndexColumnInfo(); - var relType = f.FieldType.RelationTypeParameter(); - cb.AppendLine($"r.{f.Name} = new Relation<{relType}>(Get{f.Name.Substring(1)}Index(index), _GetReferenced{localFieldName});"); - } - cb.AppendLine("return r;"); - cb.AppendLine("}"); - - cb.AppendLine("// Enumerator"); - cb.AppendLine("IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();"); - cb.AppendLine($"public IEnumerator<{t.Name}> GetEnumerator()"); - cb.AppendLine("{"); - cb.AppendLine("for (var i = 0; i < RowCount; ++i)"); - cb.AppendLine(" yield return Get(i);"); - cb.AppendLine("}"); - - cb.AppendLine($"}} // class {t.Name}Table "); - cb.AppendLine(); - } - - private static void WriteDocumentBuilder(CodeBuilder cb) - { - var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); - - cb.AppendLine("public static class DocumentBuilderExtensions"); - cb.AppendLine("{"); - - foreach (var et in entityTypes) - { - var entityType = et.Name; - cb.AppendLine($"public static EntityTableBuilder To{entityType}TableBuilder(this EntitySetBuilder<{entityType}> entitySet)"); - cb.AppendLine("{"); - - //cb.AppendLine($"var typedEntities = entities?.Cast<{entityType}>() ?? Enumerable.Empty<{entityType}>();"); - var tableName = et.GetEntityTableName(); - cb.AppendLine($"var tb = new EntityTableBuilder(TableNames.{et.Name});"); - cb.AppendLine("var entities = entitySet.Entities;"); - cb.AppendLine("var entityCount = entities.Count;"); - - var entityFields = et.GetEntityFields().ToArray(); - var relationFields = et.GetRelationFields().ToArray(); - - if ((entityFields.Length + relationFields.Length) == 0) - throw new Exception($"Entity table {tableName} does not contain any fields."); - - foreach (var fieldInfo in entityFields) - { - var (strategy, _) = fieldInfo.FieldType.GetValueSerializationStrategyAndTypePrefix(); - var functionName = strategy.GetEntityTableBuilderAddFunctionName(fieldInfo.FieldType); - cb.AppendLine("{"); - cb.AppendLine($"var columnData = new {fieldInfo.FieldType.Name}[entityCount];"); - cb.AppendLine($"for (var i = 0; i < columnData.Length; ++i) {{ columnData[i] = entities[i].{fieldInfo.Name}; }}"); - cb.AppendLine($"tb.{functionName}(\"{fieldInfo.GetSerializedValueColumnName()}\", columnData);"); - cb.AppendLine("}"); - } - - foreach (var fieldInfo in relationFields) - { - var (indexColumnName, localFieldName) = fieldInfo.GetIndexColumnInfo(); - cb.AppendLine("{"); - cb.AppendLine("var columnData = new int[entityCount];"); - cb.AppendLine($"for (var i = 0; i < columnData.Length; ++i) {{ columnData[i] = entities[i]._{localFieldName}?.Index ?? EntityRelation.None; }}"); - cb.AppendLine($"tb.AddIndexColumn(\"{indexColumnName}\", columnData);"); - cb.AppendLine("}"); - } - - cb.AppendLine("return tb;"); - cb.AppendLine("}"); - } - - cb.AppendLine("} // DocumentBuilderExtensions"); - cb.AppendLine(); - - cb.AppendLine("public partial class ObjectModelBuilder"); - cb.AppendLine("{"); - // NOTE: the following lines must not be made static since the ObjectModelBuilder is instantiated upon each new export. - // Making this static will cause the contained EntitySetBuilders to accumulate data from previous exports during the lifetime of the program. - - // Instantiates a named entity table builder for each type. - foreach (var et in entityTypes) - cb.AppendLine($"public readonly EntitySetBuilder<{et.Name}> {et.Name}Builder = new EntitySetBuilder<{et.Name}>(TableNames.{et.Name});"); - - cb.AppendLine(); - cb.AppendLine("public DocumentBuilder AddEntityTableSets(DocumentBuilder db)"); - cb.AppendLine("{"); - foreach (var et in entityTypes) - { - cb.AppendLine($"db.Tables.Add({et.Name}Builder.EntityTableName, {et.Name}Builder.To{et.Name}TableBuilder());"); - } - cb.AppendLine(); - cb.AppendLine("return db;"); - cb.AppendLine("} // AddEntityTableSets"); - - cb.AppendLine(); - cb.AppendLine("public void Clear()"); - cb.AppendLine("{"); - foreach (var et in entityTypes) - { - cb.AppendLine($"{et.Name}Builder.Clear();"); - } - cb.AppendLine("} // Clear"); - - cb.AppendLine("} // ObjectModelBuilder"); - } - - public static void WriteDocument(string file) - { - try - { - var cb = new CodeBuilder(); - - cb.AppendLine("// AUTO-GENERATED FILE, DO NOT MODIFY."); - cb.AppendLine("// ReSharper disable All"); - cb.AppendLine("using System;"); - cb.AppendLine("using System.Collections;"); - cb.AppendLine("using System.Collections.Generic;"); - cb.AppendLine("using System.Linq;"); - cb.AppendLine("using Vim.Math3d;"); - cb.AppendLine("using Vim.LinqArray;"); - cb.AppendLine("using Vim.Format.ObjectModel;"); - cb.AppendLine("using Vim.Util;"); - - cb.AppendLine(); - - cb.AppendLine("namespace Vim.Format.ObjectModel {"); - - WriteDocument(cb); - - WriteEntityTableSet(cb); - - WriteDocumentBuilder(cb); - - cb.AppendLine("} // namespace"); - var content = cb.ToString(); - File.WriteAllText(file, content); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } -} diff --git a/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs b/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs index b7556958..d8e002a4 100644 --- a/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs +++ b/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Reflection; -using Vim.Format.ObjectModel; using Vim.Util; namespace Vim.Format.CodeGen; diff --git a/src/cs/vim/Vim.Format.CodeGen/Program.cs b/src/cs/vim/Vim.Format.CodeGen/Program.cs index ccca1d5f..1ff38366 100644 --- a/src/cs/vim/Vim.Format.CodeGen/Program.cs +++ b/src/cs/vim/Vim.Format.CodeGen/Program.cs @@ -4,13 +4,13 @@ public static class Program { public static void Main(string[] args) { - var file = args[0]; - var tsFile = args[1]; - var hFile = args[2]; + var vimEntityCodeGenFilePath = args[0]; + var tsFilePath = args[1]; + var hFilePath = args[2]; - ObjectModelGenerator.WriteDocument(file); - ObjectModelTypeScriptGenerator.WriteDocument(tsFile); - ObjectModelCppGenerator.WriteDocument(hFile); + VimEntityCodeGen.WriteDocument(vimEntityCodeGenFilePath); + ObjectModelTypeScriptGenerator.WriteDocument(tsFilePath); + ObjectModelCppGenerator.WriteDocument(hFilePath); } } } diff --git a/src/cs/vim/Vim.Format.CodeGen/Vim.Format.CodeGen.csproj b/src/cs/vim/Vim.Format.CodeGen/Vim.Format.CodeGen.csproj index 80e19f14..26bebf7b 100644 --- a/src/cs/vim/Vim.Format.CodeGen/Vim.Format.CodeGen.csproj +++ b/src/cs/vim/Vim.Format.CodeGen/Vim.Format.CodeGen.csproj @@ -8,7 +8,7 @@ OnOutputUpdated - + @@ -21,7 +21,7 @@ - + diff --git a/src/cs/vim/Vim.Format.CodeGen/VimEntityCodeGen.cs b/src/cs/vim/Vim.Format.CodeGen/VimEntityCodeGen.cs new file mode 100644 index 00000000..90774e60 --- /dev/null +++ b/src/cs/vim/Vim.Format.CodeGen/VimEntityCodeGen.cs @@ -0,0 +1,389 @@ +using System; +using System.IO; +using System.Linq; +using Vim.Util; + +namespace Vim.Format.CodeGen; + +public static class VimEntityCodeGen +{ + public const string EntityNamespace = "Vim.Format"; + + public static string GetVimEntityTableGetterFunctionName(this ValueSerializationStrategy strategy, Type type) + { + return strategy switch + { + ValueSerializationStrategy.SerializeAsStringColumn + => nameof(VimEntityTable.GetStringColumnValues), + ValueSerializationStrategy.SerializeAsDataColumn + => $"{nameof(VimEntityTable.GetDataColumnValues)}<{type.Name}>", + _ => throw new Exception($"{nameof(GetVimEntityTableGetterFunctionName)} error - unknown strategy {strategy:G}") + }; + } + + private static string GetVimEntityTableBuilderAddFunctionName(this ValueSerializationStrategy strategy, Type typeName) + { + return strategy switch + { + ValueSerializationStrategy.SerializeAsStringColumn + => nameof(VimEntityTableBuilder.AddStringColumn), + ValueSerializationStrategy.SerializeAsDataColumn + => $"{nameof(VimEntityTableBuilder.AddDataColumn)}", + _ => throw new Exception($"{nameof(GetVimEntityTableBuilderAddFunctionName)} error - unknown strategy {strategy:G}") + }; + } + + private static void WriteVimEntityTableSet(CodeBuilder cb) + { + var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); + + cb.AppendLine("public partial class VimEntityTableSet"); + cb.AppendLine("{"); + cb.AppendLine("public void Initialize(bool inParallel = true)"); + cb.AppendLine("{"); + foreach (var t in entityTypes) + { + cb.AppendLine($"Tables[VimEntityTableNames.{t.Name}] = {t.Name}Table = new {t.Name}Table(GetEntityTableDataOrEmpty(VimEntityTableNames.{t.Name}), StringTable, this);"); + } + cb.AppendLine(); + cb.AppendLine("// Initialize element index maps"); + cb.AppendLine("ElementIndexMaps = new VimElementIndexMaps(this, inParallel);"); + cb.AppendLine(); + cb.AppendLine("} // end of Initialize"); + + cb.AppendLine(); + foreach (var t in entityTypes) + { + cb.AppendLine($"public {t.Name}Table {t.Name}Table {{ get; private set; }} // can be null"); + cb.AppendLine($"public {EntityNamespace}.{t.Name} Get{t.Name}(int index) => {t.Name}Table?.Get(index);"); + } + + var joiningTableTypes = entityTypes + .Select(t => (t, t.HasJoiningTable())) + .Where(tuple => tuple.Item2 != false) + .ToArray(); + cb.AppendLine(); + cb.AppendLine("public static HashSet GetJoiningTableNames()"); + cb.AppendLine(" => new HashSet()"); + cb.AppendLine(" {"); + foreach (var (t, _) in joiningTableTypes) + { + cb.AppendLine($"VimEntityTableNames.{t.Name},"); + } + cb.AppendLine(" };"); + + WriteElementKinds(cb); + + cb.AppendLine("} // end of partial class VimEntityTableSet"); + cb.AppendLine(); + } + + private static void WriteElementKinds(CodeBuilder cb) + { + var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); + + var elementKindEntityTypes = entityTypes + .Select(t => (t, t.GetElementKind())) + .Where(tuple => tuple.Item2 != ElementKind.Unknown) + .ToArray(); + cb.AppendLine(); + cb.AppendLine("public static HashSet GetElementKindTableNames()"); + cb.AppendLine(" => new HashSet()"); + cb.AppendLine(" {"); + foreach (var (t, _) in elementKindEntityTypes) + { + cb.AppendLine($"VimEntityTableNames.{t.Name},"); + } + cb.AppendLine(" };"); + + cb.AppendLine(); + cb.AppendLine("// Returns an array defining a 1:1 association of Element to its ElementKind"); + cb.AppendLine("public ElementKind[] GetElementKinds()"); + cb.AppendLine("{"); + cb.AppendLine("var elementKinds = new ElementKind[ElementTable?.RowCount ?? 0];"); + cb.AppendLine(); + cb.AppendLine("if (elementKinds.Length == 0) return elementKinds;"); + cb.AppendLine(); + cb.AppendLine("// Initialize all element kinds to unknown"); + cb.AppendLine("for (var i = 0; i < elementKinds.Length; ++i) { elementKinds[i] = ElementKind.Unknown; }"); + cb.AppendLine(); + cb.AppendLine("// Populate the element kinds from the relevant entity tables"); + foreach (var (t, elementKind) in elementKindEntityTypes) + { + var etPropertyName = $"{t.Name}Table"; + cb.AppendLine($"for (var i = 0; i < ({etPropertyName}?.RowCount ?? 0); ++i)"); + cb.AppendLine("{"); + cb.AppendLine($"var elementIndex = {etPropertyName}?.Column_ElementIndex[i] ?? EntityRelation.None;"); + cb.AppendLine("if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue;"); + cb.AppendLine(); + cb.AppendLine("var currentElementKind = elementKinds[elementIndex];"); + cb.AppendLine($"var candidateElementKind = ElementKind.{elementKind:G};"); + cb.AppendLine(); + // NOTE: In some cases, a Group entity shares the same element as a FamilyInstance entity. + // Likewise, sometimes a System entity shares the same element as a FamilyInstance entity. + // In these cases, the ElementKind.FamilyInstance takes priority because of the comparison between the currentElementKind and the candidateElementKind. + cb.AppendLine("// Only update the element kind if it is unknown or if it is less than the current kind."); + cb.AppendLine("if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue;"); + cb.AppendLine(); + cb.AppendLine("elementKinds[elementIndex] = candidateElementKind;"); + cb.AppendLine("}"); + cb.AppendLine(); + } + cb.AppendLine("return elementKinds;"); + cb.AppendLine("} // GetElementKinds()"); + } + + private static void WriteEntityTypes(CodeBuilder cb) + { + var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); + + foreach (var t in entityTypes) + { + WriteEntityClass(cb, t); + + WriteVimEntityTable(cb, t); + } + } + + private static void WriteEntityClass(CodeBuilder cb, Type t) + { + var relationFields = t.GetRelationFields().ToArray(); + + cb.AppendLine($"public partial class {t.Name}").AppendLine("{"); + foreach (var fieldInfo in relationFields) + { + var relationFieldName = fieldInfo.Name.Substring(1); + cb.AppendLine($"public {fieldInfo.FieldType.RelationTypeParameter()} {relationFieldName} => {fieldInfo.Name}?.Value;"); + cb.AppendLine($"public int {relationFieldName}Index => {fieldInfo.Name}?.Index ?? EntityRelation.None;"); + } + + cb.AppendLine($"public {t.Name}()"); + cb.AppendLine("{"); + foreach (var fieldInfo in relationFields) + { + cb.AppendLine($"{fieldInfo.Name} = new Relation<{fieldInfo.FieldType.RelationTypeParameter()}>();"); + } + + cb.AppendLine("}"); + cb.AppendLine($"}} // class {t.Name}"); + cb.AppendLine(); + } + + private static void WriteVimEntityTable(CodeBuilder cb, Type t) + { + var entityFields = t.GetEntityFields().ToArray(); + var relationFields = t.GetRelationFields().ToArray(); + + var elementKind = t.GetElementKind(); + + cb.AppendLine($"public partial class {t.Name}Table : VimEntityTable, IEnumerable<{EntityNamespace}.{t.Name}>{(elementKind != ElementKind.Unknown ? ", IElementKindTable" : "")}"); + cb.AppendLine("{"); + cb.AppendLine($"public const string TableName = VimEntityTableNames.{t.Name};"); + cb.AppendLine("public VimEntityTableSet ParentTableSet { get; } // can be null"); + cb.AppendLine($"public {t.Name}Table(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable)"); + cb.AppendLine("{"); + cb.AppendLine("ParentTableSet = parentTableSet;"); + foreach (var f in entityFields) + { + var fieldName = f.Name; + var fieldType = f.FieldType; + var fieldTypeName = f.FieldType.Name; + var loadingInfos = f.GetEntityColumnLoadingInfo(); + + var dataColumnGetters = loadingInfos.Select(eci => + { + var functionName = eci.Strategy.GetVimEntityTableGetterFunctionName(eci.EntityColumnAttribute.SerializedType); + var dataColumnGetter = $"{functionName}(\"{eci.SerializedValueColumnName}\")"; + if (eci.EntityColumnAttribute.SerializedType != fieldType) + { + dataColumnGetter += $"?.Select(v => ({fieldTypeName}) v).ToArray()"; + } + return dataColumnGetter; + }).ToArray(); + + var dataColumnGetterString = dataColumnGetters.Length > 1 + ? $"({string.Join(" ?? ", dataColumnGetters)})" + : dataColumnGetters[0]; + + cb.AppendLine($"Column_{fieldName} = {dataColumnGetterString} ?? Array.Empty<{fieldTypeName}>();"); + } + foreach (var f in relationFields) + { + var (indexColumnName, localFieldName) = f.GetIndexColumnInfo(); + cb.AppendLine($"Column_{localFieldName}Index = GetIndexColumnValues(\"{indexColumnName}\") ?? Array.Empty();"); + } + cb.AppendLine("}"); + + foreach (var f in entityFields) + { + var fieldName = f.Name; + var fieldTypeName = f.FieldType.Name; + var loadingInfos = f.GetEntityColumnLoadingInfo(); + var baseStrategy = loadingInfos[0].Strategy; // Invariant: there is always at least one entityColumnInfo (the default one) + var defaultValue = baseStrategy == ValueSerializationStrategy.SerializeAsStringColumn ? "\"\"" : "default"; + + cb.AppendLine($"public {fieldTypeName}[] Column_{fieldName} {{ get; }}"); + cb.AppendLine($"public {fieldTypeName} Get{fieldName}(int index, {fieldTypeName} @default = {defaultValue}) => Column_{fieldName}.ElementAtOrDefault(index, @default);"); + } + foreach (var f in relationFields) + { + var (_, localFieldName) = f.GetIndexColumnInfo(); + var relType = f.FieldType.RelationTypeParameter(); + cb.AppendLine($"public int[] Column_{localFieldName}Index {{ get; }}"); + cb.AppendLine($"public int Get{localFieldName}Index(int index) => Column_{localFieldName}Index.ElementAtOrDefault(index, EntityRelation.None);"); + cb.AppendLine($"public {EntityNamespace}.{relType.Name} Get{localFieldName}(int index) => _GetReferenced{localFieldName}(Get{localFieldName}Index(index));"); + cb.AppendLine($"private {EntityNamespace}.{relType.Name} _GetReferenced{localFieldName}(int referencedIndex) => ParentTableSet.Get{relType.Name}(referencedIndex);"); + } + + cb.AppendLine($"public {EntityNamespace}.{t.Name} Get(int index)"); + cb.AppendLine("{"); + cb.AppendLine("if (index < 0) return null;"); + cb.AppendLine($"var r = new {EntityNamespace}.{t.Name}();"); + cb.AppendLine("r.Index = index;"); + foreach (var f in entityFields) + { + cb.AppendLine($"r.{f.Name} = Get{f.Name}(index);"); + } + foreach (var f in relationFields) + { + var (_, localFieldName) = f.GetIndexColumnInfo(); + var relType = f.FieldType.RelationTypeParameter(); + cb.AppendLine($"r.{f.Name} = new Relation<{relType}>(Get{f.Name.Substring(1)}Index(index), _GetReferenced{localFieldName});"); + } + cb.AppendLine("return r;"); + cb.AppendLine("}"); + cb.AppendLine("IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();"); + cb.AppendLine($"public IEnumerator<{EntityNamespace}.{t.Name}> GetEnumerator()"); + cb.AppendLine("{"); + cb.AppendLine("for (var i = 0; i < RowCount; ++i)"); + cb.AppendLine(" yield return Get(i);"); + cb.AppendLine("}"); + + cb.AppendLine($"}} // class {t.Name}Table"); + cb.AppendLine(); + } + + private static void WriteVimBuilder(CodeBuilder cb) + { + var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); + + cb.AppendLine("public static class VimEntitySetBuilderExtensions"); + cb.AppendLine("{"); + + foreach (var et in entityTypes) + { + var entityType = et.Name; + cb.AppendLine($"public static VimEntityTableBuilder To{entityType}TableBuilder(this VimEntitySetBuilder<{EntityNamespace}.{entityType}> entitySetBuilder)"); + cb.AppendLine("{"); + + //cb.AppendLine($"var typedEntities = entities?.Cast<{entityType}>() ?? Enumerable.Empty<{entityType}>();"); + var tableName = et.GetEntityTableName(); + cb.AppendLine($"var tb = new VimEntityTableBuilder(VimEntityTableNames.{et.Name});"); + cb.AppendLine("var entities = entitySetBuilder.Entities;"); + cb.AppendLine("var entityCount = entities.Count;"); + + var entityFields = et.GetEntityFields().ToArray(); + var relationFields = et.GetRelationFields().ToArray(); + + if ((entityFields.Length + relationFields.Length) == 0) + throw new Exception($"Entity table {tableName} does not contain any fields."); + + foreach (var fieldInfo in entityFields) + { + var (strategy, _) = fieldInfo.FieldType.GetValueSerializationStrategyAndTypePrefix(); + var functionName = strategy.GetVimEntityTableBuilderAddFunctionName(fieldInfo.FieldType); + cb.AppendLine("{"); + cb.AppendLine($"var columnData = new {fieldInfo.FieldType.Name}[entityCount];"); + cb.AppendLine($"for (var i = 0; i < columnData.Length; ++i) {{ columnData[i] = entities[i].{fieldInfo.Name}; }}"); + cb.AppendLine($"tb.{functionName}(\"{fieldInfo.GetSerializedValueColumnName()}\", columnData);"); + cb.AppendLine("}"); + } + + foreach (var fieldInfo in relationFields) + { + var (indexColumnName, localFieldName) = fieldInfo.GetIndexColumnInfo(); + cb.AppendLine("{"); + cb.AppendLine("var columnData = new int[entityCount];"); + cb.AppendLine($"for (var i = 0; i < columnData.Length; ++i) {{ columnData[i] = entities[i]._{localFieldName}?.Index ?? EntityRelation.None; }}"); + cb.AppendLine($"tb.AddIndexColumn(\"{indexColumnName}\", columnData);"); + cb.AppendLine("}"); + } + + cb.AppendLine("return tb;"); + cb.AppendLine("}"); + } + + cb.AppendLine("} // VimEntitySetBuilderExtensions"); + cb.AppendLine(); + + cb.AppendLine("public partial class VimBuilder"); + cb.AppendLine("{"); + // NOTE: the following lines must not be made static since the ObjectModelBuilder is instantiated upon each new export. + // Making this static will cause the contained EntitySetBuilders to accumulate data from previous exports during the lifetime of the program. + + // Instantiates a named entity table builder for each type. + foreach (var et in entityTypes) + cb.AppendLine($"public readonly VimEntitySetBuilder<{EntityNamespace}.{et.Name}> {et.Name}Builder = new VimEntitySetBuilder<{EntityNamespace}.{et.Name}>(VimEntityTableNames.{et.Name});"); + + cb.AppendLine(); + cb.AppendLine("public List GetVimEntityTableBuilders()"); + cb.AppendLine("{"); + cb.AppendLine("var tableBuilders = new List();"); + foreach (var et in entityTypes) + { + cb.AppendLine($"tableBuilders.Add({et.Name}Builder.To{et.Name}TableBuilder());"); + } + cb.AppendLine(); + cb.AppendLine("return tableBuilders;"); + cb.AppendLine("} // GetVimEntityTableBuilders"); + + cb.AppendLine(); + cb.AppendLine("public void Clear()"); + cb.AppendLine("{"); + foreach (var et in entityTypes) + { + cb.AppendLine($"{et.Name}Builder.Clear();"); + } + cb.AppendLine("} // Clear"); + + cb.AppendLine("} // VimBuilder"); + } + + public static void WriteDocument(string file) + { + try + { + var cb = new CodeBuilder(); + + cb.AppendLine("// AUTO-GENERATED FILE; see VimEntityCodeGen.cs"); + cb.AppendLine("// ReSharper disable All"); + cb.AppendLine("using System;"); + cb.AppendLine("using System.Collections;"); + cb.AppendLine("using System.Collections.Generic;"); + cb.AppendLine("using System.Linq;"); + cb.AppendLine("using Vim.Math3d;"); + cb.AppendLine("using Vim.Format.ObjectModel;"); + cb.AppendLine("using Vim.Util;"); + + cb.AppendLine(); + + cb.AppendLine("namespace Vim.Format"); + cb.AppendLine("{"); + + WriteVimEntityTableSet(cb); + + WriteEntityTypes(cb); + + WriteVimBuilder(cb); + + cb.AppendLine("} // namespace"); + var content = cb.ToString(); + File.WriteAllText(file, content); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + } +} diff --git a/src/cs/vim/Vim.Format.Core/AssetInfo.cs b/src/cs/vim/Vim.Format.Core/AssetInfo.cs deleted file mode 100644 index c698cfc5..00000000 --- a/src/cs/vim/Vim.Format.Core/AssetInfo.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Vim.BFast; -using Vim.Util; -using Vim.LinqArray; - -namespace Vim.Format -{ - public enum AssetType - { - Texture, - Render, - } - - /// - /// An AssetInfo is defined by a name and an AssetType, and takes care of parsing and generating asset buffer names. - /// - public class AssetInfo - { - public const char Separator = '/'; - - public readonly string Name; - - public readonly AssetType AssetType; - - public AssetInfo(string name, AssetType assetType) - => (Name, AssetType) = (name, assetType); - - public static string[] SplitAssetBufferName(string assetBufferName) - => assetBufferName?.Split(Separator); - - public static AssetInfo Parse(string assetBufferName) - { - // Validate that the asset buffer name can be split into two tokens. - var tokens = SplitAssetBufferName(assetBufferName); - if (tokens.Length != 2) - throw new Exception($"The asset buffer name '{assetBufferName}' should be splittable into two tokens by a separator ('{Separator}'). These tokens represent: (0) the asset type, (1) the asset name."); - - // Validate the asset type token. - if (!Enum.TryParse(tokens[0], true, out var assetType)) - throw new Exception($"The first token '{assetType}' in the asset buffer name '{assetBufferName}' is not a recognized asset type."); - - // Validate the asset name token. - var name = tokens[1]; - if (string.IsNullOrEmpty(name)) - throw new Exception($"The second token in the asset buffer name '{assetBufferName}' is null or empty."); - - return new AssetInfo(name, assetType); - } - - public static bool TryParse(string assetBufferName, out AssetInfo assetInfo) - { - assetInfo = null; - try - { - assetInfo = Parse(assetBufferName); - return true; - } - catch - { - return false; - } - } - - public static string AssetTypeToString(AssetType assetType) - => assetType.ToString("G").ToLowerInvariant(); - - public string AssetTypeString - => AssetTypeToString(AssetType); - - public override string ToString() - => $"{AssetTypeString}{Separator}{Name}"; - - public string BufferName - => ToString(); - - public string GetDefaultAssetFilePathInDirectory(DirectoryInfo directoryInfo) - => Path.Combine(directoryInfo.FullName, AssetTypeString.ToValidFileName(), Name.ToValidFileName()); - } - - public static class AssetInfoExtensions - { - public static bool IsTexture(this INamedBuffer buffer) - => AssetInfo.TryParse(buffer.Name, out var assetInfo) && assetInfo.AssetType == AssetType.Texture; - - public static INamedBuffer GetAssetBuffer(this Document doc, string assetBufferName) - => doc.Assets.GetOrDefault(assetBufferName); - - public static IEnumerable GetTextures(this Document d) - => d.Assets.Values.Where(IsTexture); - - /// - /// Extracts the asset buffer to the file designated by the given FileInfo. - /// - public static FileInfo ExtractAsset(this INamedBuffer assetBuffer, FileInfo fileInfo) - { - IO.CreateFileDirectory(fileInfo.FullName); - using (var stream = fileInfo.Create()) - assetBuffer.Write(stream); - return fileInfo; - } - - /// - /// Extracts the asset and returns a FileInfo representing the extracted asset on disk.
- /// Returns null if the asset could not be extracted. - ///
- public static FileInfo ExtractAsset(this INamedBuffer assetBuffer, DirectoryInfo directoryInfo) - => !AssetInfo.TryParse(assetBuffer.Name, out var assetInfo) - ? null - : assetBuffer.ExtractAsset(new FileInfo(assetInfo.GetDefaultAssetFilePathInDirectory(directoryInfo))); - - /// - /// Extracts the asset corresponding to the assetBufferName and returns a FileInfo representing the extracted asset on disk.
- /// Returns null if the asset could not be extracted. - ///
- public static FileInfo ExtractAsset(this Document doc, string assetBufferName, FileInfo fileInfo) - => doc.GetAssetBuffer(assetBufferName)?.ExtractAsset(fileInfo); - - /// - /// Extracts the assets contained in the Document to the given directory. - /// - public static IEnumerable<(string assetBufferName, FileInfo assetFileInfo)> ExtractAssets(this Document doc, DirectoryInfo directoryInfo) - { - var result = new List<(string assetBufferName, FileInfo assetFileInfo)>(); - foreach (var assetBuffer in doc.Assets.Values.ToEnumerable()) - { - var assetBufferName = assetBuffer.Name; - var assetFilePath = assetBuffer.ExtractAsset(directoryInfo); - result.Add((assetBufferName, assetFilePath)); - } - return result; - } - - /// - /// Gets the byte array which defines the given asset. Returns false if the asset was not found or if the byte array is empty or null. - /// - public static bool TryGetAssetBytes(this Document doc, string assetBufferName, out byte[] bytes) - { - bytes = null; - - var buffer = doc.GetAssetBuffer(assetBufferName); - if (!(buffer is NamedBuffer byteBuffer)) - return false; - - bytes = byteBuffer.Array; - - return bytes != null && bytes.Length > 0; - } - - /// - /// Gets the byte array which defines the given asset. Returns false if the asset was not found or if the byte array is empty or null. - /// - public static bool TryGetAssetBytes(this Document doc, AssetType assetType, string assetName, out byte[] bytes) - => doc.TryGetAssetBytes(new AssetInfo(assetName, assetType).ToString(), out bytes); - - /// - /// Gets the byte array which defines the main image asset. Returns false if the asset was not found or if the byte array is empty or null. - /// - public static bool TryGetMainImageBytes(this Document doc, out byte[] bytes) - => doc.TryGetAssetBytes(AssetType.Render, VimConstants.MainPng, out bytes); - } -} diff --git a/src/cs/vim/Vim.Format.Core/BigG3dWriter.cs b/src/cs/vim/Vim.Format.Core/BigG3dWriter.cs deleted file mode 100644 index e70ac297..00000000 --- a/src/cs/vim/Vim.Format.Core/BigG3dWriter.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.G3d; -using Vim.BFast; -using System.IO; -using static Vim.Format.DocumentBuilder; - -namespace Vim.Format -{ - /// - /// This is a helper class for writing the really big G3Ds needed in a VIM - /// - public class BigG3dWriter : IBFastComponent - { - public INamedBuffer Meta { get; } - public string[] Names { get; } - public long[] Sizes { get; } - public BFastHeader Header { get; } - public List Meshes { get; } - public List Instances { get; } - public List Shapes { get; } - public List Materials { get; } - - // Computed fields - public int[] MeshVertexOffsets { get; } - public int[] MeshIndexOffsets { get; } - public int[] MeshSubmeshOffset { get; } - public int[] SubmeshIndexOffsets { get; } - public int[] ShapeVertexOffsets { get; } - - public BigG3dWriter(List meshes, List instances, List shapes, List materials, G3dHeader? header = null, bool useColors = false) - { - Meshes = meshes; - Instances = instances; - Shapes = shapes; - Materials = materials; - var totalSubmeshCount = meshes.Select(s => s.SubmeshesIndexOffset.Count).Sum(); - - // Compute the Vertex offsets and index offsets - MeshVertexOffsets = new int[meshes.Count]; - MeshIndexOffsets = new int[meshes.Count]; - SubmeshIndexOffsets = new int[totalSubmeshCount]; - MeshSubmeshOffset = new int[meshes.Count]; - - var n = meshes.Count; - - for (var i = 1; i < n; ++i) - { - MeshVertexOffsets[i] = MeshVertexOffsets[i - 1] + meshes[i - 1].Vertices.Count; - MeshIndexOffsets[i] = MeshIndexOffsets[i - 1] + meshes[i - 1].Indices.Count; - MeshSubmeshOffset[i] = MeshSubmeshOffset[i - 1] + meshes[i - 1].SubmeshesIndexOffset.Count; - } - - var subIndex =0; - var previousIndexCount = 0; - foreach(var geo in meshes) - { - foreach(var sub in geo.SubmeshesIndexOffset) - { - SubmeshIndexOffsets[subIndex++] = sub + previousIndexCount; - } - previousIndexCount += geo.Indices.Count; - } - - var submeshCount = meshes.Select(s => s.SubmeshesIndexOffset.Count).Sum(); - - var totalVertices = n == 0 ? 0 : MeshVertexOffsets[n - 1] + meshes[n - 1].Vertices.Count; - var totalIndices = n == 0 ? 0 : MeshIndexOffsets[n - 1] + meshes[n - 1].Indices.Count; - long totalFaces = totalIndices / 3; - - // Compute the shape vertex offsets - var numShapes = shapes.Count; - ShapeVertexOffsets = new int[numShapes]; - for (var i = 1; i < numShapes; ++i) - { - ShapeVertexOffsets[i] = ShapeVertexOffsets[i - 1] + shapes[i - 1].Vertices.Count; - } - var numShapeVertices = numShapes == 0 ? 0 : ShapeVertexOffsets[numShapes - 1] + shapes[numShapes - 1].Vertices.Count; - - Meta = (header ?? G3dHeader.Default).ToBytes().ToNamedBuffer("meta"); - - (long size, string name) AttributeSizeAndName(string attributeName, long count) - => (AttributeDescriptor.Parse(attributeName).DataElementSize * count, attributeName); - - var writers = new List<(long size, string attribute)>() - { - (Meta.NumBytes(), Meta.Name), - AttributeSizeAndName(CommonAttributes.Position, totalVertices), - AttributeSizeAndName(CommonAttributes.Index, totalIndices), - - AttributeSizeAndName(CommonAttributes.MeshSubmeshOffset, meshes.Count), - AttributeSizeAndName(CommonAttributes.SubmeshIndexOffset, submeshCount), - AttributeSizeAndName(CommonAttributes.SubmeshMaterial, submeshCount), - - AttributeSizeAndName(CommonAttributes.InstanceTransform, instances.Count), - AttributeSizeAndName(CommonAttributes.InstanceParent, instances.Count), - AttributeSizeAndName(CommonAttributes.InstanceMesh, instances.Count), - AttributeSizeAndName(CommonAttributes.InstanceFlags, instances.Count), - - AttributeSizeAndName(CommonAttributes.ShapeVertex, numShapeVertices), - AttributeSizeAndName(CommonAttributes.ShapeVertexOffset, numShapes), - AttributeSizeAndName(CommonAttributes.ShapeColor, numShapes), - AttributeSizeAndName(CommonAttributes.ShapeWidth, numShapes), - - AttributeSizeAndName(CommonAttributes.MaterialColor, materials.Count), - AttributeSizeAndName(CommonAttributes.MaterialGlossiness, materials.Count), - AttributeSizeAndName(CommonAttributes.MaterialSmoothness, materials.Count), - }; - - if (useColors) - { - writers.Add(AttributeSizeAndName(CommonAttributes.VertexColor, totalVertices)); - } - - Names = writers.Select(w => w.attribute).ToArray(); - Sizes = writers.Select(w => w.size).ToArray(); - Header = BFast.BFast.CreateBFastHeader(Sizes, Names); - } - - public long GetSize() - => BFast.BFast.ComputeNextAlignment(Header.Preamble.DataEnd); - - public void Write(Stream stream) - { - // TODO: validate in debug mode that this is producing the current data model. Look at the schema! - - stream.WriteBFastHeader(Header); - stream.WriteBFastBody(Header, Names, Sizes, (_stream, index, name, size) => - { - switch (name) - { - case "meta": - _stream.Write(Meta); - break; - - // Vertices - case CommonAttributes.Position: - Meshes.ForEach(g => stream.Write(g.Vertices.ToArray())); - break; - - // Indices - case CommonAttributes.Index: - for (var i = 0; i < Meshes.Count; ++i) - { - var g = Meshes[i]; - var offset = MeshVertexOffsets[i]; - stream.Write(g.Indices.Select(idx => idx + offset).ToArray()); - } - break; - - // Meshes - case CommonAttributes.MeshSubmeshOffset: - stream.Write(MeshSubmeshOffset); - break; - - // Instances - case CommonAttributes.InstanceMesh: - stream.Write(Instances.Select(i => i.MeshIndex).ToArray()); - break; - case CommonAttributes.InstanceTransform: - stream.Write(Instances.Select(i => i.Transform).ToArray()); - break; - case CommonAttributes.InstanceParent: - stream.Write(Instances.Select(i => i.ParentIndex).ToArray()); - break; - case CommonAttributes.InstanceFlags: - stream.Write(Instances.Select(i => (ushort) i.InstanceFlags).ToArray()); - break; - - // Shapes - case CommonAttributes.ShapeVertex: - stream.Write(Shapes.SelectMany(s => s.Vertices).ToArray()); - break; - case CommonAttributes.ShapeVertexOffset: - stream.Write(ShapeVertexOffsets); - break; - case CommonAttributes.ShapeColor: - stream.Write(Shapes.Select(s => s.Color).ToArray()); - break; - case CommonAttributes.ShapeWidth: - stream.Write(Shapes.Select(s => s.Width).ToArray()); - break; - - // Materials - case CommonAttributes.MaterialColor: - stream.Write(Materials.Select(i => i.Color).ToArray()); - break; - case CommonAttributes.MaterialGlossiness: - stream.Write(Materials.Select(i => i.Glossiness).ToArray()); - break; - case CommonAttributes.MaterialSmoothness: - stream.Write(Materials.Select(i => i.Smoothness).ToArray()); - break; - - // Submeshes - case CommonAttributes.SubmeshIndexOffset: - stream.Write(SubmeshIndexOffsets); - break; - case CommonAttributes.SubmeshMaterial: - stream.Write(Meshes.SelectMany(s => s.SubmeshMaterials).ToArray()); - break; - default: - throw new Exception($"Not a recognized geometry buffer: {name}"); - } - return size; - }); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs deleted file mode 100644 index 98b7cfb0..00000000 --- a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs +++ /dev/null @@ -1,281 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.BFast; -using Vim.LinqArray; - -namespace Vim.Format -{ - public static partial class ColumnExtensions - { - public static INamedBuffer[] GetAllColumns(this SerializableEntityTable et) - => et.DataColumns.Concat(et.IndexColumns).Concat(et.StringColumns).ToArray(); - - public static INamedBuffer[] ValidateColumnRowsAreAligned(this INamedBuffer[] columns) - { - var numRows = columns.FirstOrDefault()?.NumElements() ?? 0; - - foreach (var column in columns) - { - var columnRows = column.NumElements(); - if (columnRows == numRows) - continue; - - var msg = $"Column '{column.Name}' has {columnRows} rows which does not match the first column's {numRows} rows"; - Debug.Fail(msg); - } - - return columns; - } - - public static INamedBuffer[] ValidateColumnRowsAreAligned(this SerializableEntityTable et) - => et.GetAllColumns().ValidateColumnRowsAreAligned(); - - public static int GetRowCount(this SerializableEntityTable et) - => et.ValidateColumnRowsAreAligned().FirstOrDefault()?.NumElements() ?? 0; - - public static string ValidateCanConcatBuffers(this INamedBuffer thisBuffer, INamedBuffer otherBuffer) - { - var thisPrefix = thisBuffer.GetTypePrefix(); - if (string.IsNullOrEmpty(thisPrefix)) - throw new Exception("NamedBuffer prefix not found"); - - var otherPrefix = otherBuffer.GetTypePrefix(); - if (string.IsNullOrEmpty(otherPrefix)) - throw new Exception("NamedBuffer prefix not found"); - - if (thisPrefix != otherPrefix) - throw new Exception("NamedBuffer prefixes are not equal"); - - return thisPrefix; - } - - public static IBuffer ToBuffer(this T[] array) where T : unmanaged - => new Buffer(array); - - public const string UnknownNamedBufferPrefix = "Unknown NamedBuffer prefix"; - - public static object GetDataColumnValue(this IBuffer dataColumn, string typePrefix, int rowIndex) - { - switch (typePrefix) - { - case VimConstants.IntColumnNameTypePrefix: - return dataColumn.AsArray().ElementAtOrDefault(rowIndex); - case VimConstants.LongColumnNameTypePrefix: - return dataColumn.AsArray().ElementAtOrDefault(rowIndex); - case VimConstants.ByteColumnNameTypePrefix: - return dataColumn.AsArray().ElementAtOrDefault(rowIndex); - case VimConstants.FloatColumnNameTypePrefix: - return dataColumn.AsArray().ElementAtOrDefault(rowIndex); - case VimConstants.DoubleColumnNameTypePrefix: - return dataColumn.AsArray().ElementAtOrDefault(rowIndex); - default: - return null; - } - } - - public static object GetDataColumnValue(this INamedBuffer dataColumn, int rowIndex) - => dataColumn.GetDataColumnValue(dataColumn.GetTypePrefix(), rowIndex); - - public static IBuffer CreateDefaultDataColumnBuffer(int length, string typePrefix) - { - switch (typePrefix) - { - case (VimConstants.IntColumnNameTypePrefix): - return new int[length].ToBuffer(); - case (VimConstants.LongColumnNameTypePrefix): - return new long[length].ToBuffer(); - case (VimConstants.ByteColumnNameTypePrefix): - return new byte[length].ToBuffer(); - case (VimConstants.FloatColumnNameTypePrefix): - return new float[length].ToBuffer(); - case (VimConstants.DoubleColumnNameTypePrefix): - return new double[length].ToBuffer(); - default: - throw new Exception($"{nameof(CreateDefaultDataColumnBuffer)} - {UnknownNamedBufferPrefix}"); - } - } - - public static IBuffer RemapOrSelfDataColumn(this IBuffer dataColumn, string typePrefix, List remapping = null) - { - switch (typePrefix) - { - case (VimConstants.IntColumnNameTypePrefix): - return (dataColumn.Data as int[]).RemapOrSelf(remapping).ToBuffer(); - case (VimConstants.LongColumnNameTypePrefix): - return (dataColumn.Data as long[]).RemapOrSelf(remapping).ToBuffer(); - case (VimConstants.DoubleColumnNameTypePrefix): - return (dataColumn.Data as double[]).RemapOrSelf(remapping).ToBuffer(); - case (VimConstants.FloatColumnNameTypePrefix): - return (dataColumn.Data as float[]).RemapOrSelf(remapping).ToBuffer(); - case (VimConstants.ByteColumnNameTypePrefix): - return (dataColumn.Data as byte[]).RemapOrSelf(remapping).ToBuffer(); - default: - throw new Exception($"{nameof(RemapOrSelfDataColumn)} - {UnknownNamedBufferPrefix}"); - } - } - - public static INamedBuffer RemapOrSelfDataColumn(this INamedBuffer dataColumn, List remapping = null) - { - var typePrefix = dataColumn.GetTypePrefix(); - return new NamedBuffer(dataColumn.RemapOrSelfDataColumn(typePrefix, remapping), dataColumn.Name); - } - - public static T[] RemapOrSelf(this T[] source, List remapping = null) - { - if (remapping == null) - return source; - - var dst = new T[remapping.Count]; - - for (var i = 0; i < dst.Length; ++i) - { - var remappedIndex = remapping[i]; - dst[i] = source[remappedIndex]; - } - - return dst; - } - - public static T[] Copy(this T[] source, List remapping = null) - { - T[] result; - - if (remapping == null) - { - // Copy from the source. - result = new T[source.Length]; - - for (var i = 0; i < result.Length; ++i) - result[i] = source[i]; - } - else - { - // Copy from the remapping. - result = new T[remapping.Count]; - - for (var i = 0; i < result.Length; ++i) - { - var remappedIndex = remapping[i]; - result[i] = source[remappedIndex]; - } - } - - return result; - } - - public static IBuffer Concat(this IBuffer thisBuffer, IBuffer otherBuffer) where T : unmanaged - => thisBuffer.AsArray().Concat(otherBuffer.AsArray()).ToArray().ToBuffer(); - - public static IBuffer ConcatDataColumnBuffers(this IBuffer thisBuffer, IBuffer otherBuffer, string typePrefix) - { - switch (typePrefix) - { - case (VimConstants.IntColumnNameTypePrefix): - return thisBuffer.Concat(otherBuffer); - case (VimConstants.LongColumnNameTypePrefix): - return thisBuffer.Concat(otherBuffer); - case (VimConstants.ByteColumnNameTypePrefix): - return thisBuffer.Concat(otherBuffer); - case (VimConstants.FloatColumnNameTypePrefix): - return thisBuffer.Concat(otherBuffer); - case (VimConstants.DoubleColumnNameTypePrefix): - return thisBuffer.Concat(otherBuffer); - default: - throw new Exception($"{nameof(ConcatDataColumnBuffers)} - {UnknownNamedBufferPrefix}"); - } - } - - public static INamedBuffer ConcatDataColumns(this INamedBuffer thisColumn, INamedBuffer otherColumn) - { - var typePrefix = thisColumn.ValidateCanConcatBuffers(otherColumn); - var combinedBuffer = thisColumn.ConcatDataColumnBuffers(otherColumn, typePrefix); - return new NamedBuffer(combinedBuffer, thisColumn.Name); - } - - public static List ConcatColumns( - this IReadOnlyList thisColumnList, - IReadOnlyList otherColumnList, - Func concatFunc) where T : INamedBuffer - { - var mergedColumns = new List(); - - foreach (var thisColumn in thisColumnList) - { - var otherColumn = otherColumnList.FirstOrDefault(c => c.Name == thisColumn.Name); - if (otherColumn == null) - continue; - - var newNamedBuffer = concatFunc(thisColumn, otherColumn); - - mergedColumns.Add(newNamedBuffer); - } - - return mergedColumns; - } - - public static List ConcatDataColumns(this IReadOnlyList thisColumnList, IReadOnlyList otherColumnList) - => thisColumnList.ConcatColumns(otherColumnList, - (a, b) => a.ConcatDataColumns(b)); - - public static List> ConcatIntColumns(this IReadOnlyList> thisColumnList, IReadOnlyList> otherColumnList) - => thisColumnList.ConcatColumns(otherColumnList, - (a, b) => new NamedBuffer(a.GetTypedData().Concat(b.GetTypedData()).ToArray(), a.Name)); - - /// - /// Returns a concatenated SerializableEntityTable based on the column names of thisTable. - /// - public static SerializableEntityTable Concat( - this SerializableEntityTable thisTable, - SerializableEntityTable otherTable) - { - var concatenated = new SerializableEntityTable - { - Name = thisTable.Name, - IndexColumns = thisTable.IndexColumns.ConcatIntColumns(otherTable.IndexColumns), - StringColumns = thisTable.StringColumns.ConcatIntColumns(otherTable.StringColumns), - DataColumns = thisTable.DataColumns.ConcatDataColumns(otherTable.DataColumns), - }; - concatenated.ValidateColumnRowsAreAligned(); - return concatenated; - } - - public static T[] GetColumnValues(this INamedBuffer nb) where T : unmanaged - => nb.AsArray(); - - /// - /// Returns a new collection of index columns in which the designated column names have repeated values of VimConstants.NoEntityRelation. - /// - public static IEnumerable> NoneIndexColumnRelations( - this IEnumerable> indexColumns, - params string[] indexColumnNames) - => indexColumns.Select(ic => indexColumnNames.Contains(ic.Name) - ? new NamedBuffer(VimConstants.NoEntityRelation.Repeat(ic.Data.Length).ToArray(), ic.Name) - : ic); - - /// - /// Replaces the designated index columns of the entity table with repeated values of VimConstants.NoEntityRelation. - /// - public static void NoneIndexColumnRelations( - this SerializableEntityTable et, - params string[] indexColumnNames) - { - if (et == null) - return; - - et.IndexColumns = et.IndexColumns.NoneIndexColumnRelations(indexColumnNames).ToList(); - } - - /// - /// Replaces the entity table contained in the document with the given entity table if it is not null. - /// - public static void ReplaceEntityTable(this SerializableDocument document, SerializableEntityTable et) - { - if (document == null || et == null) - return; - - document.EntityTables = document.EntityTables.Where(e => e.Name != et.Name).Append(et).ToList(); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs index a5dc9872..4922399a 100644 --- a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs +++ b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs @@ -10,7 +10,7 @@ public static partial class ColumnExtensions { public static string GetDataColumnNameTypePrefix(this Type type) { - if (DataColumnTypeToPrefixMap.TryGetValue(type, out var typePrefix)) + if (VimEntityTableColumnTypeInfo.DataColumnTypeToPrefixMap.TryGetValue(type, out var typePrefix)) return typePrefix; throw new Exception($"{nameof(GetDataColumnNameTypePrefix)} error: no matching data column name prefix for {type}"); @@ -20,7 +20,7 @@ public static bool CanSerializeAsStringColumn(this Type type) => type == typeof(string); public static bool CanSerializeAsDataColumn(this Type type) - => DataColumnTypes.Contains(type); + => VimEntityTableColumnTypeInfo.DataColumnTypes.Contains(type); public static ValueSerializationStrategy GetValueSerializationStrategy(this Type type) { @@ -41,7 +41,7 @@ public static (ValueSerializationStrategy Strategy, string TypePrefix) GetValueS switch (strategy) { case ValueSerializationStrategy.SerializeAsStringColumn: - typePrefix = VimConstants.StringColumnNameTypePrefix; + typePrefix = VimEntityTableColumnName.StringColumnNameTypePrefix; break; case ValueSerializationStrategy.SerializeAsDataColumn: typePrefix = type.GetDataColumnNameTypePrefix(); @@ -75,8 +75,8 @@ public static IEnumerable GetRelationFields(this Type t) public static string GetEntityTableName(this Type t) => (t.GetCustomAttribute(typeof(TableNameAttribute)) as TableNameAttribute)?.Name; - public static bool HasCascadeElementRemap(this Type t) - => (t.GetCustomAttribute(typeof(CascadeElementRemapAttribute)) as CascadeElementRemapAttribute) != null; + public static bool HasJoiningTable(this Type t) + => (t.GetCustomAttribute(typeof(JoiningTableAttribute)) as JoiningTableAttribute) != null; public static (string IndexColumnName, string LocalFieldName) GetIndexColumnInfo(this FieldInfo fieldInfo) { @@ -90,7 +90,7 @@ public static (string IndexColumnName, string LocalFieldName) GetIndexColumnInfo if (string.IsNullOrEmpty(relatedTableName)) throw new Exception($"Could not find related table for type {relationTypeParameter}"); - return (GetIndexColumnName(relatedTableName, localFieldName), localFieldName); + return (VimEntityTableColumnName.GetIndexColumnName(relatedTableName, localFieldName), localFieldName); } public static string GetSerializedIndexColumnName(this FieldInfo fieldInfo) @@ -101,8 +101,7 @@ public static string GetSerializedIndexColumnName(this FieldInfo fieldInfo) public static IEnumerable GetEntityFields(this Type t, bool skipIndex = true, bool skipProperties = true) => t.GetFields().Where(fi => - !fi.FieldType.Equals(typeof(Document)) - && (skipIndex ? fi.Name != "Index" : true) + (skipIndex ? fi.Name != "Index" : true) && (skipProperties ? fi.Name != "Properties" : true) && !fi.FieldType.IsRelationType() && !fi.IsLiteral // do not include const fields diff --git a/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs b/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs deleted file mode 100644 index 422d9dc1..00000000 --- a/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text.RegularExpressions; -using Vim.BFast; - -namespace Vim.Format -{ - public static partial class ColumnExtensions - { - public static readonly IReadOnlyCollection AllColumnInfos - = new[] - { - new ColumnInfo(ColumnType.IndexColumn, VimConstants.IndexColumnNameTypePrefix, typeof(int)), - new ColumnInfo(ColumnType.StringColumn, VimConstants.StringColumnNameTypePrefix, typeof(int)), - new ColumnInfo(ColumnType.DataColumn, VimConstants.IntColumnNameTypePrefix, typeof(int), typeof(short)), - new ColumnInfo(ColumnType.DataColumn, VimConstants.LongColumnNameTypePrefix, typeof(long)), - new ColumnInfo(ColumnType.DataColumn, VimConstants.ByteColumnNameTypePrefix, typeof(byte), typeof(bool)), - new ColumnInfo(ColumnType.DataColumn, VimConstants.DoubleColumnNameTypePrefix, typeof(double)), - new ColumnInfo(ColumnType.DataColumn, VimConstants.FloatColumnNameTypePrefix, typeof(float)), - }; - - public static readonly IReadOnlyDictionary TypePrefixToColumnTypeMap - = AllColumnInfos.ToDictionary(t => t.TypePrefix, t => t.ColumnType); - - public static readonly IReadOnlyDictionary DataColumnTypeToPrefixMap - = AllColumnInfos - .Where(t => t.ColumnType == ColumnType.DataColumn) - .SelectMany(t => t.RelatedTypes.Select(type => (Type: type, t.TypePrefix))) - .ToDictionary(item => item.Type, item => item.TypePrefix); - - public static readonly IReadOnlyDictionary TypePrefixToSerializedTypeMap - = AllColumnInfos - .Where(t => t.ColumnType == ColumnType.DataColumn) - .ToDictionary(t => t.TypePrefix, t => t.SerializedType); - - public static readonly ISet DataColumnTypes - = new HashSet(AllColumnInfos.Where(t => t.ColumnType == ColumnType.DataColumn).SelectMany(t => t.RelatedTypes)); - - public static readonly ISet DataColumnNameTypePrefixes - = new HashSet(AllColumnInfos.Where(t => t.ColumnType == ColumnType.DataColumn).Select(t => t.TypePrefix)); - - public static readonly Regex DataColumnTypePrefixRegex - = new Regex($@"^(?:{string.Join("|", DataColumnNameTypePrefixes)})"); - - public static bool TryGetDataColumnNameTypePrefix(string columnName, out string typePrefix) - { - typePrefix = null; - if (string.IsNullOrEmpty(columnName)) - return false; - - var match = DataColumnTypePrefixRegex.Match(columnName); - typePrefix = match.Value; - return match.Success; - } - - public static bool IsDataColumnName(string columnName) - => TryGetDataColumnNameTypePrefix(columnName, out _); - - public const string RelatedTableNameFieldNameSeparator = ":"; - - public static string GetIndexColumnName(string relatedTableName, string localFieldName) - => VimConstants.IndexColumnNameTypePrefix + relatedTableName + RelatedTableNameFieldNameSeparator + localFieldName; - - public class ColumnNameComponents - { - public static readonly Regex ColumnNameComponentsRegex = new Regex(@"(\w+:)(.+)", RegexOptions.Compiled); - public static readonly Regex IndexColumnNameComponentsRegex = new Regex(@"(\w+:)((?:\w|\.)+):(.+)", RegexOptions.Compiled); - - public readonly string TypePrefix; - public readonly string FieldName; - public readonly string RelatedTableName; // only applicable for index columns. - public readonly ColumnType ColumnType; - - public ColumnNameComponents(string columnName) - { - var match = ColumnNameComponentsRegex.Match(columnName); - if (!match.Success) - throw new Exception($"Column name {columnName} could not be separated into its components."); - - // Collect the type prefix. - TypePrefix = match.Groups[1].Value; - switch (TypePrefix) - { - case VimConstants.IndexColumnNameTypePrefix: - ColumnType = ColumnType.IndexColumn; - break; - case VimConstants.StringColumnNameTypePrefix: - ColumnType = ColumnType.StringColumn; - break; - default: - ColumnType = ColumnType.DataColumn; - break; - } - - // Collect the field name - FieldName = match.Groups[2].Value; - - // If it's an index column, get the related table. - if (ColumnType == ColumnType.IndexColumn) - { - var indexMatch = IndexColumnNameComponentsRegex.Match(columnName); - if (!match.Success) - throw new Exception($"Index column name {columnName} could not be separated into its components."); - - RelatedTableName = indexMatch.Groups[2].Value; - FieldName = indexMatch.Groups[3].Value; // Update the field name. - } - } - - public static bool TryGetColumnNameComponents(string columnName, out ColumnNameComponents columnComponents) - { - columnComponents = null; - - try - { - columnComponents = new ColumnNameComponents(columnName); - } - catch (Exception e) - { - // Invalid column name; could not be parsed. - Debug.Fail($"Column components could not be parsed: {columnName}. Error: {e}"); - return false; - } - - return true; - } - } - - public static string GetRelatedTableNameFromColumnName(string name) - => new ColumnNameComponents(name).RelatedTableName; - - public static string GetRelatedTableName(this INamedBuffer ic) - => GetRelatedTableNameFromColumnName(ic.Name); - - public static EntityTable GetRelatedTable(this INamedBuffer ic, Document doc) - => doc.GetTable(ic.GetRelatedTableName()); - - public static string GetIndexColumnFieldName(this INamedBuffer ic) - => new ColumnNameComponents(ic.Name).FieldName; - - public static string GetStringColumnFieldName(this INamedBuffer sc) - => new ColumnNameComponents(sc.Name).FieldName; - - public static string GetDataColumnFieldName(this INamedBuffer dc) - => new ColumnNameComponents(dc.Name).FieldName; - - public static bool TryGetDataColumnType(this INamedBuffer dc, out Type type) - { - type = null; - var typePrefix = new ColumnNameComponents(dc.Name).TypePrefix; - return TypePrefixToSerializedTypeMap.TryGetValue(typePrefix, out type); - } - - public static bool TryGetColumnByFieldName( - this SerializableEntityTable entityTable, - string columnFieldName, - out INamedBuffer buffer, - out string typePrefix, - out ColumnType columnType) - { - buffer = null; - columnType = ColumnType.IndexColumn; - typePrefix = null; - - foreach (var column in entityTable.GetAllColumns()) - { - if (!ColumnNameComponents.TryGetColumnNameComponents(column.Name, out var components)) - continue; - - if (components.FieldName != columnFieldName) - continue; - - columnType = components.ColumnType; - typePrefix = components.TypePrefix; - buffer = column; - - return true; - } - - return false; - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/ColumnInfo.cs b/src/cs/vim/Vim.Format.Core/ColumnInfo.cs deleted file mode 100644 index dde7b439..00000000 --- a/src/cs/vim/Vim.Format.Core/ColumnInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Vim.Format -{ - public enum ColumnType - { - IndexColumn, - StringColumn, - DataColumn, - } - - public class ColumnInfo - { - public readonly ColumnType ColumnType; - public readonly string TypePrefix; - public readonly Type SerializedType; - public readonly ISet CastTypes; - - public ColumnInfo(ColumnType columnType, string typePrefix, Type serializedType, params Type[] castTypes) - { - (ColumnType, TypePrefix, SerializedType) = (columnType, typePrefix, serializedType); - CastTypes = new HashSet(castTypes); - } - - public IEnumerable RelatedTypes - => CastTypes.Prepend(SerializedType); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Document.cs b/src/cs/vim/Vim.Format.Core/Document.cs deleted file mode 100644 index 476bd8e7..00000000 --- a/src/cs/vim/Vim.Format.Core/Document.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Vim.LinqArray; -using Vim.BFast; - -namespace Vim.Format -{ - // TODO: this should be merged into Serializable document. - public class Document - { - public Document(SerializableDocument document) - { - _Document = document; - Header = _Document.Header; - Geometry = _Document.Geometry; - StringTable = _Document.StringTable.ToIArray(); - EntityTables = _Document.EntityTables.ToLookup( - et => et.Name, - et => et.ToEntityTable(this)); - Assets = _Document.Assets.ToLookup(et => et.Name, et => et); - } - - public string FileName => _Document.FileName; - private SerializableDocument _Document { get; } - public SerializableHeader Header { get; } - public ILookup EntityTables { get; } - public ILookup Assets { get; } - public IArray StringTable { get; } - public string GetString(int index) => StringTable.ElementAtOrDefault(index); - public G3d.G3D Geometry { get; } - } -} diff --git a/src/cs/vim/Vim.Format.Core/DocumentBuilder.cs b/src/cs/vim/Vim.Format.Core/DocumentBuilder.cs deleted file mode 100644 index a906e95e..00000000 --- a/src/cs/vim/Vim.Format.Core/DocumentBuilder.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.Math3d; -using Vim.BFast; -using System.IO; -using Vim.G3d; -using Vim.Util; - -namespace Vim.Format -{ - public partial class DocumentBuilder - { - public readonly SerializableHeader Header; - public readonly Dictionary Tables = new Dictionary(); - public readonly Dictionary Assets = new Dictionary(); - public readonly List Meshes = new List(); - public readonly List Instances = new List(); - public readonly List Shapes = new List(); - public readonly List Materials = new List(); - - public bool UseColors { get; set; } - - public DocumentBuilder( - string generator, - SerializableVersion schema, - string versionString, - IReadOnlyDictionary optionalHeaderValues = null) - { - Header = new SerializableHeader(generator, schema, versionString, optionalHeaderValues); - } - - public EntityTableBuilder GetTableBuilderOrCreate(string name) - { - if (!Tables.ContainsKey(name)) - Tables.Add(name, new EntityTableBuilder(name)); - return Tables[name]; - } - - public EntityTableBuilder CreateTableBuilder(string name) - { - if (Tables.ContainsKey(name)) - throw new Exception($"Table {name} already exists"); - return GetTableBuilderOrCreate(name); - } - - public DocumentBuilder AddAsset(string name, byte[] asset) - { - if (!Assets.ContainsKey(name)) - Assets.Add(name, asset); - return this; - } - - public DocumentBuilder AddMesh(SubdividedMesh g) - { - Meshes.Add(g); - return this; - } - - public DocumentBuilder AddMeshes(IEnumerable gb) - { - Meshes.AddRange(gb); - return this; - } - - public DocumentBuilder AddInstances(IEnumerable ib) - { - Instances.AddRange(ib); - return this; - } - public DocumentBuilder AddMaterials(IEnumerable mb) - { - Materials.AddRange(mb); - return this; - } - - public DocumentBuilder AddShapes(IEnumerable sb) - { - Shapes.AddRange(sb); - return this; - } - - public DocumentBuilder AddAsset(INamedBuffer b) - => AddAsset(b.Name, b.ToBytes()); - - public DocumentBuilder AddInstance(Matrix4x4 transform, int meshIndex, InstanceFlags flags, int parentIndex = -1) - { - Instances.Add( - new Instance() - { - Transform = transform, - MeshIndex = meshIndex, - ParentIndex = parentIndex, - InstanceFlags = flags, - } - ); - - return this; - } - - public class StringLookupInfo - { - public readonly IReadOnlyDictionary StringLookup; - public readonly IEnumerable StringTable; - - public StringLookupInfo(IEnumerable allStrings, int indexOffset = 0) - { - // NOTE: ensure the empty string is part of the string table. - var stringTable = allStrings.Prepend("").Distinct().ToList(); - - // By construction, the contents of stringTable should not have repeating items. - var stringLookup = new Dictionary(); - for (var i = 0; i < stringTable.Count; ++i) - stringLookup[stringTable[i]] = i + indexOffset; - - StringTable = stringTable; - StringLookup = stringLookup; - } - } - - public static StringLookupInfo GetStringLookupInfo(IEnumerable tableBuilders, int indexOffset = 0) - => new StringLookupInfo(tableBuilders.SelectMany(tb => tb.GetAllStrings()), indexOffset); - - public StringLookupInfo GetStringLookupInfo() - => GetStringLookupInfo(Tables.Values); - - public List ComputeEntityTables(IReadOnlyDictionary stringLookup) - { - // Create the new Entity tables - var tableList = new List(); - - // Create the geometry table - { - var tb = GetTableBuilderOrCreate(TableNames.Geometry); - tb.Clear(); - - // Populate the box - var boxMinX = new float[Meshes.Count]; - var boxMinY = new float[Meshes.Count]; - var boxMinZ = new float[Meshes.Count]; - - var boxMaxX = new float[Meshes.Count]; - var boxMaxY = new float[Meshes.Count]; - var boxMaxZ = new float[Meshes.Count]; - - for (var i = 0; i < Meshes.Count; ++i) - { - var b = AABox.Create(Meshes[i].Vertices); - boxMinX[i] = b.Min.X; - boxMinY[i] = b.Min.Y; - boxMinZ[i] = b.Min.Z; - - boxMaxX[i] = b.Max.X; - boxMaxY[i] = b.Max.Y; - boxMaxZ[i] = b.Max.Z; - } - - // TODO: TECH DEBT - this couples the object model to the data format. - tb.AddDataColumn("float:Box.Min.X", boxMinX); - tb.AddDataColumn("float:Box.Min.Y", boxMinY); - tb.AddDataColumn("float:Box.Min.Z", boxMinZ); - - tb.AddDataColumn("float:Box.Max.X", boxMaxX); - tb.AddDataColumn("float:Box.Max.Y", boxMaxY); - tb.AddDataColumn("float:Box.Max.Z", boxMaxZ); - - tb.AddDataColumn("int:VertexCount", Meshes.Select(g => g.Vertices.Count)); - tb.AddDataColumn("int:FaceCount", Meshes.Select(g => g.Indices.Count / 3)); - } - - // TODO: add bounding box information to the nodes - - foreach (var tb in Tables.Values) - { - var table = tb.ToSerializableEntityTable(stringLookup); - tableList.Add(table); - } - - return tableList; - } - - public void Write(string filePath) - { - IO.CreateFileDirectory(filePath); - IO.Delete(filePath); - using (var stream = File.OpenWrite(filePath)) - Write(stream); - } - - public void Write(Stream stream) - { - var assets = Assets.Select(kv => kv.Value.ToNamedBuffer(kv.Key)) as IEnumerable; - Debug.Assert(assets != null, "Asset conversion to IEnumerable failed."); - - var stringLookupInfo = GetStringLookupInfo(); - var entityTables = ComputeEntityTables(stringLookupInfo.StringLookup); - var stringTable = stringLookupInfo.StringTable; - - Serializer.Serialize(stream, Header, assets, stringTable, entityTables, new BigG3dWriter(Meshes, Instances, Shapes, Materials, null, UseColors)); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/DocumentBuilderExtensions.cs b/src/cs/vim/Vim.Format.Core/DocumentBuilderExtensions.cs deleted file mode 100644 index 543dc95c..00000000 --- a/src/cs/vim/Vim.Format.Core/DocumentBuilderExtensions.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Vim.BFast; -using Vim.Format.Geometry; -using Vim.G3d; -using Vim.LinqArray; -using static Vim.Format.DocumentBuilder; - -namespace Vim.Format -{ - public static class DocumentBuilderExtensions - { - public static IMesh ToIMesh(this SubdividedMesh gb) - => gb.Vertices.ToIArray().TriMesh( - gb.Indices.ToIArray(), - submeshMaterials: gb.SubmeshMaterials.ToIArray()); - - public static Material ToDocumentBuilderMaterial(this G3dMaterial g3dMaterial) - => new Material - { - Color = g3dMaterial.Color, - Glossiness = g3dMaterial.Glossiness, - Smoothness = g3dMaterial.Smoothness, - }; - - public static SubdividedMesh ToDocumentBuilderSubdividedMesh(this IMesh m) - => new SubdividedMesh( - m.Indices.ToList(), - m.Vertices.ToList(), - m.SubmeshIndexOffsets.ToList(), - m.SubmeshMaterials.ToList()); - - public static void AddMesh(this DocumentBuilder db, IMesh m) - => db.AddMesh(m.ToDocumentBuilderSubdividedMesh()); - - public static SerializableEntityTable ToSerializableEntityTable(this EntityTableBuilder tb, - IReadOnlyDictionary stringLookup) - { - var table = new SerializableEntityTable - { - // Set the table name - Name = tb.Name, - - // Convert the columns to named buffers - IndexColumns = tb.IndexColumns - .Select(kv => kv.Value.ToNamedBuffer(kv.Key)) - .ToList(), - DataColumns = tb.DataColumns - .Select(kv => kv.Value.ToNamedBuffer(kv.Key) as INamedBuffer) - .ToList(), - StringColumns = tb.StringColumns - .Select(kv => kv.Value - .Select(s => stringLookup[s ?? string.Empty]) - .ToArray() - .ToNamedBuffer(kv.Key)) - .ToList(), - }; - - table.ValidateColumnRowsAreAligned(); - - return table; - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/DocumentBuilderTypes.cs b/src/cs/vim/Vim.Format.Core/DocumentBuilderTypes.cs deleted file mode 100644 index d3a71764..00000000 --- a/src/cs/vim/Vim.Format.Core/DocumentBuilderTypes.cs +++ /dev/null @@ -1,205 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.G3d; -using Vim.Math3d; - -namespace Vim.Format -{ - public partial class DocumentBuilder - { - public class Instance - { - public Matrix4x4 Transform; - public int MeshIndex; - public int ParentIndex; - public InstanceFlags InstanceFlags; - } - - public class Shape - { - public List Vertices; - public Vector4 Color; - public float Width; - } - - public class Material - { - //RGBA - public Vector4 Color; - public float Glossiness; - public float Smoothness; - } - - /// - /// Appends faces while keeping the mesh invariants then subdivide into submesh. - /// - public class Mesh - { - public List Vertices { get; set; } - public List Indices { get; set; } - public List FaceMaterials { get; set; } - public List Colors { get; set; } - public List UVs { get; set; } - - public Mesh( - List vertices = null, - List indices = null, - List faceMaterials = null, - List colors = null, - List uvs = null) - { - Vertices = vertices ?? new List(); - Indices = indices ?? new List(); - - if (Indices.Any(i => i < 0 && i >= Vertices.Count)) - throw new Exception($"Invalid mesh. Indices out of vertex range."); - - if (Indices.Count % 3 != 0) - throw new Exception("indices.Count must be a multiple of 3."); - - FaceMaterials = faceMaterials ?? new List(Enumerable.Repeat(-1, Indices.Count / 3)); - - if (FaceMaterials.Count * 3 != Indices.Count) - throw new Exception("faceMaterials.Count must be indices.Count * 3"); - - Colors = colors ?? new List(); - UVs = uvs ?? new List(); - } - - public void SetMeshMaterial(int material) - => FaceMaterials = Enumerable.Repeat(material, Indices.Count / 3).ToList(); - - public void AppendFaces(IList indices, IList materials) - { - if (indices.Count != materials.Count * 3) - throw new Exception("index.Count must be material.Count*3"); - - for (var i = 0; i < materials.Count; i++) - { - var index = i * 3; - AppendFace(indices[index], indices[index + 1], indices[index + 2], materials[i]); - } - } - - public void AppendFace(int v0, int v1, int v2, int material) - { - Indices.Add(v0); - Indices.Add(v1); - Indices.Add(v2); - FaceMaterials.Add(material); - } - - public void AppendVertices(IEnumerable vertices) - => Vertices.AddRange(vertices); - - public void AppendUVs(IEnumerable uvs) - => UVs.AddRange(uvs); - - public SubdividedMesh Subdivide() - => new SubdividedMesh(this); - } - - /// - /// An immutable mesh were faces have been organized by submesh/material - /// - public class SubdividedMesh - { - public IReadOnlyList Indices { get; } - public IReadOnlyList Vertices { get; } - public IReadOnlyList SubmeshesIndexOffset { get; } - public IReadOnlyList SubmeshMaterials { get; } - - public SubdividedMesh(Mesh mesh) - { - if (mesh.Indices.Any(i => i < 0 && i >= mesh.Vertices.Count)) - throw new Exception($"Invalid mesh. Indices out of vertex range."); - - var facesByMats = mesh.FaceMaterials - .Select((face, index) => (face, index)) - .GroupBy(pair => pair.face, pair => pair.index); - - var submeshIndexOffset = new List(); - var submeshMaterials = new List(); - var indicesRemap = new List(); - - foreach (var group in facesByMats) - { - submeshIndexOffset.Add(indicesRemap.Count); - submeshMaterials.Add(group.Key); - foreach (var face in group) - { - var f = face * 3; - indicesRemap.Add(mesh.Indices[f]); - indicesRemap.Add(mesh.Indices[f + 1]); - indicesRemap.Add(mesh.Indices[f + 2]); - } - } - Indices = indicesRemap; - SubmeshMaterials = submeshMaterials; - SubmeshesIndexOffset = submeshIndexOffset; - - Vertices = mesh.Vertices; - } - - public SubdividedMesh( - IReadOnlyList indices, - IReadOnlyList vertices, - IReadOnlyList submeshesIndexOffset, - IReadOnlyList submeshMaterials - ) - { - Indices = indices; - Vertices = vertices; - SubmeshesIndexOffset = submeshesIndexOffset; - SubmeshMaterials = submeshMaterials; - } - - public bool IsEquivalentTo(SubdividedMesh other) - => Vertices.SequenceEqual(other.Vertices) - && Indices.SequenceEqual(other.Indices) - && SubmeshesIndexOffset.SequenceEqual(other.SubmeshesIndexOffset) - && SubmeshMaterials.SequenceEqual(other.SubmeshMaterials); - - public static SubdividedMesh CreateFromWorldSpaceBox(IReadOnlyList points, int materialIndex) - { - // 7 *--------------------------* 6 (max) - // |\ |\ - // | \ | \ - // | \ 4 | \ 5 - // | *--------------------------* - // | | | | - // 3 *---|----------------------* 2 | - // \ | \ | - // \ | \ | - // \| \| - // *--------------------------* - // (min) 0 1 - - // Faces are declared as quads in counter-clockwise order (right-handed rule, thumb points in normal direction) - var bottomQuad = new[] { points[0], points[3], points[2], points[1] }; - var topQuad = new[] { points[4], points[5], points[6], points[7] }; - var backQuad = new[] { points[2], points[3], points[7], points[6] }; - var frontQuad = new[] { points[0], points[1], points[5], points[4] }; - var leftQuad = new[] { points[3], points[0], points[4], points[7] }; - var rightQuad = new[] { points[2], points[6], points[5], points[1] }; - - var quads = new[] { bottomQuad, topQuad, backQuad, frontQuad, leftQuad, rightQuad }; - - var vertices = new List(); - var indices = new List(); - - var quadIndices = new[] { 0, 1, 2, 0, 2, 3 }; - - foreach (var quadVertices in quads) - { - var indexOffset = vertices.Count; - vertices.AddRange(quadVertices); - indices.AddRange(quadIndices.Select(i => i + indexOffset)); - } - - return new SubdividedMesh(indices, vertices, new[] { 0 }, new[] { materialIndex }); - } - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/DocumentExtensions.cs b/src/cs/vim/Vim.Format.Core/DocumentExtensions.cs deleted file mode 100644 index 1e4cf91a..00000000 --- a/src/cs/vim/Vim.Format.Core/DocumentExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Vim.LinqArray; - -namespace Vim.Format -{ - public static class DocumentExtensions - { - public static Document ToDocument(this SerializableDocument document) - => new Document(document); - - public static EntityTable ToEntityTable(this SerializableEntityTable entityTable, Document document) - => new EntityTable(document, entityTable); - - public static EntityTable GetTable(this Document doc, string name) - => doc.EntityTables.GetOrDefault(name); - - public static SerializableDocument SetFileName(this SerializableDocument doc, string fileName) - { - doc.FileName = fileName; - return doc; - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/EntityTable.cs b/src/cs/vim/Vim.Format.Core/EntityTable.cs deleted file mode 100644 index 44360bf9..00000000 --- a/src/cs/vim/Vim.Format.Core/EntityTable.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using Vim.BFast; -using Vim.LinqArray; - -namespace Vim.Format -{ - public class EntityTable - { - public EntityTable(Document document, SerializableEntityTable entityTable) - { - Document = document; - _EntityTable = entityTable; - Name = _EntityTable.Name; - - DataColumns = LinqArray.LinqArray.ToLookup(_EntityTable.DataColumns, c => c.Name, c => c); - IndexColumns = LinqArray.LinqArray.ToLookup(_EntityTable.IndexColumns, c => c.Name, c => c); - StringColumns = LinqArray.LinqArray.ToLookup(_EntityTable.StringColumns, c => c.Name, c => c); - Columns = entityTable.ValidateColumnRowsAreAligned(); - NumRows = Columns.FirstOrDefault()?.NumElements() ?? 0; - } - - private SerializableEntityTable _EntityTable { get; } - public Document Document { get; } - public string Name { get; } - public int NumRows { get; } - public LinqArray.ILookup DataColumns { get; } - public LinqArray.ILookup> StringColumns { get; } - public LinqArray.ILookup> IndexColumns { get; } - public INamedBuffer[] Columns { get; } - - public IArray GetIndexColumnValues(string columnName) - => IndexColumns.GetOrDefault(columnName)?.GetColumnValues().ToIArray(); - - public IArray GetStringColumnValues(string columnName) - => StringColumns.GetOrDefault(columnName) - ?.GetColumnValues() - ?.Select(Document.GetString) - .ToIArray(); - - public IArray GetDataColumnValues(string columnName) where T : unmanaged - { - var type = typeof(T); - - if (!ColumnExtensions.DataColumnTypes.Contains(type)) - throw new Exception($"{nameof(GetDataColumnValues)} error - unsupported data column type {type}"); - - var namedBuffer = DataColumns.GetOrDefault(columnName); - if (namedBuffer == null) - return null; - - if (type == typeof(short)) - return namedBuffer.GetColumnValues().Select(i => (short)i).ToIArray() as IArray; - - if (type == typeof(bool)) - return namedBuffer.GetColumnValues().Select(b => b != 0).ToIArray() as IArray; - - return namedBuffer.GetColumnValues().ToIArray(); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs b/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs deleted file mode 100644 index bd1da0fd..00000000 --- a/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.BFast; - -namespace Vim.Format -{ - public class EntityTableBuilder - { - public string Name { get; } - public readonly Dictionary DataColumns = new Dictionary(); - public readonly Dictionary IndexColumns = new Dictionary(); - public readonly Dictionary StringColumns = new Dictionary(); - - public int NumRows { get; private set; } - - public EntityTableBuilder(string name) - => Name = name; - - public EntityTableBuilder UpdateOrValidateRows(int n) - { - if (NumRows == 0) NumRows = n; - else if (NumRows != n) throw new Exception($"Value count {n} does not match the expected number of rows {NumRows}"); - return this; - } - - public void ValidateHasDataColumnPrefix(string columnName) - { - if (!ColumnExtensions.IsDataColumnName(columnName)) - throw new Exception($"{nameof(columnName)} {columnName} does not begin with a data column prefix"); - } - - public void ValidateHasPrefix(string columnName, string expectedPrefix) - { - if (!columnName.StartsWith(expectedPrefix)) - throw new Exception($"{nameof(columnName)} {columnName} must start with {expectedPrefix}"); - } - - public EntityTableBuilder AddIndexColumn(string columnName, int[] indices) - { - ValidateHasPrefix(columnName, VimConstants.IndexColumnNameTypePrefix); - UpdateOrValidateRows(indices.Length); - IndexColumns.Add(columnName, indices); - return this; - } - - public EntityTableBuilder AddIndexColumn(string columnName, IEnumerable ids) - => AddIndexColumn(columnName, ids.ToArray()); - - public EntityTableBuilder AddStringColumn(string columnName, string[] values) - { - ValidateHasPrefix(columnName, VimConstants.StringColumnNameTypePrefix); - UpdateOrValidateRows(values.Length); - StringColumns.Add(columnName, values); - return this; - } - - public EntityTableBuilder AddStringColumn(string columnName, IEnumerable values) - => AddStringColumn(columnName, values.ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IBuffer values) - { - ValidateHasDataColumnPrefix(columnName); - UpdateOrValidateRows(values.Data.Length); - DataColumns.Add(columnName, values); - return this; - } - - public EntityTableBuilder AddDataColumn(string columnName, T[] values) where T : unmanaged - { - ValidateHasPrefix(columnName, typeof(T).GetDataColumnNameTypePrefix()); - return AddDataColumn(columnName, values.ToBuffer()); - } - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.Select(x => (int)x).ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.ToArray()); - - public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) - => AddDataColumn(columnName, values.Select(x => x ? (byte)1 : (byte)0).ToArray()); - - public IEnumerable GetAllStrings() - => StringColumns.Values.SelectMany(sc => sc) - .Where(x => x != null); - - public void Clear() - { - NumRows = 0; - DataColumns.Clear(); - StringColumns.Clear(); - IndexColumns.Clear(); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/EntityTable_v2.cs b/src/cs/vim/Vim.Format.Core/EntityTable_v2.cs deleted file mode 100644 index e5dfc9fe..00000000 --- a/src/cs/vim/Vim.Format.Core/EntityTable_v2.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.BFast; -using Vim.Util; - -namespace Vim.Format -{ - public interface IEntityTable - { - int RowCount { get; } - } - - public class EntityTable_v2 : IEntityTable - { - private readonly string[] _stringTable; - - public Dictionary> IndexColumns { get; } = new Dictionary>(); - public Dictionary> StringColumns { get; } = new Dictionary>(); - public Dictionary DataColumns { get; } = new Dictionary(); - - /// - /// The entity table name - /// - public string Name { get; } - - /// - /// The buffers which compose the columns. - /// - public INamedBuffer[] Columns { get; } - - /// - /// The number of rows in the entity table. - /// - public int RowCount { get; } - - /// - /// Constructor. - /// - public EntityTable_v2( - SerializableEntityTable et, - string[] stringTable) - { - Name = et.Name; - Columns = et.ValidateColumnRowsAreAligned(); - RowCount = Columns.FirstOrDefault()?.NumElements() ?? 0; - - foreach (var column in et.IndexColumns) - IndexColumns[column.Name] = column; - - foreach (var column in et.StringColumns) - StringColumns[column.Name] = column; - - foreach (var column in et.DataColumns) - DataColumns[column.Name] = column; - - _stringTable = stringTable; - } - - private static T GetColumnOrDefault(Dictionary map, string key, T defaultValue = default) - => map.TryGetValue(key, out var result) ? result : defaultValue; - - /// - /// Returns the index column based on the given column name. - /// - public int[] GetIndexColumnValues(string columnName) - => GetColumnOrDefault(IndexColumns, columnName)?.GetColumnValues(); - - /// - /// Returns the string column based on the given column name. - /// - public string[] GetStringColumnValues(string columnName) - { - var stringIndices = GetColumnOrDefault(StringColumns, columnName) - ?.GetColumnValues() ?? Array.Empty(); - - var strings = new string[stringIndices.Length]; - - for (var i = 0; i < strings.Length; i++) - { - strings[i] = _stringTable == null || _stringTable.Length == 0 - ? "" // Guard against the case where the string buffer is null or empty. - : _stringTable.ElementAtOrDefault(stringIndices[i], ""); - } - - return strings; - } - - /// - /// Returns the data column based on the given column name. - /// - public T[] GetDataColumnValues(string columnName) where T : unmanaged - { - var type = typeof(T); - - if (!ColumnExtensions.DataColumnTypes.Contains(type)) - throw new Exception($"{nameof(GetDataColumnValues)} error - unsupported data column type {type}"); - - var namedBuffer = GetColumnOrDefault(DataColumns, columnName); - if (namedBuffer == null) - return null; - - if (type == typeof(short)) - return namedBuffer.GetColumnValues().Select(i => (short)i).ToArray() as T[]; - - if (type == typeof(bool)) - return namedBuffer.GetColumnValues().Select(b => b != 0).ToArray() as T[]; - - return namedBuffer.GetColumnValues(); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/ArrayOps.cs b/src/cs/vim/Vim.Format.Core/Geometry/ArrayOps.cs deleted file mode 100644 index 55bbcedb..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/ArrayOps.cs +++ /dev/null @@ -1,260 +0,0 @@ - -// AUTOGENERATED FILE: DO NOT EDIT -// This file is generated from ArrayOps.tt - - -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public static class ArrayOps - { - - public static IArray< int > Add(this IArray< int > self, IArray< int > other) => self.Zip(other, MathOps.Add); - public static IArray< int > Add(this IArray< int > self, int scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< int > Add(this int self, IArray< int > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< int > Multiply(this IArray< int > self, IArray< int > other) => self.Zip(other, MathOps.Multiply); - public static IArray< int > Multiply(this IArray< int > self, int scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< int > Multiply(this int self, IArray< int > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< int > Subtract(this IArray< int > self, IArray< int > other) => self.Zip(other, MathOps.Subtract); - public static IArray< int > Subtract(this IArray< int > self, int scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< int > Subtract(this int self, IArray< int > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< int > Divide(this IArray< int > self, IArray< int > other) => self.Zip(other, MathOps.Divide); - public static IArray< int > Divide(this IArray< int > self, int scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< int > Divide(this int self, IArray< int > vector) => vector.Select(x => MathOps.Divide(self, x)); - public static IArray< long > Add(this IArray< long > self, IArray< long > other) => self.Zip(other, MathOps.Add); - public static IArray< long > Add(this IArray< long > self, long scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< long > Add(this long self, IArray< long > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< long > Multiply(this IArray< long > self, IArray< long > other) => self.Zip(other, MathOps.Multiply); - public static IArray< long > Multiply(this IArray< long > self, long scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< long > Multiply(this long self, IArray< long > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< long > Subtract(this IArray< long > self, IArray< long > other) => self.Zip(other, MathOps.Subtract); - public static IArray< long > Subtract(this IArray< long > self, long scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< long > Subtract(this long self, IArray< long > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< long > Divide(this IArray< long > self, IArray< long > other) => self.Zip(other, MathOps.Divide); - public static IArray< long > Divide(this IArray< long > self, long scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< long > Divide(this long self, IArray< long > vector) => vector.Select(x => MathOps.Divide(self, x)); - public static IArray< float > Add(this IArray< float > self, IArray< float > other) => self.Zip(other, MathOps.Add); - public static IArray< float > Add(this IArray< float > self, float scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< float > Add(this float self, IArray< float > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< float > Multiply(this IArray< float > self, IArray< float > other) => self.Zip(other, MathOps.Multiply); - public static IArray< float > Multiply(this IArray< float > self, float scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< float > Multiply(this float self, IArray< float > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< float > Subtract(this IArray< float > self, IArray< float > other) => self.Zip(other, MathOps.Subtract); - public static IArray< float > Subtract(this IArray< float > self, float scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< float > Subtract(this float self, IArray< float > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< float > Divide(this IArray< float > self, IArray< float > other) => self.Zip(other, MathOps.Divide); - public static IArray< float > Divide(this IArray< float > self, float scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< float > Divide(this float self, IArray< float > vector) => vector.Select(x => MathOps.Divide(self, x)); - public static IArray< double > Add(this IArray< double > self, IArray< double > other) => self.Zip(other, MathOps.Add); - public static IArray< double > Add(this IArray< double > self, double scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< double > Add(this double self, IArray< double > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< double > Multiply(this IArray< double > self, IArray< double > other) => self.Zip(other, MathOps.Multiply); - public static IArray< double > Multiply(this IArray< double > self, double scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< double > Multiply(this double self, IArray< double > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< double > Subtract(this IArray< double > self, IArray< double > other) => self.Zip(other, MathOps.Subtract); - public static IArray< double > Subtract(this IArray< double > self, double scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< double > Subtract(this double self, IArray< double > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< double > Divide(this IArray< double > self, IArray< double > other) => self.Zip(other, MathOps.Divide); - public static IArray< double > Divide(this IArray< double > self, double scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< double > Divide(this double self, IArray< double > vector) => vector.Select(x => MathOps.Divide(self, x)); - public static IArray< Vector2 > Add(this IArray< Vector2 > self, IArray< Vector2 > other) => self.Zip(other, MathOps.Add); - public static IArray< Vector2 > Add(this IArray< Vector2 > self, Vector2 scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< Vector2 > Add(this Vector2 self, IArray< Vector2 > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< Vector2 > Multiply(this IArray< Vector2 > self, IArray< Vector2 > other) => self.Zip(other, MathOps.Multiply); - public static IArray< Vector2 > Multiply(this IArray< Vector2 > self, Vector2 scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< Vector2 > Multiply(this Vector2 self, IArray< Vector2 > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< Vector2 > Subtract(this IArray< Vector2 > self, IArray< Vector2 > other) => self.Zip(other, MathOps.Subtract); - public static IArray< Vector2 > Subtract(this IArray< Vector2 > self, Vector2 scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< Vector2 > Subtract(this Vector2 self, IArray< Vector2 > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< Vector2 > Divide(this IArray< Vector2 > self, IArray< Vector2 > other) => self.Zip(other, MathOps.Divide); - public static IArray< Vector2 > Divide(this IArray< Vector2 > self, Vector2 scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< Vector2 > Divide(this Vector2 self, IArray< Vector2 > vector) => vector.Select(x => MathOps.Divide(self, x)); - public static IArray< Vector3 > Add(this IArray< Vector3 > self, IArray< Vector3 > other) => self.Zip(other, MathOps.Add); - public static IArray< Vector3 > Add(this IArray< Vector3 > self, Vector3 scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< Vector3 > Add(this Vector3 self, IArray< Vector3 > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< Vector3 > Multiply(this IArray< Vector3 > self, IArray< Vector3 > other) => self.Zip(other, MathOps.Multiply); - public static IArray< Vector3 > Multiply(this IArray< Vector3 > self, Vector3 scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< Vector3 > Multiply(this Vector3 self, IArray< Vector3 > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< Vector3 > Subtract(this IArray< Vector3 > self, IArray< Vector3 > other) => self.Zip(other, MathOps.Subtract); - public static IArray< Vector3 > Subtract(this IArray< Vector3 > self, Vector3 scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< Vector3 > Subtract(this Vector3 self, IArray< Vector3 > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< Vector3 > Divide(this IArray< Vector3 > self, IArray< Vector3 > other) => self.Zip(other, MathOps.Divide); - public static IArray< Vector3 > Divide(this IArray< Vector3 > self, Vector3 scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< Vector3 > Divide(this Vector3 self, IArray< Vector3 > vector) => vector.Select(x => MathOps.Divide(self, x)); - public static IArray< Vector4 > Add(this IArray< Vector4 > self, IArray< Vector4 > other) => self.Zip(other, MathOps.Add); - public static IArray< Vector4 > Add(this IArray< Vector4 > self, Vector4 scalar) => self.Select(x => MathOps.Add(x, scalar)); - public static IArray< Vector4 > Add(this Vector4 self, IArray< Vector4 > vector) => vector.Select(x => MathOps.Add(self, x)); - public static IArray< Vector4 > Multiply(this IArray< Vector4 > self, IArray< Vector4 > other) => self.Zip(other, MathOps.Multiply); - public static IArray< Vector4 > Multiply(this IArray< Vector4 > self, Vector4 scalar) => self.Select(x => MathOps.Multiply(x, scalar)); - public static IArray< Vector4 > Multiply(this Vector4 self, IArray< Vector4 > vector) => vector.Select(x => MathOps.Multiply(self, x)); - public static IArray< Vector4 > Subtract(this IArray< Vector4 > self, IArray< Vector4 > other) => self.Zip(other, MathOps.Subtract); - public static IArray< Vector4 > Subtract(this IArray< Vector4 > self, Vector4 scalar) => self.Select(x => MathOps.Subtract(x, scalar)); - public static IArray< Vector4 > Subtract(this Vector4 self, IArray< Vector4 > vector) => vector.Select(x => MathOps.Subtract(self, x)); - public static IArray< Vector4 > Divide(this IArray< Vector4 > self, IArray< Vector4 > other) => self.Zip(other, MathOps.Divide); - public static IArray< Vector4 > Divide(this IArray< Vector4 > self, Vector4 scalar) => self.Select(x => MathOps.Divide(x, scalar)); - public static IArray< Vector4 > Divide(this Vector4 self, IArray< Vector4 > vector) => vector.Select(x => MathOps.Divide(self, x)); - - public static IArray Abs (this IArray< double > self) => self.Select(MathOps.Abs); - public static IArray Abs (this IArray< float > self) => self.Select(MathOps.Abs); - public static IArray Abs (this IArray< Vector2 > self) => self.Select(MathOps.Abs); - public static IArray Abs (this IArray< Vector3 > self) => self.Select(MathOps.Abs); - public static IArray Abs (this IArray< Vector4 > self) => self.Select(MathOps.Abs); - - public static IArray Acos (this IArray< double > self) => self.Select(MathOps.Acos); - public static IArray Acos (this IArray< float > self) => self.Select(MathOps.Acos); - public static IArray Acos (this IArray< Vector2 > self) => self.Select(MathOps.Acos); - public static IArray Acos (this IArray< Vector3 > self) => self.Select(MathOps.Acos); - public static IArray Acos (this IArray< Vector4 > self) => self.Select(MathOps.Acos); - - public static IArray Asin (this IArray< double > self) => self.Select(MathOps.Asin); - public static IArray Asin (this IArray< float > self) => self.Select(MathOps.Asin); - public static IArray Asin (this IArray< Vector2 > self) => self.Select(MathOps.Asin); - public static IArray Asin (this IArray< Vector3 > self) => self.Select(MathOps.Asin); - public static IArray Asin (this IArray< Vector4 > self) => self.Select(MathOps.Asin); - - public static IArray Atan (this IArray< double > self) => self.Select(MathOps.Atan); - public static IArray Atan (this IArray< float > self) => self.Select(MathOps.Atan); - public static IArray Atan (this IArray< Vector2 > self) => self.Select(MathOps.Atan); - public static IArray Atan (this IArray< Vector3 > self) => self.Select(MathOps.Atan); - public static IArray Atan (this IArray< Vector4 > self) => self.Select(MathOps.Atan); - - public static IArray Cos (this IArray< double > self) => self.Select(MathOps.Cos); - public static IArray Cos (this IArray< float > self) => self.Select(MathOps.Cos); - public static IArray Cos (this IArray< Vector2 > self) => self.Select(MathOps.Cos); - public static IArray Cos (this IArray< Vector3 > self) => self.Select(MathOps.Cos); - public static IArray Cos (this IArray< Vector4 > self) => self.Select(MathOps.Cos); - - public static IArray Cosh (this IArray< double > self) => self.Select(MathOps.Cosh); - public static IArray Cosh (this IArray< float > self) => self.Select(MathOps.Cosh); - public static IArray Cosh (this IArray< Vector2 > self) => self.Select(MathOps.Cosh); - public static IArray Cosh (this IArray< Vector3 > self) => self.Select(MathOps.Cosh); - public static IArray Cosh (this IArray< Vector4 > self) => self.Select(MathOps.Cosh); - - public static IArray Exp (this IArray< double > self) => self.Select(MathOps.Exp); - public static IArray Exp (this IArray< float > self) => self.Select(MathOps.Exp); - public static IArray Exp (this IArray< Vector2 > self) => self.Select(MathOps.Exp); - public static IArray Exp (this IArray< Vector3 > self) => self.Select(MathOps.Exp); - public static IArray Exp (this IArray< Vector4 > self) => self.Select(MathOps.Exp); - - public static IArray Log (this IArray< double > self) => self.Select(MathOps.Log); - public static IArray Log (this IArray< float > self) => self.Select(MathOps.Log); - public static IArray Log (this IArray< Vector2 > self) => self.Select(MathOps.Log); - public static IArray Log (this IArray< Vector3 > self) => self.Select(MathOps.Log); - public static IArray Log (this IArray< Vector4 > self) => self.Select(MathOps.Log); - - public static IArray Log10 (this IArray< double > self) => self.Select(MathOps.Log10); - public static IArray Log10 (this IArray< float > self) => self.Select(MathOps.Log10); - public static IArray Log10 (this IArray< Vector2 > self) => self.Select(MathOps.Log10); - public static IArray Log10 (this IArray< Vector3 > self) => self.Select(MathOps.Log10); - public static IArray Log10 (this IArray< Vector4 > self) => self.Select(MathOps.Log10); - - public static IArray Sin (this IArray< double > self) => self.Select(MathOps.Sin); - public static IArray Sin (this IArray< float > self) => self.Select(MathOps.Sin); - public static IArray Sin (this IArray< Vector2 > self) => self.Select(MathOps.Sin); - public static IArray Sin (this IArray< Vector3 > self) => self.Select(MathOps.Sin); - public static IArray Sin (this IArray< Vector4 > self) => self.Select(MathOps.Sin); - - public static IArray Sinh (this IArray< double > self) => self.Select(MathOps.Sinh); - public static IArray Sinh (this IArray< float > self) => self.Select(MathOps.Sinh); - public static IArray Sinh (this IArray< Vector2 > self) => self.Select(MathOps.Sinh); - public static IArray Sinh (this IArray< Vector3 > self) => self.Select(MathOps.Sinh); - public static IArray Sinh (this IArray< Vector4 > self) => self.Select(MathOps.Sinh); - - public static IArray Sqrt (this IArray< double > self) => self.Select(MathOps.Sqrt); - public static IArray Sqrt (this IArray< float > self) => self.Select(MathOps.Sqrt); - public static IArray Sqrt (this IArray< Vector2 > self) => self.Select(MathOps.Sqrt); - public static IArray Sqrt (this IArray< Vector3 > self) => self.Select(MathOps.Sqrt); - public static IArray Sqrt (this IArray< Vector4 > self) => self.Select(MathOps.Sqrt); - - public static IArray Tan (this IArray< double > self) => self.Select(MathOps.Tan); - public static IArray Tan (this IArray< float > self) => self.Select(MathOps.Tan); - public static IArray Tan (this IArray< Vector2 > self) => self.Select(MathOps.Tan); - public static IArray Tan (this IArray< Vector3 > self) => self.Select(MathOps.Tan); - public static IArray Tan (this IArray< Vector4 > self) => self.Select(MathOps.Tan); - - public static IArray Tanh (this IArray< double > self) => self.Select(MathOps.Tanh); - public static IArray Tanh (this IArray< float > self) => self.Select(MathOps.Tanh); - public static IArray Tanh (this IArray< Vector2 > self) => self.Select(MathOps.Tanh); - public static IArray Tanh (this IArray< Vector3 > self) => self.Select(MathOps.Tanh); - public static IArray Tanh (this IArray< Vector4 > self) => self.Select(MathOps.Tanh); - - public static IArray Sqr (this IArray< double > self) => self.Select(MathOps.Sqr); - public static IArray Sqr (this IArray< float > self) => self.Select(MathOps.Sqr); - public static IArray Sqr (this IArray< Vector2 > self) => self.Select(MathOps.Sqr); - public static IArray Sqr (this IArray< Vector3 > self) => self.Select(MathOps.Sqr); - public static IArray Sqr (this IArray< Vector4 > self) => self.Select(MathOps.Sqr); - - public static IArray Inverse (this IArray< double > self) => self.Select(MathOps.Inverse); - public static IArray Inverse (this IArray< float > self) => self.Select(MathOps.Inverse); - public static IArray Inverse (this IArray< Vector2 > self) => self.Select(MathOps.Inverse); - public static IArray Inverse (this IArray< Vector3 > self) => self.Select(MathOps.Inverse); - public static IArray Inverse (this IArray< Vector4 > self) => self.Select(MathOps.Inverse); - - public static IArray Ceiling (this IArray< double > self) => self.Select(MathOps.Ceiling); - public static IArray Ceiling (this IArray< float > self) => self.Select(MathOps.Ceiling); - public static IArray Ceiling (this IArray< Vector2 > self) => self.Select(MathOps.Ceiling); - public static IArray Ceiling (this IArray< Vector3 > self) => self.Select(MathOps.Ceiling); - public static IArray Ceiling (this IArray< Vector4 > self) => self.Select(MathOps.Ceiling); - - public static IArray Floor (this IArray< double > self) => self.Select(MathOps.Floor); - public static IArray Floor (this IArray< float > self) => self.Select(MathOps.Floor); - public static IArray Floor (this IArray< Vector2 > self) => self.Select(MathOps.Floor); - public static IArray Floor (this IArray< Vector3 > self) => self.Select(MathOps.Floor); - public static IArray Floor (this IArray< Vector4 > self) => self.Select(MathOps.Floor); - - public static IArray Round (this IArray< double > self) => self.Select(MathOps.Round); - public static IArray Round (this IArray< float > self) => self.Select(MathOps.Round); - public static IArray Round (this IArray< Vector2 > self) => self.Select(MathOps.Round); - public static IArray Round (this IArray< Vector3 > self) => self.Select(MathOps.Round); - public static IArray Round (this IArray< Vector4 > self) => self.Select(MathOps.Round); - - public static IArray Truncate (this IArray< double > self) => self.Select(MathOps.Truncate); - public static IArray Truncate (this IArray< float > self) => self.Select(MathOps.Truncate); - public static IArray Truncate (this IArray< Vector2 > self) => self.Select(MathOps.Truncate); - public static IArray Truncate (this IArray< Vector3 > self) => self.Select(MathOps.Truncate); - public static IArray Truncate (this IArray< Vector4 > self) => self.Select(MathOps.Truncate); - // TODO: do this over all over the numerical types - public static long Sum(this IArray self) => self.Aggregate(0L, (x, y) => x + y); - public static long Sum(this IArray self) => self.Aggregate(0L, (x, y) => x + y); - public static double Sum(this IArray self) => self.Aggregate(0.0, (x, y) => x + y); - public static double Sum(this IArray self) => self.Aggregate(0.0, (x, y) => x + y); - public static Vector2 Sum(this IArray self) => self.Aggregate(Vector2.Zero, (x, y) => x + y); - public static Vector3 Sum(this IArray self) => self.Aggregate(Vector3.Zero, (x, y) => x + y); - public static Vector4 Sum(this IArray self) => self.Aggregate(Vector4.Zero, (x, y) => x + y); - - public static double Average(this IArray self) => self.Sum() / self.Count; - public static double Average(this IArray self) => self.Sum() / self.Count; - public static double Average(this IArray self) => self.Sum() / self.Count; - public static double Average(this IArray self) => self.Sum() / self.Count; - public static Vector2 Average(this IArray self) => self.Sum() / self.Count; - public static Vector3 Average(this IArray self) => self.Sum() / self.Count; - public static Vector4 Average(this IArray self) => self.Sum() / self.Count; - - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static Vector2 Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static Vector3 Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static Vector4 Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static Vector2 StdDev(this IArray self) => self.Variance().Sqrt(); - public static Vector3 StdDev(this IArray self) => self.Variance().Sqrt(); - public static Vector4 StdDev(this IArray self) => self.Variance().Sqrt(); - - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/ArrayOps.tt b/src/cs/vim/Vim.Format.Core/Geometry/ArrayOps.tt deleted file mode 100644 index 2858a417..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/ArrayOps.tt +++ /dev/null @@ -1,96 +0,0 @@ -<#@ template language="C#" #> -<#@ output extension=".cs" #> -<#@ assembly name="System.Core" #> -<#@ import namespace="System" #> -<#@ import namespace="System.IO" #> -<#@ import namespace="System.Diagnostics" #> -<#@ import namespace="System.Linq" #> - -// AUTOGENERATED FILE: DO NOT EDIT -// This file is generated from ArrayOps.tt - -<# -var nonVectorTypes = new[] { "int", "long", "float", "double" }; -var vectorTypes = new[] { "Vector2", "Vector3", "Vector4" }; -var types = nonVectorTypes.Concat(vectorTypes); -var intTypes = new[] { "int", "long" }; -var araBinaryOps = new[] { "Add", "Sub", "Mul", "Div" }; -var araCompOps = new[] { "Gt", "Lt", "GtEq", "LtEq", "Eq", "NEq" }; -var sysUnaryOps = new[] { "Abs", "Acos", "Asin", "Atan", "Cos", "Cosh", "Exp", "Log", "Log10", "Sin", "Sinh", "Sqrt", "Tan", "Tanh" }; -var araUnaryOps = new[] { "Sqr", "Inverse", "Ceiling", "Floor", "Round", "Truncate" }; -var allUnaryOps = sysUnaryOps.Concat(araUnaryOps); -#> - -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public static class ArrayOps - { - -<# -foreach (var t in types) { -foreach (var op in new[] { "Add", "Multiply", "Subtract", "Divide" }) -{ -#> - public static IArray< <#= t #> > <#= op #>(this IArray< <#= t #> > self, IArray< <#= t #> > other) => self.Zip(other, MathOps.<#= op #>); - public static IArray< <#= t #> > <#= op #>(this IArray< <#= t #> > self, <#= t #> scalar) => self.Select(x => MathOps.<#= op #>(x, scalar)); - public static IArray< <#= t #> > <#= op #>(this <#= t #> self, IArray< <#= t #> > vector) => vector.Select(x => MathOps.<#= op #>(self, x)); -<# -} -} -foreach (var op in allUnaryOps) { -#> - - public static IArray <#= op #> (this IArray< double > self) => self.Select(MathOps.<#= op #>); - public static IArray <#= op #> (this IArray< float > self) => self.Select(MathOps.<#= op #>); - public static IArray <#= op #> (this IArray< Vector2 > self) => self.Select(MathOps.<#= op #>); - public static IArray <#= op #> (this IArray< Vector3 > self) => self.Select(MathOps.<#= op #>); - public static IArray <#= op #> (this IArray< Vector4 > self) => self.Select(MathOps.<#= op #>); -<# -} -#> - // TODO: do this over all over the numerical types - public static long Sum(this IArray self) => self.Aggregate(0L, (x, y) => x + y); - public static long Sum(this IArray self) => self.Aggregate(0L, (x, y) => x + y); - public static double Sum(this IArray self) => self.Aggregate(0.0, (x, y) => x + y); - public static double Sum(this IArray self) => self.Aggregate(0.0, (x, y) => x + y); - public static Vector2 Sum(this IArray self) => self.Aggregate(Vector2.Zero, (x, y) => x + y); - public static Vector3 Sum(this IArray self) => self.Aggregate(Vector3.Zero, (x, y) => x + y); - public static Vector4 Sum(this IArray self) => self.Aggregate(Vector4.Zero, (x, y) => x + y); - - public static double Average(this IArray self) => self.Sum() / self.Count; - public static double Average(this IArray self) => self.Sum() / self.Count; - public static double Average(this IArray self) => self.Sum() / self.Count; - public static double Average(this IArray self) => self.Sum() / self.Count; - public static Vector2 Average(this IArray self) => self.Sum() / self.Count; - public static Vector3 Average(this IArray self) => self.Sum() / self.Count; - public static Vector4 Average(this IArray self) => self.Sum() / self.Count; - - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static double Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static Vector2 Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static Vector3 Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - public static Vector4 Variance(this IArray self) { var mean = self.Average(); return self.Select(x => MathOps.Sqr(x - mean)).Average(); } - - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static double StdDev(this IArray self) => self.Variance().Sqrt(); - public static Vector2 StdDev(this IArray self) => self.Variance().Sqrt(); - public static Vector3 StdDev(this IArray self) => self.Variance().Sqrt(); - public static Vector4 StdDev(this IArray self) => self.Variance().Sqrt(); - - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - public static IArray PartialSums(this IArray self) => self.PostAccumulate((x, y) => x + y); - - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/Bounded.cs b/src/cs/vim/Vim.Format.Core/Geometry/Bounded.cs deleted file mode 100644 index ca2571de..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/Bounded.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public interface IBounded - { - AABox Bounds { get; } - } - - public static class Bounded - { - public static AABox UpdateBounds(this IBounded self, AABox box) - => box.Merge(self.Bounds); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/CatmullClark.cs b/src/cs/vim/Vim.Format.Core/Geometry/CatmullClark.cs deleted file mode 100644 index 4ffbd54a..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/CatmullClark.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using System.Collections.Generic; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - // This is used to index an edge from any two vertices. - // Vertex order doesnt matter. - public class GeometryEdgeKey : IEquatable - { - public int Vertex0 { get; } - public int Vertex1 { get; } - - public GeometryEdgeKey(int v0, int v1) - { - Vertex0 = Math.Min(v0, v1); - Vertex1 = Math.Max(v0, v1); - } - - public override int GetHashCode() - => Hash.Combine(Vertex0.GetHashCode(), Vertex1.GetHashCode()); - - public override bool Equals(object obj) - => obj is GeometryEdgeKey && Equals((GeometryEdgeKey)obj); - - public bool Equals(GeometryEdgeKey p) - => Vertex0 == p.Vertex0 && Vertex1 == p.Vertex1; - } - - // Stores information about an edge in a mesh. - public class GeometryEdge - { - public Vector3 EdgePoint { get; set; } - public int EdgePointIndex { get; set; } = -1; - public int Face0 { get; set; } = -1; - public int Face1 { get; set; } = -1; - } - - public static class CatmullClarkSmoothing - { - public static Dictionary CreateEdgeMap(this IMesh geometry) - { - var globalEdgeIndex = 0; - var edgeMap = new Dictionary(); - var currentIndex = 0; - for (var faceIndex = 0; faceIndex < geometry.NumFaces; faceIndex++) - { - var faceSize = 3; - for (var edgeIndex = 0; edgeIndex < faceSize; edgeIndex++) - { - var geometryEdgeKey = new GeometryEdgeKey(geometry.Indices[currentIndex + edgeIndex], geometry.Indices[currentIndex + (edgeIndex + 1) % faceSize]); - if (edgeMap.ContainsKey(geometryEdgeKey)) - { - edgeMap[geometryEdgeKey].Face1 = faceIndex; - } - else - { - var geometryEdge = new GeometryEdge(); - geometryEdge.EdgePointIndex = globalEdgeIndex++; - geometryEdge.Face0 = faceIndex; - edgeMap[geometryEdgeKey] = geometryEdge; - } - } - currentIndex += faceSize; - } - - return edgeMap; - } - - public static IMesh CatmullClark(this IMesh geometry, float smoothing = 0.0f) - { - var edgeMap = geometry.CreateEdgeMap(); - - var numQuads = geometry.NumFaces * 3; - var numVertices = geometry.Vertices.Count + edgeMap.Count + geometry.NumFaces; - - var facePoints = new Vector3[geometry.NumFaces]; - var vertexFPoints = new Vector3[geometry.Vertices.Count]; - var vertexRPoints = new Vector3[geometry.Vertices.Count]; - var vertexNumFaces = new float[geometry.Vertices.Count]; - var vertexNumEdges = new float[geometry.Vertices.Count]; - var newVertices = new Vector3[numVertices]; - var newIndices = new int[numQuads * 4]; - var edgeVertices = new bool[geometry.Vertices.Count]; - - foreach (var edge in edgeMap) - { - if (edge.Value.Face0 == -1 || edge.Value.Face1 == -1) - { - edgeVertices[edge.Key.Vertex0] = true; - edgeVertices[edge.Key.Vertex1] = true; - } - } - - // For each face, add a face point - // Set each face point to be the average of all original points for the respective face. - // For each edge, add an edge point. - // Set each edge point to be the average of the two neighbouring face points and its two original endpoints. - // For each face point, add an edge for every edge of the face, connecting the face point to each edge point for the face. - // For each original point P, take the average F of all n (recently created) face points for faces touching P, and take - // the average R of all n edge midpoints for (original) edges touching P, where each edge midpoint is the average of its - // two endpoint vertices (not to be confused with new "edge points" above). Move each original point to the point - // - // (F + 2 R + ( n − 3 ) P) / n - // - // This is the barycenter of P, R and F with respective weights (n − 3), 2 and 1. - // - // Connect each new vertex point to the new edge points of all original edges incident on the original vertex. - // Define new faces as enclosed by edges. - - CalculateFaceCentroidPoints(geometry, facePoints, vertexNumFaces, vertexFPoints); - CalculateEdgePoints(geometry, edgeMap, facePoints, vertexNumEdges, vertexRPoints, smoothing); - CalculateVertexPoints(geometry, vertexNumFaces, vertexFPoints, vertexNumEdges, vertexRPoints, newVertices, edgeVertices, smoothing); - - var facePointStartIndex = geometry.Vertices.Count; - var edgePointStartIndex = facePointStartIndex + facePoints.Length; - - // Copy all points into a single buffer - for (var i = 0; i < facePoints.Length; i++) - { - newVertices[facePointStartIndex + i] = facePoints[i]; - } - foreach (var edge in edgeMap) - { - newVertices[edgePointStartIndex + edge.Value.EdgePointIndex] = edge.Value.EdgePoint; - } - - return GenerateMesh(geometry, newVertices, newIndices, edgeMap, facePointStartIndex, edgePointStartIndex, numQuads); - } - - public static void CalculateFaceCentroidPoints(IMesh geometry, Vector3[] outFacePoints, float[] outVertexNumFaces, Vector3[] outVertexFPoints) - { - var currentVertexIndex = 0; - for (var faceIndex = 0; faceIndex < geometry.NumFaces; faceIndex++) - { - var faceSize = geometry.NumCornersPerFace; - - var facePoint = new Vector3(); - - for (var edgeIndex = 0; edgeIndex < faceSize; edgeIndex++) - { - var vertexIndex = geometry.Indices[currentVertexIndex + edgeIndex]; - facePoint += geometry.Vertices[vertexIndex]; - } - - facePoint /= faceSize; - - outFacePoints[faceIndex] = facePoint; - - for (var edgeIndex = 0; edgeIndex < faceSize; edgeIndex++) - { - var vertexIndex = geometry.Indices[currentVertexIndex + edgeIndex]; - outVertexNumFaces[vertexIndex]++; - outVertexFPoints[vertexIndex] += facePoint; - } - - currentVertexIndex += faceSize; - } - } - - public static void CalculateEdgePoints(IMesh geometry, Dictionary edgeMap, Vector3[] facePoints, float[] outVertexNumEdges, Vector3[] outVertexRPoints, float smoothing) - { - foreach (var edge in edgeMap) - { - var n = 2.0f; - var middlePoint = geometry.Vertices[edge.Key.Vertex0] + geometry.Vertices[edge.Key.Vertex1]; - var edgePoint = middlePoint; - - if (edge.Value.Face0 >= 0 && edge.Value.Face1 >= 0) - { - edgePoint += facePoints[edge.Value.Face0]; - edgePoint += facePoints[edge.Value.Face1]; - n += 2.0f; - } - - middlePoint /= 2.0f; - edgePoint /= n; - - edge.Value.EdgePoint = edgePoint * smoothing + middlePoint * (1.0f - smoothing); - - outVertexNumEdges[edge.Key.Vertex0]++; - outVertexNumEdges[edge.Key.Vertex1]++; - outVertexRPoints[edge.Key.Vertex0] += edge.Value.EdgePoint; - outVertexRPoints[edge.Key.Vertex1] += edge.Value.EdgePoint; - } - } - - public static void CalculateVertexPoints(IMesh geometry, float[] vertexNumFaces, Vector3[] vertexFPoints, float[] vertexNumEdges, Vector3[] vertexRPoints, Vector3[] outNewVertices, bool[] edgeVertices, float smoothing) - { - for (var index = 0; index < geometry.Vertices.Count; index++) - { - var numFaces = vertexNumFaces[index]; - var numEdges = vertexNumEdges[index]; - var newVertex = (vertexFPoints[index] / numFaces + 2.0f * vertexRPoints[index] / numEdges + (numFaces - 3.0f) * geometry.Vertices[index]) / numFaces; - - outNewVertices[index] = edgeVertices[index] ? geometry.Vertices[index] : smoothing * newVertex + (1.0f - smoothing) * geometry.Vertices[index]; - } - } - - public static IMesh GenerateMesh(IMesh geometry, Vector3[] newVertices, int[] newIndices, Dictionary edgeMap, int facePointStartIndex, int edgePointStartIndex, int numQuads) - { - var currentNewVertexIndex = 0; - var currentOldVertexIndex = 0; - for (var faceIndex = 0; faceIndex < geometry.NumFaces; faceIndex++) - { - var faceSize = geometry.NumCornersPerFace; - - for (var i = 0; i < faceSize; i++) - { - var prevFaceVertexIndex = geometry.Indices[currentOldVertexIndex + i]; - var faceVertexIndex = geometry.Indices[currentOldVertexIndex + (i + 1) % faceSize]; - var nextFaceVertexIndex = geometry.Indices[currentOldVertexIndex + (i + 2) % faceSize]; - - var edgeKey0 = new GeometryEdgeKey(prevFaceVertexIndex, faceVertexIndex); - var edgeKey1 = new GeometryEdgeKey(faceVertexIndex, nextFaceVertexIndex); - - newIndices[currentNewVertexIndex++] = faceIndex + facePointStartIndex; - newIndices[currentNewVertexIndex++] = edgeMap[edgeKey0].EdgePointIndex + edgePointStartIndex; - newIndices[currentNewVertexIndex++] = faceVertexIndex; - newIndices[currentNewVertexIndex++] = edgeMap[edgeKey1].EdgePointIndex + edgePointStartIndex; - } - - currentOldVertexIndex += faceSize; - } - - return Primitives.QuadMesh(newVertices.ToIArray(), newIndices.ToIArray()); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/GeometryCuttingUtils.cs b/src/cs/vim/Vim.Format.Core/Geometry/GeometryCuttingUtils.cs deleted file mode 100644 index 338f7776..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/GeometryCuttingUtils.cs +++ /dev/null @@ -1,173 +0,0 @@ -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public static class GeometryCuttingUtils - { - // Fins the intersection between two lines. - // Returns true if they intersect - // t and u are the distances of the intersection point along the two line - public static bool LineLineIntersection(Vector2 line1Origin, Vector2 line1Direction, Vector2 line2Origin, Vector2 line2Direction, out float t, out float u, float epsilon = 0.01f) - { - var line1P2 = line1Origin + line1Direction; - var line2P2 = line2Origin + line2Direction; - - var x1 = line1Origin.X; - var y1 = line1Origin.Y; - var x2 = line1P2.X; - var y2 = line1P2.Y; - var x3 = line2Origin.X; - var y3 = line2Origin.Y; - var x4 = line2P2.X; - var y4 = line2P2.Y; - - var denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); - - if (denominator.Abs() < epsilon) - { - t = 0.0f; - u = 0.0f; - return false; - } - - var tNeumerator = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4); - var uNeumerator = (x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3); - - t = tNeumerator / denominator; - u = -uNeumerator / denominator; - - return true; - } - - // Returns the distance between two lines - // t and u are the distances if the intersection points along the two lines - public static float LineLineDistance(Vector2 line1A, Vector2 line1B, Vector2 line2A, Vector2 line2B, out float t, out float u, float epsilon = 0.0000001f) - { - var x1 = line1A.X; - var y1 = line1A.Y; - var x2 = line1B.X; - var y2 = line1B.Y; - var x3 = line2A.X; - var y3 = line2A.Y; - var x4 = line2B.X; - var y4 = line2B.Y; - - var denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); - - if (denominator.Abs() >= epsilon) - { - // Lines are not parallel, they should intersect nicely - var tNeumerator = (x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4); - var uNeumerator = (x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3); - - t = tNeumerator / denominator; - u = -uNeumerator / denominator; - - var e = 0.0; - if (t >= -e && t <= 1.0 + e && u >= -e && u <= 1.0 + e) - { - t = t.Clamp(0.0f, 1.0f); - u = u.Clamp(0.0f, 1.0f); - return 0; - } - } - - // Parallel or non intersecting lines - default to point to line checks - - u = 0.0f; - var minDistance = LinePointDistance(line1A, line1B, line2A, out t); - var distance = LinePointDistance(line1A, line1B, line2B, out var closestPoint); - if (distance < minDistance) - { - minDistance = distance; - t = closestPoint; - u = 1.0f; - } - - distance = LinePointDistance(line2A, line2B, line1A, out closestPoint); - if (distance < minDistance) - { - minDistance = distance; - u = closestPoint; - t = 0.0f; - } - - distance = LinePointDistance(line2A, line2B, line1B, out closestPoint); - if (distance < minDistance) - { - minDistance = distance; - u = closestPoint; - t = 1.0f; - } - - return minDistance; - } - - // Returns the distance between a line and a point. - // t is the distance along the line of the closest point - public static float LinePointDistance(Vector2 v, Vector2 w, Vector2 p, out float t) - { - // Return minimum distance between line segment vw and point p - var l2 = (v - w).LengthSquared(); // i.e. |w-v|^2 - avoid a sqrt - if (l2 == 0.0f) // v == w case - { - t = 0.5f; - return (p - v).Length(); - } - - // Consider the line extending the segment, parameterized as v + t (w - v). - // We find projection of point p onto the line. - // It falls where t = [(p-v) . (w-v)] / |w-v|^2 - // We clamp t from [0,1] to handle points outside the segment vw. - t = ((p - v).Dot(w - v) / l2).Clamp(0.0f, 1.0f); - var closestPoint = v + t * (w - v); // Projection falls on the segment - return (p - closestPoint).Length(); - } - - - - // Apply a surface function that projects a 2d triangulation in UV space into a 3d triangulation - /* public static IGeometry ApplySurfaceFunction(this List triangulations, Func surfaceFunction) - { - var allIndices = new List(); - var allVertices = new List(); - - foreach (var triangulation in triangulations) - { - var vertices = triangulation.Points.ToList(); - var indices = triangulation.TriangleIndices; - - while (true) - { - List outIndices; - List outVertices; - bool done = SubdivideLargeTriangles(vertices, indices, out outVertices, out outIndices, 0.3f); - - vertices = outVertices; - indices = outIndices; - - if (done) - { - break; - } - } - - // Apply surface function - var vertices3d = vertices.Select(x => surfaceFunction(x.ToVector())); - - // Merge all triangulations - int startIndex = allVertices.Count; - allVertices.AddRange(vertices3d); - allIndices.AddRange(indices.Select(x => x + startIndex)); - } - - var cutGeometry = new G3D( - allVertices.ToIArray().ToVertexAttribute(), - allIndices.ToIArray().ToIndexAttribute(), - new FunctionalArray(allIndices.Count / 3, x => 3).ToFaceSizeAttribute() - ).ToIMesh(); - - return cutGeometry; - }*/ - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/GeometryUtil.cs b/src/cs/vim/Vim.Format.Core/Geometry/GeometryUtil.cs deleted file mode 100644 index db8d33e7..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/GeometryUtil.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - // TODO: many of these functions should live in other places - public static class GeometryUtil - { - public static IArray Normalize(this IArray vectors) - => vectors.Select(v => v.Normalize()); - - public static bool SequenceAlmostEquals(this IArray vs1, IArray vs2, float tolerance = Math3d.Constants.Tolerance) - => vs1.Count == vs2.Count && vs1.Indices().All(i => vs1[i].AlmostEquals(vs2[i], tolerance)); - - public static bool AreColinear(this IEnumerable vectors, Vector3 reference, float tolerance = (float)Math3d.Constants.OneTenthOfADegree) - => !reference.IsNaN() && vectors.All(v => v.Colinear(reference, tolerance)); - - public static bool AreColinear(this IEnumerable vectors, float tolerance = (float)Math3d.Constants.OneTenthOfADegree) - => vectors.ToList().AreColinear(tolerance); - - public static bool AreColinear(this IList vectors, float tolerance = (float)Math3d.Constants.OneTenthOfADegree) - => vectors.Count <= 1 || vectors.Skip(1).AreColinear(vectors[0], tolerance); - - public static AABox BoundingBox(this IArray vertices) - => AABox.Create(vertices.ToEnumerable()); - - public static IArray SampleZeroToOneInclusive(this int count) - => (count + 1).Select(i => i / (float)count); - - public static IArray SampleZeroToOneExclusive(this int count) - => count.Select(i => i / (float)count); - - public static IArray InterpolateInclusive(this int count, Func function) - => count.SampleZeroToOneInclusive().Select(function); - - public static IArray Interpolate(this Line self, int count) - => count.InterpolateInclusive(self.Lerp); - - public static IArray Rotate(this IArray self, Vector3 axis, float angle) - => self.Transform(Matrix4x4.CreateFromAxisAngle(axis, angle)); - - public static IArray Transform(this IArray self, Matrix4x4 matrix) - => self.Select(x => x.Transform(matrix)); - - public static Int3 Sort(this Int3 v) - { - if (v.X < v.Y) - { - return (v.Y < v.Z) - ? new Int3(v.X, v.Y, v.Z) - : (v.X < v.Z) - ? new Int3(v.X, v.Z, v.Y) - : new Int3(v.Z, v.X, v.Y); - } - else - { - return (v.X < v.Z) - ? new Int3(v.Y, v.X, v.Z) - : (v.Y < v.Z) - ? new Int3(v.Y, v.Z, v.X) - : new Int3(v.Z, v.Y, v.X); - } - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/IMesh.cs b/src/cs/vim/Vim.Format.Core/Geometry/IMesh.cs deleted file mode 100644 index f330d0e4..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/IMesh.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - /// - /// This is the interface for triangle meshes. - /// - public interface IMesh : - IGeometryAttributes, - ITransformable3D - { - IArray Vertices { get; } - IArray Indices { get; } - IArray VertexColors { get; } - IArray VertexNormals { get; } - IArray VertexUvs { get; } - - IArray SubmeshMaterials { get; } - IArray SubmeshIndexOffsets { get; } - IArray SubmeshIndexCount { get; } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/IScene.cs b/src/cs/vim/Vim.Format.Core/Geometry/IScene.cs deleted file mode 100644 index 43379e4c..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/IScene.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - /// - /// An IScene is a generic representation of a 3D scene graph. - /// - public interface IScene - { - IArray Nodes { get; } - IArray Meshes { get; } - } - - /// - /// A node in a scene graph. - /// - public interface ISceneNode - { - Matrix4x4 Transform { get; } - int MeshIndex { get; } - IMesh GetMesh(); - ISceneNode Parent { get; } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/KdTree.cs b/src/cs/vim/Vim.Format.Core/Geometry/KdTree.cs deleted file mode 100644 index 153e1a31..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/KdTree.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public class KdTree where T : IBounded - { - public int Axis => Depth % 3; - public int Depth; - public KdTree Left; - public KdTree Right; - public AABox Box; - public List Items = new List(); - - public const int MinNodesForSplit = 4; - - public KdTree(int depth) - => Depth = depth; - - public KdTree(int depth, IEnumerable items) - : this(depth) - => AddRange(items); - - public void AddRange(IEnumerable items) - { - foreach (var x in items) - Add(x); - } - - public void Add(T item) - { - if (IsSplit) - throw new Exception("Cannot add meshes after split"); - Box = item.UpdateBounds(Box); - Items.Add(item); - } - - public bool IsSplit - => Left != null || Right != null; - - public void Split() - { - if (IsSplit) - throw new Exception("Already split"); - if (Items.Count < MinNodesForSplit) - return; - var minVal = Items.Min(m => m.Bounds.Min.GetComponent(Axis)); - var maxVal = Items.Max(m => m.Bounds.Max.GetComponent(Axis)); - var n = Items.Count; - var meshes = Items.OrderBy(m => m.Bounds.Min.GetComponent(Axis)); - Left = new KdTree(Depth + 1, meshes.Take(n / 2)); - Right = new KdTree(Depth + 1, meshes.Skip(n / 2)); - Items.Clear(); - Debug.Assert(Items.Count == 0); - Debug.Assert(Left.Items.Count + Right.Items.Count == n); - Left.Split(); - Right.Split(); - } - - public bool Visit(Func intersects, Func visitAndContinue) - { - if (!intersects(Box)) - return true; - - if (IsSplit) - { - if (!Left.Visit(intersects, visitAndContinue)) - return false; - if (!Right.Visit(intersects, visitAndContinue)) - return false; - } - else - { - foreach (var item in Items) - { - if (!visitAndContinue(item)) - return false; - } - } - - return true; - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/MeshDebugView.cs b/src/cs/vim/Vim.Format.Core/Geometry/MeshDebugView.cs deleted file mode 100644 index 54a216e3..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/MeshDebugView.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public class MeshDebugView - { - IMesh Interface { get; } - - public int NumCorners => Interface.NumCorners; - public int NumFaces => Interface.NumFaces; - public int NumMeshes => Interface.NumMeshes; - public int NumInstances => Interface.NumInstances; - - public Vector3[] Vertices => Interface.Vertices.ToArray(); - public int[] Indices => Interface.Indices.ToArray(); - - public MeshDebugView(IMesh g) - => Interface = g; - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs b/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs deleted file mode 100644 index 506cb3d3..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs +++ /dev/null @@ -1,453 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; -using Vim.Util; - -namespace Vim.Format.Geometry -{ - public static class MeshExtensions - { - #region constructors - public static IMesh ToIMesh(this IArray self) - => self.ToEnumerable().ToIMesh(); - - public static IMesh ToIMesh(this IEnumerable self) - { - var tmp = new GeometryAttributes(self); - switch (tmp.NumCornersPerFace) - { - case 3: - return new TriMesh(tmp.Attributes.ToEnumerable()); - case 4: - return new QuadMesh(tmp.Attributes.ToEnumerable()).ToTriMesh(); - default: - throw new Exception($"Can not convert a geometry with {tmp.NumCornersPerFace} to a triangle mesh: only quad meshes"); - } - } - - public static IMesh ToIMesh(this IGeometryAttributes g) - => g is IMesh m ? m : g is QuadMesh q ? q.ToIMesh() : g.Attributes.ToIMesh(); - #endregion - - // Computes the topology: this is a slow O(N) operation - public static Topology ComputeTopology(this IMesh mesh) - => new Topology(mesh); - - public static double Area(this IMesh mesh) - => mesh.Triangles().Sum(t => t.Area); - - #region validation - public static bool IsDegenerateVertexIndices(this Int3 vertexIndices) - => vertexIndices.X == vertexIndices.Y || vertexIndices.X == vertexIndices.Z || vertexIndices.Y == vertexIndices.Z; - - public static bool HasDegenerateFaceVertexIndices(this IMesh self) - => self.AllFaceVertexIndices().Any(IsDegenerateVertexIndices); - #endregion - - // TODO: find a better location for this function. DotNetUtilties doesn't know about IArray unfortunately, so maybe this project needs its own Utility class. - public static DictionaryOfLists GroupBy(this IArray xs, Func groupingFunc) - { - var r = new DictionaryOfLists(); - for (var i = 0; i < xs.Count; ++i) - r.Add(groupingFunc(i), xs[i]); - return r; - } - - public static IArray GetFaceMaterials(this IMesh mesh) - { - // SubmeshIndexOffsets: [0, A, B] - // SubmeshIndexCount: [X, Y, Z] - // SubmeshMaterials: [L, M, N] - // --- - // FaceMaterials: [...Repeat(L, X / 3), ...Repeat(M, Y / 3), ...Repeat(N, Z / 3)] <-- divide by 3 for the number of corners per Triangular face - var numCornersPerFace = mesh.NumCornersPerFace; - return mesh.SubmeshIndexCount - .ToEnumerable() - .SelectMany((indexCount, i) => Enumerable.Repeat(mesh.SubmeshMaterials[i], indexCount / numCornersPerFace)) - .ToIArray(); - } - - public static IEnumerable DisctinctMaterials(this IMesh mesh) - => mesh.GetFaceMaterials().ToEnumerable().Distinct(); - - public static DictionaryOfLists IndicesByMaterial(this IMesh mesh) - { - var faceMaterials = mesh.GetFaceMaterials(); - return mesh.Indices.GroupBy(i => faceMaterials[i / 3]); - } - - public static IMesh Merge(this IArray meshes) - => meshes.Select(m => (IGeometryAttributes)m).Merge().ToIMesh(); - - public static IMesh Merge(this IEnumerable meshes) - => meshes.ToIArray().Merge(); - - public static IMesh Merge(this IMesh mesh, params IMesh[] others) - { - var gs = others.ToList(); - gs.Insert(0, mesh); - return gs.Merge(); - } - - public static IEnumerable<(int Material, IMesh Mesh)> SplitByMaterial(this IMesh mesh) - { - var submeshMaterials = mesh.SubmeshMaterials; - if (submeshMaterials == null || submeshMaterials.Count == 0) - { - // Base case: no submesh materials are defined on the mesh. - return new[] { (-1, mesh) }; - } - - var submeshIndexOffets = mesh.SubmeshIndexOffsets; - var submeshIndexCounts = mesh.SubmeshIndexCount; - if (submeshIndexOffets == null || submeshIndexCounts == null || - submeshMaterials.Count <= 1 || submeshIndexOffets.Count <= 1 || submeshIndexCounts.Count <= 1) - { - // Base case: only one submesh material. - return new [] { (submeshMaterials[0], mesh) }; - } - - // Example: - // - // ------------ - // INPUT MESH: - // ------------ - // Vertices [Va, Vb, Vc, Vd, Ve, Vf, Vg] <-- 7 vertices - // Indices [0 (Va), 1 (Vb), 2 (Vc), 1 (Vb), 2 (Vc), 3 (Vd), 4 (Ve), 5 (Vf), 6 (Vg)] <-- 3 triangles referencing the 7 vertices - // SubmeshIndexOffsets [0, 3, 6] - // SubmeshIndexCount [3, 3, 3] (computed) - // SubmeshMaterials [Ma, Mb, Mc] - // - // ------------ - // OUTPUT MESHES - // ------------ - // - MESH FOR MATERIAL Ma - // Vertices: [Va, Vb, Vc] - // Indices: [0, 1, 2] - // SubmeshIndexOffsets: [0] - // SubmeshMaterials: [Ma] - // - //- MESH FOR MATERIAL Mb - // Vertices: [Vb, Vc, Vd] - // Indices: [0, 1, 2] - // SubmeshIndexOffsets: [0] - // SubmeshMaterials: [Mb] - // - //- MESH FOR MATERIAL Mc - // Vertices: [Ve, Vf, Vg] - // Indices: [0, 1, 2] - // SubmeshIndexOffsets: [0] - // SubmeshMaterials: [Mc] - - return mesh.SubmeshMaterials - .Select((submeshMaterial, submeshIndex) => (submeshMaterial, submeshIndex)) - .GroupBy(t => t.submeshMaterial) - .SelectMany(g => - { - var material = g.Key; - var meshes = g.Select((t, _) => - { - var submeshMaterial = t.submeshMaterial; - var submeshStartIndex = submeshIndexOffets[t.submeshIndex]; - var submeshIndexCount = submeshIndexCounts[t.submeshIndex]; - - var indexSlice = mesh.Indices.Slice(submeshStartIndex, submeshStartIndex + submeshIndexCount); - - var newVertexAttributes = mesh.VertexAttributes().Select(attr => attr.Remap(indexSlice)); - var newIndexAttribute = indexSlice.Count.Select(i => i).ToIndexAttribute(); - - var newSubmeshIndexOffsets = 0.Repeat(1).ToSubmeshIndexOffsetAttribute(); - var newSubmeshMaterials = submeshMaterial.Repeat(1).ToSubmeshMaterialAttribute(); - - return newVertexAttributes - .Concat(mesh.NoneAttributes()) - .Concat(mesh.WholeGeometryAttributes()) - // TODO: TECH DEBT - face, edge, and corner attributes are ignored for now. - .Append(newIndexAttribute) - .Append(newSubmeshIndexOffsets) - .Append(newSubmeshMaterials) - .ToGeometryAttributes() - .ToIMesh(); - }); - - return meshes.Select(m => (material, m)); - }); - } - - public static IGeometryAttributes DeleteUnusedVertices(this IMesh mesh) - { - var tmp = new bool[mesh.Vertices.Count]; - for (var i = 0; i < mesh.Indices.Count; ++i) - tmp[mesh.Indices[i]] = true; - - var remap = new List(); - for (var i = 0; i < tmp.Length; ++i) - { - if (tmp[i]) - remap.Add(i); - } - - return mesh.RemapVertices(remap.ToIArray()); - } - - public static bool GeometryEquals(this IMesh mesh, IMesh other, float tolerance = Math3d.Constants.Tolerance) - { - if (mesh.NumFaces != other.NumFaces) - return false; - return mesh.Triangles().Zip(other.Triangles(), (t1, t2) => t1.AlmostEquals(t2, tolerance)).All(x => x); - } - - public static IMesh SimplePolygonTessellate(this IEnumerable points) - { - var pts = points.ToList(); - var cnt = pts.Count; - var sum = Vector3.Zero; - var idxs = new List(pts.Count * 3); - for (var i = 0; i < pts.Count; ++i) - { - idxs.Add(i); - idxs.Add(i + 1 % cnt); - idxs.Add(cnt); - sum += pts[i]; - } - - var midPoint = sum / pts.Count; - pts.Add(midPoint); - - return Primitives.TriMesh(pts.ToIArray(), idxs.ToIArray()); - } - - public static IGeometryAttributes ReverseWindingOrder(this IMesh mesh) - { - var n = mesh.Indices.Count; - var r = new int[n]; - for (var i = 0; i < n; i += 3) - { - r[i + 0] = mesh.Indices[i + 2]; - r[i + 1] = mesh.Indices[i + 1]; - r[i + 2] = mesh.Indices[i + 0]; - } - return mesh.SetAttribute(r.ToIArray().ToIndexAttribute()); - } - - /// - /// Returns the closest point in a sequence of points - /// - public static Vector3 NearestPoint(this IEnumerable points, Vector3 x) - => points.Minimize(float.MaxValue, p => p.DistanceSquared(x)); - - /// - /// Returns the closest point in a sequence of points - /// - public static Vector3 NearestPoint(this IArray points, Vector3 x) - => points.ToEnumerable().NearestPoint(x); - - /// - /// Returns the closest point in a geometry - /// - public static Vector3 NearestPoint(this IMesh mesh, Vector3 x) - => mesh.Vertices.NearestPoint(x); - - public static Vector3 FurthestPoint(this IMesh mesh, Vector3 x0, Vector3 x1) - => mesh.Vertices.FurthestPoint(x0, x1); - - public static Vector3 FurthestPoint(this IArray points, Vector3 x0, Vector3 x1) - => points.ToEnumerable().FurthestPoint(x0, x1); - - public static Vector3 FurthestPoint(this IEnumerable points, Vector3 x0, Vector3 x1) - => points.Maximize(float.MinValue, v => v.Distance(x0).Min(v.Distance(x1))); - - public static Vector3 FurthestPoint(this IMesh mesh, Vector3 x) - => mesh.Vertices.FurthestPoint(x); - - public static Vector3 FurthestPoint(this IArray points, Vector3 x) - => points.ToEnumerable().FurthestPoint(x); - - public static Vector3 FurthestPoint(this IEnumerable points, Vector3 x) - => points.Maximize(float.MinValue, v => v.Distance(x)); - - public static IGeometryAttributes SnapPoints(this IMesh mesh, float snapSize) - => snapSize.Abs() >= Math3d.Constants.Tolerance - ? mesh.Deform(v => (v * snapSize.Inverse()).Truncate() * snapSize) - : mesh.Deform(v => Vector3.Zero); - - /// - /// Returns the vertices organized by face corner. - /// - public static IArray VerticesByIndex(this IMesh mesh) - => mesh.Vertices.SelectByIndex(mesh.Indices); - - /// - /// Returns the vertices organized by face corner, normalized to the first position. - /// This is useful for detecting if two meshes are the same except offset by - /// position. - /// - public static IArray NormalizedVerticesByCorner(this IMesh m) - { - if (m.NumCorners == 0) - return Vector3.Zero.Repeat(0); - var firstVertex = m.Vertices[m.Indices[0]]; - return m.VerticesByIndex().Select(v => v - firstVertex); - } - - /// - /// Compares the face positions of two meshes normalized by the vertex buffer, returning the maximum distance, or null - /// if the meshes have different topology. - /// - public static float? MaxNormalizedDistance(this IMesh mesh, IMesh other) - { - var xs = mesh.NormalizedVerticesByCorner(); - var ys = other.NormalizedVerticesByCorner(); - if (xs.Count != ys.Count) - return null; - return xs.Zip(ys, (x, y) => x.Distance(y)).Max(); - } - - public static AABox BoundingBox(this IMesh mesh) - => AABox.Create(mesh.Vertices.ToEnumerable()); - - public static Sphere BoundingSphere(this IMesh mesh) - => mesh.BoundingBox().ToSphere(); - - public static float BoundingRadius(this IMesh mesh) - => mesh.BoundingSphere().Radius; - - public static Vector3 Center(this IMesh mesh) - => mesh.BoundingBox().Center; - - public static Vector3 Centroid(this IMesh mesh) - => mesh.Vertices.Aggregate(Vector3.Zero, (x, y) => x + y) / mesh.Vertices.Count; - - public static bool AreIndicesValid(this IMesh mesh) - => mesh.Indices.All(i => i >= 0 && i < mesh.Vertices.Count); - - public static bool AreAllVerticesUsed(this IMesh mesh) - { - var used = new bool[mesh.Vertices.Count]; - mesh.Indices.ForEach(idx => used[idx] = true); - return used.All(b => b); - } - - public static IMesh ResetPivot(this IMesh mesh) - => mesh.Translate(-mesh.BoundingBox().CenterBottom); - - #region Face operations - - /// - /// Given an array of face data, creates an array of indexed data to match vertices - /// - public static IArray FaceDataToVertexData(this IMesh mesh, IArray data) - { - if (data.Count != mesh.NumFaces) - throw new Exception("Cannot match input Face data to existing faces"); - - var vertexData = new T[mesh.NumVertices]; - for (var i = 0; i < mesh.Indices.Count; ++i) - vertexData[mesh.Indices[i]] = data[i / 3]; - return vertexData.ToIArray(); - } - - public static IArray AllFaceVertexIndices(this IMesh mesh) - => mesh.NumFaces.Select(mesh.FaceVertexIndices); - - public static Int3 FaceVertexIndices(this IMesh mesh, int faceIndex) - => new Int3(mesh.Indices[faceIndex * 3], mesh.Indices[faceIndex * 3 + 1], mesh.Indices[faceIndex * 3 + 2]); - - public static Triangle VertexIndicesToTriangle(this IMesh mesh, Int3 indices) - => new Triangle(mesh.Vertices[indices.X], mesh.Vertices[indices.Y], mesh.Vertices[indices.Z]); - - public static Triangle Triangle(this IMesh mesh, int face) - => mesh.VertexIndicesToTriangle(mesh.FaceVertexIndices(face)); - - public static IArray Triangles(this IMesh mesh) - => mesh.NumFaces.Select(mesh.Triangle); - - public static IArray GetAllEdgesAsLines(this IMesh mesh) - => mesh.Triangles().SelectMany(tri => Tuple.Create(tri.AB, tri.BC, tri.CA)); - - public static IArray ComputedNormals(this IMesh mesh) - => mesh.Triangles().Select(t => t.Normal); - - public static bool Planar(this IMesh mesh, float tolerance = Math3d.Constants.Tolerance) - { - if (mesh.NumFaces <= 1) return true; - var normal = mesh.Triangle(0).Normal; - return mesh.ComputedNormals().All(n => n.AlmostEquals(normal, tolerance)); - } - - public static IArray MidPoints(this IMesh mesh) - => mesh.Triangles().Select(t => t.MidPoint); - - public static IArray FacesToCorners(this IMesh mesh) - => mesh.NumFaces.Select(i => i * 3); - - public static IArray FaceDataToCornerData(this IMesh mesh, IArray data) - => mesh.NumCorners.Select(i => data[i / 3]); - - public static IArray GetOrComputeFaceNormals(this IMesh mesh) - => mesh.GetAttributeFaceNormal()?.Data ?? mesh.ComputedNormals(); - - public static IArray GetOrComputeVertexNormals(this IMesh mesh) - => mesh.VertexNormals ?? mesh.ComputeTopology().GetOrComputeVertexNormals(); - - /// - /// Returns vertex normals if present, otherwise computes vertex normals naively by averaging them. - /// Given a pre-computed topology, will-leverage that. - /// A more sophisticated algorithm would compute the weighted normal - /// based on an angle. - /// - public static IArray GetOrComputeVertexNormals(this Topology topo) - { - var mesh = topo.Mesh; - var r = mesh.VertexNormals; - if (r != null) return r; - var faceNormals = mesh.GetOrComputeFaceNormals().ToArray(); - return mesh - .NumVertices - .Select(vi => - { - var tmp = topo - .FacesFromVertexIndex(vi) - .Select(fi => faceNormals[fi]) - .Average(); - if (tmp.IsNaN()) - return Vector3.Zero; - return tmp.SafeNormalize(); - }); - } - - public static IMesh CopyFaces(this IMesh mesh, Func predicate) - => (mesh as IGeometryAttributes).CopyFaces(predicate).ToIMesh(); - - public static IMesh CopyFaces(this IMesh mesh, IArray keep) - => mesh.CopyFaces(i => keep[i]); - - public static IMesh CopyFaces(this IMesh mesh, IArray keep) - => mesh.RemapFaces(keep).ToIMesh(); - - public static IMesh DeleteFaces(this IMesh mesh, Func predicate) - => mesh.CopyFaces(f => !predicate(f)); - #endregion - - #region Corner extensions - /// - /// Given an array of data associated with corners, return an array of data associated with - /// vertices. If a vertex is not referenced, no data is returned. If a vertex is referenced - /// multiple times, the last reference is used. - /// TODO: supplement with a proper interpolation system. - /// - public static IArray CornerDataToVertexData(this IMesh mesh, IArray data) - { - var vertexData = new T[mesh.NumVertices]; - for (var i = 0; i < data.Count; ++i) - vertexData[mesh.Indices[i]] = data[i]; - return vertexData.ToIArray(); - } - #endregion - - - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/MeshOptimization.cs b/src/cs/vim/Vim.Format.Core/Geometry/MeshOptimization.cs deleted file mode 100644 index ce94512d..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/MeshOptimization.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Runtime.CompilerServices; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - /// - /// This class is used to compare quickly two meshes within a lookup table (e.g. Dictionary, HashTable). - /// it looks at the positions of each corner, and the number of faces, and assures that the object ID - /// and material IDs are the same. - /// When using a class within a dictionary or hash table, the equals operator is called frequently. - /// By converting an IMesh to a MeshHash we minimize the amount of comparisons done. It becomes - /// possible, but highly unlikely that two different meshes would have the same hash. - /// - public class MeshHash - { - public IMesh Mesh; - public float Tolerance; - public int NumFaces; - public int NumVertices; - public int TopologyHash; - public Int3 BoxExtents; - public Int3 BoxMin; - - public int Round(float f) - => (int)(f / Tolerance); - - public Int3 Round(Vector3 v) - => new Int3(Round(v.X), Round(v.Y), Round(v.Z)); - - public MeshHash(IMesh mesh, float tolerance) - { - Mesh = mesh; - Tolerance = tolerance; - NumFaces = mesh.NumFaces; - NumVertices = mesh.NumVertices; - TopologyHash = Hash.Combine(mesh.Indices.ToArray()); - var box = mesh.BoundingBox(); - BoxMin = Round(box.Min); - BoxExtents = Round(box.Extent); - } - - public override bool Equals(object obj) - => obj is MeshHash other && Equals(other); - - public bool Equals(MeshHash other) - => NumFaces == other.NumFaces - && NumVertices == other.NumVertices - && BoxMin.Equals(other.BoxMin) - && BoxExtents.Equals(other.BoxExtents) - && Mesh.GeometryEquals(other.Mesh); - - public override int GetHashCode() - => Hash.Combine(NumFaces, NumVertices, TopologyHash, BoxMin.GetHashCode(), BoxExtents.GetHashCode()); - } - - public class IntegerPositionColorNormal - { - public Int3 Position; - public Int3 Color; - public Int3 Normal; - - public IntegerPositionColorNormal(Int3 pos, Int3 color, Int3 normal) - => (Position, Color, Normal) = (pos, color, normal); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - => Hash.Combine(Position.GetHashCode(), Color.GetHashCode(), Normal.GetHashCode()); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override bool Equals(object obj) - => Equals(obj as IntegerPositionColorNormal); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(IntegerPositionColorNormal other) - => other != null && Position.Equals(other.Position) && Color.Equals(other.Color) && Normal.Equals(other.Normal); - } - - public static class Optimization - { - public static Dictionary> GroupMeshesByHash(this IArray meshes, float tolerance) - => meshes.ToEnumerable().GroupMeshesByHash(tolerance); - - public static Dictionary> GroupMeshesByHash(this IEnumerable meshes, float tolerance) - => meshes.AsParallel().GroupBy(m => new MeshHash(m, tolerance)).ToDictionary(grp => grp.Key, grp => grp.ToList()); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/PerimeterProjection.cs b/src/cs/vim/Vim.Format.Core/Geometry/PerimeterProjection.cs deleted file mode 100644 index 854e7292..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/PerimeterProjection.cs +++ /dev/null @@ -1,657 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.Util; -using Vim.LinqArray; -using Vim.Math3d; -using LineApprox = System.Tuple; - -namespace Vim.Format.Geometry -{ - public static class PerimeterProjection - { - public static Int2 ToXYApproximation(this Vector3 v, float tolerance) - => new Int2((int)(v.X / tolerance), (int)(v.Y / tolerance)); - - public static Vector2 FromXYApproximation(this Int2 v, float tolerance) - => new Vector2(v.X * tolerance, v.Y * tolerance); - - public static LineApprox ToXYApproximation(this Line line, float tolerance) - => Tuple.Create(line.A.ToXYApproximation(tolerance), line.B.ToXYApproximation(tolerance)); - - public static double Angle(this Int2 v) - => Math.Atan2(v.Y, v.X); - - public static double Angle(this Int2 a, Int2 b) - => (a - b).Angle(); - - public static IEnumerable PerimeterXY(this IMesh mesh, float tolerance = 0.001f) - { - var srcLines = mesh.GetAllEdgesAsLines(); - var approxLines = srcLines.Select(line => line.ToXYApproximation(tolerance)); - var lineSet = new HashSet(approxLines.ToArrayInParallel()); - Debug.WriteLine($"Went from {srcLines.Count} to {lineSet.Count}"); - var d = new DictionaryOfLists(); - foreach (var ab in lineSet) - { - d.Add(ab.Item1, ab); - d.Add(ab.Item2, ab); - } - var r = new List(); - if (d.Count == 0) - return r; - - var firstKey = d.Keys.Minimize(int.MaxValue, ab => ab.X.Min(ab.Y)); - var currentKey = firstKey; - var prevAngle = 0.0; - - // If we can't find the point in the dictionary we have completed - while (d.ContainsKey(currentKey)) - { - // Find the candidate points; - var candidates = d[currentKey].Select(line => line.Item1 == currentKey ? line.Item2 : line.Item1); - - // Find the best match by maximizing angle - var bestMatch = candidates.Maximize(0.0, c => currentKey.Angle(c) - prevAngle); - - // Update the return set - r.Add(bestMatch.FromXYApproximation(tolerance)); - - // Now save the angle for the next stage. - prevAngle = currentKey.Angle(bestMatch); - - // Remove this key from the dictionary - d.Remove(currentKey); - - // Now we are at a new point - currentKey = bestMatch; - } - - return r; - } - - public static List> GeneratePerimeter(this IMesh mesh, Vector3 planeNormal, float degenerateSegmentEpsilon = 10.0f, float edgeLoopThreshold = 1e-6f) - { - var q = GetClusterRotation(planeNormal.Normalize(), Vector3.UnitZ); - - var segments = mesh.BuildBoundarySegments(null, - input => input.Transform(q).ToVector2()); - - segments = segments.SplitIntersectingCurves(edgeLoopThreshold * 50); - - var graph = segments.BuildConnectionGraph(edgeLoopThreshold * 50); - var loops = graph.FindGraphLoops(edgeLoopThreshold * 50); - - loops = loops.RemoveDuplicatedVertices(edgeLoopThreshold * 50); - - while (true) - { - var newLoops = loops.RemoveDegenerateSegmentsLooping(edgeLoopThreshold); - if (newLoops.Count == loops.Count) - { - var notEqual = false; - for (var i = 0; i < newLoops.Count; i++) - { - if (newLoops[i].Count != loops[i].Count) - { - notEqual = true; - break; - } - } - - if (!notEqual) - { - break; - } - } - - loops = newLoops; - } - - return loops; - } - - public static bool IsNaN(this Quaternion q) - => q.X.IsNaN() || q.Y.IsNaN() || q.Z.IsNaN() || q.W.IsNaN(); - - // Finds all of the intersections between the curves and splits them - // Also adds a pseudo intersection at the left-most point, this gives the FindGraphLoops - // algorithm a good starting point - public static List> SplitIntersectingCurves(this List> curves, float threshold) - { - var thresholdSquared = threshold * threshold; - var curveList = new LinkedList>(curves); - - var intersections = new Dictionary, List>>>(); // Madness in great ones must not unwatched go. - var leftMostPoint = Vector2.MaxValue; - List leftMostCurve = null; - var leftMostIntersectionPoint = 0.0f; - - foreach (var currentCurveA in curveList) - { - for (var i = 0; i < currentCurveA.Count; i++) - { - var point = currentCurveA[i]; - if (point.X < leftMostPoint.X || (point.X == leftMostPoint.X && point.Y < leftMostPoint.Y)) - { - leftMostPoint = point; - leftMostIntersectionPoint = i; - leftMostCurve = currentCurveA; - } - } - - foreach (var currentCurveB in curveList) - { - if (currentCurveA != currentCurveB) - { - float t, u; - var distance = IntersectCurves(currentCurveA, currentCurveB, out t, out u); - if (distance < threshold) - { - if (!intersections.ContainsKey(currentCurveA)) - { - intersections[currentCurveA] = new List>>(); - } - if (!intersections.ContainsKey(currentCurveB)) - { - intersections[currentCurveB] = new List>>(); - } - - intersections[currentCurveA].Add(new Tuple>(distance, t, currentCurveB)); - intersections[currentCurveB].Add(new Tuple>(distance, u, currentCurveA)); - } - } - } - } - - // split the left most curve so that FindGraphLoops has a good starting point - if (leftMostIntersectionPoint != 0.0 && leftMostIntersectionPoint != leftMostCurve.Count - 1) - { - intersections[leftMostCurve].Add(new Tuple>(0.0f, leftMostIntersectionPoint, null)); - } - - var edgeLoops = new List>(); - foreach (var intersection in intersections) - { - var splits = intersection.Value.Select(x => x.Item2); - - edgeLoops.AddRange(intersection.Key.SplitCurve(splits)); - } - - return edgeLoops; - } - - // Cuts the curve between min and max and returns the part in between - public static List> SplitCurve(this List curve, IEnumerable splits) - { - var result = new List>(); - if (splits.Count() == 0) - { - result.Add(curve); - return result; - } - - splits = splits.OrderBy(x => x).ToList(); - var newSplits = new List(); - if (splits.First() != 0.0f) - { - newSplits.Add(0.0f); - } - - newSplits.AddRange(splits); - - if (splits.Last() < curve.Count - 1) - { - newSplits.Add(curve.Count - 1); - } - - for (var i = 0; i < newSplits.Count - 1; i++) - { - var min = newSplits[i]; - var max = newSplits[i + 1]; - - var clampedCurve = curve.ClampCurve(min, max); - - if (clampedCurve.CurveLength() > 1e-5f) - { - result.Add(clampedCurve); - } - } - - return result; - } - - - // Cuts the curve between min and max and returns the part in between - public static List ClampCurve(this List curve, float min, float max) - { - var floorMin = (float)Math.Floor(min); - var floorMax = (float)Math.Floor(max); - var fracMin = min - floorMin; - var fracMax = max - floorMax; - - if (fracMin == 0.0 && floorMin > 0) - { - floorMin--; - fracMin++; - } - if (fracMax == 0.0 && floorMax > 0) - { - floorMax--; - fracMax++; - } - - var indexMin = (int)floorMin; - var indexMax = (int)floorMax; - - var result = new List(); - if (fracMin != 1.0) - { - result.Add(curve[indexMin].Lerp(curve[indexMin + 1], (float)fracMin)); - } - for (var i = indexMin + 1; i <= indexMax; i++) - { - result.Add(curve[i]); - } - result.Add(curve[indexMax].Lerp(curve[indexMax + 1], (float)fracMax)); - - return result; - } - - // Returns the length of the curve - public static float CurveLength(this List curve) - { - var curveLength = 0.0f; - for (var x = 0; x < curve.Count - 1; x++) - { - curveLength += (curve[x] - curve[x + 1]).Length(); - } - - return curveLength; - } - - // Returns min distance between piecewise linear curves A and B. - // t = distance along curve A - // u = distance along curve B - // TODO: Return multiple intersections within a tolerance - public static float IntersectCurves(List segmentsA, List segmentsB, out float t, out float u) - { - var minDistance = float.MaxValue; - t = 0.0f; - u = 0.0f; - - for (var segmentAIndex = 0; segmentAIndex < segmentsA.Count - 1; segmentAIndex++) - { - var v1a = segmentsA[segmentAIndex]; - var v1b = segmentsA[segmentAIndex + 1]; - - for (var segmentBIndex = 0; segmentBIndex < segmentsB.Count - 1; segmentBIndex++) - { - var v2a = segmentsB[segmentBIndex]; - var v2b = segmentsB[segmentBIndex + 1]; - - float fracT, fracU; - var distance = GeometryCuttingUtils.LineLineDistance(v1a, v1b, v2a, v2b, out fracT, out fracU); - - if (distance < minDistance) - { - minDistance = distance; - t = segmentAIndex + fracT; - u = segmentBIndex + fracU; - } - } - } - - return minDistance; - } - - public static List> RemoveDuplicatedVertices(this List> edgeLoops, float threshold) - { - var thresholdSquared = threshold * threshold; - foreach (var edgeLoop in edgeLoops) - { - for (var i = 0; i < edgeLoop.Count; i++) - { - if ((edgeLoop[i] - edgeLoop[(i + 1) % edgeLoop.Count]).LengthSquared() <= thresholdSquared) - { - edgeLoop.RemoveAt(i); - i--; - } - } - } - - return edgeLoops; - } - - public static Quaternion GetClusterRotation(Vector3 clusterNormal, Vector3 alignTo, float tolerance = 0.001f) - { - var c = clusterNormal.Cross(alignTo); - var d = clusterNormal.Dot(alignTo); - - if (d >= 1f - tolerance) - return Quaternion.Identity; - - if (d <= -(1f - tolerance)) - { - // Need an axis of rotation that is perpendicular to the two input vectors - var axis = clusterNormal.Cross(alignTo.Dot(Vector3.UnitY) > 0.999f ? Vector3.UnitZ : Vector3.UnitY); - return Quaternion.CreateFromAxisAngle(axis, (float)Math.PI); - } - - var s = (float)Math.Sqrt((1.0f + d) * 2.0f); - var invs = 1.0f / s; - - var q = new Quaternion(c * invs, s * 0.5f); - q = q.Normalize(); - - Debug.Assert(!q.IsNaN()); - return q; - } - - public static void AddEdgeToDictionary(Dictionary, int> d, int x, int y) - { - var key = new Tuple(x, y); - if (!d.ContainsKey(key)) - d[key] = 1; - else - d[key]++; - } - - private class EdgeEqualityComparer : IEqualityComparer> - { - public bool Equals(Tuple x, Tuple y) - => ((x.Item1 == y.Item1) && (x.Item2 == y.Item2)) || ((x.Item1 == y.Item2) && (x.Item2 == y.Item1)); - - public int GetHashCode(Tuple obj) - => obj.Item1.GetHashCode() ^ obj.Item2.GetHashCode(); - } - - public static Dictionary, int> BuildEdgeDictionary(this IMesh mesh) - { - var edges = new Dictionary, int>(new EdgeEqualityComparer()); - - var indices = mesh.Indices; - - for (var i = 0; i < indices.Count; i += 3) - { - var i0 = indices[i + 0]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - - AddEdgeToDictionary(edges, i0, i1); - AddEdgeToDictionary(edges, i1, i2); - AddEdgeToDictionary(edges, i2, i0); - } - - return edges; - } - - public static List> BuildBoundarySegments(this IMesh mesh, Dictionary, int> edgeDictionary, Func transform) - { - var segments = new List>(); - - var indices = mesh.Indices; - var vertices = mesh.Vertices; - - for (var i = 0; i < indices.Count; i += 3) - { - var i0 = indices[i + 0]; - var i1 = indices[i + 1]; - var i2 = indices[i + 2]; - - var v0 = transform(vertices[i0]); - var v1 = transform(vertices[i1]); - var v2 = transform(vertices[i2]); - - if (edgeDictionary == null || edgeDictionary[new Tuple(i0, i1)] != 2) segments.Add(new List { v0, v1 }); - if (edgeDictionary == null || edgeDictionary[new Tuple(i1, i2)] != 2) segments.Add(new List { v1, v2 }); - if (edgeDictionary == null || edgeDictionary[new Tuple(i2, i0)] != 2) segments.Add(new List { v2, v0 }); - } - - return segments; - } - - // Builds a node connection graph from a list of curves - public static Dictionary, List>>> BuildConnectionGraph(this List> curves, float threshold) - { - var connectionGraph = new Dictionary, List>>>(); - var reverseCurves = new Dictionary, List>(); - var thresholdSquared = threshold * threshold; - - var pointList = new Vector2[curves.Count]; - for (var i = 0; i < curves.Count; i++) - { - var curve = curves[i]; - connectionGraph[curve.First()] = new List, List>>(); - connectionGraph[curve.Last()] = new List, List>>(); - - var reverseCurve = new List(curve); - reverseCurve.Reverse(); - reverseCurves[curve] = reverseCurve; - reverseCurves[reverseCurve] = curve; - } - - foreach (var point in connectionGraph) - { - foreach (var curve in curves) - { - var distanceSquared = (curve.First() - point.Key).LengthSquared(); - if (distanceSquared <= thresholdSquared) - { - point.Value.Add(new Tuple, List>(curve, reverseCurves[curve])); - } - - distanceSquared = (curve.Last() - point.Key).LengthSquared(); - if (distanceSquared <= thresholdSquared) - { - point.Value.Add(new Tuple, List>(reverseCurves[curve], curve)); - } - } - } - - return connectionGraph; - } - - // Build a loop around the perimeter of the graph - // TODO: Handle multiple loops - public static List> FindGraphLoops(this Dictionary, List>>> connectionGraph, float threshold) - { - // Start from the left most point, build the perimeter by selecting the connection with the minimum clockwise angle - var thresholdSquared = threshold * threshold; - var leftMostPoint = Vector2.MaxValue; - foreach (var item in connectionGraph) - { - if (item.Value.Count < 2) - { - continue; - } - if (item.Key.X < leftMostPoint.X || (item.Key.X == leftMostPoint.X && item.Key.Y < leftMostPoint.Y)) - { - leftMostPoint = item.Key; - } - } - - var visitedNodes = new Dictionary, bool>(); - - var result = new List>(); - var loop = new List(); - var currentPointLast = leftMostPoint + new Vector2(0, 1); - var currentPoint = leftMostPoint; - var previousPoint = currentPoint; - - var segmentCount = 0; - while (true) - { - if (!connectionGraph.ContainsKey(currentPoint)) - { - // Failed :( - result.Add(loop); - return result; - } - - var list = connectionGraph[currentPoint].Where(x => - { - if (connectionGraph[x.Item1.Last()].Count <= 1) - { - // Don't go down a dead end, this might need improving with some kind of backtracking when a dead end was found - return false; - } - - if (visitedNodes.ContainsKey(x.Item1)) - { - return false; - } - - return true; - }); - var sortedList = list.OrderBy(x => - { - var s1 = (currentPoint - currentPointLast).Normalize(); - var s2 = (x.Item1[1] - x.Item1[0]).Normalize(); - var angle = (float)Math.Atan2(s1.Cross(s2), s1.Dot(s2)); - return angle; - }).ToList(); - - if (sortedList.Count == 0) - { - // Failed :( - result.Add(loop); - return result; - } - - var nextConnection = sortedList.First(); - visitedNodes[nextConnection.Item1] = true; - visitedNodes[nextConnection.Item2] = true; - segmentCount++; - loop.AddRange(nextConnection.Item1); - previousPoint = currentPoint; - currentPoint = nextConnection.Item1.Last(); - currentPointLast = nextConnection.Item1[nextConnection.Item1.Count - 2]; - - if ((currentPoint - loop[0]).LengthSquared() < thresholdSquared) - { - result.Add(loop); - break; - } - - if (segmentCount > connectionGraph.Count) - { - // Failed :( - result.Add(loop); - return result; - } - } - - return result; - } - - // Remove degenerate segments - public static List> RemoveDegenerateSegments(this List> edgeLoops, float epsilon = 1e-10f) - { - var result = new List>(); - foreach (var edgeLoop in edgeLoops) - { - if (edgeLoop.Count < 2) - { - //result.Add(edgeLoop); - continue; - } - - var newEdgeLoop = new List(edgeLoop); - for (var i = 1; i < newEdgeLoop.Count - 1; i++) - { - var v0 = newEdgeLoop[i - 1]; - var v1 = newEdgeLoop[i]; - var v2 = newEdgeLoop[i + 1]; - var area = (v1 - v0).Cross(v1 - v2).Abs(); - if (area < epsilon) - { - newEdgeLoop.RemoveAt(i); - i--; - } - } - - if (newEdgeLoop.Count < 2) - { - continue; - } - - result.Add(newEdgeLoop); - } - - return result; - } - public static List> RemoveDegenerateSegmentsLooping(this List> edgeLoops, float epsilon = 1e-10f) - { - var result = new List>(); - foreach (var edgeLoop in edgeLoops) - { - if (edgeLoop.Count < 2) - { - //result.Add(edgeLoop); - continue; - } - - var newEdgeLoop = new List(edgeLoop); - for (var i = 0; i < newEdgeLoop.Count; i++) - { - var v0 = newEdgeLoop[(i - 1 + newEdgeLoop.Count) % newEdgeLoop.Count]; - var v1 = newEdgeLoop[i]; - var v2 = newEdgeLoop[(i + 1) % newEdgeLoop.Count]; - var area = (v1 - v0).Cross(v1 - v2).Abs(); - if (area < epsilon) - { - newEdgeLoop.RemoveAt(i); - i--; - } - } - - if (newEdgeLoop.Count < 2) - { - continue; - } - - result.Add(newEdgeLoop); - } - - return result; - } - - public static List> RemoveDegenerateSegments(this List> edgeLoops, float epsilon, Func faceFunction) - { - var result = new List>(); - foreach (var edgeLoop in edgeLoops) - { - if (edgeLoop.Count < 2) - { - //result.Add(edgeLoop); - continue; - } - - var newEdgeLoop = new List(edgeLoop); - for (var i = 1; i < newEdgeLoop.Count - 1; i++) - { - var v0 = faceFunction(newEdgeLoop[i - 1]); - var v1 = faceFunction(newEdgeLoop[i]); - var v2 = faceFunction(newEdgeLoop[i + 1]); - var area = (v1 - v0).Cross(v1 - v2).LengthSquared(); - if (area < epsilon * epsilon) - { - newEdgeLoop.RemoveAt(i); - i--; - } - } - - if (newEdgeLoop.Count < 2) - { - continue; - } - - result.Add(newEdgeLoop); - } - - return result; - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/Primitives.cs b/src/cs/vim/Vim.Format.Core/Geometry/Primitives.cs deleted file mode 100644 index 2e41024c..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/Primitives.cs +++ /dev/null @@ -1,357 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - // TODO: plane, cylinder, cone, ruled face, - public static class Primitives - { - public static IMesh TriMesh(IEnumerable attributes) - => attributes.Where(x => x != null).ToIMesh(); - - public static IMesh TriMesh(params GeometryAttribute[] attributes) - => TriMesh(attributes.AsEnumerable()); - - public static IMesh TriMesh( - this IArray vertices, - IArray indices = null, - IArray uvs = null, - IArray colors = null, - IArray materials = null, - IArray submeshMaterials = null) - => TriMesh( - vertices?.ToPositionAttribute(), - indices?.ToIndexAttribute(), - uvs?.ToVertexUvAttribute(), - materials?.ToFaceMaterialAttribute(), - colors?.ToVertexColorAttribute(), - submeshMaterials?.ToSubmeshMaterialAttribute() - ); - - public static IMesh TriMesh(this IArray vertices, IArray indices = null, params GeometryAttribute[] attributes) - => new GeometryAttribute[] { - vertices?.ToPositionAttribute(), - indices?.ToIndexAttribute(), - }.Concat(attributes).ToIMesh(); - - public static IMesh QuadMesh(params GeometryAttribute[] attributes) - => QuadMesh(attributes.AsEnumerable()); - - public static IMesh QuadMesh(this IEnumerable attributes) - => new QuadMesh(attributes.Where(x => x != null)).ToTriMesh(); - - public static IMesh QuadMesh(this IArray vertices, IArray indices = null, IArray uvs = null, IArray materials = null, IArray objectIds = null) - => QuadMesh( - vertices.ToPositionAttribute(), - indices?.ToIndexAttribute(), - uvs?.ToVertexUvAttribute(), - materials?.ToFaceMaterialAttribute() - ); - - public static IMesh QuadMesh(Vector3 a, Vector3 b, Vector3 c, Vector3 d) - => QuadMesh(new[] { a, b, c, d }.ToIArray()); - - public static IMesh Cube - { - get - { - var vertices = new[] { - // front - new Vector3(-0.5f, -0.5f, 0.5f), - new Vector3(0.5f, -0.5f, 0.5f), - new Vector3(0.5f, 0.5f, 0.5f), - new Vector3(-0.5f, 0.5f, 0.5f), - // back - new Vector3(-0.5f, -0.5f, -0.5f), - new Vector3(0.5f, -0.5f, -0.5f), - new Vector3(0.5f, 0.5f, -0.5f), - new Vector3(-0.5f, 0.5f, -0.5f) - }.ToIArray(); - - var indices = new[] { - // front - 0, 1, 2, - 2, 3, 0, - // right - 1, 5, 6, - 6, 2, 1, - // back - 7, 6, 5, - 5, 4, 7, - // left - 4, 0, 3, - 3, 7, 4, - // bottom - 4, 5, 1, - 1, 0, 4, - // top - 3, 2, 6, - 6, 7, 3 - }.ToIArray(); - - return vertices.TriMesh(indices); - } - } - - public static IMesh CubeFaceted - { - get - { - var cube = Cube; - return cube.Indices.Select(i => cube.Vertices[i]).TriMesh(cube.Indices.Count.Range()); - } - } - - public static IMesh ToIMesh(this AABox box) - => Cube.Scale(box.Extent).Translate(box.Center); - - public static float Sqrt2 = 2.0f.Sqrt(); - - public static readonly IMesh Tetrahedron - = TriMesh(LinqArray.LinqArray.Create( - new Vector3(1f, 0.0f, -1f / Sqrt2), - new Vector3(-1f, 0.0f, -1f / Sqrt2), - new Vector3(0.0f, 1f, 1f / Sqrt2), - new Vector3(0.0f, -1f, 1f / Sqrt2)), - LinqArray.LinqArray.Create(0, 1, 2, 1, 0, 3, 0, 2, 3, 1, 3, 2)); - - public static readonly IMesh Square - = LinqArray.LinqArray.Create( - new Vector2(-0.5f, -0.5f), - new Vector2(-0.5f, 0.5f), - new Vector2(0.5f, 0.5f), - new Vector2(0.5f, -0.5f)).Select(x => x.ToVector3()).QuadMesh(); - - public static readonly IMesh Octahedron - = Square.Vertices.Append(Vector3.UnitZ, -Vector3.UnitZ).Normalize().TriMesh( - LinqArray.LinqArray.Create( - 0, 1, 4, 1, 2, 4, 2, 3, 4, - 3, 2, 5, 2, 1, 5, 1, 0, 5)); - - // see: https://github.com/mrdoob/three.js/blob/9ef27d1af7809fa4d9943f8d4c4644e365ab6d2d/src/geometries/TorusBufferGeometry.js#L52 - public static Vector3 TorusFunction(Vector2 uv, float radius, float tube) - { - uv *= Math3d.Constants.TwoPi; - return new Vector3( - (radius + tube * uv.Y.Cos()) * uv.X.Cos(), - (radius + tube * uv.Y.Cos()) * uv.X.Sin(), - tube * uv.Y.Sin()); - } - - public static IMesh Torus(float radius, float tubeRadius, int uSegs, int vSegs) - => QuadMesh(uv => TorusFunction(uv, radius, tubeRadius), uSegs, vSegs); - - // see: https://github.com/mrdoob/three.js/blob/9ef27d1af7809fa4d9943f8d4c4644e365ab6d2d/src/geometries/SphereBufferGeometry.js#L76 - public static Vector3 SphereFunction(Vector2 uv, float radius) - => new Vector3( - (float)(-radius * Math.Cos(uv.X * Math3d.Constants.TwoPi) * Math.Sin(uv.Y * Math3d.Constants.Pi)), - (float)(radius * Math.Cos(uv.Y * Math3d.Constants.Pi)), - (float)(radius * Math.Sin(uv.X * Math3d.Constants.TwoPi) * Math.Sin(uv.Y * Math3d.Constants.Pi))); - - public static IMesh Sphere(float radius, int uSegs, int vSegs) - => QuadMesh(uv => SphereFunction(uv, radius), uSegs, vSegs); - - /// - /// Creates a TriMesh from four points. - /// - public static IMesh TriMeshFromQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d) - => TriMesh(new[] { a, b, c, c, d, a }.ToIArray()); - - // Icosahedron, Dodecahedron, - - /// - /// Returns a collection of circular points. - /// - public static IArray CirclePoints(float radius, int numPoints) - => CirclePoints(numPoints).Select(x => x * radius); - - public static IArray CirclePoints(int numPoints) - => numPoints.Select(i => CirclePoint(i, numPoints)); - - public static Vector2 CirclePoint(int i, int numPoints) - => new Vector2((i * (Math3d.Constants.TwoPi / numPoints)).Cos(), (i * (Math3d.Constants.TwoPi / numPoints)).Sin()); - - /// - /// Computes the indices of a quad mesh astrip. - /// - public static IArray ComputeQuadMeshStripIndices(int usegs, int vsegs, bool wrapUSegs = false, bool wrapVSegs = false) - { - var indices = new List(); - - var maxUSegs = wrapUSegs ? usegs : usegs + 1; - var maxVSegs = wrapVSegs ? vsegs : vsegs + 1; - - for (var i = 0; i < vsegs; ++i) - { - var rowA = i * maxUSegs; - var rowB = ((i + 1) % maxVSegs) * maxUSegs; - - for (var j = 0; j < usegs; ++j) - { - var colA = j; - var colB = (j + 1) % maxUSegs; - - indices.Add(rowA + colA); - indices.Add(rowA + colB); - indices.Add(rowB + colB); - indices.Add(rowB + colA); - } - } - - return indices.ToIArray(); - } - - /// - /// Returns the index buffer of a quad mesh strip. - /// Returns an empty array if either numRowPoints or numPointsPerRow is less than 2. - /// - public static List QuadMeshStripIndicesFromPointRows( - int numPointRows, - int numPointsPerRow, - bool clockwise = false) - { - // A quad(ABCD) is defined as 4 indices, counter clock-wise: - // - // col col - // row D------C quad(ABCD) = (counter-clockwise) { A, B, C, D } - // |t1 / | triangle(t0) = (counter-clockwise) { A, B, C } - // | / t0| triangle(t1) = (counter-clockwise) { A, C, D } - // row A------B - - var indices = new List(); // 4 indices per quad. - for (var rowIndex = 0; rowIndex < numPointRows - 1; ++rowIndex) - { - for (var colIndex = 0; colIndex < numPointsPerRow - 1; ++colIndex) - { - // The vertices will all be inserted in a flat list in the vertex buffer - // [ ...row0, ...row1, ...row2, ..., ...rowN] - // - // colIndex - // ... ... - // | | - // rowIndex + 1: [... ---D------C--- ...] - // |t1 / | - // | / t0| - // rowIndex: [... ---A------B--- ...] - // | | - // ... ... - // - // rowSize: |<-----numColumns----->| - // - - var A = colIndex + rowIndex * numPointsPerRow; - var B = A + 1; - var D = colIndex + (rowIndex + 1) * numPointsPerRow; - var C = D + 1; - - if (clockwise) - { - indices.Add(D); - indices.Add(C); - indices.Add(B); - indices.Add(A); - } - else - { - indices.Add(A); - indices.Add(B); - indices.Add(C); - indices.Add(D); - } - } - } - - return indices; - } - - public static int[] TriMeshCylinderCapIndices(int numEdgeVertices) - { - // Example cap where numEdgeVertices is 6: - // - // (!) It is assumed that vertex 0 is at the center of the cap - // and that this center vertex is omitted from the numEdgeVertices count. - // - // 3<------2 - // / \t1 / ^ t0 = (O, 1, 2) - // v t2 \ / t0 \ t1 = (O, 2, 3) - // 4------0------1 <---- start t2 = (O, 3, 4) - // \ t3 / \ t5 ^ t3 = (O, 4, 5) - // v /t4 \ / t4 = (O, 5, 6) - // 5------>6 <---- end t5 = (O, 6, 1) <-- special case. - - var center = 0; - var indices = new List(); - - var numTriangles = numEdgeVertices; - - // Do all the triangles except the last one. - for (var triangle = 0; triangle < numTriangles - 1; ++triangle) - { - var index0 = center; // 0 - var index1 = triangle + 1; - var index2 = index1 + 1; - - indices.Add(index0); - indices.Add(index1); - indices.Add(index2); - } - - // The last triangle loops back onto the first edge vertex. - var lastTriangleIndex0 = center; - var lastTriangleIndex1 = numEdgeVertices; - var lastTriangleIndex2 = 1; - indices.Add(lastTriangleIndex0); - indices.Add(lastTriangleIndex1); - indices.Add(lastTriangleIndex2); - - return indices.ToArray(); - } - - /// - /// Creates a quad mesh given a mapping from 2 space to 3 space - /// - public static IMesh QuadMesh(this Func f, int segs) - => QuadMesh(f, segs, segs); - - /// - /// Creates a quad mesh given a mapping from 2 space to 3 space - /// - public static IMesh QuadMesh(this Func f, int usegs, int vsegs, bool wrapUSegs = false, bool wrapVSegs = false) - { - var verts = new List(); - var maxUSegs = wrapUSegs ? usegs : usegs + 1; - var maxVSegs = wrapVSegs ? vsegs : vsegs + 1; - - for (var i = 0; i < maxVSegs; ++i) - { - var v = (float)i / vsegs; - for (var j = 0; j < maxUSegs; ++j) - { - var u = (float)j / usegs; - verts.Add(f(new Vector2(u, v))); - } - } - - return QuadMesh(verts.ToIArray(), ComputeQuadMeshStripIndices(usegs, vsegs, wrapUSegs, wrapVSegs)); - } - - /// - /// Creates a revolved face ... note that the last points are on top of the original - /// - public static IMesh RevolveAroundAxis(this IArray points, Vector3 axis, int segments = 4) - { - var verts = new List(); - for (var i = 0; i < segments; ++i) - { - var angle = Math3d.Constants.TwoPi / segments; - points.Rotate(axis, angle).AddTo(verts); - } - - return QuadMesh(verts.ToIArray(), ComputeQuadMeshStripIndices(segments - 1, points.Count - 1)); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/QuadMesh.cs b/src/cs/vim/Vim.Format.Core/Geometry/QuadMesh.cs deleted file mode 100644 index deb3af9f..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/QuadMesh.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using Vim.Util; -using Vim.G3d; - -namespace Vim.Format.Geometry -{ - /// - /// This is a quadrilateral mesh. Note that it does not implement the IMesh interface, - /// but does implement IGeometryAttributes and inherits from a G3D. - /// - public class QuadMesh : G3D, IGeometryAttributes - { - public QuadMesh(IEnumerable attributes) - : base(attributes.Append(new[] { 4 }.ToObjectFaceSizeAttribute())) - => Debug.Assert(NumCornersPerFace == 4); - - public IMesh ToTriMesh() - => this.TriangulateQuadMesh().ToIMesh(); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/SceneExtensions.cs b/src/cs/vim/Vim.Format.Core/Geometry/SceneExtensions.cs deleted file mode 100644 index f4aa1bf6..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/SceneExtensions.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Vim.Util; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public static class SceneExtensions - { - public static IMesh TransformedMesh(this ISceneNode node) - => node.GetMesh()?.Transform(node.Transform); - - public static IEnumerable TransformedMeshes(this IScene scene) - => scene.Nodes.Where(n => n.GetMesh() != null).Select(TransformedMesh); - - public static IMesh ToIMesh(this IScene scene) - => scene.TransformedMeshes().Merge(); - - public static IMesh MergedGeometry(this IScene scene) - => scene.Nodes.ToEnumerable().MergedGeometry(); - - public static IMesh MergedGeometry(this IEnumerable nodes) - => nodes.Where(n => n.GetMesh() != null).Select(TransformedMesh).Merge(); - - public static Matrix4x4 LocalTransform(this ISceneNode node) - => node.Parent != null - ? node.Transform * node.Parent.Transform.Inverse() - : node.Transform; - - public static IEnumerable AllDistinctMeshes(this IScene scene) - => scene.UntransformedMeshes().Where(x => x != null).Distinct(); - - public static IndexedSet GeometryLookup(this IScene scene) - => scene.Meshes.ToEnumerable().ToIndexedSet(); - - public static IArray UntransformedMeshes(this IScene scene) - => scene.Nodes.Select(n => n.GetMesh()); - - public static bool HasGeometry(this IScene scene) - => scene.Nodes.Any(n => n.GetMesh() != null); - - public static Dictionary GeometryCounts(this IScene scene) - => scene.Nodes.ToEnumerable().CountInstances(x => x.GetMesh()); - - public static IEnumerable AllVertices(this IScene scene) - => scene.TransformedMeshes().SelectMany(g => g.Vertices.ToEnumerable()); - - public static AABox BoundingBox(this IScene scene) - => AABox.Create(scene.AllVertices()); - - public static IArray Transforms(this IScene scene) - => scene.Nodes.Select(n => n.Transform); - - public static IArray NodePositions(this IScene scene) - => scene.Transforms().Select(m => m.Translation); - - public static AABox NodePositionBoundingBox(this IScene scene) - => AABox.Create(scene.NodePositions().ToEnumerable()); - - public static Sphere BoundingSphere(this IScene scene) - => scene.BoundingBox().ToSphere(); - - public static float BoundingRadius(this IScene scene) - => scene.BoundingSphere().Radius; - - public static IArray TransformedVertices(this ISceneNode node) - => node.TransformedMesh()?.Vertices; - - public static AABox TransformedBoundingBox(this ISceneNode node) - => AABox.Create(node.TransformedVertices()?.ToEnumerable()); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/Serialization.cs b/src/cs/vim/Vim.Format.Core/Geometry/Serialization.cs deleted file mode 100644 index 8a7f15a0..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/Serialization.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Vim.G3d; - -namespace Vim.Format.Geometry -{ - public static class Serialization - { - public static IMesh ReadG3D(string filePath) - => G3D.Read(filePath).ToIMesh(); - - public static G3D ToG3d(this IMesh mesh) - => mesh is G3D r ? r : mesh.Attributes.ToG3d(); - - public static void WriteG3d(this IMesh mesh, string filePath) - => mesh.ToG3d().Write(filePath); - - public static void WriteObj(this IMesh mesh, string filePath) - => mesh.ToG3d().WriteObj(filePath); - - public static void WritePly(this IMesh mesh, string filePath) - => mesh.ToG3d().WritePly(filePath); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/Topology.cs b/src/cs/vim/Vim.Format.Core/Geometry/Topology.cs deleted file mode 100644 index f7ef75c5..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/Topology.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - /// - /// The base class of topology face, topology edge, topology vertex, and topology element - /// - public class TopoElement - { - public TopoElement(Topology topology, int index) - => (Topology, Index) = (topology, index); - public Topology Topology { get; } - public int Index { get; } - } - - /// - /// A topological face. - /// - public class TopoFace : TopoElement - { - public TopoFace(Topology topology, int index) - : base(topology, index) - => Debug.Assert(index >= 0 && index < topology.Mesh.NumFaces); - } - - /// - /// A directed edge around a polygon (aka a half-edge). There is exactly one half-edge per "corner" in a mesh. - /// A non-border edge in a manifold mesh has exactly two half-edges, and a border edge has one edge. - /// - public class TopoEdge : TopoElement - { - public TopoEdge(Topology topology, int index) - : base(topology, index) - => Debug.Assert(index >= 0 && index < topology.Mesh.NumCorners); - } - - /// - /// A vertex in the mesh. - /// - public class TopoVertex : TopoElement - { - public TopoVertex(Topology topology, int index) - : base(topology, index) - => Debug.Assert(index >= 0 && index < topology.Mesh.NumVertices); - } - - /// - /// Also called a "face-corner". Associated with exactly one face, and one vertex. - /// A vertex may be associated with multiple corners - /// - public class TopoCorner : TopoElement - { - public TopoCorner(Topology topology, int index) - : base(topology, index) - => Debug.Assert(index >= 0 && index < topology.Mesh.NumCorners); - } - - /// - /// This class is used to make efficient topological queries for an IGeometry. - /// Construction is a O(N) operation, so it is not created automatically. - /// - public class Topology - { - public TopoFace Face(int f) - => new TopoFace(this, f); - - public TopoEdge Edge(int e) - => new TopoEdge(this, e); - - public Topology(IMesh m) - { - Mesh = m; - Corners = Mesh.Indices.Indices(); - Faces = Mesh.NumFaces.Range(); - Vertices = Mesh.Vertices.Indices(); - - // Compute the mapping from vertex indices to faces that reference them - VerticesToFaces = new List[m.Vertices.Count]; - for (var c = 0; c < m.Indices.Count; ++c) - { - var v = m.Indices[c]; - var f = m.CornerToFace(c); - - Debug.Assert(f.Within(0, m.NumFaces)); - Debug.Assert(v.Within(0, m.NumVertices)); - Debug.Assert(c.Within(0, m.NumCorners)); - - if (VerticesToFaces[v] == null) - VerticesToFaces[v] = new List { f }; - else - VerticesToFaces[v].Add(f); - } - - // NOTE: the same edge can occur in more than two faces, only in non-manifold meshes - - // Compute the face on the other side of an edge - EdgeToOtherFace = (-1).Repeat(Mesh.NumCorners).ToArray(); - for (var c = 0; c < Mesh.NumCorners; ++c) - { - var c2 = NextCorner(c); - var f0 = CornerToFace(c); - foreach (var f1 in FacesFromCorner(c).ToEnumerable()) - { - if (f1 != f0) - { - foreach (var f2 in FacesFromCorner(c2).ToEnumerable()) - { - if (f2 == f1) - { - if (EdgeToOtherFace[c] != -1) - NonManifold = true; - EdgeToOtherFace[c] = f2; - } - } - } - } - } - - // TODO: there is some serious validation I coudl be doing doing here. - } - - public IMesh Mesh { get; } - - public List[] VerticesToFaces { get; } - public int[] EdgeToOtherFace { get; } // Assumes manifold meshes - public bool NonManifold { get; } - public IArray Corners { get; } - public IArray Vertices { get; } - public IArray Edges => Corners; - public IArray Faces { get; } - - public int CornerToFace(int i) - => Mesh.CornerToFace(i); - - public IArray FacesFromVertexIndex(int v) - => VerticesToFaces[v]?.ToIArray() ?? 0.Repeat(0); - - public IArray FacesFromCorner(int c) - => FacesFromVertexIndex(Mesh.Indices[c]); - - public int VertexIndexFromCorner(int c) - => Mesh.Indices[c]; - - /// - /// Differs from neighbour faces in that the faces have to share an edge, not just a vertex. - /// An alternative construction would have been to getNeighbourFaces and filter out those that don't share - /// - public IEnumerable BorderingFacesFromFace(int f) - => EdgesFromFace(f).Select(BorderFace).Where(bf => bf >= 0); - - public int BorderFace(int e) - => EdgeToOtherFace[e]; - - public bool IsBorderEdge(int e) - => EdgeToOtherFace[e] < 0; - - public bool IsBorderFace(int f) - => EdgesFromFace(f).Any(IsBorderEdge); - - public IArray CornersFromFace(int f) - => Mesh.NumCornersPerFace.Range().Add(FirstCornerInFace(f)); - - public IArray EdgesFromFace(int f) - => CornersFromFace(f); - - public int FirstCornerInFace(int f) - => f * Mesh.NumCornersPerFace; - - public bool FaceHasCorner(int f, int c) - => CornersFromFace(f).Contains(c); - - public int NextCorner(int c) - { - var f = CornerToFace(c); - var begin = FirstCornerInFace(f); - var end = begin + Mesh.NumCornersPerFace; - Debug.Assert(c >= begin); - Debug.Assert(c < end); - var c2 = c + 1; - if (c2 < end) - return c2; - Debug.Assert(c2 == end); - return begin; - } - - public IArray CornersFromEdge(int e) - => LinqArray.LinqArray.Create(e, NextCorner(e)); - - public IArray VertexIndicesFromEdge(int e) - => CornersFromEdge(e).Select(VertexIndexFromCorner); - - public IArray VertexIndicesFromFace(int f) - => Mesh.Indices.SelectByIndex(LinqArray.LinqArray.Create(f * 3, f * 3 + 1, f * 3 + 2)); - - public IEnumerable NeighbourVertices(int v) - => FacesFromVertexIndex(v).SelectMany(f => VertexIndicesFromFace(f)).Where(v2 => v2 != v).Distinct(); - - public IEnumerable BorderEdges - => Edges.Where(IsBorderEdge); - - public IEnumerable BorderFaces - => Faces.Where(IsBorderFace); - - public int EdgeFirstCorner(int e) - => e; - - public int EdgeNextCorner(int e) - => NextCorner(e); - - public int EdgeFirstVertex(int e) - => VertexIndexFromCorner(EdgeFirstCorner(e)); - - public int EdgeNextVertex(int e) - => VertexIndexFromCorner(EdgeFirstCorner(e)); - - public IArray EdgeVertices(int e) - => LinqArray.LinqArray.Create(EdgeFirstVertex(e), EdgeNextVertex(e)); - - public Vector3 PointFromVertex(int v) - => Mesh.Vertices[v]; - - public IArray EdgePoints(int e) - => EdgeVertices(e).Select(PointFromVertex); - } - - public static class TopologyExtensions - { - public static IMesh Mesh(this TopoElement self) - => self.Topology.Mesh; - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/TriMesh.cs b/src/cs/vim/Vim.Format.Core/Geometry/TriMesh.cs deleted file mode 100644 index 17678088..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/TriMesh.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using Vim.G3d; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - /// - /// A triangular mesh data structure. - /// - public class TriMesh : G3D, IMesh - { - public TriMesh(IEnumerable attributes) - : base(attributes) - => Debug.Assert(NumCornersPerFace == 3); - - public IMesh Transform(Matrix4x4 mat) - => ((IGeometryAttributes)this).Transform(mat).ToIMesh(); - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/Validation.cs b/src/cs/vim/Vim.Format.Core/Geometry/Validation.cs deleted file mode 100644 index 5ccca143..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/Validation.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using Vim.BFast; -using Vim.G3d; -using Vim.LinqArray; - -namespace Vim.Format.Geometry -{ - public static class Validation - { - public static void ValidateTableRows(this Document doc) - { - foreach (var et in doc.EntityTables.Values.ToArray()) - { - foreach (var c in et.IndexColumns.Values.ToArray()) - { - if (c.Array.Length != et.NumRows) - throw new Exception($"Expected array length {c.Array.Length} of column {c.Name} to be the same as number of rows {et.NumRows}"); - } - - foreach (var c in et.DataColumns.Values.ToArray()) - { - if (c.NumElements() != et.NumRows) - throw new Exception($"Expected array length {c.NumElements()} of column {c.Name} to be the same as number of rows {et.NumRows}"); - } - - foreach (var c in et.StringColumns.Values.ToArray()) - { - if (c.Array.Length != et.NumRows) - throw new Exception($"Expected array length {c.Array.Length} of column {c.Name} to be the same as number of rows {et.NumRows}"); - } - } - } - - public static void ValidateIndexColumns(this Document doc) - { - foreach (var et in doc.EntityTables.Values.ToArray()) - { - foreach (var ic in et.IndexColumns.Values.ToEnumerable()) - { - var table = ic.GetRelatedTable(doc); - if (table == null) - throw new Exception($"Could not find related table for index column {ic.Name}"); - } - } - } - - public static string[] RequiredAttributeNames => new [] - { - // Vertices - CommonAttributes.Position, - CommonAttributes.Index, - - // Meshes - CommonAttributes.MeshSubmeshOffset, - - // Submeshes - CommonAttributes.SubmeshIndexOffset, - - // Instances - CommonAttributes.InstanceMesh, - CommonAttributes.InstanceTransform, - }; - - public static void ValidateGeometryAttributes(this Document doc) - { - var attributes = doc.Geometry.Attributes; - var attributeNameSet = new HashSet(attributes.Select(a => a.Name).ToEnumerable()); - foreach (var attributeName in RequiredAttributeNames) - { - if (!attributeNameSet.Contains(attributeName)) - throw new Exception($"Required attribute {attributeName} was not found."); - } - } - - public static void ValidateAssets(this Document doc) - { - foreach (var asset in doc.Assets.Values.ToEnumerable()) - AssetInfo.Parse(asset.Name); // This will throw if it fails to parse. - } - - public static void Validate(this Document doc) - { - doc.ValidateTableRows(); - doc.ValidateIndexColumns(); - doc.ValidateGeometryAttributes(); - doc.ValidateAssets(); - } - - // TODO: ValidateShapes() to validate VIM files which contain optional 2d data (shapes/overlays). - - public static void ValidateIndices(this IMesh mesh) - { - foreach (var index in mesh.Indices.ToEnumerable()) - { - if (index < 0 || index >= mesh.NumVertices) - throw new Exception($"Invalid mesh index: {index}. Expected a value greater or equal to 0 and less than {mesh.NumVertices}"); - } - } - - public static void Validate(this IMesh mesh) - { - mesh.ValidateIndices(); - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Geometry/VimMaterial.cs b/src/cs/vim/Vim.Format.Core/Geometry/VimMaterial.cs deleted file mode 100644 index 4799219f..00000000 --- a/src/cs/vim/Vim.Format.Core/Geometry/VimMaterial.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Vim.G3d; -using Vim.Math3d; - -namespace Vim.Format.Geometry -{ - public interface IMaterial - { - Vector4 Color { get; } - float Smoothness { get; } - float Glossiness { get; } - } - - public class VimMaterial : IMaterial - { - public G3dMaterial Material; - public VimMaterial(G3dMaterial material) => Material = material; - public Vector4 Color => Material.Color; - public float Smoothness => Material.Smoothness; - public float Glossiness => Material.Glossiness; - } -} diff --git a/src/cs/vim/Vim.Format.Core/CascadeElementRemapAttribute.cs b/src/cs/vim/Vim.Format.Core/JoiningTableAttribute.cs similarity index 51% rename from src/cs/vim/Vim.Format.Core/CascadeElementRemapAttribute.cs rename to src/cs/vim/Vim.Format.Core/JoiningTableAttribute.cs index 3e058e45..52fb0309 100644 --- a/src/cs/vim/Vim.Format.Core/CascadeElementRemapAttribute.cs +++ b/src/cs/vim/Vim.Format.Core/JoiningTableAttribute.cs @@ -3,9 +3,9 @@ namespace Vim.Format { [AttributeUsage(AttributeTargets.Class)] - public class CascadeElementRemapAttribute : Attribute + public class JoiningTableAttribute : Attribute { - public CascadeElementRemapAttribute() + public JoiningTableAttribute() { } } } diff --git a/src/cs/vim/Vim.Format.Core/SerializableDocument.cs b/src/cs/vim/Vim.Format.Core/SerializableDocument.cs deleted file mode 100644 index 6b834739..00000000 --- a/src/cs/vim/Vim.Format.Core/SerializableDocument.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Vim.BFast; - -namespace Vim.Format -{ - /// - /// Tracks all of the data for a particular entity type in a conceptual table. - /// A column maybe a relation to another entity table (IndexColumn) - /// a data value stored as a double (DataColumn) or else - /// it is string data, stored as an index into the global lookup table (StringColumn). - /// - public class SerializableEntityTable - { - /// - /// Name of - /// - public string Name; - - /// - /// Relation to another entity table. For example surface to element. - /// - public List> IndexColumns = new List>(); - - /// - /// Data encoded as strings in the global string table - /// - public List> StringColumns = new List>(); - - /// - /// Numeric data encoded as byte, int, float, or doubles - /// - public List DataColumns = new List(); - - public IEnumerable ColumnNames - => IndexColumns.Select(c => c.Name) - .Concat(StringColumns.Select(c => c.Name)) - .Concat(DataColumns.Select(c => c.Name)); - } - - /// - /// Controls what parts of the VIM file are loaded - /// - public class LoadOptions - { - public bool SkipGeometry = false; - public bool SkipAssets = false; - public bool SchemaOnly = false; - } - - /// - /// The low-level representation of a VIM data file. - /// - public class SerializableDocument - { - /// - /// Controls how the file is read and loaded into memory - /// - public LoadOptions Options = new LoadOptions(); - - /// - /// A collection of endline terminated = pairs information about the file - /// - public SerializableHeader Header; - - /// - /// A an array of tables, one for each entity - /// - public List EntityTables = new List(); - - /// - /// Used for looking up property strings and entity string fields by Id - /// - public string[] StringTable = Array.Empty(); - - /// - /// A list of named buffers each representing a different asset in the file - /// - public INamedBuffer[] Assets = Array.Empty(); - - /// - /// The uninstanced / untransformed geometry - /// - public G3d.G3D Geometry; - - /// - /// The originating file name (if provided) - /// - public string FileName; - } -} diff --git a/src/cs/vim/Vim.Format.Core/Serializer.cs b/src/cs/vim/Vim.Format.Core/Serializer.cs deleted file mode 100644 index 28ef14f9..00000000 --- a/src/cs/vim/Vim.Format.Core/Serializer.cs +++ /dev/null @@ -1,372 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System; -using Vim.BFast; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using Vim.G3d; -using Vim.Util; - -namespace Vim.Format -{ - public static class Serializer - { - public static List ToBuffers(this SerializableEntityTable table) - { - var r = new List(); - - r.AddRange(table.DataColumns); - r.AddRange(table.IndexColumns); - r.AddRange(table.StringColumns); - - return r; - } - - public static readonly Regex TypePrefixRegex = new Regex(@"(\w+:).*"); - - public static string GetTypePrefix(this string name) - { - var match = TypePrefixRegex.Match(name); - return match.Success ? match.Groups[1].Value : ""; - } - - /// - /// Returns the named buffer prefix, or null if no prefix was found. - /// - public static string GetTypePrefix(this INamedBuffer namedBuffer) - => namedBuffer.Name.GetTypePrefix(); - - /// - /// Returns a NamedBuffer representing to an entity table column. - /// If schemaOnly is enabled, the column is returned without any of its contained data; - /// this is useful for rapidly querying the schema of the entity table. - /// - public static NamedBuffer ReadEntityTableColumn( - this BFastBufferReader columnBufferReader, - bool schemaOnly) where T : unmanaged - { - var (name, size) = columnBufferReader; - - if (schemaOnly) - return new Buffer(Array.Empty()).ToNamedBuffer(name); - - return columnBufferReader - .Seek() - .ReadBufferFromNumberOfBytes(size) - .ToNamedBuffer(name); - } - - public delegate bool EntityTableColumnFilter(string entityTableName, string columnName); - - /// - /// Returns a SerializableEntityTable based on the given buffer reader. - /// - public static SerializableEntityTable ReadEntityTable( - this BFastBufferReader entityTableBufferReader, - bool schemaOnly, - EntityTableColumnFilter entityTableColumnFilter = null) - { - var et = new SerializableEntityTable { Name = entityTableBufferReader.Name }; - - foreach (var colBr in entityTableBufferReader.Seek().GetBFastBufferReaders()) - { - var name = colBr.Name; - var typePrefix = name.GetTypePrefix(); - - if (entityTableColumnFilter != null && !entityTableColumnFilter(et.Name, name)) - continue; - - switch (typePrefix) - { - case VimConstants.IndexColumnNameTypePrefix: - { - et.IndexColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - case VimConstants.StringColumnNameTypePrefix: - { - et.StringColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - case VimConstants.IntColumnNameTypePrefix: - { - et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - case VimConstants.LongColumnNameTypePrefix: - { - et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - case VimConstants.DoubleColumnNameTypePrefix: - { - et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - case VimConstants.FloatColumnNameTypePrefix: - { - et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - case VimConstants.ByteColumnNameTypePrefix: - { - et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); - break; - } - // For flexibility, we ignore the columns which do not contain a recognized prefix. - } - } - - return et; - } - - /// - /// Enumerates the SerializableEntityTables contained in the given entities buffer. - /// - public static IEnumerable EnumerateEntityTables( - this BFastBufferReader entitiesBufferReader, - bool schemaOnly, - Func entityTableNameFilterFunc = null, - EntityTableColumnFilter entityTableColumnFilter = null) - { - var entityTableBufferReaders = entitiesBufferReader.Seek() - .GetBFastBufferReaders(br => entityTableNameFilterFunc?.Invoke(br.Name) ?? true); - - foreach (var entityTableBufferReader in entityTableBufferReaders) - { - yield return entityTableBufferReader.ReadEntityTable(schemaOnly, entityTableColumnFilter); - } - } - - /// - /// Enumerates the SerializableEntityTables contained in the given VIM file. - /// - public static IEnumerable EnumerateEntityTables( - this FileInfo vimFileInfo, - bool schemaOnly, - Func entityTableNameFilterFunc = null, - EntityTableColumnFilter entityTableColumnFilter = null) - { - using (var stream = vimFileInfo.OpenRead()) - { - var entitiesBufferReader = stream.GetBFastBufferReader(BufferNames.Entities); - if (entitiesBufferReader == null) - yield break; - - foreach (var entityTable in entitiesBufferReader.EnumerateEntityTables(schemaOnly, entityTableNameFilterFunc, entityTableColumnFilter)) - { - yield return entityTable; - } - } - } - - /// - /// Returns the string table contained in the given VIM file. - /// - public static string[] GetStringTable(this FileInfo vimFileInfo) - { - using (var stream = vimFileInfo.OpenRead()) - { - var stringTableReader = stream.GetBFastBufferReader(BufferNames.Strings); - if (stringTableReader == null) - return Array.Empty(); - - stringTableReader.Seek(); - - var (_, numBytes) = stringTableReader; - - return ReadStrings(stream, numBytes); - } - } - - /// - /// Returns the geometry contained in the given VIM file. - /// - public static G3D GetGeometry(this FileInfo vimFileInfo) - { - using (var stream = vimFileInfo.OpenRead()) - { - var geometryReader = stream.GetBFastBufferReader(BufferNames.Geometry); - if (geometryReader == null) - return G3D.Empty; - - geometryReader.Seek(); - - return G3D.Read(stream); - } - } - - public static BFastBuilder ToBFastBuilder(this IEnumerable entityTables) - { - var bldr = new BFastBuilder(); - foreach (var et in entityTables) - { - bldr.Add(et.Name, et.ToBuffers()); - } - return bldr; - } - - public static BFastBuilder ToBFastBuilder(this SerializableDocument doc) - => CreateBFastBuilder( - doc.Header, - doc.Assets, - doc.StringTable, - doc.EntityTables, - doc.Geometry.ToG3DWriter()); - - public static BFastBuilder CreateBFastBuilder( - SerializableHeader header, - IEnumerable assets, - IEnumerable stringTable, - IEnumerable entityTables, - IBFastComponent geometry) - { - var bfastBuilder = new BFastBuilder(); - bfastBuilder.Add(BufferNames.Header, header.ToString().ToBytesUtf8().ToBuffer()); - bfastBuilder.Add(BufferNames.Assets, assets ?? Array.Empty()); - bfastBuilder.Add(BufferNames.Entities, entityTables.ToBFastBuilder()); - bfastBuilder.Add(BufferNames.Strings, stringTable.PackStrings().ToBuffer()); - bfastBuilder.Add(BufferNames.Geometry, geometry); - return bfastBuilder; - } - - public static void Serialize( - Stream stream, - SerializableHeader header, - IEnumerable assets, - IEnumerable stringTable, - IEnumerable entityTables, - IBFastComponent geometry) - { - CreateBFastBuilder(header, assets, stringTable, entityTables, geometry).Write(stream); - } - - public static void Serialize(this SerializableDocument doc, Stream stream) - => doc.ToBFastBuilder().Write(stream); - - public static void Serialize(this SerializableDocument document, string filePath) - { - using (var stream = File.OpenWrite(filePath)) - document.Serialize(stream); - } - - public static SerializableHeader ToSerializableHeader(this byte[] bytes) - => SerializableHeader.Parse(Encoding.UTF8.GetString(bytes)); - - /// - /// Returns true if the SerializableHeader in the stream is successfully parsed. - /// - public static bool TryParseSerializableHeader(this Stream stream, out SerializableHeader header) - { - using (new SeekContext(stream)) - { - try - { - header = stream.ReadBFastBuffer(BufferNames.Header)?.Array.ToSerializableHeader(); - } - catch - { - header = null; - } - return header != null; - } - } - - /// - /// Returns true if the SerializableHeader in the given VIM file is successfully parsed. - /// - public static bool TryParseSerializableHeader(this FileInfo fileInfo, out SerializableHeader header) - { - using (var fs = fileInfo.OpenRead()) - { - return fs.TryParseSerializableHeader(out header); - } - } - - /// - /// Returns the VIM file's header schema version. Returns null if the header schema is not found. - /// - public static string GetSchemaVersion(this FileInfo fileInfo) - => fileInfo.TryParseSerializableHeader(out var header) - ? header.Schema?.ToString() - : null; - - public static void ReadBuffer(this SerializableDocument doc, BFastBufferReader bufferReader) - { - var (name, numBytes) = bufferReader; - var stream = bufferReader.Seek(); - - switch (name) - { - case BufferNames.Header: - { - doc.Header = stream.ReadArray((int)numBytes).ToSerializableHeader(); - break; - } - - case BufferNames.Assets: - { - if (doc.Options?.SkipAssets == true) - break; - - doc.Assets = stream.ReadBFast().ToArray(); - break; - } - - case BufferNames.Strings: - { - doc.StringTable = ReadStrings(stream, numBytes); - break; - } - - case BufferNames.Geometry: - { - if (doc.Options?.SkipGeometry == true) - break; - - doc.Geometry = G3D.Read(stream); - break; - } - - case BufferNames.Entities: - { - doc.EntityTables = - bufferReader - .EnumerateEntityTables(doc.Options?.SchemaOnly ?? false) - .ToList(); - break; - } - } - } - - public static string[] ReadStrings(Stream stream, long numBytes) - { - var stringBytes = stream.ReadArray((int)numBytes); - var joinedStringTable = Encoding.UTF8.GetString(stringBytes); - return joinedStringTable.Split('\0'); - } - - public static SerializableDocument Deserialize(Stream stream, LoadOptions loadOptions = null) - { - var doc = new SerializableDocument { Options = loadOptions }; - - foreach (var buffer in stream.GetBFastBufferReaders()) - { - doc.ReadBuffer(buffer); - } - - return doc; - } - - public static SerializableDocument Deserialize(string filePath, LoadOptions loadOptions = null) - { - using (var stream = File.OpenRead(filePath)) - { - var doc = Deserialize(stream, loadOptions); - doc.SetFileName(filePath); - return doc; - } - } - } -} diff --git a/src/cs/vim/Vim.Format.Core/Validation.cs b/src/cs/vim/Vim.Format.Core/Validation.cs deleted file mode 100644 index bb5287ab..00000000 --- a/src/cs/vim/Vim.Format.Core/Validation.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using Vim.BFast; -using Vim.G3d; -using Vim.LinqArray; - -namespace Vim.Format -{ - public static class Validation - { - public static void ValidateTableRows(this Document doc) - { - foreach (var et in doc.EntityTables.Values.ToArray()) - { - foreach (var c in et.IndexColumns.Values.ToArray()) - { - if (c.Array.Length != et.NumRows) - throw new Exception($"Expected array length {c.Array.Length} of column {c.Name} to be the same as number of rows {et.NumRows}"); - } - - foreach (var c in et.DataColumns.Values.ToArray()) - { - if (c.NumElements() != et.NumRows) - throw new Exception($"Expected array length {c.NumElements()} of column {c.Name} to be the same as number of rows {et.NumRows}"); - } - - foreach (var c in et.StringColumns.Values.ToArray()) - { - if (c.Array.Length != et.NumRows) - throw new Exception($"Expected array length {c.Array.Length} of column {c.Name} to be the same as number of rows {et.NumRows}"); - } - } - } - - public static void ValidateIndexColumns(this Document doc) - { - foreach (var et in doc.EntityTables.Values.ToArray()) - { - foreach (var ic in et.IndexColumns.Values.ToEnumerable()) - { - var table = ic.GetRelatedTable(doc); - if (table == null) - throw new Exception($"Could not find related table for index column {ic.Name}"); - } - } - } - - public static string[] RequiredAttributeNames => new [] - { - // Vertices - CommonAttributes.Position, - CommonAttributes.Index, - - // Meshes - CommonAttributes.MeshSubmeshOffset, - - // Submeshes - CommonAttributes.SubmeshIndexOffset, - - // Instances - CommonAttributes.InstanceMesh, - CommonAttributes.InstanceTransform, - }; - - public static void ValidateGeometryAttributes(this Document doc) - { - var attributes = doc.Geometry.Attributes; - var attributeNameSet = new HashSet(attributes.Select(a => a.Name).ToEnumerable()); - foreach (var attributeName in RequiredAttributeNames) - { - if (!attributeNameSet.Contains(attributeName)) - throw new Exception($"Required attribute {attributeName} was not found."); - } - } - - public static void ValidateAssets(this Document doc) - { - foreach (var asset in doc.Assets.Values.ToEnumerable()) - AssetInfo.Parse(asset.Name); // This will throw if it fails to parse. - } - - public static void Validate(this Document doc) - { - doc.ValidateTableRows(); - doc.ValidateIndexColumns(); - doc.ValidateGeometryAttributes(); - doc.ValidateAssets(); - } - - // TODO: ValidateShapes() to validate VIM files which contain optional 2d data (shapes/overlays). - } -} diff --git a/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj b/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj index d845180e..1eda2461 100644 --- a/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj +++ b/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj @@ -8,8 +8,6 @@ - - @@ -20,23 +18,4 @@ - - - - - - - TextTemplatingFileGenerator - ArrayOps.cs - - - - - - True - True - ArrayOps.tt - - - diff --git a/src/cs/vim/Vim.Format.Core/VimAssetInfo.cs b/src/cs/vim/Vim.Format.Core/VimAssetInfo.cs new file mode 100644 index 00000000..afb3bb30 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimAssetInfo.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Vim.BFast; +using Vim.Util; +using System.Linq; + +namespace Vim.Format +{ + public enum VimAssetType + { + Texture, + Render, + } + + /// + /// A VimAssetInfo is defined by a name and an VimAssetType, and takes care of parsing and generating asset buffer names. + /// + public class VimAssetInfo + { + public const string MainPng = "main.png"; + + public const char Separator = '/'; + + public readonly string Name; + + public readonly VimAssetType AssetType; + + public VimAssetInfo(string name, VimAssetType assetType) + => (Name, AssetType) = (name, assetType); + + public static string[] SplitAssetBufferName(string assetBufferName) + => assetBufferName?.Split(Separator); + + public static VimAssetInfo Parse(string assetBufferName) + { + // Validate that the asset buffer name can be split into two tokens. + var tokens = SplitAssetBufferName(assetBufferName); + if (tokens.Length != 2) + throw new Exception($"The asset buffer name '{assetBufferName}' should be splittable into two tokens by a separator ('{Separator}'). These tokens represent: (0) the asset type, (1) the asset name."); + + // Validate the asset type token. + if (!Enum.TryParse(tokens[0], true, out var assetType)) + throw new Exception($"The first token '{assetType}' in the asset buffer name '{assetBufferName}' is not a recognized asset type."); + + // Validate the asset name token. + var name = tokens[1]; + if (string.IsNullOrEmpty(name)) + throw new Exception($"The second token in the asset buffer name '{assetBufferName}' is null or empty."); + + return new VimAssetInfo(name, assetType); + } + + public static bool TryParse(string assetBufferName, out VimAssetInfo assetInfo) + { + assetInfo = null; + try + { + assetInfo = Parse(assetBufferName); + return true; + } + catch + { + return false; + } + } + + public static string AssetTypeToString(VimAssetType assetType) + => assetType.ToString("G").ToLowerInvariant(); + + public string AssetTypeString + => AssetTypeToString(AssetType); + + public override string ToString() + => $"{AssetTypeString}{Separator}{Name}"; + + public string BufferName + => ToString(); + + public string GetDefaultAssetFilePathInDirectory(DirectoryInfo directoryInfo) + => Path.Combine(directoryInfo.FullName, AssetTypeString.ToValidFileName(), Name.ToValidFileName()); + + + public static IEnumerable GetTextures(IEnumerable assetBuffers) + { + return assetBuffers.Where(IsTexture); + } + + public static bool IsTexture(INamedBuffer assetBuffer) + { + return TryParse(assetBuffer.Name, out var assetInfo) && assetInfo.AssetType == VimAssetType.Texture; + } + + /// + /// Extracts the asset buffer to the file designated by the given FileInfo. + /// + public static FileInfo ExtractAsset(INamedBuffer assetBuffer, FileInfo fileInfo) + { + IO.CreateFileDirectory(fileInfo.FullName); + using (var stream = fileInfo.Create()) + assetBuffer.Write(stream); + return fileInfo; + } + + /// + /// Extracts the asset and returns a FileInfo representing the extracted asset on disk.
+ /// Returns null if the asset could not be extracted. + ///
+ public static FileInfo ExtractAsset(INamedBuffer assetBuffer, DirectoryInfo directoryInfo) + => !TryParse(assetBuffer.Name, out var assetInfo) + ? null + : ExtractAsset(assetBuffer, new FileInfo(assetInfo.GetDefaultAssetFilePathInDirectory(directoryInfo))); + + + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimBufferNames.cs b/src/cs/vim/Vim.Format.Core/VimBufferNames.cs new file mode 100644 index 00000000..93f288d3 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimBufferNames.cs @@ -0,0 +1,11 @@ +namespace Vim.Format +{ + public static class VimBufferNames + { + public const string Header = "header"; + public const string Assets = "assets"; + public const string Entities = "entities"; + public const string Strings = "strings"; + public const string Geometry = "geometry"; + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTable.cs b/src/cs/vim/Vim.Format.Core/VimEntityTable.cs new file mode 100644 index 00000000..3cedf24b --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTable.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vim.BFast; +using Vim.Util; + +namespace Vim.Format +{ + public interface IVimEntityTable + { + int RowCount { get; } + } + + public class VimEntityTable : IVimEntityTable + { + public VimEntityTableData TableData { get; } + public string Name => TableData.Name; + protected string[] StringTable { get; } + public Dictionary> IndexColumnMap { get; } = new Dictionary>(); + public Dictionary> StringColumnMap { get; } = new Dictionary>(); + public Dictionary DataColumnMap { get; } = new Dictionary(); + public int RowCount { get; } + + /// + /// Constructor + /// + public VimEntityTable(VimEntityTableData tableData, string[] stringTable) + { + TableData = tableData; + StringTable = stringTable; + + RowCount = tableData.GetRowCount(); + + foreach (var column in TableData.IndexColumns) + IndexColumnMap[column.Name] = column; + + foreach (var column in TableData.StringColumns) + StringColumnMap[column.Name] = column; + + foreach (var column in TableData.DataColumns) + DataColumnMap[column.Name] = column; + } + + private static T GetColumnOrDefault(Dictionary map, string key, T defaultValue = default) + => map.TryGetValue(key, out var result) ? result : defaultValue; + + /// + /// Returns the index column based on the given column name. + /// + public int[] GetIndexColumnValues(string columnName) + => GetColumnOrDefault(IndexColumnMap, columnName)?.AsArray(); + + /// + /// Returns the string column based on the given column name. + /// + public string[] GetStringColumnValues(string columnName) + { + var stringIndices = GetColumnOrDefault(StringColumnMap, columnName) + ?.AsArray() ?? Array.Empty(); + + var strings = new string[stringIndices.Length]; + + for (var i = 0; i < strings.Length; i++) + { + strings[i] = StringTable == null || StringTable.Length == 0 + ? "" // Guard against the case where the string buffer is null or empty. + : StringTable.ElementAtOrDefault(stringIndices[i], ""); + } + + return strings; + } + + /// + /// Returns the data column based on the given column name. + /// + public T[] GetDataColumnValues(string columnName) where T : unmanaged + { + var type = typeof(T); + + if (!VimEntityTableColumnTypeInfo.DataColumnTypes.Contains(type)) + throw new Exception($"{nameof(GetDataColumnValues)} error - unsupported data column type {type}"); + + var namedBuffer = GetColumnOrDefault(DataColumnMap, columnName); + if (namedBuffer == null) + return null; + + return VimEntityTableColumnTypeInfo.GetDataColumnAsTypedArray(namedBuffer); + } + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableBuilder.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableBuilder.cs new file mode 100644 index 00000000..37ac474c --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableBuilder.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Vim.BFast; +using Vim.Util; + +namespace Vim.Format +{ + public interface IReadOnlyVimEntityTableBuilder + { + string Name { get; } + int RowCount { get; } + IReadOnlyDictionary DataColumns { get; } + IReadOnlyDictionary> IndexColumns { get; } + IReadOnlyDictionary> StringColumns { get; } + } + + public class VimEntityTableBuilder : IReadOnlyVimEntityTableBuilder + { + public string Name { get; } + public Dictionary DataColumns { get; } = new Dictionary(); + IReadOnlyDictionary IReadOnlyVimEntityTableBuilder.DataColumns => DataColumns; + + public Dictionary IndexColumns { get; } = new Dictionary(); + IReadOnlyDictionary> IReadOnlyVimEntityTableBuilder.IndexColumns + => IndexColumns.ToDictionary(kv => kv.Key, kv => { + var result = kv.Value as IReadOnlyList; + Debug.Assert(result != null, "Invalid readonly index column cast"); + return result; + }); + + public Dictionary StringColumns { get; } = new Dictionary(); + IReadOnlyDictionary>IReadOnlyVimEntityTableBuilder.StringColumns + => StringColumns.ToDictionary(kv => kv.Key, kv => { + var result = kv.Value as IReadOnlyList; + Debug.Assert(result != null, "Invalid readonly string column cast"); + return result; + }); + + public int RowCount { get; private set; } + + public VimEntityTableBuilder(string name) + => Name = name; + + public VimEntityTableBuilder(VimEntityTableData tableData, string[] stringTable) + { + Name = tableData.Name; + RowCount = tableData.GetRowCount(); + + foreach (var column in tableData.IndexColumns) + IndexColumns[column.Name] = column.AsArray(); + + foreach (var column in tableData.StringColumns) + StringColumns[column.Name] = column.AsArray().Select(i => stringTable.ElementAtOrDefault(i, "")).ToArray(); + + foreach (var column in tableData.DataColumns) + DataColumns[column.Name] = column; + } + + public VimEntityTableBuilder UpdateOrValidateRows(int n) + { + if (RowCount == 0) RowCount = n; + else if (RowCount != n) throw new Exception($"Value count {n} does not match the expected number of rows {RowCount}"); + return this; + } + + public void ValidateHasDataColumnPrefix(string columnName) + { + if (!VimEntityTableColumnName.IsDataColumnName(columnName)) + throw new Exception($"{nameof(columnName)} {columnName} does not begin with a data column prefix"); + } + + public void ValidateHasPrefix(string columnName, string expectedPrefix) + { + if (!columnName.StartsWith(expectedPrefix)) + throw new Exception($"{nameof(columnName)} {columnName} must start with {expectedPrefix}"); + } + + public VimEntityTableBuilder AddIndexColumn(string columnName, int[] indices) + { + ValidateHasPrefix(columnName, VimEntityTableColumnName.IndexColumnNameTypePrefix); + UpdateOrValidateRows(indices.Length); + IndexColumns.Add(columnName, indices); + return this; + } + + public VimEntityTableBuilder AddIndexColumn(string columnName, IEnumerable ids) + => AddIndexColumn(columnName, ids.ToArray()); + + public VimEntityTableBuilder AddStringColumn(string columnName, string[] values) + { + ValidateHasPrefix(columnName, VimEntityTableColumnName.StringColumnNameTypePrefix); + UpdateOrValidateRows(values.Length); + StringColumns.Add(columnName, values); + return this; + } + + public VimEntityTableBuilder AddStringColumn(string columnName, IEnumerable values) + => AddStringColumn(columnName, values.ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IBuffer values) + { + ValidateHasDataColumnPrefix(columnName); + UpdateOrValidateRows(values.Data.Length); + DataColumns.Add(columnName, values); + return this; + } + + public VimEntityTableBuilder AddDataColumn(string columnName, T[] values) where T : unmanaged + { + ValidateHasPrefix(columnName, typeof(T).GetDataColumnNameTypePrefix()); + return AddDataColumn(columnName, values.ToBuffer()); + } + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.Select(x => (int)x).ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.ToArray()); + + public VimEntityTableBuilder AddDataColumn(string columnName, IEnumerable values) + => AddDataColumn(columnName, values.Select(x => x ? (byte)1 : (byte)0).ToArray()); + + public IEnumerable GetAllStrings() + => StringColumns.Values.SelectMany(sc => sc) + .Where(x => x != null); + + public void Clear() + { + RowCount = 0; + DataColumns.Clear(); + StringColumns.Clear(); + IndexColumns.Clear(); + } + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableColumnActions.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnActions.cs new file mode 100644 index 00000000..3c81eec4 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnActions.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vim.BFast; + +namespace Vim.Format +{ + public static class VimEntityTableColumnActions + { + public const string UnknownNamedBufferPrefix = "Unknown NamedBuffer prefix"; + + public static IBuffer RemapOrSelfDataColumn(IBuffer dataColumn, string typePrefix, IReadOnlyList remapping = null) + { + switch (typePrefix) + { + case VimEntityTableColumnName.IntColumnNameTypePrefix: + return new Buffer(RemapOrSelf(dataColumn.Data as int[], remapping)); + case VimEntityTableColumnName.LongColumnNameTypePrefix: + return new Buffer(RemapOrSelf(dataColumn.Data as long[], remapping)); + case VimEntityTableColumnName.DoubleColumnNameTypePrefix: + return new Buffer(RemapOrSelf(dataColumn.Data as double[], remapping)); + case VimEntityTableColumnName.FloatColumnNameTypePrefix: + return new Buffer(RemapOrSelf(dataColumn.Data as float[], remapping)); + case VimEntityTableColumnName.ByteColumnNameTypePrefix: + return new Buffer(RemapOrSelf(dataColumn.Data as byte[], remapping)); + default: + throw new ArgumentException($"{nameof(RemapOrSelfDataColumn)} - {UnknownNamedBufferPrefix}: {typePrefix}"); + } + } + + public static INamedBuffer RemapOrSelfDataColumn(INamedBuffer dataColumn, List remapping = null) + { + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(dataColumn.Name, out var typePrefix)) + return null; + + return new NamedBuffer(RemapOrSelfDataColumn(dataColumn, typePrefix, remapping), dataColumn.Name); + } + + public static T[] RemapOrSelf(T[] source, IReadOnlyList remapping = null) + { + if (remapping == null) + return source; + + var dst = new T[remapping.Count]; + + for (var i = 0; i < dst.Length; ++i) + { + var remappedIndex = remapping[i]; + dst[i] = source[remappedIndex]; + } + + return dst; + } + + public static IBuffer CreateDefaultDataColumnBuffer(int length, string typePrefix) + { + switch (typePrefix) + { + case VimEntityTableColumnName.IntColumnNameTypePrefix: + return new Buffer(new int[length]); + case VimEntityTableColumnName.LongColumnNameTypePrefix: + return new Buffer(new long[length]); + case VimEntityTableColumnName.ByteColumnNameTypePrefix: + return new Buffer(new byte[length]); + case VimEntityTableColumnName.FloatColumnNameTypePrefix: + return new Buffer(new float[length]); + case VimEntityTableColumnName.DoubleColumnNameTypePrefix: + return new Buffer(new double[length]); + default: + throw new ArgumentException($"{nameof(CreateDefaultDataColumnBuffer)} - {UnknownNamedBufferPrefix}: {typePrefix}"); + } + } + + public static IBuffer Concat(IBuffer thisBuffer, IBuffer otherBuffer) where T : unmanaged + { + var arrayA = thisBuffer.AsArray(); + var arrayB = otherBuffer.AsArray(); + var result = new T[arrayA.Length + arrayB.Length]; + + for (var i = 0; i < arrayA.Length; ++i) + { + result[i] = arrayA[i]; + } + + var a = arrayA.Length; + for (var i = 0; i < arrayB.Length; ++i) + { + result[a + i] = arrayB[i]; + } + + return result.ToBuffer(); + } + + public static IBuffer ConcatDataColumnBuffers(IBuffer thisBuffer, IBuffer otherBuffer, string typePrefix) + { + switch (typePrefix) + { + case VimEntityTableColumnName.IntColumnNameTypePrefix: + return Concat(thisBuffer, otherBuffer); + case VimEntityTableColumnName.LongColumnNameTypePrefix: + return Concat(thisBuffer, otherBuffer); + case VimEntityTableColumnName.ByteColumnNameTypePrefix: + return Concat(thisBuffer, otherBuffer); + case VimEntityTableColumnName.FloatColumnNameTypePrefix: + return Concat(thisBuffer, otherBuffer); + case VimEntityTableColumnName.DoubleColumnNameTypePrefix: + return Concat(thisBuffer, otherBuffer); + default: + throw new ArgumentException($"{nameof(ConcatDataColumnBuffers)} - {UnknownNamedBufferPrefix}: {typePrefix}"); + } + } + + public static string ValidateCanConcatBuffers(INamedBuffer thisBuffer, INamedBuffer otherBuffer) + { + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(thisBuffer.Name, out var thisPrefix)) + throw new Exception("NamedBuffer prefix not found"); + + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(otherBuffer.Name, out var otherPrefix)) + throw new Exception("NamedBuffer prefix not found"); + + if (thisPrefix != otherPrefix) + throw new Exception($"NamedBuffer prefixes are not equal: {thisPrefix} <> {otherPrefix}"); + + return thisPrefix; + } + + public static INamedBuffer ConcatDataColumns(INamedBuffer thisColumn, INamedBuffer otherColumn) + { + var typePrefix = ValidateCanConcatBuffers(thisColumn, otherColumn); + var combinedBuffer = ConcatDataColumnBuffers(thisColumn, otherColumn, typePrefix); + return new NamedBuffer(combinedBuffer, thisColumn.Name); + } + + public static List ConcatDataColumns( + IReadOnlyList thisColumnList, + IReadOnlyList otherColumnList) + => ConcatColumns( + thisColumnList, + otherColumnList, + (a, b) => ConcatDataColumns(a, b)); + + public static List> ConcatIntColumns( + IReadOnlyList> thisColumnList, + IReadOnlyList> otherColumnList) + => ConcatColumns(thisColumnList, otherColumnList, + (a, b) => new NamedBuffer(a.GetTypedData().Concat(b.GetTypedData()).ToArray(), a.Name)); + + public static List ConcatColumns( + IReadOnlyList thisColumnList, + IReadOnlyList otherColumnList, + Func concatFunc) where T : INamedBuffer + { + var mergedColumns = new List(); + + foreach (var thisColumn in thisColumnList) + { + var otherColumn = otherColumnList.FirstOrDefault(c => c.Name == thisColumn.Name); + if (otherColumn == null) + continue; + + var newNamedBuffer = concatFunc(thisColumn, otherColumn); + + mergedColumns.Add(newNamedBuffer); + } + + return mergedColumns; + } + + public static T[] Copy(T[] source, List remapping = null) + { + T[] result; + + if (remapping == null) + { + // Copy from the source. + result = new T[source.Length]; + + for (var i = 0; i < result.Length; ++i) + result[i] = source[i]; + } + else + { + // Copy from the remapping. + result = new T[remapping.Count]; + + for (var i = 0; i < result.Length; ++i) + { + var remappedIndex = remapping[i]; + result[i] = source[remappedIndex]; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableColumnName.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnName.cs new file mode 100644 index 00000000..8cb47f05 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnName.cs @@ -0,0 +1,199 @@ +using System; +using System.Diagnostics; +using System.Text.RegularExpressions; +using Vim.BFast; + +namespace Vim.Format +{ + /// + /// Parses an entity table column name into its components. + /// + public class VimEntityTableColumnName + { + // Index column prefix + + public const string IndexColumnNameTypePrefix = "index:"; + + // String column prefix + + public const string StringColumnNameTypePrefix = "string:"; + + // Data column prefixes + + public const string IntColumnNameTypePrefix = "int:"; + public const string UintColumnNameTypePrefix = "uint:"; // unused for now + public const string LongColumnNameTypePrefix = "long:"; + public const string UlongColumnNameTypePrefix = "ulong:"; // unused for now + public const string ByteColumnNameTypePrefix = "byte:"; + public const string UbyteColumNameTypePrefix = "ubyte:"; // unused for now + public const string FloatColumnNameTypePrefix = "float:"; + public const string DoubleColumnNameTypePrefix = "double:"; + + /// + /// Matches the type prefix and the remainder of the column name. + /// + public static readonly Regex ColumnNameComponentsRegex + = new Regex(@"(\w+:)(.+)", RegexOptions.Compiled); + + /// + /// Matches the index column's components. + /// + public static readonly Regex IndexColumnNameComponentsRegex + = new Regex(@"(\w+:)((?:\w|\.)+):(.+)", RegexOptions.Compiled); + + /// + /// The type prefix. Ex: "string:" in "string:Name". + /// + public string TypePrefix { get; } + + /// + /// The field name. Ex: "Name" in "string:Name". + /// + public string FieldName { get; } + + /// + /// The related table name, if the column name is an index column. Otherwise null. Ex: "Vim.Level" in "index:Vim.Level:Level" + /// + public string RelatedTableName { get; } + + /// + /// The column type. Ex: StringColumn if the columnName is "string:Name" + /// + public readonly VimEntityTableColumnType ColumnType; + + /// + /// Constructor. Parses the column name into its components. + /// + public VimEntityTableColumnName(string columnName) + { + var match = ColumnNameComponentsRegex.Match(columnName); + if (!match.Success) + throw new Exception($"Column name {columnName} could not be separated into its components."); + + // Collect the type prefix. + TypePrefix = match.Groups[1].Value; + switch (TypePrefix) + { + case IndexColumnNameTypePrefix: + ColumnType = VimEntityTableColumnType.IndexColumn; + break; + case StringColumnNameTypePrefix: + ColumnType = VimEntityTableColumnType.StringColumn; + break; + default: + ColumnType = VimEntityTableColumnType.DataColumn; + break; + } + + // Collect the field name + FieldName = match.Groups[2].Value; + + // If it's an index column, get the related table. + if (ColumnType == VimEntityTableColumnType.IndexColumn) + { + var indexMatch = IndexColumnNameComponentsRegex.Match(columnName); + if (!match.Success) + throw new Exception($"Index column name {columnName} could not be separated into its components."); + + RelatedTableName = indexMatch.Groups[2].Value; + FieldName = indexMatch.Groups[3].Value; // Update the field name. + } + } + + /// + /// Constructor. Parses the given buffer's name into its components. + /// + public VimEntityTableColumnName(INamedBuffer namedBuffer) + : this(namedBuffer.Name) + { } + + /// + /// Returns the parsed VimEntityTableColumnName or null if the column name could not be parsed. + /// + public static VimEntityTableColumnName ParseVimEntityTableColumnNameOrNull(string columnName) + => TryParseVimEntityTableColumnName(columnName, out var value) ? value : null; + + /// + /// Returns true along with the parsed VimEntityTableColumnName if the column could be parsed. Returns false otherwise. + /// + public static bool TryParseVimEntityTableColumnName(string columnName, out VimEntityTableColumnName columnComponents) + { + columnComponents = null; + + if (string.IsNullOrEmpty(columnName)) + { + Debug.Fail("Column components could not be parsed - column name is null"); + return false; + } + + try + { + columnComponents = new VimEntityTableColumnName(columnName); + } + catch (Exception e) + { + // Invalid column name; could not be parsed. + Debug.Fail($"Column components could not be parsed: {columnName}. Error: {e}"); + return false; + } + + return true; + } + + /// + /// Returns true along with the type prefix of the column name if it could be parsed. + /// + public static bool TryParseColumnTypePrefix(string columnName, out string typePrefix) + { + typePrefix = null; + + var name = ParseVimEntityTableColumnNameOrNull(columnName); + if (name == null) + return false; + + typePrefix = name.TypePrefix; + + return true; + } + + /// + /// Returns true along with the data column type prefix of the column name if it is a valid data column name. + /// + public static bool TryParseDataColumnNameTypePrefix(string columnName, out string typePrefix) + { + typePrefix = null; + + var name = ParseVimEntityTableColumnNameOrNull(columnName); + if (name == null) + return false; + + if (!VimEntityTableColumnTypeInfo.DataColumnNameTypePrefixes.Contains(name.TypePrefix)) + return false; + + typePrefix = name.TypePrefix; + + return true; + } + + public static bool IsDataColumnName(string columnName) + => TryParseDataColumnNameTypePrefix(columnName, out _); + + public static string GetIndexColumnName(string relatedTableName, string localFieldName) + => VimEntityTableColumnName.IndexColumnNameTypePrefix + relatedTableName + ":" + localFieldName; + + public static string GetRelatedTableNameFromColumnName(string name) + => ParseVimEntityTableColumnNameOrNull(name)?.RelatedTableName; + + public static string GetRelatedTableName(INamedBuffer ic) + => GetRelatedTableNameFromColumnName(ic.Name); + + public static string GetIndexColumnFieldName(INamedBuffer ic) + => ParseVimEntityTableColumnNameOrNull(ic.Name)?.FieldName; + + public static string GetStringColumnFieldName(INamedBuffer sc) + => ParseVimEntityTableColumnNameOrNull(sc.Name)?.FieldName; + + public static string GetDataColumnFieldName(INamedBuffer dc) + => ParseVimEntityTableColumnNameOrNull(dc.Name)?.FieldName; + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableColumnType.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnType.cs new file mode 100644 index 00000000..de38c388 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnType.cs @@ -0,0 +1,9 @@ +namespace Vim.Format +{ + public enum VimEntityTableColumnType + { + IndexColumn, + StringColumn, + DataColumn, + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableColumnTypeInfo.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnTypeInfo.cs new file mode 100644 index 00000000..1332fc3d --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableColumnTypeInfo.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vim.BFast; + +namespace Vim.Format +{ + /// + /// Defines the serialized type information of entity table columns. + /// + public class VimEntityTableColumnTypeInfo + { + public readonly VimEntityTableColumnType ColumnType; + public readonly string TypePrefix; + public readonly Type SerializedType; + public readonly ISet CastTypes; + + /// + /// Constructor + /// + public VimEntityTableColumnTypeInfo( + VimEntityTableColumnType columnType, string typePrefix, Type serializedType, params Type[] castTypes) + { + (ColumnType, TypePrefix, SerializedType) = (columnType, typePrefix, serializedType); + CastTypes = new HashSet(castTypes); + } + + public IEnumerable RelatedTypes + => CastTypes.Prepend(SerializedType); + + /// + /// Returns the supported serialization types for each column type. + /// + public static readonly IReadOnlyCollection SupportedColumnTypes + = new[] + { + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.IndexColumn, VimEntityTableColumnName.IndexColumnNameTypePrefix, typeof(int)), + + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.StringColumn, VimEntityTableColumnName.StringColumnNameTypePrefix, typeof(int)), + + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.DataColumn, VimEntityTableColumnName.IntColumnNameTypePrefix, typeof(int), typeof(short)), + + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.DataColumn, VimEntityTableColumnName.LongColumnNameTypePrefix, typeof(long)), + + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.DataColumn, VimEntityTableColumnName.ByteColumnNameTypePrefix, typeof(byte), typeof(bool)), + + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.DataColumn, VimEntityTableColumnName.DoubleColumnNameTypePrefix, typeof(double)), + + new VimEntityTableColumnTypeInfo( + VimEntityTableColumnType.DataColumn, VimEntityTableColumnName.FloatColumnNameTypePrefix, typeof(float)), + }; + + public static readonly IReadOnlyDictionary TypePrefixToColumnTypeMap + = SupportedColumnTypes.ToDictionary(t => t.TypePrefix, t => t.ColumnType); + + public static readonly IReadOnlyDictionary DataColumnTypeToPrefixMap + = SupportedColumnTypes + .Where(t => t.ColumnType == VimEntityTableColumnType.DataColumn) + .SelectMany(t => t.RelatedTypes.Select(type => (Type: type, t.TypePrefix))) + .ToDictionary(item => item.Type, item => item.TypePrefix); + + public static readonly IReadOnlyDictionary TypePrefixToSerializedTypeMap + = SupportedColumnTypes + .Where(t => t.ColumnType == VimEntityTableColumnType.DataColumn) + .ToDictionary(t => t.TypePrefix, t => t.SerializedType); + + public static readonly ISet DataColumnTypes + = new HashSet(SupportedColumnTypes + .Where(t => t.ColumnType == VimEntityTableColumnType.DataColumn) + .SelectMany(t => t.RelatedTypes)); + + public static readonly ISet DataColumnNameTypePrefixes + = new HashSet(SupportedColumnTypes + .Where(t => t.ColumnType == VimEntityTableColumnType.DataColumn) + .Select(t => t.TypePrefix)); + + public static bool TryGetDataColumnType(INamedBuffer dc, out Type type) + { + type = null; + + if (!VimEntityTableColumnName.TryParseDataColumnNameTypePrefix(dc.Name, out var typePrefix)) + return false; + + return TypePrefixToSerializedTypeMap.TryGetValue(typePrefix, out type); + } + + public static T[] GetDataColumnAsTypedArray(IBuffer buffer) where T: unmanaged + { + if (buffer == null) + return null; + + var type = typeof(T); + + if (type == typeof(short)) + return buffer.AsArray().Select(i => (short)i).ToArray() as T[]; + + if (type == typeof(bool)) + return buffer.AsArray().Select(b => b != 0).ToArray() as T[]; + + return buffer.AsArray(); + } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableConstants.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableConstants.cs new file mode 100644 index 00000000..7e626bb7 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableConstants.cs @@ -0,0 +1,15 @@ +namespace Vim.Format +{ + public static class VimEntityTableConstants + { + public const int NoEntityRelation = -1; + public const long SyntheticElementId = -1; + public const long SyntheticCategoryId = -1; + public const string SystemFamilyTypeElementType = "System Family Type"; + public const string SystemFamilyElementType = "System Family"; + public const string UnassignedSystem = "Unassigned System"; + public const string BimDocumentParameterHolderElementType = "BimDocument Parameter Holder"; + public const string BuildingParameterHolderElementType = "Building Parameter Holder"; + public const string SiteParameterHolderElementType = "Site Parameter Holder"; + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimEntityTableData.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableData.cs new file mode 100644 index 00000000..32319ed7 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableData.cs @@ -0,0 +1,290 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Vim.BFast; +using Vim.Util; + +namespace Vim.Format +{ + /// + /// Represents the serializable data buffers which define an entity table. + /// + public class VimEntityTableData + { + /// + /// The name of the entity table. + /// + public string Name { get; set; } + + /// + /// The relational index columns of the entity table. + /// + public List> IndexColumns { get; set; } = new List>(); + + /// + /// The string columns of the entity table. + /// + public List> StringColumns { get; set; } = new List>(); + + /// + /// The data columns of the entity table. + /// + public List DataColumns { get; set; } = new List(); + + /// + /// A delegate which filters entity tables by name. + /// + public delegate bool EntityTableFilter(string entityTableName); + + /// + /// A delegate which filters entity table columns. + /// + public delegate bool EntityTableColumnFilter(string entityTableName, string columnName); + + /// + /// Default constructor + /// + public VimEntityTableData() + { } + + /// + /// Constructor. Loads data from an entity table buffer reader. + /// + public VimEntityTableData( + BFastBufferReader entityTableBufferReader, + bool schemaOnly, + EntityTableColumnFilter entityTableColumnFilter = null) + { + Name = entityTableBufferReader.Name; + + foreach (var colBr in entityTableBufferReader.Seek().GetBFastBufferReaders()) + { + var columnName = colBr.Name; + + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(columnName, out var columnTypePrefix)) + continue; + + if (entityTableColumnFilter != null && !entityTableColumnFilter(Name, columnName)) + continue; + + switch (columnTypePrefix) + { + case VimEntityTableColumnName.IndexColumnNameTypePrefix: + { + IndexColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + case VimEntityTableColumnName.StringColumnNameTypePrefix: + { + StringColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + case VimEntityTableColumnName.IntColumnNameTypePrefix: + { + DataColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + case VimEntityTableColumnName.LongColumnNameTypePrefix: + { + DataColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + case VimEntityTableColumnName.DoubleColumnNameTypePrefix: + { + DataColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + case VimEntityTableColumnName.FloatColumnNameTypePrefix: + { + DataColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + case VimEntityTableColumnName.ByteColumnNameTypePrefix: + { + DataColumns.Add(ReadEntityTableColumn(colBr, schemaOnly)); + break; + } + default: + // For flexibility, we ignore the columns which do not contain a recognized prefix. + break; + } + } + } + + /// + /// Returns a NamedBuffer representing a entity table column. + /// If schemaOnly is enabled, the column is returned without any of its contained data; + /// this is useful for rapidly querying the schema of the table. + /// + private static NamedBuffer ReadEntityTableColumn( + BFastBufferReader columnBufferReader, bool schemaOnly) where T : unmanaged + { + var (name, size) = columnBufferReader; + + if (schemaOnly) + return new Buffer(Array.Empty()).ToNamedBuffer(name); + + return columnBufferReader + .Seek() + .ReadBufferFromNumberOfBytes(size) + .ToNamedBuffer(name); + } + + /// + /// Returns all the columns as an array of named buffers. + /// + public INamedBuffer[] GetColumns() + => DataColumns.Concat(IndexColumns).Concat(StringColumns).ToArray(); + + /// + /// Returns the column names contained in the entity table. + /// + public IEnumerable ColumnNames + => IndexColumns.Select(c => c.Name) + .Concat(StringColumns.Select(c => c.Name)) + .Concat(DataColumns.Select(c => c.Name)); + + /// + /// Causes an assertion error in debug mode if the number of rows is not consistent among the columns. + /// + public INamedBuffer[] AssertColumnRowsAreAligned() + => AssertColumnRowsAreAligned(GetColumns()); + + /// + /// Causes an assertion error in debug mode if the number of rows is not consistent among the columns. + /// + public static INamedBuffer[] AssertColumnRowsAreAligned(INamedBuffer[] columns) + { + var numRows = columns.FirstOrDefault()?.NumElements() ?? 0; + + foreach (var column in columns) + { + var columnRows = column.NumElements(); + if (columnRows == numRows) + continue; + + var msg = $"Column '{column.Name}' has {columnRows} rows which does not match the first column's {numRows} rows"; + Debug.Fail(msg); + } + + return columns; + } + + /// + /// Returns the number of rows in the entity table. + /// + public int GetRowCount() + => AssertColumnRowsAreAligned().FirstOrDefault()?.NumElements() ?? 0; + + /// + /// Enumerates the VimEntityTables contained in the given VIM file. + /// + public static IEnumerable EnumerateEntityTables( + FileInfo vimFileInfo, + bool schemaOnly, + EntityTableFilter entityTableNameFilter = null, + EntityTableColumnFilter entityTableColumnFilter = null) + { + using (var fileStream = vimFileInfo.OpenRead()) + { + foreach (var entityTable in EnumerateEntityTables(fileStream, schemaOnly, entityTableNameFilter, entityTableColumnFilter)) + { + yield return entityTable; + } + } + } + + /// + /// Enumerates the VimEntityTables contained in the given VIM stream. + /// + public static IEnumerable EnumerateEntityTables( + Stream vimStream, + bool schemaOnly, + EntityTableFilter entityTableNameFilter = null, + EntityTableColumnFilter entityTableColumnFilter = null) + { + vimStream.ThrowIfNotSeekable("Could not enumerate entity tables."); + + var entitiesBufferReader = vimStream.GetBFastBufferReader(VimBufferNames.Entities); + if (entitiesBufferReader == null) + yield break; + + foreach (var entityTable in EnumerateEntityTables(entitiesBufferReader, schemaOnly, entityTableNameFilter, entityTableColumnFilter)) + { + yield return entityTable; + } + } + + /// + /// Enumerates the VimEntityTables contained in the given buffer. + /// + public static IEnumerable EnumerateEntityTables( + BFastBufferReader entitiesBufferReader, + bool schemaOnly, + EntityTableFilter entityTableNameFilter = null, + EntityTableColumnFilter entityTableColumnFilter = null) + { + var entityTableBufferReaders = entitiesBufferReader.Seek() + .GetBFastBufferReaders(br => entityTableNameFilter?.Invoke(br.Name) ?? true); + + foreach (var entityTableBufferReader in entityTableBufferReaders) + { + yield return new VimEntityTableData(entityTableBufferReader, schemaOnly, entityTableColumnFilter); + } + } + + /// + /// Returns true along with the buffer, type prefix, and column type based on the given column field name, if it matches + /// any of the columns in the data. + /// + public bool TryGetColumnByFieldName( + string columnFieldName, + out INamedBuffer buffer, + out string typePrefix, + out VimEntityTableColumnType columnType) + { + buffer = null; + columnType = VimEntityTableColumnType.IndexColumn; + typePrefix = null; + + foreach (var column in GetColumns()) + { + if (!VimEntityTableColumnName.TryParseVimEntityTableColumnName(column.Name, out var components)) + continue; + + if (components.FieldName != columnFieldName) + continue; + + columnType = components.ColumnType; + typePrefix = components.TypePrefix; + buffer = column; + + return true; + } + + return false; + } + + public static VimEntityTableData Concat( + VimEntityTableData thisTable, + VimEntityTableData otherTable) + { + var concatenated = new VimEntityTableData + { + Name = thisTable.Name, + IndexColumns = VimEntityTableColumnActions.ConcatIntColumns( + thisTable.IndexColumns, otherTable.IndexColumns), + StringColumns = VimEntityTableColumnActions.ConcatIntColumns( + thisTable.StringColumns, otherTable.StringColumns), + DataColumns = VimEntityTableColumnActions.ConcatDataColumns( + thisTable.DataColumns, otherTable.DataColumns), + }; + + concatenated.AssertColumnRowsAreAligned(); + + return concatenated; + } + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimConstants.cs b/src/cs/vim/Vim.Format.Core/VimEntityTableNames.cs similarity index 59% rename from src/cs/vim/Vim.Format.Core/VimConstants.cs rename to src/cs/vim/Vim.Format.Core/VimEntityTableNames.cs index 72867a68..225c818d 100644 --- a/src/cs/vim/Vim.Format.Core/VimConstants.cs +++ b/src/cs/vim/Vim.Format.Core/VimEntityTableNames.cs @@ -1,20 +1,11 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace Vim.Format { - public static class BufferNames - { - public const string Header = "header"; - public const string Assets = "assets"; - public const string Entities = "entities"; - public const string Strings = "strings"; - public const string Geometry = "geometry"; - } - - public static class TableNames + public static class VimEntityTableNames { public const string Geometry = "Vim.Geometry"; - public const string Node = "Vim.Node"; + public const string Node = "Vim.Node"; public const string Asset = "Vim.Asset"; public const string Shape = "Vim.Shape"; public const string ShapeCollection = "Vim.ShapeCollection"; @@ -68,54 +59,17 @@ public static class TableNames public const string ViewInViewSheet = "Vim.ViewInViewSheet"; public const string Site = "Vim.Site"; public const string Building = "Vim.Building"; - } - - public static class VimConstants - { - public const string MainPng = "main.png"; - - public const string IndexColumnNameTypePrefix = "index:"; - public const string StringColumnNameTypePrefix = "string:"; - - public const string IntColumnNameTypePrefix = "int:"; - public const string UintColumnNameTypePrefix = "uint:"; // unused for now - public const string LongColumnNameTypePrefix = "long:"; - public const string UlongColumnNameTypePrefix = "ulong:"; // unused for now - public const string ByteColumnNameTypePrefix = "byte:"; - public const string UbyteColumNameTypePrefix = "ubyte:"; // unused for now - public const string FloatColumnNameTypePrefix = "float:"; - public const string DoubleColumnNameTypePrefix = "double:"; - - public const int NoEntityRelation = -1; - public const long SyntheticElementId = -1; - public const long SyntheticCategoryId = -1; - public const string SystemFamilyTypeElementType = "System Family Type"; - public const string SystemFamilyElementType = "System Family"; - public const string UnassignedSystem = "Unassigned System"; - public const string BimDocumentParameterHolderElementType = "BimDocument Parameter Holder"; - public const string BuildingParameterHolderElementType = "Building Parameter Holder"; - public const string SiteParameterHolderElementType = "Site Parameter Holder"; public static HashSet ComputedTableNames = new HashSet { - TableNames.Geometry + Geometry }; public static HashSet NonBimNames = new HashSet { - TableNames.Geometry, - TableNames.Asset, - TableNames.Material, + Geometry, + Asset, + Material, }; - - public static class DisciplineNames - { - public const string Mechanical = nameof(Mechanical); - public const string Architecture = nameof(Architecture); - public const string Generic = nameof(Generic); - public const string Electrical = nameof(Electrical); - public const string Plumbing = nameof(Plumbing); - public const string Structural = nameof(Structural); - } } } diff --git a/src/cs/vim/Vim.Format.Core/ErrorCode.cs b/src/cs/vim/Vim.Format.Core/VimErrorCode.cs similarity index 78% rename from src/cs/vim/Vim.Format.Core/ErrorCode.cs rename to src/cs/vim/Vim.Format.Core/VimErrorCode.cs index 9d3a33af..af81bfdf 100644 --- a/src/cs/vim/Vim.Format.Core/ErrorCode.cs +++ b/src/cs/vim/Vim.Format.Core/VimErrorCode.cs @@ -2,7 +2,7 @@ namespace Vim.Format { - public enum ErrorCode + public enum VimErrorCode { VimDataFormatError = unchecked((int)(HResult.CustomFailureMask | 0x00003000)), // starting error code range at 0xA0003000. VimHeaderTokenizationError, @@ -18,7 +18,7 @@ public enum ErrorCode public class VimHeaderTokenizationException : HResultException { public VimHeaderTokenizationException(string line, int numTokens) - : base((int) ErrorCode.VimHeaderTokenizationError, + : base((int) VimErrorCode.VimHeaderTokenizationError, $"Unexpected number of tokens: {numTokens} ({line})") { } } @@ -26,14 +26,14 @@ public VimHeaderTokenizationException(string line, int numTokens) public class VimHeaderDuplicateFieldException : HResultException { public VimHeaderDuplicateFieldException(string fieldName) - : base((int) ErrorCode.VimHeaderDuplicateFieldError, fieldName) + : base((int) VimErrorCode.VimHeaderDuplicateFieldError, fieldName) { } } public class VimHeaderFieldParsingException : HResultException { public VimHeaderFieldParsingException(string fieldName, string fieldValue) - : base((int) ErrorCode.VimHeaderFieldParsingError, + : base((int) VimErrorCode.VimHeaderFieldParsingError, $"Could not parse field {fieldName} with value {fieldValue}") { } } @@ -41,7 +41,7 @@ public VimHeaderFieldParsingException(string fieldName, string fieldValue) public class VimHeaderRequiredFieldsNotFoundException : HResultException { public VimHeaderRequiredFieldsNotFoundException(params string[] fieldNames) - : base((int) ErrorCode.VimHeaderRequiredFieldsNotFoundError, string.Join(", ", fieldNames)) + : base((int) VimErrorCode.VimHeaderRequiredFieldsNotFoundError, string.Join(", ", fieldNames)) { } } } diff --git a/src/cs/vim/Vim.Format.Core/VimGeometryData.cs b/src/cs/vim/Vim.Format.Core/VimGeometryData.cs new file mode 100644 index 00000000..0a942a8f --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimGeometryData.cs @@ -0,0 +1,386 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Vim.BFast; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + /// + /// Represents the geometric elements which compose a building design. + /// + public class VimGeometryData + { + /// + /// A header buffer which identifies that this collection of buffers is a VimGeometry. Preserved for continuity. + /// + public VimGeometryDataHeader Header { get; } = new VimGeometryDataHeader(); + public const string HeaderBufferName = "meta"; + + /// + /// An array of 32-bit single-precision floating point values, arranged in slices of 3 to represent the (X, Y, Z) vertices of all the meshes in the VIM. We refer to this as the "vertex buffer". + /// + public Vector3[] Vertices { get; } = Array.Empty(); + public const string VerticesBufferName = "g3d:vertex:position:0:float32:3"; + public const int VerticesBufferDataItemSizeInBytes = 4 * 3; // float32 = 4 bytes | 3 = arity -> 4 * 3 = 12 bytes per vertex + + /// + /// An array of 32-bit integers representing the combined index buffer of all the meshes in the VIM. The values in this index buffer are relative to the beginning of the vertex buffer. Meshes in a VIM are composed of triangular faces, whose corners are defined by 3 indices. + /// + public int[] Indices { get; } = Array.Empty(); + public const string IndicesBufferName = "g3d:corner:index:0:int32:1"; + public const int IndicesBufferDataItemSizeInBytes = 4 * 1; // int32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per index + + /// + /// An array of 32-bit integers representing the index offset of the index buffer of a given submesh. + /// + public int[] SubmeshIndexOffsets { get; } = Array.Empty(); + public const string SubmeshIndexOffsetsBufferName = "g3d:submesh:indexoffset:0:int32:1"; + public const int SubmeshIndexOffsetsDataItemSizeInBytes = 4 * 1; // int32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per submesh index offset + + /// + /// An array of 32-bit integers representing the index of the material associated with a given submesh. + /// + public int[] SubmeshMaterials { get; } = Array.Empty(); + public const string SubmeshMaterialsBufferName = "g3d:submesh:material:0:int32:1"; + public const int SubmeshMaterialsDataItemSizeInBytes = 4 * 1; // int32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per submesh material index + + /// + /// An array of 32-bit integers representing the index offset of a submesh in a given mesh. + /// + public int[] MeshSubmeshOffsets { get; } = Array.Empty(); + public const string MeshSubmeshOffsetsBufferName = "g3d:mesh:submeshoffset:0:int32:1"; + public const int MeshSubmeshOffsetsDataItemSizeInBytes = 4 * 1; // int32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per mesh submesh offset + + /// + /// An array of 32-bit single-precision floating point values in the domain [0.0f, 1.0f], arranged in slices of 4 to represent the (R, G, B, A) diffuse color of a given material. + /// + public Vector4[] MaterialColors { get; } = Array.Empty(); + public const string MaterialColorsBufferName = "g3d:material:color:0:float32:4"; + public const int MaterialColorsDataItemSizeInBytes = 4 * 4; // float32 = 4 bytes | 4 = arity -> 4 * 4 = 16 bytes per material color + + /// + /// An array of 32-bit single-precision floating point values in the domain [0.0f, 1.0f] representing the glossiness of a given material. + /// + public float[] MaterialGlossiness { get; } = Array.Empty(); + public const string MaterialGlossinessBufferName = "g3d:material:glossiness:0:float32:1"; + public const int MaterialGlossinessDataItemSizeInBytes = 4 * 1; // float32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per material glossiness + + /// + /// An array of 32-bit single-precision floating point values in the domain [0.0f, 1.0f] representing the smoothness of a given material. + /// + public float[] MaterialSmoothness { get; } = Array.Empty(); + public const string MaterialSmoothnessBufferName = "g3d:material:smoothness:0:float32:1"; + public const int MaterialSmoothnessDataItemSizeInBytes = 4 * 1; // float32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per material smoothness + + /// + /// An array of 32-bit single-precision floating point values, arranged in slices of 16 to represent the 4x4 row-major transformation matrix associated with a given instance. + /// + public Matrix4x4[] InstanceTransforms { get; } = Array.Empty(); + public const string InstanceTransformsBufferName = "g3d:instance:transform:0:float32:16"; + public const int InstanceTransformsDataItemSizeInBytes = 4 * 16; // float32 = 4 bytes | 16 = arity -> 4 * 16 = 64 bytes per instance transform + + /// + /// (Optional) An array of 16-bit unsigned integers representing the flags of a given instance. The first bit of each flag designates whether the instance should be initially hidden (1) or not (0) when rendered. + /// + public ushort[] InstanceFlags { get; } = Array.Empty(); + public const string InstanceFlagsBufferName = "g3d:instance:flags:0:uint16:1"; + public const int InstanceFlagsDataItemSizeInBytes = 2 * 1; // uint16 = 2 bytes | 1 = arity -> 2 * 1 = 2 bytes per instance flag + + /// + /// An array of 32-bit integers representing the index of the parent instance associated with a given instance. + /// + public int[] InstanceParents { get; } = Array.Empty(); + public const string InstanceParentsBufferName = "g3d:instance:parent:0:int32:1"; + public const int InstanceParentsDataItemSizeInBytes = 4 * 1; // int32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per instance parent index + + /// + /// An array of 32-bit integers representing the index of a mesh associated with a given instance. + /// + public int[] InstanceMeshes { get; } = Array.Empty(); + public const string InstanceMeshesBufferName = "g3d:instance:mesh:0:int32:1"; + public const int InstanceMeshesDataItemSizeInBytes = 4 * 1; // int32 = 4 bytes | 1 = arity -> 4 * 1 = 4 bytes per instance mesh index + + public int InstanceCount => InstanceTransforms?.Length ?? 0; + public int MeshCount => MeshSubmeshOffsets?.Length ?? 0; + public int SubmeshCount => SubmeshIndexOffsets?.Length ?? 0; + public int IndexCount => Indices?.Length ?? 0; + public int VertexCount => Vertices?.Length ?? 0; + public int MaterialCount => MaterialColors?.Length ?? 0; + + public int[] MeshIndexOffsets { get; } = Array.Empty(); + public int[] MeshSubmeshCount { get; } = Array.Empty(); + public int[] MeshIndexCounts { get; } = Array.Empty(); + public int[] MeshVertexOffsets { get; } = Array.Empty(); + public int[] MeshVertexCounts { get; } = Array.Empty(); + public int[] SubmeshIndexCount { get; } = Array.Empty(); + + /// + /// Default empty constructor. + /// + public VimGeometryData() + { } + + /// + /// Reads the stream and returns a VimGeometry instance. + /// + public VimGeometryData(Stream stream) + { + stream.ThrowIfNotSeekable("Could not read geometry"); + + foreach (var bufferReader in stream.GetBFastBufferReaders()) + { + var name = bufferReader.Name; + var bufferSizeInBytes = bufferReader.Size; + bufferReader.Seek(); + + switch (name) + { + case HeaderBufferName: + Header = VimGeometryDataHeader.Read(stream, bufferSizeInBytes); + break; + case VerticesBufferName: + Vertices = ReadDataItems(stream, bufferSizeInBytes, VerticesBufferDataItemSizeInBytes); + break; + case IndicesBufferName: + Indices = ReadDataItems(stream, bufferSizeInBytes, IndicesBufferDataItemSizeInBytes); + break; + case SubmeshIndexOffsetsBufferName: + SubmeshIndexOffsets = ReadDataItems(stream, bufferSizeInBytes, SubmeshIndexOffsetsDataItemSizeInBytes); + break; + case SubmeshMaterialsBufferName: + SubmeshMaterials = ReadDataItems(stream, bufferSizeInBytes, SubmeshMaterialsDataItemSizeInBytes); + break; + case MeshSubmeshOffsetsBufferName: + MeshSubmeshOffsets = ReadDataItems(stream, bufferSizeInBytes, MeshSubmeshOffsetsDataItemSizeInBytes); + break; + case MaterialColorsBufferName: + MaterialColors = ReadDataItems(stream, bufferSizeInBytes, MaterialColorsDataItemSizeInBytes); + break; + case MaterialGlossinessBufferName: + MaterialGlossiness = ReadDataItems(stream, bufferSizeInBytes, MaterialGlossinessDataItemSizeInBytes); + break; + case MaterialSmoothnessBufferName: + MaterialSmoothness = ReadDataItems(stream, bufferSizeInBytes, MaterialSmoothnessDataItemSizeInBytes); + break; + case InstanceTransformsBufferName: + InstanceTransforms = ReadDataItems(stream, bufferSizeInBytes, InstanceTransformsDataItemSizeInBytes); + break; + case InstanceFlagsBufferName: + InstanceFlags = ReadDataItems(stream, bufferSizeInBytes, InstanceFlagsDataItemSizeInBytes); + break; + case InstanceParentsBufferName: + InstanceParents = ReadDataItems(stream, bufferSizeInBytes, InstanceParentsDataItemSizeInBytes); + break; + case InstanceMeshesBufferName: + InstanceMeshes = ReadDataItems(stream, bufferSizeInBytes, InstanceMeshesDataItemSizeInBytes); + break; + } + } + + // Synchronize the optional instance flags + + if ((InstanceFlags?.Length ?? 0) == 0) + { + InstanceFlags = Enumerable.Repeat((ushort)0, InstanceCount).ToArray(); + } + + // Compute offsets + + if (MeshCount > 0) + { + if (MeshSubmeshOffsets != null) + { + MeshIndexOffsets = MeshSubmeshOffsets.Select(submesh => SubmeshIndexOffsets[submesh]).ToArray(); + MeshSubmeshCount = GetSubArrayCounts(MeshSubmeshOffsets.Length, MeshSubmeshOffsets, SubmeshCount); + } + + if (MeshIndexOffsets.Length != 0) + { + MeshIndexCounts = GetSubArrayCounts(MeshCount, MeshIndexOffsets, IndexCount); + MeshVertexOffsets = MeshIndexOffsets.Zip(MeshIndexCounts, + (start, count) => GetMinValue(Indices, start, count)) + .ToArray(); + } + + if (MeshVertexOffsets.Length != 0) + { + MeshVertexCounts = GetSubArrayCounts(MeshCount, MeshVertexOffsets, VertexCount); + } + } + + if (SubmeshIndexOffsets != null) + { + SubmeshIndexCount = GetSubArrayCounts(SubmeshIndexOffsets.Length, SubmeshIndexOffsets, IndexCount); + } + } + + private static T[] ReadDataItems(Stream stream, long bufferSizeInBytes, int dataItemSizeInBytes) where T : unmanaged + { + if (bufferSizeInBytes % dataItemSizeInBytes != 0) + throw new Exception($"The number of bytes in the buffer {bufferSizeInBytes} does not divide by the item size in bytes {dataItemSizeInBytes}"); + + var itemCount = bufferSizeInBytes / dataItemSizeInBytes; + + if (itemCount > int.MaxValue) + throw new Exception($"Trying to read {itemCount} which is more than the maximum number of items in an array."); + + var data = stream.ReadArray((int)itemCount); + + return data; + } + + private static int GetMinValue(int[] array, int startIndex, int count) + { + var min = int.MaxValue; + for (var i = startIndex; i < startIndex + count; ++i) + { + var value = array[i]; + if (value < min) min = value; + } + return min; + } + + private int[] GetSubArrayCounts(int numItems, int[] offsets, int totalCount) + { + var counts = new int[numItems]; + for (var i = 0; i < numItems; ++i) + { + counts[i] = i < (numItems - 1) + ? offsets[i + 1] - offsets[i] + : totalCount - offsets[i]; + } + return counts; + } + + public bool TryGetVimMeshView(int meshIndex, out VimMeshView vimMeshView) + { + vimMeshView = default; + + if (meshIndex < 0 || meshIndex >= MeshCount) + return false; + + vimMeshView = new VimMeshView(this, meshIndex); + + return true; + } + + public VimMeshView? GetMeshView(int meshIndex) + { + if (meshIndex < 0 || meshIndex >= MeshCount) + return null; + + return new VimMeshView(this, meshIndex); + } + + public IEnumerable> GroupMeshViews(IEnumerable meshIndices) + { + return meshIndices + .AsParallel() + .Select(i => GetMeshView(i)) + .Where(mv => mv != null) + .OfType() + .GroupBy(mv => new VimMeshComparer(mv)) + .AsSequential(); + } + + public static Vector3[] GetTransformedVertices(Vector3[] sourceVertices, Matrix4x4 transform) + { + var transformedVertices = new Vector3[sourceVertices.Length]; + for (var i = 0; i < sourceVertices.Length; ++i) + { + transformedVertices[i] = sourceVertices[i].Transform(transform); + } + return transformedVertices; + } + + public bool TryGetTransformedMesh(int instanceIndex, int meshIndex, out VimMeshData vimMeshData) + { + vimMeshData = default; + + if (!TryGetVimMeshView(meshIndex, out var vimMeshView)) + return false; + + var transform = InstanceTransforms.ElementAtOrDefault(instanceIndex, Matrix4x4.Identity); + + var sourceVertices = vimMeshView.GetVertices(); + var transformedVertices = GetTransformedVertices(sourceVertices, transform); + + vimMeshData = new VimMeshData(transformedVertices, vimMeshView.GetIndices()); + return true; + } + + public AABox GetWorldSpaceBoundingBox() + { + // Iterate over each instance and get its mesh. + var result = AABox.Empty; + for (var i = 0; i < InstanceCount; ++i) + { + var instanceMeshIndex = InstanceMeshes[i]; + if (!TryGetVimMeshView(instanceMeshIndex, out var vimMeshView)) + continue; + + var instanceTransform = InstanceTransforms[i]; + var worldSpaceVertices = GetTransformedVertices(vimMeshView.GetVertices(), instanceTransform); + var aabbInstance = AABox.Create(worldSpaceVertices); + result = result.Merge(aabbInstance); + } + return result; + } + + public IEnumerable GetMeshViews() + { + for (var i = 0; i < MeshCount; ++i) + { + yield return new VimMeshView(this, i); + } + } + + public int GetItemCountByBufferName(string bufferName) + { + switch (bufferName) + { + case VerticesBufferName: + return Vertices.Length; + + case IndicesBufferName: + return Indices.Length; + + case SubmeshIndexOffsetsBufferName: + return SubmeshIndexOffsets.Length; + + case SubmeshMaterialsBufferName: + return SubmeshMaterials.Length; + + case MeshSubmeshOffsetsBufferName: + return MeshSubmeshOffsets.Length; + + case MaterialColorsBufferName: + return MaterialColors.Length; + + case MaterialGlossinessBufferName: + return MaterialGlossiness.Length; + + case MaterialSmoothnessBufferName: + return MaterialSmoothness.Length; + + case InstanceTransformsBufferName: + return InstanceTransforms.Length; + + case InstanceFlagsBufferName: + return InstanceFlags.Length; + + case InstanceParentsBufferName: + return InstanceParents.Length; + + case InstanceMeshesBufferName: + return InstanceMeshes.Length; + + default: + return 0; + } + } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimGeometryDataHeader.cs b/src/cs/vim/Vim.Format.Core/VimGeometryDataHeader.cs new file mode 100644 index 00000000..3a0a92d0 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimGeometryDataHeader.cs @@ -0,0 +1,122 @@ +using System; +using System.IO; +using Vim.BFast; +using Vim.Util; + +namespace Vim.Format +{ + public class VimGeometryDataHeader + { + public static class Constants + { + public const byte MagicA = 0x63; // MagicA + MagicB -> 63D0 (for continuity with the original G3D file format, VIM geometry maintains these magic numbers) + public const byte MagicB = 0xD0; + + //------------------------------------------------------------------------------------ + // HISTORICAL NOTES ABOUT THE FIELDS NOW KNOWN AS 'FieldA' and 'FieldB' + // + // Martin Ashton, November 8 2025 + // + // First off, the VIM file format's geometry has always been in feet to mirror Autodesk Revit's internal units (which are in feet). + // + // Prior to refactoring this code, the following constants were defined in the G3D header: + // - 'UnitA' + // - 'UnitB' + // + // The intent of 'UnitA' and 'UnitB' was to identify the units of scale of the geometry. In theory, you could combine both bytes to declare + // units like 'm', 'cm', 'in', 'ft', etc (i.e. 'c' + 'm' = 'cm'). + // + // In practice however, 'UnitA' was always hard-coded to 'm' and 'UnitB' was always 0. This oversight was misleading since VIM's geometry is de-facto + // defined in feet ('ft'). Thankfully, 'UnitA' and 'UnitB' were never actually consumed; all readers of VIM's geometry correctly interpreted it in feet. + // + // Now that I'm cleaning things up, I'm going to declare that 'UnitA' and 'UnitB' shall henceforth be known as 'FieldA' and 'FieldB', + // and that 'FieldA' will always be 'm' and that 'FieldB' will always be empty. + // + // Since I'm the only one in here anyway, I'll also add that the 'm' stands for 'meow meow'. There, I said it. No takesie-backsies. + // + public const byte FieldA = (byte)'m'; + public const byte FieldB = 0; + //------------------------------------------------------------------------------------ + public const byte UpAxis = 2; // 2 -> z axis (preserved for continuity) + public const byte ForwardVector = 0; // 0 -> x axis (preserved for continuity) + public const byte Handedness = 0; // 0 -> left handed (preserved for continuity) + public const byte Padding = 0; // has always been 0 + } + + public byte MagicA { get; private set; } + public byte MagicB { get; private set; } + public byte FieldA { get; private set; } + public byte FieldB { get; private set; } + public byte UpAxis { get; private set; } + public byte ForwardVector { get; private set; } + public byte Handedness { get; private set; } + public byte Padding { get; private set; } + + /// + /// Constructor. Creates a default header with correctly populated values. + /// + public VimGeometryDataHeader() + { + MagicA = Constants.MagicA; + MagicB = Constants.MagicB; + FieldA = Constants.FieldA; + FieldB = Constants.FieldB; + UpAxis = Constants.UpAxis; + ForwardVector = Constants.ForwardVector; + Handedness = Constants.Handedness; + Padding = Constants.Padding; + } + + /// + /// Constructor. Loads and validates the byte values to create the header. + /// + public VimGeometryDataHeader(byte[] bytes) + { + if (bytes.Length < 7) + throw new ArgumentException($"Failed to read VIM Geometry Header: {nameof(bytes)} argument must have length 7 or greater but received length {bytes.Length}"); + + MagicA = bytes[0]; + MagicB = bytes[1]; + FieldA = bytes[2]; + FieldB = bytes[3]; + UpAxis = bytes[4]; + ForwardVector = bytes[5]; + Handedness = bytes[6]; + Padding = Constants.Padding; + + Validate(); + } + + public static VimGeometryDataHeader Read(Stream stream, long size) + { + stream.ThrowIfNotSeekable("Failed to read VIM Geometry Header"); + + var bytes = stream.ReadArray((int)size); + + return new VimGeometryDataHeader(bytes); + } + + public byte[] ToBytes() + => new[] { + MagicA, + MagicB, + FieldA, + FieldB, + UpAxis, + ForwardVector, + Handedness, + Padding, + }; + + public void Validate() + { + if (MagicA != Constants.MagicA) throw new Exception($"First magic number must be {Constants.MagicA} and not {MagicA}"); + if (MagicB != Constants.MagicB) throw new Exception($"Second magic number must be {Constants.MagicB} and not {MagicB}"); + if (FieldA != Constants.FieldA) throw new Exception($"FieldA must be {Constants.FieldA} and not {FieldA}"); + if (FieldB != Constants.FieldB) throw new Exception($"FieldB must be {Constants.FieldB} and not {FieldB}"); + if (UpAxis != Constants.UpAxis) throw new Exception($"Up axis must be {Constants.UpAxis} and not {UpAxis}"); + if (ForwardVector != Constants.ForwardVector) throw new Exception($"Forward vector must be {Constants.ForwardVector} and not {ForwardVector}"); + if (Handedness != Constants.Handedness) throw new Exception($"Handedness must be {Constants.Handedness} and not {Handedness}"); + } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimGeometryDataWriter.cs b/src/cs/vim/Vim.Format.Core/VimGeometryDataWriter.cs new file mode 100644 index 00000000..d09b1afe --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimGeometryDataWriter.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Vim.BFast; + +namespace Vim.Format +{ + /// + /// A helper class which writes large collections of meshes and instances efficiently into a serializable stream. + /// + public class VimGeometryDataWriter : IBFastComponent + { + /// + /// The deferred serialization function. + /// + private readonly Action _writeAction; + + /// + /// The number of bytes which will be written into the buffer. + /// + private readonly long _bufferSizeInBytes; + + /// + /// Constructor + /// + public VimGeometryDataWriter( + List meshes, + List instances, + List materials) + { + //------------------------------------------- + // Calculate buffer sizes + //------------------------------------------- + + var totalSubmeshCount = meshes.Select(s => s.SubmeshesIndexOffset.Count).Sum(); + + // Compute the Vertex offsets and index offsets + var meshVertexOffsets = new int[meshes.Count]; + var meshIndexOffsets = new int[meshes.Count]; + var submeshIndexOffsets = new int[totalSubmeshCount]; + var meshSubmeshOffsets = new int[meshes.Count]; + + var meshCount = meshes.Count; + + for (var i = 1; i < meshCount; ++i) + { + meshVertexOffsets[i] = meshVertexOffsets[i - 1] + meshes[i - 1].Vertices.Count; + meshIndexOffsets[i] = meshIndexOffsets[i - 1] + meshes[i - 1].Indices.Count; + meshSubmeshOffsets[i] = meshSubmeshOffsets[i - 1] + meshes[i - 1].SubmeshesIndexOffset.Count; + } + + var subIndex = 0; + var previousIndexCount = 0; + foreach(var geo in meshes) + { + foreach(var sub in geo.SubmeshesIndexOffset) + { + submeshIndexOffsets[subIndex++] = sub + previousIndexCount; + } + previousIndexCount += geo.Indices.Count; + } + + var submeshCount = meshes.Select(s => s.SubmeshesIndexOffset.Count).Sum(); + + var totalVertices = meshCount == 0 ? 0 : meshVertexOffsets[meshCount - 1] + meshes[meshCount - 1].Vertices.Count; + var totalIndices = meshCount == 0 ? 0 : meshIndexOffsets[meshCount - 1] + meshes[meshCount - 1].Indices.Count; + long totalFaces = totalIndices / 3; + + var instanceCount = instances.Count; + var materialCount = materials.Count; + + //------------------------------------------- + // Prepare buffer info + //------------------------------------------- + + var vimGeometryHeaderBuffer = new VimGeometryDataHeader().ToBytes().ToNamedBuffer(VimGeometryData.HeaderBufferName); + + (string BufferName, long BufferSizeInBytes) GetWritableBufferInfo(string bufferName, int dataItemSizeInBytes, int itemCount) + => (bufferName, dataItemSizeInBytes * itemCount); + + var writableBufferInfos = new List<(string BufferName, long BufferSizeInBytes)>() + { + (vimGeometryHeaderBuffer.Name, vimGeometryHeaderBuffer.NumBytes()), + GetWritableBufferInfo(VimGeometryData.VerticesBufferName, VimGeometryData.VerticesBufferDataItemSizeInBytes, totalVertices), + GetWritableBufferInfo(VimGeometryData.IndicesBufferName, VimGeometryData.IndicesBufferDataItemSizeInBytes, totalIndices), + + GetWritableBufferInfo(VimGeometryData.MeshSubmeshOffsetsBufferName, VimGeometryData.MeshSubmeshOffsetsDataItemSizeInBytes, meshCount), + + GetWritableBufferInfo(VimGeometryData.SubmeshIndexOffsetsBufferName, VimGeometryData.SubmeshIndexOffsetsDataItemSizeInBytes, submeshCount), + GetWritableBufferInfo(VimGeometryData.SubmeshMaterialsBufferName, VimGeometryData.SubmeshMaterialsDataItemSizeInBytes, submeshCount), + + GetWritableBufferInfo(VimGeometryData.InstanceTransformsBufferName, VimGeometryData.InstanceTransformsDataItemSizeInBytes, instanceCount), + GetWritableBufferInfo(VimGeometryData.InstanceParentsBufferName, VimGeometryData.InstanceParentsDataItemSizeInBytes, instanceCount), + GetWritableBufferInfo(VimGeometryData.InstanceMeshesBufferName, VimGeometryData.InstanceMeshesDataItemSizeInBytes, instanceCount), + GetWritableBufferInfo(VimGeometryData.InstanceFlagsBufferName, VimGeometryData.InstanceFlagsDataItemSizeInBytes, instanceCount), + + GetWritableBufferInfo(VimGeometryData.MaterialColorsBufferName, VimGeometryData.MaterialColorsDataItemSizeInBytes, materialCount), + GetWritableBufferInfo(VimGeometryData.MaterialGlossinessBufferName, VimGeometryData.MaterialGlossinessDataItemSizeInBytes, materialCount), + GetWritableBufferInfo(VimGeometryData.MaterialSmoothnessBufferName, VimGeometryData.MaterialSmoothnessDataItemSizeInBytes, materialCount), + }; + + var bufferNames = writableBufferInfos.Select(w => w.BufferName).ToArray(); + var bufferSizesInBytes = writableBufferInfos.Select(w => w.BufferSizeInBytes).ToArray(); + var bfastHeader = BFast.BFast.CreateBFastHeader(bufferSizesInBytes, bufferNames); + + //------------------------------------------- + // Store properties + //------------------------------------------- + _bufferSizeInBytes = BFast.BFast.ComputeNextAlignment(bfastHeader.Preamble.DataEnd); + _writeAction = stream => + { + stream.WriteBFastHeader(bfastHeader); + + stream.WriteBFastBody(bfastHeader, bufferNames, bufferSizesInBytes, (_stream, index, bufferName, size) => + { + switch (bufferName) + { + case VimGeometryData.HeaderBufferName: + _stream.Write(vimGeometryHeaderBuffer); + break; + + // Vertices + case VimGeometryData.VerticesBufferName: + meshes.ForEach(g => stream.Write(g.Vertices.ToArray())); + break; + + // Indices + case VimGeometryData.IndicesBufferName: + for (var i = 0; i < meshes.Count; ++i) + { + var g = meshes[i]; + var offset = meshVertexOffsets[i]; + stream.Write(g.Indices.Select(idx => idx + offset).ToArray()); + } + break; + + // Meshes + case VimGeometryData.MeshSubmeshOffsetsBufferName: + stream.Write(meshSubmeshOffsets); + break; + + // Submeshes + case VimGeometryData.SubmeshIndexOffsetsBufferName: + stream.Write(submeshIndexOffsets); + break; + case VimGeometryData.SubmeshMaterialsBufferName: + stream.Write(meshes.SelectMany(s => s.SubmeshMaterials).ToArray()); + break; + + // Instances + case VimGeometryData.InstanceMeshesBufferName: + stream.Write(instances.Select(i => i.MeshIndex).ToArray()); + break; + case VimGeometryData.InstanceTransformsBufferName: + stream.Write(instances.Select(i => i.Transform).ToArray()); + break; + case VimGeometryData.InstanceParentsBufferName: + stream.Write(instances.Select(i => i.ParentIndex).ToArray()); + break; + case VimGeometryData.InstanceFlagsBufferName: + stream.Write(instances.Select(i => (ushort)i.InstanceFlags).ToArray()); + break; + + // Materials + case VimGeometryData.MaterialColorsBufferName: + stream.Write(materials.Select(i => i.Color).ToArray()); + break; + case VimGeometryData.MaterialGlossinessBufferName: + stream.Write(materials.Select(i => i.Glossiness).ToArray()); + break; + case VimGeometryData.MaterialSmoothnessBufferName: + stream.Write(materials.Select(i => i.Smoothness).ToArray()); + break; + + default: + Debug.Fail($"Not a recognized geometry buffer: {bufferName}"); + break; + } + return size; + }); + }; + } + + public long GetSize() => _bufferSizeInBytes; + + public void Write(Stream stream) => _writeAction(stream); + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/SerializableHeader.cs b/src/cs/vim/Vim.Format.Core/VimHeader.cs similarity index 92% rename from src/cs/vim/Vim.Format.Core/SerializableHeader.cs rename to src/cs/vim/Vim.Format.Core/VimHeader.cs index c1c3a97c..dcde6833 100644 --- a/src/cs/vim/Vim.Format.Core/SerializableHeader.cs +++ b/src/cs/vim/Vim.Format.Core/VimHeader.cs @@ -1,15 +1,16 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using Vim.BFast; using Vim.Util; namespace Vim.Format { - public class SerializableHeader + public class VimHeader { public static readonly SerializableVersion CurrentVimFormatVersion = VimFormatVersion.Current; - + public const string FormatVersionField = "vim"; public const string IdField = "id"; public const string RevisionField = "revision"; @@ -45,7 +46,7 @@ public class SerializableHeader /// /// Private constructor /// - private SerializableHeader( + private VimHeader( SerializableVersion fileFormatVersion, Guid id, Guid revision, @@ -82,7 +83,11 @@ private static IReadOnlyDictionary AddOptionalValues( /// /// Constructor used during serialization of a new VIM. /// - public SerializableHeader(string generator, SerializableVersion schema, string versionString, IReadOnlyDictionary values = null) + public VimHeader( + string generator, + SerializableVersion schema, + string versionString, + IReadOnlyDictionary values = null) : this( CurrentVimFormatVersion, Guid.NewGuid(), @@ -93,6 +98,12 @@ public SerializableHeader(string generator, SerializableVersion schema, string v AddOptionalValues(values ?? new Dictionary(), versionString)) { } + /// + /// Default constructor. + /// + public VimHeader() : this("", new SerializableVersion(), "") + { } + /// /// Parses the input. Throws exceptions if the input does not define a correctly formatted header. /// @@ -100,7 +111,7 @@ public SerializableHeader(string generator, SerializableVersion schema, string v /// /// /// - public static SerializableHeader Parse(string input) + public static VimHeader Parse(string input) { var lines = input.Split(EndOfLineChar) .Where(str => !string.IsNullOrEmpty(str)); @@ -119,7 +130,7 @@ public static SerializableHeader Parse(string input) { var tokens = line.Split(Separator); var numTokens = tokens.Length; - + // skip empty lines. if (numTokens == 0) continue; @@ -215,7 +226,7 @@ public static SerializableHeader Parse(string input) if (requiredSet.Count > 0) throw new VimHeaderRequiredFieldsNotFoundException(requiredSet.ToArray()); - return new SerializableHeader( + return new VimHeader( fileFormatVersion, id ?? Guid.Empty, revision ?? Guid.Empty, @@ -247,7 +258,7 @@ public override string ToString() } public override bool Equals(object obj) - => obj is SerializableHeader other && ToString() == other.ToString(); + => obj is VimHeader other && ToString() == other.ToString(); public override int GetHashCode() => ToString().GetHashCode(); @@ -273,5 +284,11 @@ public static string CreateDummyPersistingId() ///
public string PersistingId => CreatePersistingId(Id, Revision); + + /// + /// Returns the serializable buffer representation of this VIM header. + /// + public IBuffer ToBuffer() + => ToString().ToBytesUtf8().ToBuffer(); } } diff --git a/src/cs/vim/Vim.Format.Core/VimInstance.cs b/src/cs/vim/Vim.Format.Core/VimInstance.cs new file mode 100644 index 00000000..b8c3e16c --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimInstance.cs @@ -0,0 +1,28 @@ +using System; +using Vim.Math3d; + +namespace Vim.Format +{ + public class VimInstance + { + public Matrix4x4 Transform; + public int MeshIndex; + public int ParentIndex; + public InstanceFlags InstanceFlags; + } + + [Flags] + public enum InstanceFlags + { + /// + /// Default - no instance options defined. + /// + None = 0, + + /// + /// When enabled, indicates that the renderer (or the consuming application) should hide + /// the instance by default. + /// + Hidden = 1, + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimMaterial.cs b/src/cs/vim/Vim.Format.Core/VimMaterial.cs new file mode 100644 index 00000000..7a6aebc4 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimMaterial.cs @@ -0,0 +1,14 @@ +using Vim.Math3d; + +namespace Vim.Format +{ + public class VimMaterial + { + //RGBA + public Vector4 Color; + public float Glossiness; + public float Smoothness; + + public VimMaterial() {} + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimMeshData.cs b/src/cs/vim/Vim.Format.Core/VimMeshData.cs new file mode 100644 index 00000000..1b7460dc --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimMeshData.cs @@ -0,0 +1,242 @@ +using System; +using System.Linq; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + /// + /// An interface for simple tri-meshes with vertices and indices. + /// + public interface IVimMesh + { + Vector3[] GetVertices(); + int[] GetIndices(); + int FaceCount { get; } + } + + public static class VimMeshExtensions + { + public static AABox GetBoundingBox(this IVimMesh vimMesh) + { + return AABox.Create(vimMesh.GetVertices()); + } + } + + public struct VimMeshData : IVimMesh + { + public readonly Vector3[] Vertices; + public readonly int[] Indices; + public const int IndexCountPerFace = 3; // VimMeshData defines meshes composed of triangles (i.e. 3 vertex indices per face) + public int FaceCount => Indices.Length / IndexCountPerFace; + + /// + /// Constructor. + /// + public VimMeshData(Vector3[] vertices, int[] indices) + { + Vertices = vertices; + Indices = indices; + } + + public Vector3[] GetVertices() => Vertices; + public int[] GetIndices() => Indices; + } + + /// + /// A struct representing a view of triangular mesh data contained in VimGeometryData composed + /// of submeshes each having their own materials. + /// + public struct VimMeshView : IVimMesh + { + public VimGeometryData VimGeometryData { get; } + public int MeshIndex { get; } + public int VertexOffset => VimGeometryData.MeshVertexOffsets[MeshIndex]; + public int VertexCount => VimGeometryData.MeshVertexCounts[MeshIndex]; + public int IndexOffset => VimGeometryData.MeshIndexOffsets[MeshIndex]; + public int IndexCount => VimGeometryData.MeshIndexCounts[MeshIndex]; + public int FaceCount => IndexCount / VimMeshData.IndexCountPerFace; + + /// + /// Constructor. + /// + public VimMeshView(VimGeometryData vimGeometryData, int meshIndex) + { + VimGeometryData = vimGeometryData; + MeshIndex = meshIndex; + _submeshIndex = null; // lazily instantiated + _submeshCount = null; // lazily instantiated + } + + public Vector3[] GetVertices() + { + return GetSubArray(VimGeometryData.Vertices, VertexOffset, VertexCount); + } + + public int[] GetIndices() + { + var vertexOffset = VertexOffset; + return GetSubArray(VimGeometryData.Indices, IndexOffset, IndexCount) + .Select(i => i - vertexOffset).ToArray(); + } + + private int? _submeshIndex; + public int SubmeshIndex + { + get + { + if (!_submeshIndex.HasValue) + { + _submeshIndex = Array.BinarySearch(VimGeometryData.SubmeshIndexOffsets, IndexOffset); + } + return _submeshIndex.Value; + } + } + + private int? _submeshCount; + public int SubmeshCount + { + get + { + if (!_submeshCount.HasValue) + { + _submeshCount = 0; + var submeshIndex = SubmeshIndex; + var submeshArray = VimGeometryData.SubmeshIndexOffsets; + var meshIndexOffset = IndexOffset; + var meshIndexCount = IndexCount; + for (var i = submeshIndex; i < submeshArray.Length; i++) + { + var indexOffset = submeshArray[i]; + if (indexOffset - meshIndexOffset >= meshIndexCount) + break; + _submeshCount++; + } + } + return _submeshCount.Value; + } + } + + public int[] GetSubmeshMaterials() + { + return GetSubArray(VimGeometryData.SubmeshMaterials, SubmeshIndex, SubmeshCount); + } + + public int[] GetSubmeshIndexOffsets() + { + var indexOffset = IndexOffset; + return GetSubArray(VimGeometryData.SubmeshIndexOffsets, SubmeshIndex, SubmeshCount) + .Select(i => i - indexOffset) + .ToArray(); + } + + private static T[] GetSubArray(T[] source, int startIndex, int count, T @default = default) where T: unmanaged + { + var values = new T[count]; + + for (var i = 0; i < count; ++i) + { + var sourceIndex = startIndex + i; + values[i] = source?.ElementAtOrDefault(sourceIndex, @default) ?? @default; + } + return values; + } + } + + /// + /// Compares two meshes + /// + public class VimMeshComparer : IVimMesh, IEquatable + { + public VimMeshView MeshView { get; } + public int MeshIndex => MeshView.MeshIndex; + public Vector3[] Vertices { get; } + public int VertexCount => Vertices.Length; + public int[] Indices { get; } + public int FaceCount { get; } + public int TopologyHash { get; } + public Int3 BoxExtents { get; } + public Int3 BoxMin { get; } + public const float DefaultRoundingPrecision = 1f / 12f / 8f; + + /// + /// Constructor + /// + public VimMeshComparer(VimMeshView vimMeshView, float roundingPrecision = DefaultRoundingPrecision) + { + MeshView = vimMeshView; + Vertices = vimMeshView.GetVertices(); + Indices = vimMeshView.GetIndices(); + FaceCount = vimMeshView.FaceCount; + TopologyHash = HashCodeStd2.GetSequenceHash(Indices); + var box = AABox.Create(Vertices); + BoxMin = RoundVector3(box.Min, roundingPrecision); + BoxExtents = RoundVector3(box.Extent, roundingPrecision); + } + + public Vector3[] GetVertices() + => Vertices; + + public int[] GetIndices() + => Indices; + + private static Int3 RoundVector3(Vector3 v, float roundingPrecision) + => new Int3( + RoundFloat(v.X, roundingPrecision), + RoundFloat(v.Y, roundingPrecision), + RoundFloat(v.Z, roundingPrecision) + ); + + private static int RoundFloat(float f, float roundingPrecision) + => (int)(f / roundingPrecision); + + public override bool Equals(object obj) + => obj is VimMeshComparer other && Equals(other); + + public bool Equals(VimMeshComparer other) + => FaceCount == other.FaceCount + && VertexCount == other.VertexCount + && BoxMin.Equals(other.BoxMin) + && BoxExtents.Equals(other.BoxExtents) + && IsGeometryEqual(other); + + public override int GetHashCode() + => HashCodeStd2.Combine( + FaceCount, + VertexCount, + TopologyHash, + BoxMin.GetHashCode(), + BoxExtents.GetHashCode() + ); + + private bool IsGeometryEqual(VimMeshComparer other, float tolerance = Constants.Tolerance) + { + if (FaceCount != other.FaceCount || Indices.Length != other.Indices.Length || VertexCount != other.VertexCount) + return false; + + for (var i = 0; i < FaceCount; ++i) + { + var i0 = i * 3; + var i1 = i0 + 1; + var i2 = i0 + 2; + + var a_p0 = Vertices[Indices[i0]]; + var b_p0 = other.Vertices[other.Indices[i0]]; + if (!a_p0.AlmostEquals(b_p0, tolerance)) + return false; + + var a_p1 = Vertices[Indices[i1]]; + var b_p1 = other.Vertices[other.Indices[i1]]; + if (!a_p1.AlmostEquals(b_p1, tolerance)) + return false; + + var a_p2 = Vertices[Indices[i2]]; + var b_p2 = other.Vertices[other.Indices[i2]]; + if (!a_p2.AlmostEquals(b_p2, tolerance)) + return false; + } + + return true; + } + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimMeshWithFaceMaterials.cs b/src/cs/vim/Vim.Format.Core/VimMeshWithFaceMaterials.cs new file mode 100644 index 00000000..85be3fe4 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimMeshWithFaceMaterials.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vim.Math3d; + +namespace Vim.Format +{ + public class VimMeshWithFaceMaterials + { + public List Vertices { get; set; } + public List Indices { get; set; } + public List FaceMaterials { get; set; } + public List Colors { get; set; } + public List UVs { get; set; } + + public VimMeshWithFaceMaterials( + List vertices = null, + List indices = null, + List faceMaterials = null, + List colors = null, + List uvs = null) + { + Vertices = vertices ?? new List(); + Indices = indices ?? new List(); + + if (Indices.Any(i => i < 0 && i >= Vertices.Count)) + throw new Exception($"Invalid mesh. Indices out of vertex range."); + + if (Indices.Count % 3 != 0) + throw new Exception("indices.Count must be a multiple of 3."); + + FaceMaterials = faceMaterials ?? new List(Enumerable.Repeat(-1, Indices.Count / 3)); + + if (FaceMaterials.Count * 3 != Indices.Count) + throw new Exception("faceMaterials.Count must be indices.Count * 3"); + + Colors = colors ?? new List(); + UVs = uvs ?? new List(); + } + + public void SetMeshMaterial(int material) + => FaceMaterials = Enumerable.Repeat(material, Indices.Count / 3).ToList(); + + public void AppendFaces(IList indices, IList materials) + { + if (indices.Count != materials.Count * 3) + throw new Exception("index.Count must be material.Count*3"); + + for (var i = 0; i < materials.Count; i++) + { + var index = i * 3; + AppendFace(indices[index], indices[index + 1], indices[index + 2], materials[i]); + } + } + + public void AppendFace(int v0, int v1, int v2, int material) + { + Indices.Add(v0); + Indices.Add(v1); + Indices.Add(v2); + FaceMaterials.Add(material); + } + + public void AppendVertices(IEnumerable vertices) + => Vertices.AddRange(vertices); + + public void AppendUVs(IEnumerable uvs) + => UVs.AddRange(uvs); + + public VimSubdividedMesh Subdivide() + => new VimSubdividedMesh(this); + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimQuadMeshStrip.cs b/src/cs/vim/Vim.Format.Core/VimQuadMeshStrip.cs new file mode 100644 index 00000000..f555a570 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimQuadMeshStrip.cs @@ -0,0 +1,143 @@ +using System.Collections.Generic; + +namespace Vim.Format +{ + public class VimQuadMeshStrip + { + /// + /// Computes the indices of a quad mesh astrip. + /// + public static List ComputeQuadMeshStripIndices(int usegs, int vsegs, bool wrapUSegs = false, bool wrapVSegs = false) + { + var indices = new List(); + + var maxUSegs = wrapUSegs ? usegs : usegs + 1; + var maxVSegs = wrapVSegs ? vsegs : vsegs + 1; + + for (var i = 0; i < vsegs; ++i) + { + var rowA = i * maxUSegs; + var rowB = ((i + 1) % maxVSegs) * maxUSegs; + + for (var j = 0; j < usegs; ++j) + { + var colA = j; + var colB = (j + 1) % maxUSegs; + + indices.Add(rowA + colA); + indices.Add(rowA + colB); + indices.Add(rowB + colB); + indices.Add(rowB + colA); + } + } + + return indices; + } + + /// + /// Returns the index buffer of a quad mesh strip. + /// Returns an empty array if either numRowPoints or numPointsPerRow is less than 2. + /// + public static List QuadMeshStripIndicesFromPointRows( + int numPointRows, + int numPointsPerRow, + bool clockwise = false) + { + // A quad(ABCD) is defined as 4 indices, counter clock-wise: + // + // col col + // row D------C quad(ABCD) = (counter-clockwise) { A, B, C, D } + // |t1 / | triangle(t0) = (counter-clockwise) { A, B, C } + // | / t0| triangle(t1) = (counter-clockwise) { A, C, D } + // row A------B + + var indices = new List(); // 4 indices per quad. + for (var rowIndex = 0; rowIndex < numPointRows - 1; ++rowIndex) + { + for (var colIndex = 0; colIndex < numPointsPerRow - 1; ++colIndex) + { + // The vertices will all be inserted in a flat list in the vertex buffer + // [ ...row0, ...row1, ...row2, ..., ...rowN] + // + // colIndex + // ... ... + // | | + // rowIndex + 1: [... ---D------C--- ...] + // |t1 / | + // | / t0| + // rowIndex: [... ---A------B--- ...] + // | | + // ... ... + // + // rowSize: |<-----numColumns----->| + // + + var A = colIndex + rowIndex * numPointsPerRow; + var B = A + 1; + var D = colIndex + (rowIndex + 1) * numPointsPerRow; + var C = D + 1; + + if (clockwise) + { + indices.Add(D); + indices.Add(C); + indices.Add(B); + indices.Add(A); + } + else + { + indices.Add(A); + indices.Add(B); + indices.Add(C); + indices.Add(D); + } + } + } + + return indices; + } + + public static int[] TriMeshCylinderCapIndices(int numEdgeVertices) + { + // Example cap where numEdgeVertices is 6: + // + // (!) It is assumed that vertex 0 is at the center of the cap + // and that this center vertex is omitted from the numEdgeVertices count. + // + // 3<------2 + // / \t1 / ^ t0 = (O, 1, 2) + // v t2 \ / t0 \ t1 = (O, 2, 3) + // 4------0------1 <---- start t2 = (O, 3, 4) + // \ t3 / \ t5 ^ t3 = (O, 4, 5) + // v /t4 \ / t4 = (O, 5, 6) + // 5------>6 <---- end t5 = (O, 6, 1) <-- special case. + + var center = 0; + var indices = new List(); + + var numTriangles = numEdgeVertices; + + // Do all the triangles except the last one. + for (var triangle = 0; triangle < numTriangles - 1; ++triangle) + { + var index0 = center; // 0 + var index1 = triangle + 1; + var index2 = index1 + 1; + + indices.Add(index0); + indices.Add(index1); + indices.Add(index2); + } + + // The last triangle loops back onto the first edge vertex. + var lastTriangleIndex0 = center; + var lastTriangleIndex1 = numEdgeVertices; + var lastTriangleIndex2 = 1; + indices.Add(lastTriangleIndex0); + indices.Add(lastTriangleIndex1); + indices.Add(lastTriangleIndex2); + + return indices.ToArray(); + } + } +} diff --git a/src/cs/vim/Vim.Format.Core/VimSubdividedMesh.cs b/src/cs/vim/Vim.Format.Core/VimSubdividedMesh.cs new file mode 100644 index 00000000..95ef362e --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/VimSubdividedMesh.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vim.Math3d; + +namespace Vim.Format +{ + public class VimSubdividedMesh + { + public IReadOnlyList Indices { get; } + public IReadOnlyList Vertices { get; } + public IReadOnlyList SubmeshesIndexOffset { get; } + public IReadOnlyList SubmeshMaterials { get; } + + public VimSubdividedMesh( + List vertices = null, + List indices = null, + List faceMaterials = null) + { + var vertexCount = vertices.Count; + if (indices.Any(i => i < 0 || i >= vertexCount)) + throw new ArgumentException($"Indices out of vertex range."); + + var facesByMats = faceMaterials + .Select((face, index) => (face, index)) + .GroupBy(pair => pair.face, pair => pair.index); + + var submeshIndexOffset = new List(); + var submeshMaterials = new List(); + var indicesRemap = new List(); + + foreach (var group in facesByMats) + { + submeshIndexOffset.Add(indicesRemap.Count); + submeshMaterials.Add(group.Key); + foreach (var face in group) + { + var f = face * 3; + indicesRemap.Add(indices[f]); + indicesRemap.Add(indices[f + 1]); + indicesRemap.Add(indices[f + 2]); + } + } + Indices = indicesRemap; + SubmeshMaterials = submeshMaterials; + SubmeshesIndexOffset = submeshIndexOffset; + + Vertices = vertices; + } + + public VimSubdividedMesh(VimMeshWithFaceMaterials mesh) + : this(mesh.Vertices, mesh.Indices, mesh.FaceMaterials) + { } + + public VimSubdividedMesh( + IReadOnlyList indices, + IReadOnlyList vertices, + IReadOnlyList submeshesIndexOffset, + IReadOnlyList submeshMaterials + ) + { + Indices = indices; + Vertices = vertices; + SubmeshesIndexOffset = submeshesIndexOffset; + SubmeshMaterials = submeshMaterials; + } + + public VimSubdividedMesh(VimMeshView meshView) : + this( + meshView.GetIndices(), + meshView.GetVertices(), + meshView.GetSubmeshIndexOffsets(), + meshView.GetSubmeshMaterials() + ) + { } + + public bool IsEquivalentTo(VimSubdividedMesh other) + => Vertices.SequenceEqual(other.Vertices) + && Indices.SequenceEqual(other.Indices) + && SubmeshesIndexOffset.SequenceEqual(other.SubmeshesIndexOffset) + && SubmeshMaterials.SequenceEqual(other.SubmeshMaterials); + + public static VimSubdividedMesh CreateFromWorldSpaceBox(IReadOnlyList points, int materialIndex) + { + // 7 *--------------------------* 6 (max) + // |\ |\ + // | \ | \ + // | \ 4 | \ 5 + // | *--------------------------* + // | | | | + // 3 *---|----------------------* 2 | + // \ | \ | + // \ | \ | + // \| \| + // *--------------------------* + // (min) 0 1 + + // Faces are declared as quads in counter-clockwise order (right-handed rule, thumb points in normal direction) + var bottomQuad = new[] { points[0], points[3], points[2], points[1] }; + var topQuad = new[] { points[4], points[5], points[6], points[7] }; + var backQuad = new[] { points[2], points[3], points[7], points[6] }; + var frontQuad = new[] { points[0], points[1], points[5], points[4] }; + var leftQuad = new[] { points[3], points[0], points[4], points[7] }; + var rightQuad = new[] { points[2], points[6], points[5], points[1] }; + + var quads = new[] { bottomQuad, topQuad, backQuad, frontQuad, leftQuad, rightQuad }; + + var vertices = new List(); + var indices = new List(); + + var quadIndices = new[] { 0, 1, 2, 0, 2, 3 }; + + foreach (var quadVertices in quads) + { + var indexOffset = vertices.Count; + vertices.AddRange(quadVertices); + indices.AddRange(quadIndices.Select(i => i + indexOffset)); + } + + return new VimSubdividedMesh(indices, vertices, new[] { 0 }, new[] { materialIndex }); + } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.ILMerge/ILRepack.targets b/src/cs/vim/Vim.Format.ILMerge/ILRepack.targets index 019949d7..27776b8d 100644 --- a/src/cs/vim/Vim.Format.ILMerge/ILRepack.targets +++ b/src/cs/vim/Vim.Format.ILMerge/ILRepack.targets @@ -5,8 +5,6 @@ - - @@ -27,8 +25,6 @@ $(OutputPath)Vim.Format.dll ^ $(OutputPath)Vim.Format.Core.dll ^ $(OutputPath)Vim.BFast.dll ^ - $(OutputPath)Vim.G3d.dll ^ - $(OutputPath)Vim.LinqArray.dll ^ $(OutputPath)Vim.Math3D.dll ^ $(OutputPath)Vim.Util.dll ^ $(OutputPath)Vim.Util.Logging.Serilog.dll ^ diff --git a/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs b/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs deleted file mode 100644 index 307e6272..00000000 --- a/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs +++ /dev/null @@ -1,90 +0,0 @@ -using NUnit.Framework; -using System; -using System.IO; -using System.Linq; -using Vim.Format.ObjectModel; -using Vim.LinqArray; -using Vim.Util.Tests; - -namespace Vim.Format.Tests; - -[TestFixture] -public static class EntityTable_v2_Tests -{ - [Test] - public static void TestEntityTable_v2_Parity() - { - var vimFilePath = VimFormatRepoPaths.GetDataFilePath("Dwelling*.vim", true); - - // Classic deserialization (using VIM Scene) - var vim = VimScene.LoadVim(vimFilePath); - var stringBuffer = vim.Document.StringTable.ToArray(); - var dm = vim.DocumentModel; - - // EntityTable_v2 manual construction. - var fileInfo = new FileInfo(vimFilePath); - var entityTableSet = new EntityTableSet(fileInfo, stringBuffer); - - var baseElementCount = dm.NumElement; - var nextElementCount = entityTableSet.ElementTable.RowCount; - - Assert.AreEqual(baseElementCount, nextElementCount); - - for (var i = 0; i < baseElementCount; ++i) - { - var @base = dm.ElementList[i]; - var next = entityTableSet.ElementTable.Get(i); - - Assert.AreEqual(@base.Index, next.Index); - Assert.AreEqual(@base.Id, next.Id); - Assert.AreEqual(@base.Type, next.Type); - Assert.AreEqual(@base.UniqueId, next.UniqueId); - Assert.AreEqual(@base.Location_X, next.Location_X); - Assert.AreEqual(@base.Location_Y, next.Location_Y); - Assert.AreEqual(@base.Location_Z, next.Location_Z); - Assert.AreEqual(@base.FamilyName, next.FamilyName); - Assert.AreEqual(@base.IsPinned, next.IsPinned); - Assert.AreEqual(@base._Level.Index, next._Level.Index); - Assert.AreEqual(@base._PhaseCreated.Index, next._PhaseCreated.Index); - Assert.AreEqual(@base._PhaseDemolished.Index, next._PhaseDemolished.Index); - Assert.AreEqual(@base._Category.Index, next._Category.Index); - Assert.AreEqual(@base._Workset.Index, next._Workset.Index); - Assert.AreEqual(@base._DesignOption.Index, next._DesignOption.Index); - Assert.AreEqual(@base._OwnerView.Index, next._OwnerView.Index); - Assert.AreEqual(@base._Group.Index, next._Group.Index); - Assert.AreEqual(@base._AssemblyInstance.Index, next._AssemblyInstance.Index); - Assert.AreEqual(@base._BimDocument.Index, next._BimDocument.Index); - Assert.AreEqual(@base._Room.Index, next._Room.Index); - } - } - - [Test] - public static void TestElementTableKinds() - { - var fileInfo = new FileInfo(VimFormatRepoPaths.GetDataFilePath("Dwelling*.vim", true)); - - Console.WriteLine($"Loading {fileInfo.FullName}"); - - var elementKinds = EntityTableSet.GetElementKinds(fileInfo); - - var ets = new EntityTableSet(fileInfo); - - Assert.IsNotEmpty(elementKinds); - Assert.AreEqual(ets.ElementTable.RowCount, elementKinds.Length); - - var familyInstanceCount = elementKinds.Count(e => e == ElementKind.FamilyInstance); - Assert.Greater(familyInstanceCount, 0); - Assert.AreEqual(ets.FamilyInstanceTable.Column_ElementIndex.Distinct().Count(ei => ei != EntityRelation.None), familyInstanceCount); - Assert.IsTrue(ets.FamilyInstanceTable.Column_ElementIndex.All(ei => ei == EntityRelation.None || elementKinds[ei] == ElementKind.FamilyInstance)); - - var familyTypeCount = elementKinds.Count(e => e == ElementKind.FamilyType); - Assert.Greater(familyTypeCount, 0); - Assert.AreEqual(ets.FamilyTypeTable.Column_ElementIndex.Distinct().Count(ei => ei != EntityRelation.None), familyTypeCount); - Assert.IsTrue(ets.FamilyTypeTable.Column_ElementIndex.All(ei => ei == EntityRelation.None || elementKinds[ei] == ElementKind.FamilyType)); - - var familyCount = elementKinds.Count(e => e == ElementKind.Family); - Assert.Greater(familyCount, 0); - Assert.AreEqual(ets.FamilyTable.Column_ElementIndex.Distinct().Count(ei => ei != EntityRelation.None), familyCount); - Assert.IsTrue(ets.FamilyTable.Column_ElementIndex.All(ei => ei == EntityRelation.None || elementKinds[ei] == ElementKind.Family)); - } -} diff --git a/src/cs/vim/Vim.Format.Tests/FormatTests.cs b/src/cs/vim/Vim.Format.Tests/FormatTests.cs deleted file mode 100644 index 15b20f90..00000000 --- a/src/cs/vim/Vim.Format.Tests/FormatTests.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using NUnit.Framework; -using Vim.BFast; -using Vim.LinqArray; - -namespace Vim.Format.Tests -{ - public static class FormatTests - { - public static void AssertNameAndSizesAreEqual(INamedBuffer b1, INamedBuffer b2) - { - Assert.AreEqual(b1.ElementSize, b2.ElementSize); - Assert.AreEqual(b1.NumElements(), b2.NumElements()); - Assert.AreEqual(b1.Name, b2.Name); - } - - public static void AssertNameAndSizesAreEqual(SerializableEntityTable t1, SerializableEntityTable t2) - { - Assert.AreEqual(t1.Name, t2.Name); - Assert.AreEqual(t1.IndexColumns.Count, t2.IndexColumns.Count); - for (var i = 0; i < t1.IndexColumns.Count; ++i) - AssertNameAndSizesAreEqual(t1.IndexColumns[i], t2.IndexColumns[i]); - - Assert.AreEqual(t1.DataColumns.Count, t2.DataColumns.Count); - for (var i = 0; i < t1.DataColumns.Count; ++i) - AssertNameAndSizesAreEqual(t1.DataColumns[i], t2.DataColumns[i]); - - Assert.AreEqual(t1.StringColumns.Count, t2.StringColumns.Count); - for (var i = 0; i < t1.StringColumns.Count; ++i) - AssertNameAndSizesAreEqual(t1.StringColumns[i], t2.StringColumns[i]); - - /* Can't expect the numerical values to be precise, because of non-determinism of parallelism when generating string table. - for (var i=0; i < t1.Properties.Length; ++i) - { - var p1 = t1.Properties[i]; - var p2 = t2.Properties[i]; - Assert.AreEqual(p1.EntityId, p2.EntityId); - Assert.AreEqual(p1.Name, p2.Name); - Assert.AreEqual(p1.Value, p2.Value); - } - */ - } - - public static void AssertEquals(SerializableDocument d1, SerializableDocument d2, bool compareStringTables = true) - { - Assert.AreEqual(d1.EntityTables.Count, d2.EntityTables.Count); - Assert.AreEqual(d1.Header, d2.Header); - if (compareStringTables) - { - var strings1 = d1.StringTable.OrderBy(x => x).ToArray(); - var strings2 = d2.StringTable.OrderBy(x => x).ToArray(); - Assert.AreEqual(strings1, strings2); - } - - // TODO: upgrade to a proper Geometry comparer - //Assert.AreEqual(d1.Geometry.FaceCount(), d2.Geometry.FaceCount()); - //Assert.AreEqual(d1.Geometry.VertexCount(), d2.Geometry.VertexCount()); - - Assert.AreEqual(d1.Assets.Length, d2.Assets.Length); - - for (var i = 0; i < d1.EntityTables.Count; ++i) - { - AssertNameAndSizesAreEqual(d1.EntityTables[i], d2.EntityTables[i]); - } - } - - public static void AssertEquals(EntityTable et1, EntityTable et2) - { - Assert.AreEqual(et1.Name, et2.Name); - Assert.AreEqual(et1.DataColumns.Keys.ToEnumerable().OrderBy(n => n).ToArray(), et2.DataColumns.Keys.ToEnumerable().OrderBy(n => n).ToArray()); - Assert.AreEqual(et1.IndexColumns.Keys.ToEnumerable().OrderBy(n => n).ToArray(), et2.IndexColumns.Keys.ToEnumerable().OrderBy(n => n).ToArray()); - Assert.AreEqual(et1.StringColumns.Keys.ToEnumerable().OrderBy(n => n).ToArray(), et2.StringColumns.Keys.ToEnumerable().OrderBy(n => n).ToArray()); - - var columns1 = et1.Columns.OrderBy(c => c.Name).ToArray(); - var columns2 = et2.Columns.OrderBy(c => c.Name).ToArray(); - - Assert.AreEqual( - columns1.Select(ec => ec.Name).ToArray(), - columns2.Select(ec => ec.Name).ToArray()); - - Assert.AreEqual( - columns1.Select(ec => ec.NumElements()).ToArray(), - columns2.Select(ec => ec.NumElements()).ToArray()); - - Assert.AreEqual( - columns1.Select(ec => ec.NumBytes()).ToArray(), - columns2.Select(ec => ec.NumBytes()).ToArray()); - } - - /// - /// Returns true if |(set(a)-set(b))| >= 0 - /// - public static bool IsSupersetOf(IEnumerable a, IEnumerable b) - { - var hashSetA = new HashSet(a); - var hashSetB = new HashSet(b); - return hashSetA.IsSupersetOf(hashSetB); - } - - /// - /// Asserts that et1 is equal or a superset of et2. - /// - public static void AssertIsSupersetOf(EntityTable et1, EntityTable et2) - { - Assert.AreEqual(et1.Name, et2.Name); - Assert.IsTrue(IsSupersetOf(et1.DataColumns.Keys.ToEnumerable(), et2.DataColumns.Keys.ToEnumerable())); - Assert.IsTrue(IsSupersetOf(et1.IndexColumns.Keys.ToEnumerable(), et2.IndexColumns.Keys.ToEnumerable())); - Assert.IsTrue(IsSupersetOf(et1.StringColumns.Keys.ToEnumerable(), et2.StringColumns.Keys.ToEnumerable())); - - var columns1 = et1.Columns.ToArray(); - var columns2 = et2.Columns.ToArray(); - Assert.IsTrue(IsSupersetOf( - columns1.Select(c => c.Name), - columns2.Select(c => c.Name))); - - foreach (var column in columns2) - { - var key = column.Name; - var matchingColumn = - columns1.FirstOrDefault(c => c.Name == key); - if (matchingColumn == null) - Assert.Fail($"No matching column key found: {key}"); - Assert.GreaterOrEqual(matchingColumn.NumElements(), column.NumElements()); - Assert.GreaterOrEqual(matchingColumn.NumBytes(), column.NumBytes()); - } - } - - /// - /// Returns true if d1 is equal or a superset of d2. - /// - public static void AssertIsSuperSetOf(Document d1, Document d2, bool skipGeometryAndNodes = true) - { - var schema1 = VimSchema.Create(d1); - var schema2 = VimSchema.Create(d2); - Assert.IsTrue(VimSchema.IsSuperSetOf(schema1, schema2)); - - var etKeys1 = d1.EntityTables.Keys; - var etKeys2 = d2.EntityTables.Keys; - Assert.IsTrue(IsSupersetOf(etKeys1.ToEnumerable(), etKeys2.ToEnumerable())); - - foreach (var key in etKeys2.ToEnumerable()) - { - if (skipGeometryAndNodes && key.ToLowerInvariant().Contains("geometry")) - continue; - - var et2 = d2.EntityTables[key]; - var et1 = d1.EntityTables.GetOrDefault(key); - if (et1 == null) - Assert.Fail($"No matching entity table found: {key}"); - AssertIsSupersetOf(et1, et2); - } - } - - public static void AssertEquals(Document d1, Document d2, bool skipGeometryAndNodes = false) - { - var schema1 = VimSchema.Create(d1); - var schema2 = VimSchema.Create(d2); - Assert.IsTrue(VimSchema.IsSame(schema1, schema2)); - - var entityTables1 = d1.EntityTables.Keys.ToEnumerable().OrderBy(n => n).ToArray(); - var entityTables2 = d2.EntityTables.Keys.ToEnumerable().OrderBy(n => n).ToArray(); - Assert.AreEqual(entityTables1, entityTables2); - - foreach (var k in entityTables1) - { - if (skipGeometryAndNodes && k.ToLowerInvariant().Contains("geometry")) - continue; - AssertEquals(d1.EntityTables[k], d2.EntityTables[k]); - } - } - } -} diff --git a/src/cs/vim/Vim.Format.Tests/Geometry/GeometryTests.cs b/src/cs/vim/Vim.Format.Tests/Geometry/GeometryTests.cs deleted file mode 100644 index 9efac292..00000000 --- a/src/cs/vim/Vim.Format.Tests/Geometry/GeometryTests.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Linq; -using NUnit.Framework; -using Vim.Format.Geometry; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.Tests.Geometry -{ - public static class GeometryTests - { - public static IMesh XYTriangle = new[] { new Vector3(0f, 0f, 0f), new Vector3(0f, 1f, 0f), new Vector3(1f, 0f, 0f) }.ToIArray().TriMesh(3.Range()); - public static IMesh XYQuad = new[] { new Vector3(0f, 0f, 0f), new Vector3(0f, 1f, 0f), new Vector3(1f, 1f, 0f), new Vector3(1f, 0f, 0f) }.ToIArray().QuadMesh(4.Range()); - public static IMesh XYQuadFromFunc = Primitives.QuadMesh(uv => uv.ToVector3(), 1, 1); - public static IMesh XYQuad2x2 = Primitives.QuadMesh(uv => uv.ToVector3(), 2, 2); - public static IMesh XYTriangleTwice = XYTriangle.Merge(XYTriangle.Translate(new Vector3(1, 0, 0))); - - public static readonly Vector3[] TestTetrahedronVertices = { Vector3.Zero, Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ }; - public static readonly int[] TestTetrahedronIndices = { 0, 1, 2, 0, 3, 1, 1, 3, 2, 2, 3, 0 }; - - public static IMesh Tetrahedron = - TestTetrahedronVertices.ToIArray().TriMesh(TestTetrahedronIndices.ToIArray()); - - public static IMesh Torus = Primitives.Torus(10, 0.2f, 10, 24); - - static IMesh RevolvedVerticalCylinder(float height, float radius, int verticalSegments, int radialSegments) - => (Vector3.UnitZ * height).ToLine().Interpolate(verticalSegments).Add(-radius.AlongX()).RevolveAroundAxis(Vector3.UnitZ, radialSegments); - - public static IMesh Cylinder = RevolvedVerticalCylinder(5, 1, 4, 12); - - public static IMesh[] AllMeshes = { - XYTriangle, // 0 - XYQuad, // 1 - XYQuadFromFunc, // 2 - XYQuad2x2, // 3 - Tetrahedron, // 4 - Torus, // 5 - Cylinder, // 6 - XYTriangleTwice, // 7 - }; - - public static double SmallTolerance = 0.0001; - - public static void AssertEquals(IMesh g1, IMesh g2) - { - Assert.AreEqual(g1.NumFaces, g2.NumFaces); - Assert.AreEqual(g1.NumCorners, g2.NumCorners); - Assert.AreEqual(g1.NumVertices, g2.NumVertices); - for (var i = 0; i < g1.Indices.Count; i++) - { - var v1 = g1.Vertices[g1.Indices[i]]; - var v2 = g2.Vertices[g2.Indices[i]]; - Assert.IsTrue(v1.AlmostEquals(v2, (float)SmallTolerance)); - } - } - - public static void AssertEqualsWithAttributes(IMesh g1, IMesh g2) - { - AssertEquals(g1, g2); - - Assert.AreEqual( - g1.Attributes.Select(attr => attr.Name).ToArray(), - g2.Attributes.Select(attr => attr.Name).ToArray()); - - Assert.AreEqual( - g1.Attributes.Select(attr => attr.ElementCount).ToArray(), - g2.Attributes.Select(attr => attr.ElementCount).ToArray()); - } - - public static void OutputTriangleStats(Triangle t) - { - Console.WriteLine($"Vertices: {t.A} {t.B} {t.C}"); - Console.WriteLine($"Area: {t.Area} Perimeter: {t.Perimeter} Midpoint: {t.MidPoint}"); - Console.WriteLine($"Bounding box: {t.BoundingBox}"); - Console.WriteLine($"Bounding sphere: {t.BoundingSphere}"); - Console.WriteLine($"Normal: {t.Normal}, normal direction {t.NormalDirection}"); - Console.WriteLine($"Lengths: {t.LengthA} {t.LengthB} {t.LengthC}"); - } - - public static void OutputTriangleStatsSummary(IMesh g) - { - var triangles = g.Triangles(); - for (var i = 0; i < Math.Min(3, triangles.Count); ++i) - { - Console.WriteLine($"Triangle {i}"); - OutputTriangleStats(triangles[i]); - } - - if (triangles.Count > 3) - { - Console.WriteLine("..."); - Console.WriteLine($"Triangle {triangles.Count - 1}"); - OutputTriangleStats(triangles.Last()); - } - } - - public static void OutputIMeshStats(IMesh g) - { - g.Validate(); - foreach (var attr in g.Attributes.ToEnumerable()) - Console.WriteLine($"{attr.Descriptor} elementCount={attr.ElementCount}"); - } - - public static void GeometryNullOps(IMesh g) - { - AssertEqualsWithAttributes(g, g); - AssertEqualsWithAttributes(g, g.Attributes.ToIMesh()); - AssertEqualsWithAttributes(g, g.Translate(Vector3.Zero)); - AssertEqualsWithAttributes(g, g.Scale(1.0f)); - AssertEqualsWithAttributes(g, g.Transform(Matrix4x4.Identity)); - - AssertEquals(g, g.CopyFaces(0, g.NumFaces).ToIMesh()); - } - - - [Test] - public static void BasicTests() - { - var nMesh = 0; - foreach (var g in AllMeshes) - { - Console.WriteLine($"Testing mesh {nMesh++}"); - g.Validate(); - //ValidateGeometry(g.ToTriMesh()); - } - - Assert.AreEqual(3, XYTriangle.NumCornersPerFace); - Assert.AreEqual(1, XYTriangle.NumFaces); - Assert.AreEqual(3, XYTriangle.Vertices.Count); - Assert.AreEqual(3, XYTriangle.Indices.Count); - Assert.AreEqual(1, XYTriangle.Triangles().Count); - Assert.AreEqual(0.5, XYTriangle.Area(), SmallTolerance); - Assert.IsTrue(XYTriangle.Planar()); - Assert.AreEqual(new[] { 0, 1, 2 }, XYTriangle.Indices.ToArray()); - - Assert.AreEqual(3, XYQuad.NumCornersPerFace); - Assert.AreEqual(2, XYQuad.NumFaces); - Assert.AreEqual(4, XYQuad.Vertices.Count); - Assert.AreEqual(6, XYQuad.Indices.Count); - - Assert.IsTrue(XYQuad.Planar()); - Assert.AreEqual(new[] { 0, 1, 2, 0, 2, 3 }, XYQuad.Indices.ToArray()); - - Assert.AreEqual(3, XYQuadFromFunc.NumCornersPerFace); - Assert.AreEqual(2, XYQuadFromFunc.NumFaces); - Assert.AreEqual(4, XYQuadFromFunc.Vertices.Count); - Assert.AreEqual(6, XYQuadFromFunc.Indices.Count); - - Assert.AreEqual(3, XYQuad2x2.NumCornersPerFace); - Assert.AreEqual(8, XYQuad2x2.NumFaces); - Assert.AreEqual(9, XYQuad2x2.Vertices.Count); - Assert.AreEqual(24, XYQuad2x2.Indices.Count); - - Assert.AreEqual(3, Tetrahedron.NumCornersPerFace); - Assert.AreEqual(4, Tetrahedron.NumFaces); - Assert.AreEqual(4, Tetrahedron.Vertices.Count); - Assert.AreEqual(12, Tetrahedron.Indices.Count); - Assert.AreEqual(TestTetrahedronIndices, Tetrahedron.Indices.ToArray()); - - Assert.AreEqual(3, XYTriangleTwice.NumCornersPerFace); - Assert.AreEqual(2, XYTriangleTwice.NumFaces); - Assert.AreEqual(6, XYTriangleTwice.Vertices.Count); - Assert.AreEqual(6, XYTriangleTwice.Indices.Count); - Assert.AreEqual(2, XYTriangleTwice.Triangles().Count); - Assert.AreEqual(1.0, XYTriangleTwice.Area(), SmallTolerance); - Assert.IsTrue(XYTriangleTwice.Planar()); - Assert.AreEqual(new[] { 0, 1, 2, 3, 4, 5 }, XYTriangleTwice.Indices.ToArray()); - } - - [Test] - public static void BasicManipulationTests() - { - foreach (var g in AllMeshes) - GeometryNullOps(g); - } - - [Test] - public static void OutputGeometryData() - { - var n = 0; - foreach (var g in AllMeshes) - { - Console.WriteLine($"Geometry {n++}"); - for (var i = 0; i < g.Vertices.Count && i < 10; ++i) - { - Console.WriteLine($"Vertex {i} {g.Vertices[i]}"); - } - - if (g.Vertices.Count > 10) - { - var last = g.Vertices.Count - 1; - Console.WriteLine("..."); - Console.WriteLine($"Vertex {last} {g.Vertices[last]}"); - } - - for (var i = 0; i < g.NumFaces && i < 10; ++i) - { - Console.WriteLine($"Face {i}: {g.Triangle(i)}"); - } - - if (g.Vertices.Count > 10) - { - var last = g.NumFaces - 1; - Console.WriteLine("..."); - Console.WriteLine($"Face {last}: {g.Triangle(last)}"); - } - } - } - - [Test] - public static void StripIndicesTests() - { - var emptyStrip00 = Primitives.QuadMeshStripIndicesFromPointRows(0, 0); - Assert.AreEqual(0, emptyStrip00.Count); - - var emptyStrip01 = Primitives.QuadMeshStripIndicesFromPointRows(0, 1); - Assert.AreEqual(0, emptyStrip01.Count); - - var emptyStrip10 = Primitives.QuadMeshStripIndicesFromPointRows(1, 0); - Assert.AreEqual(0, emptyStrip10.Count); - - var emptyStrip11 = Primitives.QuadMeshStripIndicesFromPointRows(1, 1); - Assert.AreEqual(0, emptyStrip11.Count); - - var emptyStrip12 = Primitives.QuadMeshStripIndicesFromPointRows(1, 2); - Assert.AreEqual(0, emptyStrip12.Count); - - var emptyStrip21 = Primitives.QuadMeshStripIndicesFromPointRows(2, 1); - Assert.AreEqual(0, emptyStrip21.Count); - - // COUNTER-CLOCKWISE TEST (DEFAULT) - // 2------3 <--- row 1: [2,3] - // | | => counter-clockwise quad: (0,1,3,2) - // | | - // 0------1 <--- row 0: [0,1] - var strip22 = Primitives.QuadMeshStripIndicesFromPointRows(2, 2); - Assert.AreEqual(4, strip22.Count); - Assert.AreEqual(0, strip22[0]); - Assert.AreEqual(1, strip22[1]); - Assert.AreEqual(3, strip22[2]); - Assert.AreEqual(2, strip22[3]); - - // CLOCKWISE TEST - // 2------3 <--- row 1: [2,3] - // | | => clockwise quad: (2,3,1,0) - // | | - // 0------1 <--- row 0: [0,1] - var clockwiseStrip22 = Primitives.QuadMeshStripIndicesFromPointRows(2, 2, true); - Assert.AreEqual(4, clockwiseStrip22.Count); - Assert.AreEqual(2, clockwiseStrip22[0]); - Assert.AreEqual(3, clockwiseStrip22[1]); - Assert.AreEqual(1, clockwiseStrip22[2]); - Assert.AreEqual(0, clockwiseStrip22[3]); - var reversed22 = clockwiseStrip22.ToIArray().Reverse(); - for (var i = 0; i < strip22.Count; ++i) - { - Assert.AreEqual(strip22[i], reversed22[i]); - } - - // *------*------* - // | | | - // | | | - // *------*------* - var strip23 = Primitives.QuadMeshStripIndicesFromPointRows(2, 3); - Assert.AreEqual(4 * 2, strip23.Count); - - // *------*------*------* - // | | | | - // | | | | - // *------*------*------* - // | | | | - // | | | | - // *------*------*------* - var strip34 = Primitives.QuadMeshStripIndicesFromPointRows(3, 4); - Assert.AreEqual(4 * 6, strip34.Count); - } - - [Test] - public static void TriangleSerializationTest() - { - // Serialize a triangle g3d to a bfast 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 submeshIndexOffsets = new[] { 0 }; - var submeshMaterials = new[] { 0 }; - - var g3d = new G3DBuilder() - .AddVertices(vertices.ToIArray()) - .AddIndices(indices.ToIArray()) - .Add(submeshIndexOffsets.ToIArray().ToSubmeshIndexOffsetAttribute()) - .Add(submeshMaterials.ToIArray().ToSubmeshMaterialAttribute()) - .ToG3D(); - - var bfastBytes = g3d.WriteToBytes(); - var readG3d = G3D.Read(bfastBytes); - - Assert.IsNotNull(readG3d); - var mesh = readG3d.ToIMesh(); - mesh.Validate(); - - Assert.AreEqual(3, mesh.NumVertices); - Assert.AreEqual(new Vector3(0, 0, 0), mesh.Vertices[0]); - Assert.AreEqual(new Vector3(0, 1, 0), mesh.Vertices[1]); - Assert.AreEqual(new Vector3(0, 1, 1), mesh.Vertices[2]); - Assert.AreEqual(1, mesh.NumFaces); - Assert.AreEqual(0, mesh.SubmeshIndexOffsets.ToEnumerable().Single()); - Assert.AreEqual(0, mesh.SubmeshMaterials.ToEnumerable().Single()); - Assert.AreEqual(0, mesh.GetFaceMaterials().First()); - } - } -} diff --git a/src/cs/vim/Vim.Format.Tests/Geometry/PerimeterTest.cs b/src/cs/vim/Vim.Format.Tests/Geometry/PerimeterTest.cs deleted file mode 100644 index 82f2ac6c..00000000 --- a/src/cs/vim/Vim.Format.Tests/Geometry/PerimeterTest.cs +++ /dev/null @@ -1,27 +0,0 @@ -using NUnit.Framework; -using Vim.Format.Geometry; -using Vim.Math3d; - -namespace Vim.Format.Tests.Geometry -{ - public static class PerimeterTest - { - - [Test] - public static void Test() - { - var torus = Primitives.QuadMesh(uv => TorusFunction(uv, 10, 0.2f), 10, 24); - - var perimeter = torus.GeneratePerimeter(Vector3.UnitX); - } - - public static Vector3 TorusFunction(Vector2 uv, float radius, float tube) - { - uv = uv * Constants.TwoPi; - return new Vector3( - (radius + tube * uv.Y.Cos()) * uv.X.Cos(), - (radius + tube * uv.Y.Cos()) * uv.X.Sin(), - tube * uv.X.Sin()); - } - } -} diff --git a/src/cs/vim/Vim.Format.Tests/Geometry/RayTests.cs b/src/cs/vim/Vim.Format.Tests/Geometry/RayTests.cs deleted file mode 100644 index 2ece1b56..00000000 --- a/src/cs/vim/Vim.Format.Tests/Geometry/RayTests.cs +++ /dev/null @@ -1,236 +0,0 @@ -using NUnit.Framework; -using System; -using System.Diagnostics; -using Vim.Math3d; - -namespace Vim.Format.Tests.Geometry -{ - [TestFixture] - public static class RayTests - { - [Test] - public static void Ray_IntersectBox_IsFalse_OutsideBox() - { - var ray = new Ray(new Vector3(-2, 0, -2), new Vector3(0, 0, 1)); - var box = new AABox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); - - Assert.IsNull(ray.Intersects(box)); - } - - [Test] - public static void Ray_IntersectBox_IsTrue_Through() - { - var front = new Ray(new Vector3(0, 0, -2), new Vector3(0, 0, 1)); - var back = new Ray(new Vector3(0, 0, 2), new Vector3(0, 0, -1)); - var left = new Ray(new Vector3(-2, 0, 0), new Vector3(1, 0, 0)); - var right = new Ray(new Vector3(2, 0, 0), new Vector3(-1, 0, 0)); - var top = new Ray(new Vector3(0, 2, 0), new Vector3(0, -1, 0)); - var under = new Ray(new Vector3(0, -2, 0), new Vector3(0, 1, 0)); - - var sides = new (Ray ray, string msg, float min, float max)[] - { - (front, nameof(front), 1, 3), - (back, nameof(back), 1, 3), - (left, nameof(left), 1, 3), - (right, nameof(right), 1, 3), - (top, nameof(top), 1, 3), - (under, nameof(under), 1, 3), - }; - - var box = new AABox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); - - foreach (var (ray, msg, min, max) in sides) - { - Assert.IsNotNull(ray.Intersects(box), msg); - } - } - - - [Test] - public static void Ray_IntersectBox_IsTrue_ThroughDiagonals() - { - var XYnZ = new Ray(new Vector3(2, 2, -2), new Vector3(-1, -1, 1)); - var nXYnZ = new Ray(new Vector3(-2, 2, -2), new Vector3(1, -1, 1)); - var nXnYnZ = new Ray(new Vector3(-2, -2, -2), new Vector3(1, 1, 1)); - var XnYnZ = new Ray(new Vector3(2, -2, -2), new Vector3(-1, 1, 1)); - - var sides = new (Ray ray, string msg, float min, float max)[] - { - (XYnZ, nameof(XYnZ), 1, 3), - (nXYnZ, nameof(nXYnZ), 1, 3), - (nXnYnZ, nameof(nXnYnZ), 1, 3), - (XnYnZ, nameof(XnYnZ), 1, 3), - }; - - var box = new AABox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); - - foreach (var (ray, msg, min, max) in sides) - { - Assert.IsNotNull(ray.Intersects(box), msg); - } - } - - - [Test] - public static void Ray_IntersectBox_IsFalse_AwayFromBox() - { - var front = new Ray(new Vector3(0, 0, -2), new Vector3(0, 0, -1)); - var back = new Ray(new Vector3(0, 0, 2), new Vector3(0, 0, 1)); - var left = new Ray(new Vector3(-2, 0, 0), new Vector3(-1, 0, 0)); - var right = new Ray(new Vector3(2, 0, 0), new Vector3(1, 0, 0)); - var top = new Ray(new Vector3(0, 2, 0), new Vector3(0, 1, 0)); - var under = new Ray(new Vector3(0, -2, 0), new Vector3(0, -1, 0)); - - var sides = new (Ray, string)[] - { - (front, nameof(front)), - (back, nameof(back)), - (left, nameof(left)), - (right, nameof(right)), - (top, nameof(top)), - (under, nameof(under)), - }; - - var box = new AABox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); - - foreach (var (ray, msg) in sides) - { - Assert.IsNull(ray.Intersects(box), msg); - } - } - - [Test] - public static void Ray_IntersectBox_IsTrue_OnEdge() - { - var front = new Ray(new Vector3(0, 2, -1), new Vector3(0, -1, 0)); - var back = new Ray(new Vector3(0, 2, 1), new Vector3(0, -1, 0)); - var left = new Ray(new Vector3(-1, 0, -2), new Vector3(0, 0, 1)); - var right = new Ray(new Vector3(1, 0, -2), new Vector3(0, 0, 1)); - var top = new Ray(new Vector3(0, 1, -2), new Vector3(0, 0, 1)); - var under = new Ray(new Vector3(0, -1, -2), new Vector3(0, 0, 1)); - - var sides = new (Ray, string)[] - { - (front, nameof(front)), - (back, nameof(back)), - (left, nameof(left)), - (right, nameof(right)), - (top, nameof(top)), - (under, nameof(under)), - }; - - var box = new AABox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); - - foreach (var (ray, msg) in sides) - { - Assert.IsNotNull(ray.Intersects(box), msg); - } - } - - [Test] - public static void Ray_IntersectBox_IsFalse_NearEdge() - { - var ray = new Ray(new Vector3(0, 0, -2), new Vector3(0, 1.1f, 1)); - var box = new AABox(new Vector3(-1, -1, -1), new Vector3(1, 1, 1)); - - Assert.IsNull(ray.Intersects(box)); - } - - [Test] - public static void Ray_IntersectBox_IsTrue_FlatBox() - { - var box = new AABox(new Vector3(-1, -1, 0), new Vector3(1, 1, 0)); - var ray = new Ray(new Vector3(0, 0, -1), new Vector3(0, 0, 1)); - - Assert.IsNotNull(ray.Intersects(box)); - } - - [Test] - public static void Ray_IntersectTriangle_IsTrue_Inside() - { - var ray = new Ray(new Vector3(0, 0, -1), new Vector3(0, 0, 1)); - - var triangle = new Triangle( - new Vector3(0, 1, 0), - new Vector3(1, -1, 0), - new Vector3(-1, -1, 0) - ); - - Assert.IsNotNull(ray.Intersects(triangle)); - } - - [Test] - public static void Ray_IntersectTriangle_IsFalse_Parralel() - { - var ray = new Ray(new Vector3(0, 0, -1), new Vector3(0, 0, 1)); - - var triangle = new Triangle( - new Vector3(1, 0, 0), - new Vector3(-1, 0, 0), - new Vector3(0, 0, 1) - ); - - Assert.IsNull(ray.Intersects(triangle)); - } - - [Test] - public static void Ray_IntersectTriangle_IsTrue_OnCorner() - { - var ray = new Ray(new Vector3(0, 1, -1), new Vector3(0, 0, 1)); - - var triangle = new Triangle( - new Vector3(0, 1, 0), - new Vector3(1, -1, 0), - new Vector3(-1, -1, 0) - ); - - Assert.IsNotNull(ray.Intersects(triangle)); - } - - [Test] - public static void Ray_IntersectTriangle_IsFalse_InTrickyCorner() - { - var ray = new Ray(new Vector3(-0.1f, 0, -1), new Vector3(0, 0, 1)); - var triangle = new Triangle(new Vector3(0, 0, 0), new Vector3(-1, 1, 0), new Vector3(1, 0, 0)); - - Assert.IsNull(ray.Intersects(triangle)); - } - - [Test, Explicit] - public static void Ray_IntersectTriangle_PerfTest() - { - //IsFalse_InTrickyCorner - var ray1 = new Ray(new Vector3(-0.1f, 0, -1), new Vector3(0, 0, 1)); - var triangle1 = new Triangle(new Vector3(0, 0, 0), new Vector3(-1, 1, 0), new Vector3(1, 0, 0)); - - //IsTrue_OnCorner - var ray2 = new Ray(new Vector3(0, 1, -1), new Vector3(0, 0, 1)); - var triangle2 = new Triangle(new Vector3(0, 1, 0), new Vector3(1, -1, 0), new Vector3(-1, -1, 0)); - - //IsTrue_OnCorner - var ray3 = new Ray(new Vector3(0, 0, -1), new Vector3(0, 0, 1)); - var triangle3 = new Triangle(new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1)); - - // IsFalse_Parralel - var ray4 = new Ray(new Vector3(0, 0, -1), new Vector3(0, 0, 1)); - var triangle4 = new Triangle(new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1)); - - var watch = new Stopwatch(); - for (var j = 0; j < 10; j++) - { - watch.Restart(); - for (var i = 0; i < 1000000; i++) - { - ray1.Intersects(triangle1); - ray2.Intersects(triangle2); - ray3.Intersects(triangle3); - ray4.Intersects(triangle4); - } - watch.Stop(); - var thombore = watch.ElapsedMilliseconds; - - Console.WriteLine($"TomboreMoller {thombore} ms"); - } - } - } -} diff --git a/src/cs/vim/Vim.Format.Tests/PublishedVersionTests.cs b/src/cs/vim/Vim.Format.Tests/PublishedVersionTests.cs deleted file mode 100644 index 9b5f9b62..00000000 --- a/src/cs/vim/Vim.Format.Tests/PublishedVersionTests.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.IO; -using System.Text.RegularExpressions; -using NUnit.Framework; -using Vim.Util.Tests; -using Vim.Util.Logging; - -namespace Vim.Format.Tests -{ - public class PublishedVersionTests - { - public static Regex VersionRegex - => new (@"([0-9.]*)"); - - public static Regex BFastVersionRegex - => new(@"([0-9.]*)"); - - public static Regex LinqArrayVersionRegex - => new(@"([0-9.]*)"); - - public static Regex Math3DVersionRegex - => new(@"([0-9.]*)"); - - [Test, Ignore("Ignoring until the new package is published")] - public static void TestPublishedVersions() - { - var ctx = new CallerTestContext(); - ctx.PrepareDirectory(); - var logger = ctx.CreateLogger(); - - // Parse BFast version - - var bfastProj = Path.Combine(VimFormatRepoPaths.SrcDir, "cs", "bfast", "Vim.BFast", "Vim.BFast.csproj"); - var bfastProjContent = File.ReadAllText(bfastProj); - var bfastVersionMatch = VersionRegex.Match(bfastProjContent); - Assert.IsTrue(bfastVersionMatch.Success); - var bfastVersion = bfastVersionMatch.Groups[1].ToString(); - logger.LogInformation($"{Path.GetFileName(bfastProj)} Version: {bfastVersion}"); - - // Parse LinqArray version - - var linqArrayProj = Path.Combine(VimFormatRepoPaths.SrcDir, "cs", "linqarray", "Vim.LinqArray", "Vim.LinqArray.csproj"); - var linqArrayProjContent = File.ReadAllText(linqArrayProj); - var linqArrayVersionMatch = VersionRegex.Match(linqArrayProjContent); - Assert.IsTrue(linqArrayVersionMatch.Success); - var linqArrayVersion = linqArrayVersionMatch.Groups[1].ToString(); - logger.LogInformation($"{Path.GetFileName(linqArrayProj)} Version: {linqArrayVersion}"); - - // Parse Math3D version - - var math3dProj = Path.Combine(VimFormatRepoPaths.SrcDir, "cs", "math3d", "Vim.Math3D", "Vim.Math3D.csproj"); - var math3dProjContent = File.ReadAllText(math3dProj); - var math3dVersionMatch = VersionRegex.Match(math3dProjContent); - Assert.IsTrue(math3dVersionMatch.Success); - var math3dVersion = math3dVersionMatch.Groups[1].ToString(); - logger.LogInformation($"{Path.GetFileName(math3dProj)} Version: {math3dVersion}"); - - logger.LogInformation("---"); - - // -- Check for matches in the g3d project - - var g3dProj = Path.Combine(VimFormatRepoPaths.SrcDir, "cs", "g3d", "Vim.G3d", "Vim.G3d.csproj"); - var g3dProjContent = File.ReadAllText(g3dProj); - logger.LogInformation($"{Path.GetFileName(g3dProj)}:"); - - var g3dBfastVersionMatch = BFastVersionRegex.Match(g3dProjContent); - Assert.IsTrue(g3dBfastVersionMatch.Success); - var g3dBfastVersion = g3dBfastVersionMatch.Groups[1].ToString(); - logger.LogInformation($" BFast Version: {g3dBfastVersion}"); - - var g3dLinqArrayVersionMatch = LinqArrayVersionRegex.Match(g3dProjContent); - Assert.IsTrue(g3dLinqArrayVersionMatch.Success); - var g3dLinqArrayVersion = g3dLinqArrayVersionMatch.Groups[1].ToString(); - logger.LogInformation($" LinqArray Version: {g3dLinqArrayVersion}"); - - var g3dMath3dVersionMatch = Math3DVersionRegex.Match(g3dProjContent); - Assert.IsTrue(g3dMath3dVersionMatch.Success); - var g3dMath3dVersion = g3dMath3dVersionMatch.Groups[1].ToString(); - logger.LogInformation($" Math3D Version: {g3dMath3dVersion}"); - - Assert.AreEqual(bfastVersion, g3dBfastVersion, $"BFast version ({bfastVersion}) does not match G3d referenced BFast version ({g3dBfastVersion})"); - Assert.AreEqual(linqArrayVersion, g3dLinqArrayVersion, $"LinqArray version ({linqArrayVersion}) does not match G3d referenced LinqArray version ({g3dLinqArrayVersion})"); - Assert.AreEqual(math3dVersion, g3dMath3dVersion, $"Math3D version ({math3dVersion}) does not match G3d referenced Math3D version ({g3dMath3dVersion})"); - } - } -} diff --git a/src/cs/vim/Vim.Format.Tests/ReferenceAppTests.cs b/src/cs/vim/Vim.Format.Tests/ReferenceAppTests.cs index 87d0b017..dcc17cf8 100644 --- a/src/cs/vim/Vim.Format.Tests/ReferenceAppTests.cs +++ b/src/cs/vim/Vim.Format.Tests/ReferenceAppTests.cs @@ -5,6 +5,8 @@ using NUnit.Framework; using Vim.Util.Tests; +using Sys = System; + namespace Vim.Format.Tests; [TestFixture] @@ -88,7 +90,7 @@ public static void Validate() Console.WriteLine($"Reading names, total byte count = {nameByteCount}"); var nameBytes = reader.ReadBytes((int)nameByteCount); - var names = System.Text.Encoding.UTF8.GetString(nameBytes).Split((char)0, StringSplitOptions.RemoveEmptyEntries).ToArray(); + var names = Sys.Text.Encoding.UTF8.GetString(nameBytes).Split((char)0, StringSplitOptions.RemoveEmptyEntries).ToArray(); Console.WriteLine($"Found {names.Length} buffer names, expected {numArrays - 1}"); if ((ulong) names.Length != numArrays - 1) @@ -110,7 +112,7 @@ public static void Validate() var headerByteCount = headerRange.End - headerRange.Begin; var headerBytes = reader.ReadBytes((int)headerByteCount); - var header = System.Text.Encoding.UTF8.GetString(headerBytes); + var header = Sys.Text.Encoding.UTF8.GetString(headerBytes); Console.WriteLine("---Begin Header Contents---"); Console.WriteLine(); Console.WriteLine(header); diff --git a/src/cs/vim/Vim.Format.Tests/TrainingSetTests.cs b/src/cs/vim/Vim.Format.Tests/TrainingSetTests.cs deleted file mode 100644 index 55981164..00000000 --- a/src/cs/vim/Vim.Format.Tests/TrainingSetTests.cs +++ /dev/null @@ -1,108 +0,0 @@ -using CsvHelper; -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using Vim.LinqArray; -using Vim.Format.ObjectModel; -using Vim.Util; -using Vim.Util.Tests; - -namespace Vim.Format.Tests; - -[TestFixture] -public static class TrainingSetTests -{ - public record QuestionRecord(string Question, string Answer); - - public static void WriteQuestions(string filePath, IEnumerable questions) - { - using var writer = new StreamWriter(filePath); - using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture); - - csv.WriteRecords(questions); - } - - [Test, Explicit("Local")] - public static void GenerateTrainingSet() - { - var vimFilePath = @"path/to/file.vim"; // TODO: Replace with your VIM file - var ctx = new CallerTestContext(); - var dir = ctx.PrepareDirectory(); - - var vimScene = VimScene.LoadVim(vimFilePath); - - var dm = vimScene.DocumentModel; - var elements = dm.ElementList.Select(e => dm.GetElementInfo(e)).ToArray(); - - var questions = new List(); - - void AddQ(string q, string a) - => questions.Add(new(q, a)); - - void BatchAddQ(string initialQuestion, Func groupFunc, Func getQuestion) - { - var groups = elements - .GroupBy(groupFunc) - .Where(g => !string.IsNullOrWhiteSpace(g.Key)) - .ToArray(); - - AddQ(initialQuestion, groups.Length.ToString()); - - foreach (var g in groups) - { - var answer = g.Count().ToString(); - var groupName = g.Key; - AddQ(getQuestion(groupName), answer); - } - } - - // ELEMENTS - BatchAddQ("How many categories are there?", e => e.Category?.Name, x => $"How many elements are there in the {x} category?"); - BatchAddQ("How many families are there?", e => e.FamilyName, x => $"How many elements are in the {x} family?"); - BatchAddQ("How many family types are there?", e => e.FamilyTypeName, x => $"How many elements are in the {x} family type?"); - BatchAddQ("How many levels are there?", e => e.LevelName, x => $"How many elements are on level {x}?"); - - // LEVELS - var levels = dm.LevelList.ToArray(); - foreach (var level in levels) - { - AddQ($"What is the elevation of level {level}?", level.Elevation.ToString()); - } - - // ROOMS - var rooms = dm.RoomList.Select(r => (r, dm.GetElementInfo(r))).ToArray(); - AddQ("How many rooms are there?", rooms.Length.ToString()); - - var roomToElementMap = elements.Where(e => e.Element.Room != null).ToDictionaryOfLists(e => e.Element.Room.Number); - foreach (var (room, roomElement) in rooms) - { - AddQ($"What is the area of room number {room.Number} in square feet?", room.Area.ToString()); - AddQ($"What is the volume of room number {room.Number} in cubic feet?", room.Volume.ToString()); - - var roomElements = roomToElementMap.TryGetValue(room.Number, out var list) ? list : new List(); - var roomElementsExcludingSelf = roomElements.Where(e => e.ElementIndex != roomElement.ElementIndex).ToArray(); - AddQ($"How many elements are there in room {room.Number}?", roomElementsExcludingSelf.Length.ToString()); - - var roomFurnitureElements = roomElementsExcludingSelf.Where(e => e.FamilyName == "Furniture"); - AddQ($"How many furniture elements are there in room {room.Number}?", roomFurnitureElements.Count().ToString()); - } - - var roomGroups = rooms - .GroupBy(t => t.Item2.LevelName) - .ToArray(); - foreach (var g in roomGroups) - { - var levelName = g.Key; - var roomCount = g.Count().ToString(); - AddQ($"How many rooms are on level {levelName}?", roomCount); - AddQ($"What is the total square footage of the rooms on level {levelName}?", g.Sum(t => t.r.Area).ToString()); - } - - // Write the training set out as a CSV file - var csvFilePath = Path.Combine(dir, "Training_Set.csv"); - WriteQuestions(csvFilePath, questions); - } -} diff --git a/src/cs/vim/Vim.Format.Tests/TransformServiceTests.cs b/src/cs/vim/Vim.Format.Tests/TransformServiceTests.cs deleted file mode 100644 index 0244708e..00000000 --- a/src/cs/vim/Vim.Format.Tests/TransformServiceTests.cs +++ /dev/null @@ -1,197 +0,0 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Vim.Format.Geometry; -using Vim.Format.Merge; -using Vim.Format.ObjectModel; -using Vim.Format.SceneBuilder; -using Vim.LinqArray; -using Vim.Math3d; -using Vim.Util.Tests; - -namespace Vim.Format.Tests; - -[TestFixture] -public static class TransformServiceTests -{ - [TestCase("Walls")] - [TestCase("Doors")] - [TestCase("BOGUS_CATEGORY_THIS_REMOVES_ALL_NODES")] - public static void TestTransformService(string categoryName) - { - var ctx = new CallerTestContext(subDirComponents: categoryName); - var dir = ctx.PrepareDirectory(); - - var vimFilePath = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); - var vim = VimScene.LoadVim(vimFilePath); - - // Keep the nodes of the given category and rotate them upside down. - var transformService = new TransformService(nameof(TestTransformService), "0.0.0"); - var db = transformService.Transform( - vim, - n => n.CategoryName == categoryName, - null, - n => Matrix4x4.CreateFromAxisAngle(Vector3.UnitX, (float)Math.PI) * n.Transform, - null, - false); - - var transformedVimFilePath = Path.Combine(dir, $"transformed_{categoryName}.vim"); - db.Write(transformedVimFilePath); - - Assert.IsTrue(File.Exists(transformedVimFilePath)); - - var transformedVim = VimScene.LoadVim(transformedVimFilePath); - transformedVim.Validate(); - - Assert.IsTrue(transformedVim.VimNodes.ToEnumerable().All(n => n.CategoryName == categoryName)); - - var dm = transformedVim.DocumentModel; - Assert.IsTrue(dm.NodeList.All(n => n.Element.Category.Name == categoryName)); - - foreach (var fi in dm.FamilyInstanceList.ToArray()) - { - var elementInfo = dm.GetElementInfo(fi.Element.Index); - if (elementInfo.IsSystem) // TECH DEBT - skipping systems for now. - continue; - - Assert.AreEqual(categoryName, elementInfo.CategoryName, $"FamilyInstance Element category is not {categoryName}"); - } - } - - [Test] - public static void TestSplitMerge() - { - var ctx = new CallerTestContext(); - var dir = ctx.PrepareDirectory(); - - var vimFilePath = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); - var vim = VimScene.LoadVim(vimFilePath); - var transformService = new TransformService(nameof(TestTransformService), "0.0.0"); - - var box = vim.BoundingBox(); - - bool IsLeft(VimSceneNode n) - => n.TransformedMesh().Center().X < box.Center.X; - - // Get the left part of the VIM file - var leftVimFilePath = Path.Combine(dir, "left.vim"); - { - var db = transformService.Filter(vim, n => n.GetMesh() != null && IsLeft(n)); - db.Write(leftVimFilePath); - Assert.IsTrue(File.Exists(leftVimFilePath)); - } - var leftVim = VimScene.LoadVim(leftVimFilePath); - leftVim.Validate(); - - // Get the right part of the VIM file. - var rightVimFilePath = Path.Combine(dir, "right.vim"); - { - var db = transformService.Filter(vim, n => n.GetMesh() != null && !IsLeft(n)); - db.Write(rightVimFilePath); - Assert.IsTrue(File.Exists(rightVimFilePath)); - } - var rightVim = VimScene.LoadVim(rightVimFilePath); - rightVim.Validate(); - - - bool HasGeometry(ISceneNode n) => n.GetMesh() != null; - Assert.AreEqual(vim.Nodes.Where(HasGeometry).Count(), leftVim.Nodes.Where(HasGeometry).Count() + rightVim.Nodes.Where(HasGeometry).Count()); - - Assert.AreEqual(vim.Document.EntityTables.Keys.Count, leftVim.Document.EntityTables.Keys.Count); - Assert.AreEqual(vim.Document.EntityTables.Keys.Count, rightVim.Document.EntityTables.Keys.Count); - - var mergedVimFilePath = Path.Combine(dir, "merged.vim"); - var documentBuilder = MergeService.MergeVimScenes(new MergeConfigVimScenes(new[] { leftVim, rightVim })); - documentBuilder.Write(mergedVimFilePath); - Assert.IsTrue(File.Exists(mergedVimFilePath)); - var mergedVim = VimScene.LoadVim(mergedVimFilePath); - mergedVim.Validate(); - - Assert.AreEqual(vim.Nodes.Where(HasGeometry).Count(), mergedVim.Nodes.Where(HasGeometry).Count()); - - Assert.AreEqual(vim.Document.EntityTables.Keys.Count, vim.Document.EntityTables.Keys.Count); - - var sourceStringSet = new HashSet(vim.Document.StringTable.ToEnumerable()); - var mergedStringSet = new HashSet(mergedVim.Document.StringTable.ToEnumerable()); - mergedStringSet.ExceptWith(sourceStringSet); - Assert.AreEqual(0, mergedStringSet.Count); - - Assert.AreEqual(vim.Document.Assets.Keys.Count, mergedVim.Document.Assets.Keys.Count); - } - - [Test] - public static void TestFilter() - { - var ctx = new CallerTestContext(); - var dir = ctx.PrepareDirectory(); - - var vimFilePath = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); - var vim = VimScene.LoadVim(vimFilePath); - - // Just keep the even-numbered nodes. - var transformService = new TransformService(nameof(TestTransformService), "0.0.0"); - var counter = 0; - var db = transformService.Filter(vim, n => n.GetMesh() != null && (counter++ % 2 == 0)); - - var filteredVimFilePath = Path.Combine(dir, "evens.vim"); - db.Write(filteredVimFilePath); - - Assert.IsTrue(File.Exists(filteredVimFilePath)); - - var filteredVim = VimScene.LoadVim(filteredVimFilePath); - filteredVim.Validate(); - } - - [Test] - public static void TestMergeDedupAndFilter() - { - var ctx = new CallerTestContext(); - var dir = ctx.PrepareDirectory(); - - var vimFilePath = VimFormatRepoPaths.GetDataFilePath("Dwelling*.vim", true); - - // Setup: Merge two identical VIM files as a grid. - var vim1 = VimScene.LoadVim(vimFilePath); - var vim2 = VimScene.LoadVim(vimFilePath); - - var generatorString = nameof(TestMergeDedupAndFilter); - var versionString = "0.0.0"; - - var mergedDb = MergeService.MergeVimScenes( - new MergeConfigVimScenes(new[] { vim1, vim2 }), - new MergeConfigOptions - { - MergeAsGrid = true, - GridPadding = 10f, - GeneratorString = generatorString, - VersionString = versionString - }); - - var mergedVimFilePath = Path.Combine(dir, "merged.vim"); - mergedDb.Write(mergedVimFilePath); - var mergedVim = VimScene.LoadVim(mergedVimFilePath); - mergedVim.Validate(); - - // Deduplicate identical meshes using the transform service. - - var transformService = new TransformService(generatorString, versionString); - - var dedupDb = transformService.DeduplicateGeometry(mergedVim); - var dedupVimFilePath = Path.Combine(dir, "dedup.vim"); - dedupDb.Write(dedupVimFilePath); - var dedupVim = VimScene.LoadVim(dedupVimFilePath); - dedupVim.Validate(); - - Assert.Less(dedupVim.Meshes.Count, mergedVim.Meshes.Count); - - // Bonus: filter the deduplicated VIM and only keep the windows - - var filteredDb = transformService.Filter(dedupVim, n => n.CategoryName == "Casework"); - var filteredVimFilePath = Path.Combine(dir, "filtered.vim"); - filteredDb.Write(filteredVimFilePath); - var filteredVim = VimScene.LoadVim(filteredVimFilePath); - filteredVim.Validate(); - } -} diff --git a/src/cs/vim/Vim.Format.Tests/ElementHierarchyTests.cs b/src/cs/vim/Vim.Format.Tests/VimElementHierarchyTests.cs similarity index 85% rename from src/cs/vim/Vim.Format.Tests/ElementHierarchyTests.cs rename to src/cs/vim/Vim.Format.Tests/VimElementHierarchyTests.cs index 5b3804c8..3d9d9a68 100644 --- a/src/cs/vim/Vim.Format.Tests/ElementHierarchyTests.cs +++ b/src/cs/vim/Vim.Format.Tests/VimElementHierarchyTests.cs @@ -1,19 +1,16 @@ using NUnit.Framework; using System.Collections.Generic; -using System.IO; using System.Linq; -using Vim.Format.ObjectModel; -using Vim.LinqArray; using Vim.Util; using Vim.Util.Tests; namespace Vim.Format.Tests; [TestFixture] -public static class ElementHierarchyTests +public static class VimElementHierarchyTests { [Test] - public static void TestFlattenElementHierarchy() + public static void TestFlattenVimElementHierarchy() { var ctx = new CallerTestContext(); var _ = ctx.PrepareDirectory(); @@ -43,22 +40,22 @@ public static void TestFlattenElementHierarchy() // Observations: // - RootDistance is always the distance of the terminal object from the root. - var dummyA = new ElementGeometryInfo(0); - var dummyB = new ElementGeometryInfo(1); - var dummyC = new ElementGeometryInfo(2); - var dummyD = new ElementGeometryInfo(3); - dummyD.NodeAndGeometryIndices.Add((33, 33)); - var dummyE = new ElementGeometryInfo(4); - dummyE.NodeAndGeometryIndices.Add((44, 44)); + var dummyA = new VimElementGeometryInfo(0); + var dummyB = new VimElementGeometryInfo(1); + var dummyC = new VimElementGeometryInfo(2); + var dummyD = new VimElementGeometryInfo(3); + dummyD.InstanceAndMeshIndices.Add((33, 33)); + var dummyE = new VimElementGeometryInfo(4); + dummyE.InstanceAndMeshIndices.Add((44, 44)); - var dummyMap = new ElementGeometryMap(new[] + var dummyMap = new[] { dummyA, dummyB, dummyC, dummyD, dummyE - }); + }; var A = new Tree { Value = dummyA.ElementIndex }; var B = new Tree { Value = dummyB.ElementIndex }; @@ -74,14 +71,14 @@ public static void TestFlattenElementHierarchy() var treeRoot = new Tree { Value = -1 }; // Add a dummy root. treeRoot.AddChild(A); - var flattened = ElementHierarchyService.FlattenElementHierarchy( + var flattened = VimElementHierarchyService.FlattenElementHierarchy( treeRoot, false, dummyMap) .OrderBy(r => (Element: r.Element, Descendant: r.Descendant, r.Distance, r.RootDistance)) .ToList(); - var expected = new List() + var expected = new List() { // A | A | 0 | 0 new () @@ -207,7 +204,7 @@ public static void TestFlattenElementHierarchy() .OrderBy(r => (Element: r.Element, Descendant: r.Descendant, r.Distance, r.RootDistance)) .ToList(); - void logRecords(IReadOnlyCollection records, string title) + void logRecords(IReadOnlyCollection records, string title) { logger.Log($"~~~ {title} ({records.Count}) ~~~"); foreach (var item in records) @@ -237,17 +234,16 @@ void logRecords(IReadOnlyCollection records, string title) [TestCase(true)] [TestCase(false)] - public static void TestElementHierarchy(bool isElementAndDescendantPrimaryKey) + public static void TestVimElementHierarchy(bool isElementAndDescendantPrimaryKey) { var ctx = new CallerTestContext(); ctx.PrepareDirectory(); var vimFilePath = VimFormatRepoPaths.GetDataFilePath("Wolford_Residence.r2025.om_v5.6.0.vim", false); - var fileInfo = new FileInfo(vimFilePath); - var g3d = Serializer.Deserialize(vimFilePath, new() { SchemaOnly = true, SkipAssets = true }).Geometry; - var map = new ElementGeometryMap(fileInfo, g3d); - var service = new ElementHierarchyService(fileInfo, map, isElementAndDescendantPrimaryKey); + var vim = VIM.Open(vimFilePath, new VimOpenOptions { IncludeAssets = false }); + + var service = vim.GetElementHierarchyService(isElementAndDescendantPrimaryKey); var root = service.GetElementIndexHierarchy(); Assert.IsNotEmpty(root.Children); @@ -257,8 +253,7 @@ public static void TestElementHierarchy(bool isElementAndDescendantPrimaryKey) if (!isElementAndDescendantPrimaryKey) { // Validate that the descendant element's node correctly references the element. - var vim = VimScene.LoadVim(vimFilePath); - var nodes = vim.DocumentModel.NodeList.ToArray(); + var nodes = vim.GetEntityTableSet().NodeTable.ToArray(); foreach (var item in flatHierarchy) { var descendantElementIndex = item.Descendant; diff --git a/src/cs/vim/Vim.Format.Tests/VimElementKindTests.cs b/src/cs/vim/Vim.Format.Tests/VimElementKindTests.cs new file mode 100644 index 00000000..3e5e8507 --- /dev/null +++ b/src/cs/vim/Vim.Format.Tests/VimElementKindTests.cs @@ -0,0 +1,41 @@ +using NUnit.Framework; +using System; +using System.IO; +using System.Linq; +using Vim.Util.Tests; + +namespace Vim.Format.Tests; + +[TestFixture] +public static class VimElementKindTests +{ + [Test] + public static void TestElementTableKinds() + { + var fileInfo = new FileInfo(VimFormatRepoPaths.GetDataFilePath("Dwelling*.vim", true)); + + Console.WriteLine($"Loading {fileInfo.FullName}"); + + var elementKinds = VimEntityTableSet.GetElementKinds(fileInfo); + + var ets = VIM.Open(fileInfo).GetEntityTableSet(); + + Assert.IsNotEmpty(elementKinds); + Assert.AreEqual(ets.ElementTable.RowCount, elementKinds.Length); + + var familyInstanceCount = elementKinds.Count(e => e == ElementKind.FamilyInstance); + Assert.Greater(familyInstanceCount, 0); + Assert.AreEqual(ets.FamilyInstanceTable.Column_ElementIndex.Distinct().Count(ei => ei != EntityRelation.None), familyInstanceCount); + Assert.IsTrue(ets.FamilyInstanceTable.Column_ElementIndex.All(ei => ei == EntityRelation.None || elementKinds[ei] == ElementKind.FamilyInstance)); + + var familyTypeCount = elementKinds.Count(e => e == ElementKind.FamilyType); + Assert.Greater(familyTypeCount, 0); + Assert.AreEqual(ets.FamilyTypeTable.Column_ElementIndex.Distinct().Count(ei => ei != EntityRelation.None), familyTypeCount); + Assert.IsTrue(ets.FamilyTypeTable.Column_ElementIndex.All(ei => ei == EntityRelation.None || elementKinds[ei] == ElementKind.FamilyType)); + + var familyCount = elementKinds.Count(e => e == ElementKind.Family); + Assert.Greater(familyCount, 0); + Assert.AreEqual(ets.FamilyTable.Column_ElementIndex.Distinct().Count(ei => ei != EntityRelation.None), familyCount); + Assert.IsTrue(ets.FamilyTable.Column_ElementIndex.All(ei => ei == EntityRelation.None || elementKinds[ei] == ElementKind.Family)); + } +} diff --git a/src/cs/vim/Vim.Format.Tests/ElementParameterInfoServiceTests.cs b/src/cs/vim/Vim.Format.Tests/VimElementParameterInfoServiceTests.cs similarity index 90% rename from src/cs/vim/Vim.Format.Tests/ElementParameterInfoServiceTests.cs rename to src/cs/vim/Vim.Format.Tests/VimElementParameterInfoServiceTests.cs index 32cbcfd4..bb9f7b7b 100644 --- a/src/cs/vim/Vim.Format.Tests/ElementParameterInfoServiceTests.cs +++ b/src/cs/vim/Vim.Format.Tests/VimElementParameterInfoServiceTests.cs @@ -4,14 +4,13 @@ using System.IO; using System.Linq; using Vim.Format.ElementParameterInfo; -using Vim.Format.ObjectModel; using Vim.Util.Logging; using Vim.Util.Tests; namespace Vim.Format.Tests; [TestFixture] -public static class ElementParameterInfoServiceTests +public static class VimElementParameterInfoServiceTests { public static IEnumerable TestVimFilePaths => TestFiles.VimFilePaths; @@ -26,20 +25,18 @@ public static void TestElementParameterInfoService(string vimFilePath) using var _ = logger.LogDuration($"{nameof(TestElementParameterInfoService)}: {vimFilePath}"); var vimFileInfo = new FileInfo(vimFilePath); + var vim = VIM.Open(vimFileInfo); - var stringTable = vimFileInfo.GetStringTable(); + var stringTable = vim.StringTable; - var infos = ElementParameterInfoService.GetElementParameterInfos(vimFileInfo, stringTable); + var infos = VimElementParameterInfoService.GetElementParameterInfos(vimFileInfo, stringTable); var levelInfos = infos.LevelInfos; var elementLevelInfos = infos.ElementLevelInfos; var elementMeasureInfos = infos.ElementMeasureInfos; var elementIfcInfos = infos.ElementIfcInfos; var parameterMeasureTypes = infos.ParameterMeasureTypes; - var validationTableSet = new EntityTableSet( - vimFileInfo, - stringTable, - n => n is TableNames.Level or TableNames.Element or TableNames.FamilyInstance or TableNames.Parameter); + var validationTableSet = vim.GetEntityTableSet(); Assert.AreEqual(validationTableSet.LevelTable.RowCount, levelInfos.Length); diff --git a/src/cs/vim/Vim.Format.Tests/MergeServiceTests.cs b/src/cs/vim/Vim.Format.Tests/VimMergeServiceTests.cs similarity index 62% rename from src/cs/vim/Vim.Format.Tests/MergeServiceTests.cs rename to src/cs/vim/Vim.Format.Tests/VimMergeServiceTests.cs index 3ed9f5ee..48f9a268 100644 --- a/src/cs/vim/Vim.Format.Tests/MergeServiceTests.cs +++ b/src/cs/vim/Vim.Format.Tests/VimMergeServiceTests.cs @@ -3,10 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Vim.Format.Merge; -using Vim.Format.ObjectModel; -using Vim.Format.SceneBuilder; -using Vim.LinqArray; using Vim.Math3d; using Vim.Util; using Vim.Util.Tests; @@ -14,7 +10,7 @@ namespace Vim.Format.Tests { [TestFixture] - public static class MergeServiceTests + public static class VimMergeServiceTests { [Test] public static void TestSameMergeFile() @@ -26,7 +22,7 @@ public static void TestSameMergeFile() var mergedVimFilePath = Path.Combine(dir, "rooms_merged.vim"); - var configFiles = new MergeConfigFiles( + var configFiles = new VimMergeConfigFiles( new[] { // First VIM is centered at the origin @@ -35,36 +31,38 @@ public static void TestSameMergeFile() (vim, Matrix4x4.CreateTranslation(Vector3.UnitX * 100)) }, mergedVimFilePath); - var configOptions = new MergeConfigOptions() + var configOptions = new VimMergeConfigOptions() { GeneratorString = ctx.TestName, DeduplicateEntities = true, KeepBimData = true, }; - MergeService.MergeVimFiles(configFiles, configOptions); + VimMergeService.Merge(configFiles, configOptions); - var baseVim = VimScene.LoadVim(vim); + var baseVim = VIM.Open(vim); baseVim.Validate(); + var baseVimTableSet = baseVim.GetEntityTableSet(); - var mergedVim = VimScene.LoadVim(mergedVimFilePath); + var mergedVim = VIM.Open(mergedVimFilePath); mergedVim.Validate(); + var mergedVimTableSet = mergedVim.GetEntityTableSet(); // The categories should be deduplicated - var numCategoriesBase = baseVim.DocumentModel.NumCategory; - var numCategoriesMerged = mergedVim.DocumentModel.NumCategory; + var numCategoriesBase = baseVimTableSet.CategoryTable.RowCount; + var numCategoriesMerged = mergedVimTableSet.CategoryTable.RowCount; Assert.AreEqual(numCategoriesBase, numCategoriesMerged); // The number of elements which originally had a category must be doubled in the merged VIM file. - var numElementsWithCategoryBase = baseVim.DocumentModel.ElementList.ToList().Count(e => e.Category != null); - var numElementsWithCategoryMerged = mergedVim.DocumentModel.ElementList.ToList().Count(e => e.Category != null); + var numElementsWithCategoryBase = baseVimTableSet.ElementTable.Count(e => e.Category != null); + var numElementsWithCategoryMerged = mergedVimTableSet.ElementTable.Count(e => e.Category != null); Assert.Greater(numElementsWithCategoryBase, 0); Assert.Greater(numElementsWithCategoryMerged, 0); Assert.AreEqual(numElementsWithCategoryBase * 2, numElementsWithCategoryMerged); // The display units should be deduplicated. - var numDisplayUnitsMerged = mergedVim.DocumentModel.NumDisplayUnit; - var numDisplayUnitsBase = baseVim.DocumentModel.NumDisplayUnit; + var numDisplayUnitsMerged = mergedVimTableSet.DisplayUnitTable.RowCount; + var numDisplayUnitsBase = baseVimTableSet.DisplayUnitTable.RowCount; Assert.AreEqual(numDisplayUnitsBase, numDisplayUnitsMerged); } @@ -78,14 +76,14 @@ public static void TestMergeDifferentFilesAsGrid() var vimFilePath2 = Path.Combine(VimFormatRepoPaths.DataDir, "Wolford_Residence.r2023.om_v5.0.0.vim"); var mergedVimFilePath = Path.Combine(dir, "merged.vim"); - var configFiles = new MergeConfigFiles( + var configFiles = new VimMergeConfigFiles( new[] { (vimFilePath1, Matrix4x4.Identity), (vimFilePath2, Matrix4x4.Identity) }, mergedVimFilePath); - var configOptions = new MergeConfigOptions() + var configOptions = new VimMergeConfigOptions() { GeneratorString = ctx.TestName, DeduplicateEntities = true, @@ -93,29 +91,32 @@ public static void TestMergeDifferentFilesAsGrid() MergeAsGrid = true, }; - MergeService.MergeVimFiles(configFiles, configOptions); + VimMergeService.Merge(configFiles, configOptions); - var vim1 = VimScene.LoadVim(vimFilePath1); + var vim1 = VIM.Open(vimFilePath1); vim1.Validate(); + var vim1TableSet = vim1.GetEntityTableSet(); - var vim2 = VimScene.LoadVim(vimFilePath2); + var vim2 = VIM.Open(vimFilePath2); vim2.Validate(); + var vim2TableSet = vim2.GetEntityTableSet(); - var mergedVim = VimScene.LoadVim(mergedVimFilePath); + var mergedVim = VIM.Open(mergedVimFilePath); mergedVim.Validate(); + var mergedVimTableSet = mergedVim.GetEntityTableSet(); // The categories in the merged VIM must be a distinct count of the categories in vim1 and vim2. - var categoriesVim1 = vim1.DocumentModel.CategoryList.ToEnumerable(); - var categoriesVim2 = vim2.DocumentModel.CategoryList.ToEnumerable(); + var categoriesVim1 = vim1TableSet.CategoryTable.ToArray(); + var categoriesVim2 = vim2TableSet.CategoryTable.ToArray(); var distinctCategoryCount = categoriesVim1.Concat(categoriesVim2).Distinct(new CategoryEqualityComparer()).Count(); - var mergedCategoryCount = mergedVim.DocumentModel.NumCategory; + var mergedCategoryCount = mergedVimTableSet.CategoryTable.RowCount; Assert.AreEqual(distinctCategoryCount, mergedCategoryCount); // The display units in the merged VIM must be a distinct count of the display units in vim1 and vim2. - var displayUnitsVim1 = vim1.DocumentModel.DisplayUnitList.ToEnumerable(); - var displayUnitsVim2 = vim2.DocumentModel.DisplayUnitList.ToEnumerable(); + var displayUnitsVim1 = vim1TableSet.DisplayUnitTable.ToArray(); + var displayUnitsVim2 = vim2TableSet.DisplayUnitTable.ToArray(); var distinctDisplayUnitCount = displayUnitsVim1.Concat(displayUnitsVim2).Distinct(new DisplayUnitEqualityComparer()).Count(); - var mergedDisplayUnitCount = mergedVim.DocumentModel.NumDisplayUnit; + var mergedDisplayUnitCount = mergedVimTableSet.DisplayUnitTable.RowCount; Assert.AreEqual(distinctDisplayUnitCount, mergedDisplayUnitCount); } @@ -153,6 +154,35 @@ public int GetHashCode(DisplayUnit obj) } } + [Test] + public static void TestMergeShouldSucceedOnCompatibleObjectModelVersions() + { + var ctx = new CallerTestContext(); + var dir = ctx.PrepareDirectory(); + + var vim1 = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); + var vim2 = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTestModified.vim"); + + var mergedVimFilePath = Path.Combine(dir, "room_merge.vim"); + + var configFiles = new VimMergeConfigFiles( + new[] + { + // First VIM is centered at the origin + (vim1, Matrix4x4.Identity), + // Second VIM is offset by 100 units along +X + (vim2, Matrix4x4.CreateTranslation(Vector3.UnitX * 100)) + }, mergedVimFilePath); + + var configOptions = new VimMergeConfigOptions() { GeneratorString = ctx.TestName, VersionString = "0.0.0", }; + VimMergeService.Merge(configFiles, configOptions); + + Assert.IsTrue(File.Exists(mergedVimFilePath)); + + var mergedVim = VIM.Open(mergedVimFilePath); + mergedVim.Validate(); + } + [Test] public static void TestMergeFailsOnMismatchedObjectModelVersions() { @@ -163,7 +193,7 @@ public static void TestMergeFailsOnMismatchedObjectModelVersions() var vim2 = Path.Combine(VimFormatRepoPaths.DataDir, "Wolford_Residence.r2023.om_v4.4.0.vim"); var mergedVimFilePath = Path.Combine(dir, "should_fail.vim"); - var configFiles = new MergeConfigFiles( + var configFiles = new VimMergeConfigFiles( new[] { // First VIM is centered at the origin @@ -172,7 +202,7 @@ public static void TestMergeFailsOnMismatchedObjectModelVersions() (vim2, Matrix4x4.CreateTranslation(Vector3.UnitX * 100)) }, mergedVimFilePath); - var configOptions = new MergeConfigOptions() + var configOptions = new VimMergeConfigOptions() { GeneratorString = ctx.TestName, DeduplicateEntities = true, @@ -182,12 +212,12 @@ public static void TestMergeFailsOnMismatchedObjectModelVersions() // Validate that an exception is thrown due to mismatching object model major versions try { - MergeService.MergeVimFiles(configFiles, configOptions); - Assert.Fail($"Expected an exception to be thrown ({ErrorCode.VimMergeObjectModelMajorVersionMismatch:G})"); + VimMergeService.Merge(configFiles, configOptions); + Assert.Fail($"Expected an exception to be thrown ({VimErrorCode.VimMergeObjectModelMajorVersionMismatch:G})"); } catch (HResultException e) { - Assert.AreEqual((int) ErrorCode.VimMergeObjectModelMajorVersionMismatch, e.HResult); + Assert.AreEqual((int) VimErrorCode.VimMergeObjectModelMajorVersionMismatch, e.HResult); } } } diff --git a/src/cs/vim/Vim.Format.Tests/VimQuadMeshStripTests.cs b/src/cs/vim/Vim.Format.Tests/VimQuadMeshStripTests.cs new file mode 100644 index 00000000..cebeaddd --- /dev/null +++ b/src/cs/vim/Vim.Format.Tests/VimQuadMeshStripTests.cs @@ -0,0 +1,78 @@ +using System.Linq; +using Vim.Util; +using NUnit.Framework; + +namespace Vim.Format.Tests +{ + [TestFixture] + public static class VimQuadMeshStripTests + { + [Test] + public static void QuadMeshStripIndicesTests() + { + var emptyStrip00 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(0, 0); + Assert.AreEqual(0, emptyStrip00.Count); + + var emptyStrip01 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(0, 1); + Assert.AreEqual(0, emptyStrip01.Count); + + var emptyStrip10 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(1, 0); + Assert.AreEqual(0, emptyStrip10.Count); + + var emptyStrip11 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(1, 1); + Assert.AreEqual(0, emptyStrip11.Count); + + var emptyStrip12 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(1, 2); + Assert.AreEqual(0, emptyStrip12.Count); + + var emptyStrip21 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(2, 1); + Assert.AreEqual(0, emptyStrip21.Count); + + // COUNTER-CLOCKWISE TEST (DEFAULT) + // 2------3 <--- row 1: [2,3] + // | | => counter-clockwise quad: (0,1,3,2) + // | | + // 0------1 <--- row 0: [0,1] + var strip22 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(2, 2); + Assert.AreEqual(4, strip22.Count); + Assert.AreEqual(0, strip22[0]); + Assert.AreEqual(1, strip22[1]); + Assert.AreEqual(3, strip22[2]); + Assert.AreEqual(2, strip22[3]); + + // CLOCKWISE TEST + // 2------3 <--- row 1: [2,3] + // | | => clockwise quad: (2,3,1,0) + // | | + // 0------1 <--- row 0: [0,1] + var clockwiseStrip22 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(2, 2, true); + Assert.AreEqual(4, clockwiseStrip22.Count); + Assert.AreEqual(2, clockwiseStrip22[0]); + Assert.AreEqual(3, clockwiseStrip22[1]); + Assert.AreEqual(1, clockwiseStrip22[2]); + Assert.AreEqual(0, clockwiseStrip22[3]); + var reversed22 = clockwiseStrip22.Reversed().ToArray(); + for (var i = 0; i < strip22.Count; ++i) + { + Assert.AreEqual(strip22[i], reversed22[i]); + } + + // *------*------* + // | | | + // | | | + // *------*------* + var strip23 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(2, 3); + Assert.AreEqual(4 * 2, strip23.Count); + + // *------*------*------* + // | | | | + // | | | | + // *------*------*------* + // | | | | + // | | | | + // *------*------*------* + var strip34 = VimQuadMeshStrip.QuadMeshStripIndicesFromPointRows(3, 4); + Assert.AreEqual(4 * 6, strip34.Count); + } + } +} diff --git a/src/cs/vim/Vim.Format.Tests/RoomServiceTests.cs b/src/cs/vim/Vim.Format.Tests/VimRoomServiceTests.cs similarity index 57% rename from src/cs/vim/Vim.Format.Tests/RoomServiceTests.cs rename to src/cs/vim/Vim.Format.Tests/VimRoomServiceTests.cs index 8359ca8e..82cc826c 100644 --- a/src/cs/vim/Vim.Format.Tests/RoomServiceTests.cs +++ b/src/cs/vim/Vim.Format.Tests/VimRoomServiceTests.cs @@ -1,16 +1,13 @@ using NUnit.Framework; using System.IO; -using System.Linq; -using Vim.Format.Merge; -using Vim.Format.ObjectModel; -using Vim.Format.SceneBuilder; using Vim.Math3d; using Vim.Util.Tests; +using System.Collections.Generic; namespace Vim.Format.Tests; [TestFixture] -public static class RoomServiceTests +public static class VimRoomServiceTests { /// /// Merges two unrelated VIM files and then calculates the inclusion of elements @@ -27,38 +24,35 @@ public static void TestRoomService_ComputeElementsInRoom() var vim2 = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); var mergedFilePath = Path.Combine(dir, "merged.vim"); - var mergeFiles = new MergeConfigFiles(new[] + var mergeFiles = new VimMergeConfigFiles(new[] { (vim1, Matrix4x4.Identity), (vim2, Matrix4x4.Identity) }, mergedFilePath); - var mergeOptions = new MergeConfigOptions() + var mergeOptions = new VimMergeConfigOptions() { GeneratorString = nameof(TestRoomService_ComputeElementsInRoom), VersionString = "0.0.0", }; - MergeService.MergeVimFiles(mergeFiles, mergeOptions); + VimMergeService.Merge(mergeFiles, mergeOptions); - var mergedVim = VimScene.LoadVim(mergedFilePath); + var mergedVim = VIM.Open(mergedFilePath); Assert.DoesNotThrow(() => mergedVim.Validate()); - var dm = mergedVim.DocumentModel; + var mergedVimTableSet = mergedVim.GetEntityTableSet(); + var elementKinds = mergedVimTableSet.GetElementKinds(); - var elementInfos = - Enumerable.Range(0, mergedVim.DocumentModel.NumElement) - .AsParallel() - .Select(elementIndex => dm.GetElementInfo(elementIndex)) - .ToArray(); - - var wolfordFamilyInstances = elementInfos - .Where(ei => ei.BimDocumentFileName.Contains("Wolford") && ei.IsFamilyInstance) - .ToArray(); - var wolfordFamilyInstanceElementIndices = wolfordFamilyInstances.Select(ei => ei.ElementIndex).ToHashSet(); + var wolfordFamilyInstanceElementIndices = new HashSet(); + for (var i = 0; i < elementKinds.Length; ++i) + { + if (elementKinds[i] == ElementKind.FamilyInstance) + wolfordFamilyInstanceElementIndices.Add(i); + } // Compute the element association in each room. - var familyInstancesInRooms = RoomService.ComputeElementsInRoom( + var familyInstancesInRooms = VimRoomService.ComputeElementsInRoom( mergedVim, ei => wolfordFamilyInstanceElementIndices.Contains(ei.ElementIndex)); diff --git a/src/cs/vim/Vim.Format.Tests/VimTransformServiceTests.cs b/src/cs/vim/Vim.Format.Tests/VimTransformServiceTests.cs new file mode 100644 index 00000000..b5c0a75b --- /dev/null +++ b/src/cs/vim/Vim.Format.Tests/VimTransformServiceTests.cs @@ -0,0 +1,219 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Vim.Math3d; +using Vim.Util.Tests; + +namespace Vim.Format.Tests; + +[TestFixture] +public static class VimTransformServiceTests +{ + [TestCase("Walls")] + [TestCase("Doors")] + [TestCase("BOGUS_CATEGORY_THIS_REMOVES_ALL_NODES")] + public static void TestVimTransformService(string categoryName) + { + var ctx = new CallerTestContext(subDirComponents: categoryName); + var dir = ctx.PrepareDirectory(); + + bool IsFamilyInstanceWithCategoryOrTrue(int i, VimEntityTableSet t, ElementKind[] k) + => k[i] == ElementKind.FamilyInstance + ? t.GetElement(i)?.Category?.Name == categoryName + : true; + + var vimFilePath = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); + var vim = VIM.Open(vimFilePath); + var tableSet = vim.GetEntityTableSet(); + var elementKinds = tableSet.GetElementKinds(); + + // Keep the elements of the given category and rotate them upside down. + var transformService = new VimTransformService(nameof(TestVimTransformService), "0.0.0"); + var transformResult = transformService.Transform( + vim, + e => IsFamilyInstanceWithCategoryOrTrue(e.ElementIndex, tableSet, elementKinds), + (i, t) => Matrix4x4.CreateFromAxisAngle(Vector3.UnitX, (float)Math.PI) * t, + false); + + var transformedVimFilePath = Path.Combine(dir, $"transformed_{categoryName}.vim"); + transformResult.Write(transformedVimFilePath); + + Assert.IsTrue(File.Exists(transformedVimFilePath)); + + var transformedVim = VIM.Open(transformedVimFilePath); + transformedVim.Validate(); + + var transformedElementGeometryInfoList = transformedVim.GetElementGeometryInfoList(); + var transformedTableSet = transformedVim.GetEntityTableSet(); + var transformedElementKinds = transformedTableSet.GetElementKinds(); + + Assert.IsTrue(transformedElementGeometryInfoList.All(e => + IsFamilyInstanceWithCategoryOrTrue(e.ElementIndex, transformedTableSet, transformedElementKinds))); + + Assert.IsTrue(transformedTableSet.NodeTable.All(n => + IsFamilyInstanceWithCategoryOrTrue(n.ElementIndex, transformedTableSet, transformedElementKinds))); + + Assert.IsTrue(transformedTableSet.FamilyInstanceTable.All(fi => + transformedElementKinds[fi.ElementIndex] == ElementKind.FamilyInstance && + IsFamilyInstanceWithCategoryOrTrue(fi.ElementIndex, transformedTableSet, transformedElementKinds))); + } + + [Test] + public static void TestSplitMerge() + { + var ctx = new CallerTestContext(); + var dir = ctx.PrepareDirectory(); + + var vimFilePath = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); + var vim = VIM.Open(vimFilePath); + var transformService = new VimTransformService(nameof(TestSplitMerge), "0.0.0"); + + var gd = vim.GeometryData; + var box = gd.GetWorldSpaceBoundingBox(); + + bool IsLeft(int instanceIndex, int meshIndex) + { + if (!vim.GeometryData.TryGetTransformedMesh(instanceIndex, meshIndex, out var vimMeshData)) + return false; + + var meshBb = vimMeshData.GetBoundingBox(); + + return meshBb.Center.X < box.Center.X; + } + + // Get the left part of the VIM file + var leftVimFilePath = Path.Combine(dir, "left.vim"); + { + var filterResult = transformService.Filter(vim, e => + { + if (!e.HasMesh) return true; + return e.InstanceAndMeshIndices.Any(t => IsLeft(t.InstanceIndex, t.MeshIndex)); + }); + filterResult.Write(leftVimFilePath); + Assert.IsTrue(File.Exists(leftVimFilePath)); + } + var leftVim = VIM.Open(leftVimFilePath); + leftVim.Validate(); + + // Get the right part of the VIM file. + var rightVimFilePath = Path.Combine(dir, "right.vim"); + { + var filterResult = transformService.Filter(vim, e => + { + if (!e.HasMesh) return true; + return e.InstanceAndMeshIndices.All(t => !IsLeft(t.InstanceIndex, t.MeshIndex)); + }); + filterResult.Write(rightVimFilePath); + Assert.IsTrue(File.Exists(rightVimFilePath)); + } + var rightVim = VIM.Open(rightVimFilePath); + rightVim.Validate(); + + bool HasGeometry(VimElementGeometryInfo egi) => egi.HasMesh; + + Assert.AreEqual( + vim.GetElementGeometryInfoList().Count(HasGeometry), + leftVim.GetElementGeometryInfoList().Count(HasGeometry) + rightVim.GetElementGeometryInfoList().Count(HasGeometry)); + + Assert.AreEqual(vim.EntityTableData.Count, leftVim.EntityTableData.Count); + Assert.AreEqual(vim.EntityTableData.Count, rightVim.EntityTableData.Count); + + var mergedVimFilePath = Path.Combine(dir, "merged.vim"); + var mergeResult = VimMergeService.Merge( + new VimMergeConfig(new[] { leftVim, rightVim }), + new VimMergeConfigOptions()); + mergeResult.Write(mergedVimFilePath); + Assert.IsTrue(File.Exists(mergedVimFilePath)); + var mergedVim = VIM.Open(mergedVimFilePath); + mergedVim.Validate(); + + Assert.AreEqual( + vim.GetElementGeometryInfoList().Count(HasGeometry), + mergedVim.GetElementGeometryInfoList().Count(HasGeometry)); + + Assert.AreEqual(vim.EntityTableData.Count, mergedVim.EntityTableData.Count); + + var sourceStringSet = new HashSet(vim.StringTable); + var mergedStringSet = new HashSet(mergedVim.StringTable); + mergedStringSet.ExceptWith(sourceStringSet); + Assert.AreEqual(0, mergedStringSet.Count); + + Assert.AreEqual(vim.Assets.Length, mergedVim.Assets.Length); + } + + [Test] + public static void TestFilter() + { + var ctx = new CallerTestContext(); + var dir = ctx.PrepareDirectory(); + + var vimFilePath = Path.Combine(VimFormatRepoPaths.DataDir, "RoomTest.vim"); + var vim = VIM.Open(vimFilePath); + + // Just keep the even-numbered nodes. + var transformService = new VimTransformService(nameof(TestFilter), "0.0.0"); + var counter = 0; + var transformed = transformService.Filter(vim, e => !e.HasMesh || (counter++ % 2 == 0)); + + var filteredVimFilePath = Path.Combine(dir, "evens.vim"); + transformed.Write(filteredVimFilePath); + + Assert.IsTrue(File.Exists(filteredVimFilePath)); + + var filteredVim = VIM.Open(filteredVimFilePath); + filteredVim.Validate(); + } + + [Test] + public static void TestMergeDedupAndFilter() + { + var ctx = new CallerTestContext(); + var dir = ctx.PrepareDirectory(); + + var vimFilePath = VimFormatRepoPaths.GetDataFilePath("Dwelling*.vim", true); + + // Setup: Merge two identical VIM files as a grid. + var vim1 = VIM.Open(vimFilePath); + var vim2 = VIM.Open(vimFilePath); + + var generatorString = nameof(TestMergeDedupAndFilter); + var versionString = "0.0.0"; + + var merged = VimMergeService.Merge( + new VimMergeConfig(new[] { vim1, vim2 }), + new VimMergeConfigOptions + { + MergeAsGrid = true, + GridPadding = 10f, + GeneratorString = generatorString, + VersionString = versionString + }); + + var mergedVimFilePath = Path.Combine(dir, "merged.vim"); + merged.Write(mergedVimFilePath); + var mergedVim = VIM.Open(mergedVimFilePath); + mergedVim.Validate(); + + // Deduplicate identical meshes using the transform service. + + var transformService = new VimTransformService(generatorString, versionString); + + var dedup = transformService.DeduplicateGeometry(mergedVim); + var dedupVimFilePath = Path.Combine(dir, "dedup.vim"); + dedup.Write(dedupVimFilePath); + var dedupVim = VIM.Open(dedupVimFilePath); + dedupVim.Validate(); + + Assert.Less(dedupVim.GeometryData.MeshCount, mergedVim.GeometryData.MeshCount); + + // Bonus: filter the deduplicated VIM and only keep the windows + + var filtered = transformService.Filter(dedupVim, e => !e.HasMesh || dedupVim.GetEntityTableSet().GetElement(e.ElementIndex).Category?.Name == "Casework"); + var filteredVimFilePath = Path.Combine(dir, "filtered.vim"); + filtered.Write(filteredVimFilePath); + var filteredVim = VIM.Open(filteredVimFilePath); + filteredVim.Validate(); + } +} diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementIfcInfo.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementIfcInfo.cs index de4e619b..46ad8d00 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementIfcInfo.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementIfcInfo.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Vim.Format.ObjectModel; // SOME BACKGROUND INFORMATION ABOUT ELEMENT IFC GUIDS // @@ -22,7 +21,7 @@ public class ElementIfcInfo : IElementIndex public Element Element { get; } public int GetElementIndexOrNone() - => Element.IndexOrDefault(); + => EntityRelation.IndexOrDefault(Element); /// /// A 22 character IFC encoded GUID composed of case-sensitive characters. @@ -52,7 +51,7 @@ public int GetElementIndexOrNone() public ElementIfcInfo( Element element, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) { Element = element; diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementLevelInfo.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementLevelInfo.cs index 04280226..474fa001 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementLevelInfo.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementLevelInfo.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using Vim.Format.ObjectModel; +using System.Linq; using Vim.Util; // ReSharper disable InconsistentNaming @@ -77,7 +77,7 @@ public class ElementLevelInfo : IElementIndex /// Returns the element index. /// public int GetElementIndexOrNone() - => Element.IndexOrDefault(); + => EntityRelation.IndexOrDefault(Element); /// /// The schedule level associated to the element parameters. Can be null. @@ -226,8 +226,8 @@ public ElementLevelInfo( FamilyInstanceTable familyInstanceTable, LevelTable levelTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps, - ElementGeometryMap elementGeometryMap, + VimElementIndexMaps elementIndexMaps, + VimElementGeometryInfo[] elementGeometryMap, IReadOnlyDictionary levelInfoMap, IReadOnlyList orderedLevelInfosByProjectElevation, IReadOnlyDictionary elementIdToLevelInfoMap, @@ -247,7 +247,7 @@ public ElementLevelInfo( LevelInfo = levelInfo; } } - + if (TryGetHostLevel(element, elementTable, familyInstanceTable, levelTable, elementIndexMaps, elementIdToLevelInfoMap, out var hostLevelInfo)) HostLevelInfo = hostLevelInfo; @@ -306,7 +306,7 @@ private static bool TryGetHostLevel( ElementTable elementTable, FamilyInstanceTable familyInstanceTable, LevelTable levelTable, - ElementIndexMaps elementIndexMaps, + VimElementIndexMaps elementIndexMaps, IReadOnlyDictionary elementIdToLevelInfoMap, out LevelInfo hostLevelInfo) { @@ -369,9 +369,9 @@ private static BuildingStoryGeometryContainment GetBuildingStoryGeometryContainm int elementIndex, double? primaryProjectElevation, IReadOnlyList orderedLevelInfosByProjectElevation, - ElementGeometryMap elementGeometryMap, + VimElementGeometryInfo[] elementGeometryMap, double geometryContainmentTolerance, - out LevelInfo maybeBuildingStoryAbove, + out LevelInfo maybeBuildingStoryAbove, out LevelInfo maybeBuildingStoryCurrentOrBelow, out LevelInfo maybeBuildingStoryGeometryMin, out LevelInfo maybeBuildingStoryGeometryMax) @@ -387,7 +387,7 @@ private static BuildingStoryGeometryContainment GetBuildingStoryGeometryContainm // Note: Level.ProjectElevation is relative to the internal scene origin (0,0,0), and so is the vim scene's geometry. var elementGeometryInfo = elementGeometryMap.ElementAtOrDefault(elementIndex); - var hasGeometry = elementGeometryInfo?.HasGeometry ?? false; + var hasGeometry = elementGeometryInfo?.HasMesh ?? false; if (!hasGeometry) return BuildingStoryGeometryContainment.NoGeometry; diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementMeasureInfo.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementMeasureInfo.cs index 851d64bc..e32ad607 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementMeasureInfo.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementMeasureInfo.cs @@ -1,5 +1,4 @@ -using Vim.Format.ObjectModel; -using Vim.Util; +using Vim.Util; namespace Vim.Format.ElementParameterInfo { @@ -17,7 +16,7 @@ public class ElementMeasureInfo : IElementIndex /// Returns the element index. /// public int GetElementIndexOrNone() - => Element.IndexOrDefault(); + => EntityRelation.IndexOrDefault(Element); public double? Angle { get; } @@ -40,7 +39,7 @@ public ElementMeasureInfo( Element element, ParameterTable parameterTable, MeasureType[] parameterMeasureInfos, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) { Element = element; diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementParameterInfoService.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementParameterInfoService.cs index 63f4bfc7..6dc17e9d 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/ElementParameterInfoService.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/ElementParameterInfoService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Vim.Format.ObjectModel; using Vim.Util; namespace Vim.Format.ElementParameterInfo @@ -55,7 +54,7 @@ public class ElementParameterInfo public MeasureType[] ParameterMeasureTypes { get; set; } } - public static class ElementParameterInfoService + public static class VimElementParameterInfoService { /// /// Returns the element parameter information from the given VIM file. @@ -63,23 +62,24 @@ public static class ElementParameterInfoService public static ElementParameterInfo GetElementParameterInfos( FileInfo vimFileInfo, string[] stringTable = null, - ElementGeometryMap elementGeometryMap = null) + VimElementGeometryInfo[] elementGeometryMap = null) { - elementGeometryMap = elementGeometryMap ?? new ElementGeometryMap(vimFileInfo); - - var tableSet = new EntityTableSet( - vimFileInfo, - stringTable, - n => - n is TableNames.Element || - n is TableNames.Family || - n is TableNames.FamilyInstance || - n is TableNames.FamilyType || - n is TableNames.Parameter || - n is TableNames.ParameterDescriptor || - n is TableNames.DisplayUnit || - n is TableNames.Level || - n is TableNames.BasePoint); + elementGeometryMap = elementGeometryMap ?? VimElementGeometryInfo.GetElementGeometryInfoList(vimFileInfo); + + var tableSet = VimEntityTableSet.GetEntityTableSet(vimFileInfo, new VimEntityTableSetOptions() + { + StringTable = stringTable, + EntityTableNameFilter = n => + n is VimEntityTableNames.Element || + n is VimEntityTableNames.Family || + n is VimEntityTableNames.FamilyInstance || + n is VimEntityTableNames.FamilyType || + n is VimEntityTableNames.Parameter || + n is VimEntityTableNames.ParameterDescriptor || + n is VimEntityTableNames.DisplayUnit || + n is VimEntityTableNames.Level || + n is VimEntityTableNames.BasePoint + }); return GetElementParameterInfos(tableSet, elementGeometryMap); } @@ -88,8 +88,8 @@ n is TableNames.Level || /// Returns the element parameter information from the given entity table set and element geometry map. /// public static ElementParameterInfo GetElementParameterInfos( - EntityTableSet tableSet, - ElementGeometryMap elementGeometryMap) + VimEntityTableSet tableSet, + VimElementGeometryInfo[] elementGeometryMap) { var elementIndexMaps = tableSet.ElementIndexMaps; var elementTable = tableSet.ElementTable; @@ -160,7 +160,7 @@ private static LevelInfo[] CreateLevelInfos( ElementTable elementTable, FamilyTypeTable familyTypeTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps, + VimElementIndexMaps elementIndexMaps, IReadOnlyDictionary> levelsByBimDocumentIndexAndElementId, IReadOnlyDictionary> basePointsByBimDocumentIndexAndElementId) => levels @@ -214,8 +214,8 @@ private static ElementLevelInfo[] CreateElementLevelInfos( FamilyInstanceTable familyInstanceTable, ParameterTable parameterTable, LevelTable levelTable, - ElementIndexMaps elementIndexMaps, - ElementGeometryMap elementGeometryMap, + VimElementIndexMaps elementIndexMaps, + VimElementGeometryInfo[] elementGeometryMap, IReadOnlyDictionary levelInfoMap, IReadOnlyDictionary> levelInfoByBimDocumentIndex) { @@ -267,7 +267,7 @@ public static ElementMeasureInfo[] CreateElementMeasureInfos( ElementTable elementTable, ParameterTable parameterTable, MeasureType[] parameterMeasureTypes, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) => elementTable .AsParallel() .Select(e => new ElementMeasureInfo(e, parameterTable, parameterMeasureTypes, elementIndexMaps)) @@ -276,7 +276,7 @@ public static ElementMeasureInfo[] CreateElementMeasureInfos( public static ElementIfcInfo[] CreateElementIfcInfos( ElementTable elementTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) => elementTable .AsParallel() .Select(e => new ElementIfcInfo(e, parameterTable, elementIndexMaps)) @@ -285,7 +285,7 @@ public static ElementIfcInfo[] CreateElementIfcInfos( public static FamilyOmniClassInfo[] CreateFamilyOmniClassInfos( FamilyTable familyTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) => familyTable.AsParallel() .Select(f => new FamilyOmniClassInfo(f, parameterTable, elementIndexMaps)) .ToArray(); @@ -293,7 +293,7 @@ public static FamilyOmniClassInfo[] CreateFamilyOmniClassInfos( public static FamilyTypeUniformatInfo[] CreateFamilyTypeUniformatInfos( FamilyTypeTable familyTypeTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) => familyTypeTable.AsParallel() .Select(ft => new FamilyTypeUniformatInfo(ft, parameterTable, elementIndexMaps)) .ToArray(); diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyOmniClassInfo.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyOmniClassInfo.cs index e592feab..061abb64 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyOmniClassInfo.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyOmniClassInfo.cs @@ -1,5 +1,4 @@ using System; -using Vim.Format.ObjectModel; namespace Vim.Format.ElementParameterInfo { @@ -79,7 +78,7 @@ private static int IndexOfThird(string str, char c) public FamilyOmniClassInfo( Family family, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) { Family = family; diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyTypeUniformatInfo.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyTypeUniformatInfo.cs index 55078c4a..c66fbdad 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyTypeUniformatInfo.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/FamilyTypeUniformatInfo.cs @@ -1,5 +1,4 @@ using System; -using Vim.Format.ObjectModel; namespace Vim.Format.ElementParameterInfo { @@ -54,7 +53,7 @@ public string UniformatLevel3 public FamilyTypeUniformatInfo( FamilyType familyType, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) { FamilyType = familyType; diff --git a/src/cs/vim/Vim.Format/ElementParameterInfo/LevelInfo.cs b/src/cs/vim/Vim.Format/ElementParameterInfo/LevelInfo.cs index e68a77aa..8d1877b0 100644 --- a/src/cs/vim/Vim.Format/ElementParameterInfo/LevelInfo.cs +++ b/src/cs/vim/Vim.Format/ElementParameterInfo/LevelInfo.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Vim.Format.ObjectModel; using Vim.Util; // ReSharper disable InconsistentNaming @@ -24,7 +23,7 @@ public class LevelInfo : IElementIndex // // b) the "survey point" of the bim document // - // For more information on these values, check the Revit API documentation and see ObjectModel.cs > BasePoint. + // For more information on these values, check the Revit API documentation and see cs > BasePoint. // // Additionally, a Level may be qualified as either a building story or not. // @@ -45,7 +44,7 @@ public class LevelInfo : IElementIndex /// public int GetElementIndexOrNone() => Level.GetElementIndexOrNone(); - + /// /// The name of the Level. /// @@ -85,7 +84,7 @@ public string NameWithElevationMeters /// public double? ElevationRelativeToProjectBasePointDecimalFeet => ElevationRelativeToProjectBasePointDecimalFeetUnrounded == null - ? (double?) null + ? (double?)null : Math.Round(ElevationRelativeToProjectBasePointDecimalFeetUnrounded.Value, RoundingDigits); /// @@ -178,7 +177,7 @@ public double? BuildingStoryAboveHeightFeetDecimalUnrounded /// public double? BuildingStoryAboveHeightFeetDecimal => BuildingStoryAboveHeightFeetDecimalUnrounded == null - ? (double?) null + ? (double?)null : Math.Round(BuildingStoryAboveHeightFeetDecimalUnrounded.Value, RoundingDigits); /// @@ -207,7 +206,7 @@ public LevelInfo( Level level, FamilyTypeTable familyTypeTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps, + VimElementIndexMaps elementIndexMaps, IReadOnlyDictionary elementIdToLevelMap, IReadOnlyDictionary elementIdToBasePointMap) { @@ -215,12 +214,12 @@ public LevelInfo( var projectBasePoint = elementIdToBasePointMap.Values.FirstOrDefault(bp => bp.IsSurveyPoint == false); ElevationRelativeToProjectBasePointDecimalFeetUnrounded = projectBasePoint == null - ? (double?) null + ? (double?)null : Level.ProjectElevation - projectBasePoint.Position_Z; - + var surveyPoint = elementIdToBasePointMap.Values.FirstOrDefault(bp => bp.IsSurveyPoint); ElevationRelativeToSurveyPointDecimalFeetUnrounded = surveyPoint == null - ? (double?) null + ? (double?)null : Level.ProjectElevation - surveyPoint.Position_Z; ReadLevelParameters(parameterTable, elementIndexMaps, elementIdToLevelMap); @@ -230,7 +229,7 @@ public LevelInfo( private void ReadLevelParameters( ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps, + VimElementIndexMaps elementIndexMaps, IReadOnlyDictionary elementIdToLevelMap) { var levelElementParameterIndices = elementIndexMaps.GetParameterIndicesFromElementIndex(GetElementIndexOrNone()); @@ -267,7 +266,7 @@ private void ReadLevelParameters( private void ReadLevelTypeParameters( FamilyTypeTable familyTypeTable, ParameterTable parameterTable, - ElementIndexMaps elementIndexMaps) + VimElementIndexMaps elementIndexMaps) { var levelTypeElementIndex = familyTypeTable.GetElementIndex(Level.FamilyTypeIndex); diff --git a/src/cs/vim/Vim.Format/Merge/MergeConfigFiles.cs b/src/cs/vim/Vim.Format/Merge/MergeConfigFiles.cs deleted file mode 100644 index 5ec67293..00000000 --- a/src/cs/vim/Vim.Format/Merge/MergeConfigFiles.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using Vim.Math3d; -using Vim.Util; - -namespace Vim.Format.Merge -{ - public class MergeConfigFiles - { - /// - /// The input VIM file paths and their transforms. - /// - public (string VimFilePath, Matrix4x4 Transform)[] InputVimFilePathsAndTransforms { get; } - - /// - /// The input VIM file paths - /// - public string[] InputVimFilePaths - => InputVimFilePathsAndTransforms.Select(t => t.VimFilePath).ToArray(); - - /// - /// The input VIM file path transforms - /// - public Matrix4x4[] InputTransforms - => InputVimFilePathsAndTransforms.Select(t => t.Transform).ToArray(); - - /// - /// The merged VIM file path. - /// - public string MergedVimFilePath { get; } - - /// - /// Constructor - /// - public MergeConfigFiles( - (string VimFilePath, Matrix4x4 Transform)[] inputVimFilePathsAndTransforms, - string mergedVimFilePath) - { - InputVimFilePathsAndTransforms = inputVimFilePathsAndTransforms; - MergedVimFilePath = mergedVimFilePath; - } - - /// - /// Throws an exception if the input configuration is invalid. - /// - public void Validate() - { - if (string.IsNullOrWhiteSpace(MergedVimFilePath)) - throw new HResultException((int) ErrorCode.VimMergeConfigFilePathIsEmpty, "Merged VIM file path is empty."); - - var emptyFilePaths = InputVimFilePathsAndTransforms.Where(t => string.IsNullOrWhiteSpace(t.VimFilePath)).ToArray(); - if (emptyFilePaths.Length > 0) - { - var msg = string.Join(Environment.NewLine, emptyFilePaths.Select((t, i) => $"Input VIM file path at index {i} is empty.")); - throw new HResultException((int)ErrorCode.VimMergeInputFileNotFound, msg); - } - - var notFoundFilePaths = InputVimFilePathsAndTransforms.Where(t => !File.Exists(t.VimFilePath)).ToArray(); - if (notFoundFilePaths.Length > 0) - { - var msg = string.Join(Environment.NewLine, notFoundFilePaths.Select(t => $"Input VIM file not found: {t.VimFilePath}")); - throw new HResultException((int)ErrorCode.VimMergeInputFileNotFound, msg); - } - } - } -} diff --git a/src/cs/vim/Vim.Format/Merge/MergeConfigOptions.cs b/src/cs/vim/Vim.Format/Merge/MergeConfigOptions.cs deleted file mode 100644 index aecb0d27..00000000 --- a/src/cs/vim/Vim.Format/Merge/MergeConfigOptions.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Vim.Format.Merge -{ - public class MergeConfigOptions - { - /// - /// The generator string to embed into the VIM file header - /// - public string GeneratorString { get; set; } = "Unknown"; - - /// - /// The version string to embed into the VIM file header. - /// - public string VersionString { get; set; } = "0.0.0"; - - /// - /// Preserves the BIM data - /// - public bool KeepBimData { get; set; } = true; - - /// - /// Merges the given VIM files as a grid. - /// - public bool MergeAsGrid { get; set; } = false; - - /// - /// Applied when merging as a grid. - /// - public float GridPadding { get; set; } = 0f; - - /// - /// Deduplicates Elements and EntityWithElements based on their Element's unique ids. - /// If the unique ID is empty, the entities are not merged. - /// - public bool DeduplicateEntities { get; set; } = true; - } -} diff --git a/src/cs/vim/Vim.Format/Merge/MergeConfigVimScenes.cs b/src/cs/vim/Vim.Format/Merge/MergeConfigVimScenes.cs deleted file mode 100644 index 2baebd57..00000000 --- a/src/cs/vim/Vim.Format/Merge/MergeConfigVimScenes.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Linq; -using Vim.Math3d; - -namespace Vim.Format.Merge -{ - public class MergeConfigVimScenes - { - /// - /// The input VIM scenes and their transforms. - /// - public (VimScene VimScene, Matrix4x4 Transform)[] InputVimScenesAndTransforms { get; } - - /// - /// The input VIM scenes - /// - public VimScene[] InputVimScenes - => InputVimScenesAndTransforms.Select(t => t.VimScene).ToArray(); - - /// - /// The input VIM scene transforms - /// - public Matrix4x4[] InputTransforms - => InputVimScenesAndTransforms.Select(t => t.Transform).ToArray(); - - /// - /// Constructor. - /// - public MergeConfigVimScenes((VimScene VimScene, Matrix4x4 Transform)[] inputVimScenesAndTransforms) - => InputVimScenesAndTransforms = inputVimScenesAndTransforms; - - /// - /// Constructor. Applies an identity matrix to the input VimScenes - /// - public MergeConfigVimScenes(VimScene[] vimScenes) - : this(vimScenes.Select(v => (v, Matrix4x4.Identity)).ToArray()) - { } - } -} diff --git a/src/cs/vim/Vim.Format/Merge/MergeService.cs b/src/cs/vim/Vim.Format/Merge/MergeService.cs deleted file mode 100644 index ec44d4f7..00000000 --- a/src/cs/vim/Vim.Format/Merge/MergeService.cs +++ /dev/null @@ -1,319 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Vim.BFast; -using Vim.Format.Geometry; -using Vim.LinqArray; -using Vim.Math3d; -using Vim.Format.ObjectModel; - -using Vim.Util; - -namespace Vim.Format.Merge -{ - public static class MergeService - { - /// - /// Merges the VIM files in the specified MergeConfiguration object. - /// - public static void MergeVimFiles( - MergeConfigFiles fileConfig, - MergeConfigOptions optionsConfig, - IProgress progress = null, - CancellationToken cancellationToken = default) - { - fileConfig.Validate(); - - progress?.Report("Loading VIM files"); - cancellationToken.ThrowIfCancellationRequested(); - var inputVimScenesAndTransforms = - fileConfig.InputVimFilePathsAndTransforms - .AsParallel() - .Select(t => (VimScene.LoadVim(t.VimFilePath), t.Transform)) - .ToArray(); - - progress?.Report("Merging VIM files"); - cancellationToken.ThrowIfCancellationRequested(); - var documentBuilder = MergeVimScenes( - new MergeConfigVimScenes(inputVimScenesAndTransforms), - optionsConfig, - progress, - cancellationToken); - - progress?.Report("Writing merged VIM file"); - cancellationToken.ThrowIfCancellationRequested(); - var mergedVimFilePath = fileConfig.MergedVimFilePath; - documentBuilder.Write(mergedVimFilePath); - - progress?.Report("Completed VIM file merge"); - } - - /// - /// Merge the given VIM scenes into a DocumentBuilder - /// - public static DocumentBuilder MergeVimScenes( - MergeConfigVimScenes vimSceneConfig, - MergeConfigOptions optionsConfig = null, - IProgress progress = null, - CancellationToken ct = default) - { - optionsConfig = optionsConfig ?? new MergeConfigOptions(); - - // Validate that all VIMs are in the same object model major version - var vims = vimSceneConfig.InputVimScenes.ToArray(); - ValidateSameObjectModelSchemaMajorVersion(vims); - - var db = new DocumentBuilder(optionsConfig.GeneratorString, SchemaVersion.Current, optionsConfig.VersionString); - - // Merge the entity data - progress?.Report("Merging entities"); - ct.ThrowIfCancellationRequested(); - MergeEntities(db, vims, optionsConfig.KeepBimData, ct); - - // Optionally deduplicate the entity data. - if (optionsConfig.DeduplicateEntities) - { - progress?.Report("Deduplicating entities"); - ct.ThrowIfCancellationRequested(); - RemappedEntityTableBuilder.DeduplicateEntities(db, ct); - } - - // Merge the materials - // - // IMPORTANT: there must be a 1:1 aligned relationship between the material entities and the renderable materials. - // To ensure this constraint, We use the existing material entities in the document builder, whose entities have been - // previously populated and optionally deduplicated above. - progress?.Report("Merging materials"); - ct.ThrowIfCancellationRequested(); - - var materialTable = db.Tables.Values.FirstOrDefault(et => et.Name == TableNames.Material); - if (materialTable != null) - { - var mdcs = materialTable.DataColumns; - - var colorXColumn = mdcs.TryGetValue("double:Color.X", out var cX) - ? cX.AsArray() - : Array.Empty(); - - var colorYColumn = mdcs.TryGetValue("double:Color.Y", out var cY) - ? cY.AsArray() - : Array.Empty(); - - var colorZColumn = mdcs.TryGetValue("double:Color.Z", out var cZ) - ? cZ.AsArray() - : Array.Empty(); - - var transparencyColumn = mdcs.TryGetValue("double:Transparency", out var t) - ? t.AsArray() - : Array.Empty(); - - var glossinessColumn = mdcs.TryGetValue("double:Glossiness", out var g) - ? g.AsArray() - : Array.Empty(); - - var smoothnessColumn = mdcs.TryGetValue("double:Smoothness", out var s) - ? s.AsArray() - : Array.Empty(); - - for (var i = 0; i < materialTable.NumRows; ++i) - { - db.Materials.Add(ObjectModelStore.ConvertMaterialEntityFieldsToRenderableMaterial( - colorX: (float)colorXColumn.ElementAtOrDefault(i), - colorY: (float)colorYColumn.ElementAtOrDefault(i), - colorZ: (float)colorZColumn.ElementAtOrDefault(i), - transparency: (float)transparencyColumn.ElementAtOrDefault(i), - glossiness: (float)glossinessColumn.ElementAtOrDefault(i), - smoothness: (float)smoothnessColumn.ElementAtOrDefault(i) - )); - } - } - - // Merge the geometry - progress?.Report("Merging geometry"); - ct.ThrowIfCancellationRequested(); - - var materialCounts = vims.Select(v => v.Materials.Count); - var materialOffsets = materialCounts.ToIArray().PartialSums().DropLast(); - - db.Meshes.AddRange(vims - .SelectMany((vim, vimIndex) => vim.Meshes.Select(mesh => (mesh, vimIndex)).ToEnumerable()) - .Select( - pair => new DocumentBuilder.SubdividedMesh( - indices: pair.mesh.Indices?.ToList(), - vertices: pair.mesh.Vertices?.ToList(), - submeshesIndexOffset: pair.mesh.SubmeshIndexOffsets?.ToList(), - submeshMaterials: pair.mesh.SubmeshMaterials.Select( - mat => mat == -1 ? -1 : mat + materialOffsets[pair.vimIndex])?.ToList() - ) - ) - .ToList()); - - ct.ThrowIfCancellationRequested(); - - // Apply the optional grid transforms. - var vimTransforms = vimSceneConfig.InputTransforms.ToArray(); - if (optionsConfig.MergeAsGrid) - { - progress?.Report("Calculating merge grid"); - var gridTransforms = GetGridTransforms(vims, optionsConfig.GridPadding); - vimTransforms = gridTransforms.Zip(vimTransforms, (g, t) => g * t).ToArray(); - } - - var meshCounts = vims.Select(v => v.Meshes.Count); - var meshOffsets = meshCounts.ToIArray().PartialSums().DropLast(); - - // Merge the instances - progress?.Report("Merging instances"); - ct.ThrowIfCancellationRequested(); - - var allIdentity = vimTransforms.All(t => t.IsIdentity); - db.Instances.AddRange( - vims - .SelectMany((vim, vimIndex) => vim.VimNodes.Select(node => (node, vimIndex)).ToEnumerable()) - .Select(pair => new DocumentBuilder.Instance() - { - ParentIndex = -1, - InstanceFlags = pair.node.InstanceFlags, - MeshIndex = pair.node.MeshIndex == -1 ? -1 : pair.node.MeshIndex + meshOffsets[pair.vimIndex], - Transform = allIdentity - ? pair.node.Transform - : pair.node.Transform * vimTransforms[pair.vimIndex] - }).ToList()); - - // Merge the assets - progress?.Report("Merging assets"); - ct.ThrowIfCancellationRequested(); - foreach (var asset in vims.SelectMany(vim => vim.Document.Assets.Values.ToEnumerable())) - db.AddAsset(asset); - - return db; - } - - /// - /// Throws if the given VIM files do not all have the same object model schema major version. - /// - public static void ValidateSameObjectModelSchemaMajorVersion(VimScene[] vims) - { - var objectModelMajorVersions = vims - .Select(v => v.Document.Header.Schema.Major) - .Distinct() - .OrderBy(i => i) - .ToArray(); - - // If we are only dealing with one major object model schema version, we are fine. - if (objectModelMajorVersions.Length == 1) - return; - - // Throw otherwise with a helpful error message. - var sb = new StringBuilder(); - sb.AppendLine($"Object model schema major version mismatch ({string.Join(", ", objectModelMajorVersions.Select(v => $"v{v}.*"))})"); - sb.AppendLine(); - foreach (var vim in vims.OrderBy(v => v.Document.Header.Schema.Major)) - sb.AppendLine($"- v{vim.Document.Header.Schema.ToString()}: '{vim.FileName}'"); - sb.AppendLine(); - sb.AppendLine("Please ensure the VIM files have all been exported with matching schema major versions."); - - throw new HResultException((int)ErrorCode.VimMergeObjectModelMajorVersionMismatch, sb.ToString()); - } - - /// - /// Returns a collection of transforms based on the largest dimension of the largest VIM bounding box. - /// - public static Matrix4x4[] GetGridTransforms(VimScene[] vims, float padding) - { - var boxes = vims.Select(v => v.BoundingBox()).ToArray(); - var centerBottomTransforms = boxes.Select(b => Matrix4x4.CreateTranslation(-b.CenterBottom)).ToIArray(); - - var columnSize = boxes.Select(b => b.Extent.X).Max() + padding; - var rowSize = boxes.Select(b => b.Extent.Y).Max() + padding; - - var numRows = (int)Math.Sqrt(vims.Length).Ceiling(); - - var transforms = GetGridOfTransforms( - vims.Length, - numRows, - columnSize, - rowSize) - .Zip(centerBottomTransforms, (g, b) => b * g) - .ToArray(); - - return transforms; - } - - private static IArray GetGridOfTransforms(int count, int numRows, float xSide, float ySide) - => count.Select(i => Matrix4x4.CreateTranslation(i % numRows * xSide, i / numRows * ySide, 0)); - - private static void MergeEntities( - DocumentBuilder db, - VimScene[] vims, - bool keepBimData = true, - CancellationToken cancellationToken = default) - { - // Compute the offsets for the new entities - var offsets = ComputeMergedEntityTableOffsets(vims.Select(v => v.Document)); - - // Collect the entity tables, grouped by name - var mergedTableBuilders = new Dictionary(); - foreach (var vim in vims) - { - cancellationToken.ThrowIfCancellationRequested(); - - foreach (var entityTable in vim.Document.EntityTables.Values.ToEnumerable()) - { - cancellationToken.ThrowIfCancellationRequested(); - - var name = entityTable.Name; - if (VimConstants.ComputedTableNames.Contains(entityTable.Name)) - continue; - - if (!keepBimData && !VimConstants.NonBimNames.Contains(entityTable.Name)) - continue; - - var mergedTableBuilder = mergedTableBuilders.GetOrCompute(name, (s) => new MergedTableBuilder(s)); - mergedTableBuilder.AddTable(entityTable, offsets); - } - } - - // Add the new merged table builder - var tableBuilders = mergedTableBuilders.Values.Select(mtb => db.GetTableBuilderOrCreate(mtb.Name)).ToArray(); - Parallel.For(0, tableBuilders.Length, i => - { - cancellationToken.ThrowIfCancellationRequested(); - - var tb = tableBuilders[i]; - var mtb = mergedTableBuilders[tb.Name]; - mtb.UpdateTableBuilder(tb, cancellationToken); - }); - } - - /// - /// For every entity table in each document, computes the offset of that entity table - /// in a merged document. This is used for remapping entity table relations when merging VIM files. - /// - private static Dictionary ComputeMergedEntityTableOffsets(IEnumerable documents) - { - var aggregateOffsetMap = new Dictionary(); - var entityTableOffsetMap = new Dictionary(); - foreach (var doc in documents) - { - foreach (var entityTable in doc.EntityTables.Values.ToEnumerable()) - { - var entityTableName = entityTable.Name; - - // Add the entity table name to the aggregate offset map - aggregateOffsetMap.TryAdd(entityTableName, 0); - - // Assign the current offset to the given entity table. - entityTableOffsetMap.Add(entityTable, aggregateOffsetMap[entityTableName]); - - // Update the aggregated offsets - aggregateOffsetMap[entityTableName] += entityTable.NumRows; - } - } - return entityTableOffsetMap; - } - } -} diff --git a/src/cs/vim/Vim.Format/Merge/MergedTableBuilder.cs b/src/cs/vim/Vim.Format/Merge/MergedTableBuilder.cs deleted file mode 100644 index 3237114e..00000000 --- a/src/cs/vim/Vim.Format/Merge/MergedTableBuilder.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using Vim.BFast; -using Vim.LinqArray; -using Vim.Util; - -namespace Vim.Format.Merge -{ - public class MergedTableBuilder - { - public readonly string Name; - public int NumRows; - - public MergedTableBuilder(string name) - => Name = name; - - public Dictionary DataColumns = new Dictionary(); - public DictionaryOfLists IndexColumns = new DictionaryOfLists(); - public DictionaryOfLists StringColumns = new DictionaryOfLists(); - - public void AddTable(EntityTable entityTable, Dictionary entityIndexOffsets) - { - Debug.Assert(entityIndexOffsets[entityTable] == NumRows); - - // Add index columns from the entity table - foreach (var k in entityTable.IndexColumns.Keys.ToEnumerable()) - { - var col = entityTable.IndexColumns[k]; - var indexColumnFullName = col.Name; - - if (!IndexColumns.ContainsKey(indexColumnFullName)) - IndexColumns.Add(indexColumnFullName, Enumerable.Repeat(-1, NumRows).ToList()); - - Debug.Assert(col.Array.Length == entityTable.NumRows); - var relatedTable = col.GetRelatedTable(entityTable.Document); - var vals = IndexColumns[indexColumnFullName]; - - var offset = entityIndexOffsets[relatedTable]; - foreach (var v in col.Array) - vals.Add(v < 0 ? v : v + offset); - } - - // Add data columns from the entity table - foreach (var colName in entityTable.DataColumns.Keys.ToEnumerable()) - { - var col = entityTable.DataColumns[colName]; - if (!DataColumns.ContainsKey(colName)) - { - DataColumns[colName] = col; - } - else - { - var cur = DataColumns[colName]; - DataColumns[colName] = cur.ConcatDataColumnBuffers(col, colName.GetTypePrefix()); - } - } - - // Add string columns from the entity table - foreach (var k in entityTable.StringColumns.Keys.ToEnumerable()) - { - if (!StringColumns.ContainsKey(k)) - StringColumns.Add(k, Enumerable.Repeat("", NumRows).ToList()); - - var col = entityTable.StringColumns[k]; - Debug.Assert(col.Array.Length == entityTable.NumRows); - var vals = StringColumns[k]; - foreach (var v in col.Array) - vals.Add(entityTable.Document.GetString(v)); - } - - // For each column in the builder but not in the entity table add default values - foreach (var kv in DataColumns) - { - var colName = kv.Key; - var typePrefix = colName.GetTypePrefix(); - if (!entityTable.DataColumns.Contains(colName)) - { - var cur = DataColumns[colName]; - var defaultBuffer = ColumnExtensions.CreateDefaultDataColumnBuffer(entityTable.NumRows, typePrefix); - DataColumns[colName] = cur.ConcatDataColumnBuffers(defaultBuffer, typePrefix); - } - } - - foreach (var kv in IndexColumns) - { - if (!entityTable.IndexColumns.Contains(kv.Key)) - IndexColumns[kv.Key].AddRange(Enumerable.Repeat(-1, entityTable.NumRows)); - } - - foreach (var kv in StringColumns) - { - if (!entityTable.StringColumns.Contains(kv.Key)) - StringColumns[kv.Key].AddRange(Enumerable.Repeat("", entityTable.NumRows)); - } - - NumRows += entityTable.NumRows; - - foreach (var kv in DataColumns) - Debug.Assert(kv.Value.Data.Length == NumRows); - foreach (var kv in IndexColumns) - Debug.Assert(kv.Value.Count == NumRows); - foreach (var kv in StringColumns) - Debug.Assert(kv.Value.Count == NumRows); - } - - public void UpdateTableBuilder(EntityTableBuilder tb, CancellationToken cancellationToken = default) - { - foreach (var kv in DataColumns) - { - cancellationToken.ThrowIfCancellationRequested(); - tb.AddDataColumn(kv.Key, kv.Value); - } - - foreach (var kv in StringColumns) - { - cancellationToken.ThrowIfCancellationRequested(); - tb.AddStringColumn(kv.Key, kv.Value.ToArray()); - } - - foreach (var kv in IndexColumns) - { - cancellationToken.ThrowIfCancellationRequested(); - tb.AddIndexColumn(kv.Key, kv.Value.ToArray()); - } - } - } -} diff --git a/src/cs/vim/Vim.Format/Merge/RemappedEntityTableBuilder.cs b/src/cs/vim/Vim.Format/Merge/RemappedEntityTableBuilder.cs deleted file mode 100644 index 5aa31479..00000000 --- a/src/cs/vim/Vim.Format/Merge/RemappedEntityTableBuilder.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Vim.Format.ObjectModel; - -namespace Vim.Format.Merge -{ - public class RemappedEntityTableBuilder - { - public EntityTableBuilder EntityTableBuilder { get; } - public int[] OldToNewIndexMap { get; } - public bool IsRemapped => OldToNewIndexMap != null; - - /// - /// Constructor - /// - private RemappedEntityTableBuilder( - EntityTableBuilder entityTableBuilder, - int[] oldToNewIndexMap) - { - EntityTableBuilder = entityTableBuilder; - OldToNewIndexMap = oldToNewIndexMap; - } - - /// - /// Returns a default remapped entity table builder in which no remapping has occurred. - /// - private static RemappedEntityTableBuilder CreateDefault(EntityTableBuilder et) - => new RemappedEntityTableBuilder(et, null); - - /// - /// Returns a RemappedTableBuilder whose contained EntityTableBuilder is duplicated based on the given keyFn. - /// - private static RemappedEntityTableBuilder CreateRemapped(EntityTableBuilder et, Func keyFn) - { - // We maintain a mapping of the keys to their new indices in this dictionary. - // - // ex: input keyFn sequence: [ "a", "b", "c", "b", "a", "c", "d" ] - // keyToIndexMap: { - // "a" -> 0, - // "b" -> 1, - // "c" -> 2, - // "d" -> 3, - // } - var keyToNewIndexMap = new Dictionary(); - - // We retain the non-duplicate indices in this array. - // - // ex: input keyFn sequence: [ "a", "b", "c", "b", "a", "c", "d" ] - // retainedIndices: [ 0 , 1 , 2 , 6 ] - var retainedIndices = new List(); - - // We map the old index to the new index in this array. - // - // ex: input keyFn sequence: ["a", "b", "c", "b", "a", "c", "d" ] - // old index: [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] - // oldToNewIndexMap: [ 0 , 1 , 2 , 1 , 0 , 2 , 3 ] - var oldToNewIndexMap = new int[et.NumRows]; - - // Iterate over the rows and build the maps - for (var i = 0; i < et.NumRows; ++i) - { - var key = keyFn(i, et); - - if (keyToNewIndexMap.TryGetValue(key, out var newIndex)) - { - // The key was already found, so store the remapping. - oldToNewIndexMap[i] = newIndex; - } - else - { - // This is the first time we encounter this key. - var nextIndex = keyToNewIndexMap.Count; - keyToNewIndexMap.Add(key, nextIndex); - retainedIndices.Add(i); - oldToNewIndexMap[i] = nextIndex; - } - } - - // ex: input keyFn sequence: [ "a", "b", "c", "b", "a", "c", "d" ] - // desired output sequence: [ "a", "b", "c", "d" ] - var remapped = new EntityTableBuilder(et.Name); - - // Remap Index columns directly/naively now. In a second pass, the indices are adjusted based OldToNewIndexMap. - foreach (var kv in et.IndexColumns) - { - var colName = kv.Key; - var col = kv.Value; - var newCol = retainedIndices.Select(retainedIndex => col[retainedIndex]); - remapped.AddIndexColumn(colName, newCol); - } - - // Remap the data columns. - foreach (var kv in et.DataColumns) - { - var colName = kv.Key; - var col = kv.Value; - var typePrefix = colName.GetTypePrefix(); - var newCol = col.RemapOrSelfDataColumn(typePrefix, retainedIndices); - remapped.AddDataColumn(colName, newCol); - } - - // Remap the string columns. - foreach (var kv in et.StringColumns) - { - var colName = kv.Key; - var col = kv.Value; - var newCol = retainedIndices.Select(retainedIndex => col[retainedIndex]); - remapped.AddStringColumn(colName, newCol); - } - - return new RemappedEntityTableBuilder(remapped, oldToNewIndexMap); - } - - private static void UpdateEntityTableBuilderRelations( - List remappedEntityTableBuilders, - CancellationToken ct = default) - { - var remappedTableIndices = remappedEntityTableBuilders - .Where(r => r.IsRemapped) - .ToDictionary( - r => r.EntityTableBuilder.Name, - r => r.OldToNewIndexMap); - - if (remappedTableIndices.Count == 0) - return; // nothing to do. - - // Update the index relationships using the remapped entity table builders' indices. - foreach (var et in remappedEntityTableBuilders.Select(r => r.EntityTableBuilder)) - { - ct.ThrowIfCancellationRequested(); - - foreach (var kv in et.IndexColumns) - { - var indexColumnName = kv.Key; - var indexColumn = kv.Value; - - // Get the related index remapping. - var tableName = ColumnExtensions.GetRelatedTableNameFromColumnName(indexColumnName); - if (!remappedTableIndices.TryGetValue(tableName, out var oldToNewIndexMap)) - continue; - - // Update the indices - for (var i = 0; i < indexColumn.Length; ++i) - { - var oldIndex = indexColumn[i]; - indexColumn[i] = oldIndex == VimConstants.NoEntityRelation - ? oldIndex - : oldToNewIndexMap[oldIndex]; - } - } - } - } - - private static List GetRemappedEntityTableBuilders( - DocumentBuilder db, - CancellationToken ct = default) - { - var remappedEntityTableBuilders = new List(); - - // Deduplicate the entities. - foreach (var kv in db.Tables) - { - ct.ThrowIfCancellationRequested(); - - var tableName = kv.Key; - var table = kv.Value; - - RemappedEntityTableBuilder r; - switch (tableName) - { - //////////////////////////////////// - // FUTURE MAINTENANCE NOTES: - // - if we ever remap materials, we must also propagate this remapping to the submeshMaterials in the geometry buffer. - // - if we ever remap assets, we must also propagate this remapping to the merged assets in the asset buffer. - //////////////////////////////////// - - // Merge all the categories by name and by built-in category. - case TableNames.Category: - { - var hasNameCol = table.StringColumns.TryGetValue("string:Name", out var nameCol); - var hasBuiltInCol = table.StringColumns.TryGetValue("string:BuiltInCategory", out var builtInCol); - if (!hasNameCol || !hasBuiltInCol) - { - r = CreateDefault(table); - break; - } - - r = CreateRemapped(table, (i, _) => (nameCol[i], builtInCol[i])); - break; - } - // Merge all the display units - case TableNames.DisplayUnit: - { - var hasSpecCol = table.StringColumns.TryGetValue("string:Spec", out var specCol); - var hasTypeCol = table.StringColumns.TryGetValue("string:Type", out var typeCol); - var hasLabelCol = table.StringColumns.TryGetValue("string:Label", out var labelCol); - if (!hasSpecCol || !hasTypeCol || !hasLabelCol) - { - r = CreateDefault(table); - break; - } - - r = CreateRemapped(table, (i, _) => (specCol[i], typeCol[i], labelCol[i])); - break; - } - - // Default case. - default: - r = CreateDefault(table); - break; - } - - remappedEntityTableBuilders.Add(r); - } - - // Update the entity index relations. - UpdateEntityTableBuilderRelations(remappedEntityTableBuilders, ct); - - return remappedEntityTableBuilders; - } - - /// - /// Mutates the document builder by deduplicating specific entities which would be meaninglessly duplicated in the same VIM file. - /// - public static void DeduplicateEntities(DocumentBuilder db, CancellationToken ct = default) - { - var remappedEntityTableBuilders = GetRemappedEntityTableBuilders(db, ct); - - db.Tables.Clear(); - - foreach (var table in remappedEntityTableBuilders.Select(r => r.EntityTableBuilder)) - { - db.Tables.Add(table.Name, table); - } - } - } -} diff --git a/src/cs/vim/Vim.Format/ObjectModel/ElementGeometryMap.cs b/src/cs/vim/Vim.Format/ObjectModel/ElementGeometryMap.cs deleted file mode 100644 index f6276e8b..00000000 --- a/src/cs/vim/Vim.Format/ObjectModel/ElementGeometryMap.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.ObjectModel -{ - /// - /// Represents the geometric information of an element. - /// - public class ElementGeometryInfo - { - public int ElementIndex { get; } - - public int VertexCount { get; set; } - - public int FaceCount { get; set; } - - public AABox WorldSpaceBoundingBox { get; set; } = AABox.Empty; - - public List<(int NodeIndex, int GeometryIndex)> NodeAndGeometryIndices { get; } = new List<(int NodeIndex, int GeometryIndex)>(); - - public int NodeCount - => NodeAndGeometryIndices.Count; - - public bool HasGeometry - => FaceCount > 0; - - /// - /// Constructor - /// - public ElementGeometryInfo(int elementIndex) - { - ElementIndex = elementIndex; - } - } - - /// - /// A 1:1 list mapping ElementIndex -> ElementGeometryInfo - /// - public class ElementGeometryMap : IReadOnlyList - { - private readonly ElementGeometryInfo[] _items; - - public IEnumerator GetEnumerator() - { - foreach (var item in _items) - yield return item; - } - - IEnumerator IEnumerable.GetEnumerator() - => GetEnumerator(); - - public int Count - => _items.Length; - - public ElementGeometryInfo this[int index] - => _items[index]; - - public ElementGeometryInfo ElementAtOrDefault(int index) - => _items.ElementAtOrDefault(index); - - /// - /// Constructor. - /// - public ElementGeometryMap(FileInfo vimFileInfo, G3D g3d = null) - : this( - new EntityTableSet( - vimFileInfo, - Array.Empty(), - n => n is TableNames.Node || n is TableNames.Element - ), - g3d ?? vimFileInfo.GetGeometry()) - { } - - /// - /// Constructor - /// - public ElementGeometryMap(EntityTableSet tableSet, G3D g3d) - { - var elementCount = tableSet.ElementTable?.RowCount ?? 0; - - _items = new ElementGeometryInfo[elementCount]; - - for (var elementIndex = 0; elementIndex < _items.Length; ++elementIndex) - _items[elementIndex] = new ElementGeometryInfo(elementIndex); - - if (!(tableSet.NodeTable is NodeTable nodeTable)) - return; - - // Calculate the element associations to nodes and geometry. - // NOTE: one element may have more than one node and associated geometry - - var elementIndexGroups = nodeTable - .Column_ElementIndex - .AsParallel() - .Select((elementIndex, nodeIndex) => (ElementIndex: elementIndex, NodeIndex: nodeIndex)) - .GroupBy(t => t.ElementIndex) - .Where(g => g.Key >= 0); - - foreach (var group in elementIndexGroups) - { - foreach (var (elementIndex, nodeIndex) in group) - { - if (elementIndex < 0 || elementIndex >= _items.Length) - continue; - - // INVARIANT: there is a 1:1 relationship between Node entities and instances in the g3d buffer. - var instanceIndex = nodeIndex; - - if (!TryGetGeometryIndex(g3d, instanceIndex, out var geometryIndex)) - continue; // Skip nodes with no geometry. - - _items[elementIndex].NodeAndGeometryIndices.Add((nodeIndex, geometryIndex)); - } - } - - // Calculate the element geometry in parallel. - - Parallel.For(0, _items.Length, elementIndex => - { - var item = _items[elementIndex]; - var list = item.NodeAndGeometryIndices; - var vertexCount = 0; - var faceCount = 0; - var bb = new AABox(Vector3.MaxValue, Vector3.MinValue); // world space element bounding box - - // Aggregate the geometry info - foreach (var (nodeIndex, geometryIndex) in list) - { - // INVARIANT: there is a 1:1 relationship between Node entities and instances in the g3d buffer. - var instanceIndex = nodeIndex; - - if (!TryGetTransformedGeometryInfo( - g3d, - instanceIndex, - geometryIndex, - out var geometryVertexCount, - out var geometryFaceCount, - out var nodeBb)) - { - continue; - } - - // Aggregate the ElementGeometry data - vertexCount += geometryVertexCount; - faceCount += geometryFaceCount; - bb = bb.Merge(nodeBb); - } - - item.VertexCount = vertexCount; - item.FaceCount = faceCount; - item.WorldSpaceBoundingBox = bb; - }); - } - - /// - /// Test constructor - /// - public ElementGeometryMap(IEnumerable items) - { - _items = items.ToArray(); - } - - private static bool TryGetGeometryIndex(G3D g3d, int instanceIndex, out int geometryIndex) - { - geometryIndex = -1; - geometryIndex = g3d.InstanceMeshes.ElementAtOrDefault(instanceIndex, -1); - return geometryIndex >= 0; - } - - private static bool TryGetTransformedGeometryInfo( - G3D g3d, - int instanceIndex, - int geometryIndex, - out int vertexCount, - out int faceCount, - out AABox worldSpaceBb) - { - vertexCount = 0; - faceCount = 0; - worldSpaceBb = AABox.Empty; - - if (geometryIndex < 0) - return false; - - var g3dMesh = g3d.Meshes.ElementAtOrDefault(geometryIndex); - if (g3dMesh == null) - return false; - - vertexCount = g3dMesh.NumVertices; - faceCount = g3dMesh.NumFaces; - - var transform = g3d.InstanceTransforms.ElementAtOrDefault(instanceIndex, Matrix4x4.Identity); - - // Calculate the world-space bounding box of the mesh. - worldSpaceBb = AABox.Create(g3dMesh.Vertices.ToArray().Select(v => v.Transform(transform))); - - return true; - } - } -} diff --git a/src/cs/vim/Vim.Format/ObjectModel/ElementInfo.cs b/src/cs/vim/Vim.Format/ObjectModel/ElementInfo.cs deleted file mode 100644 index ad545f29..00000000 --- a/src/cs/vim/Vim.Format/ObjectModel/ElementInfo.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Collections.Generic; -using Vim.LinqArray; - -namespace Vim.Format.ObjectModel -{ - /// - /// Represents common element information - /// - public class ElementInfo - { - public readonly DocumentModel DocumentModel; - public readonly int ElementIndex; - - // Lazy properties - - private int? _familyInstanceIndex; - public int FamilyInstanceIndex - { - get - { - if (_familyInstanceIndex != null) - return _familyInstanceIndex.Value; - - _familyInstanceIndex = DocumentModel.ElementIndexMaps.FamilyInstanceIndexFromElementIndex - .TryGetValue(ElementIndex, out var value) ? value : EntityRelation.None; - - return _familyInstanceIndex.Value; - } - } - - private IArray _parameterIndices; - public IArray ParameterIndices - { - get - { - if (_parameterIndices != null) - return _parameterIndices; - - _parameterIndices = (DocumentModel.ElementIndexMaps.ParameterIndicesFromElementIndex - .TryGetValue(ElementIndex, out var parameterIndices) ? parameterIndices : new List()) - .ToIArray(); - - return _parameterIndices; - } - } - - private int? _systemIndex; - public int SystemIndex - { - get - { - if (_systemIndex != null) - return _systemIndex.Value; - - _systemIndex = DocumentModel.ElementIndexMaps.SystemIndexFromElementIndex - .TryGetValue(ElementIndex, out var value) ? value : EntityRelation.None; - - return _systemIndex.Value; - } - } - - public void EvaluateLazyProperties() - { - _ = FamilyInstanceIndex; - _ = ParameterIndices; - _ = SystemIndex; - } - - // Boolean queries - - public bool IsFamilyInstance - => DocumentModel.ElementIndexMaps.FamilyInstanceIndexFromElementIndex.ContainsKey(ElementIndex); - - public bool IsFamilyType - => DocumentModel.ElementIndexMaps.FamilyTypeIndexFromElementIndex.ContainsKey(ElementIndex); - - public bool IsFamily - => DocumentModel.ElementIndexMaps.FamilyIndexFromElementIndex.ContainsKey(ElementIndex); - - public bool IsSystem - => DocumentModel.ElementIndexMaps.SystemIndexFromElementIndex.ContainsKey(ElementIndex); - - // Derived Index Properties - - public int CategoryIndex => DocumentModel.GetElementCategoryIndex(ElementIndex); - public int LevelIndex => DocumentModel.GetElementLevelIndex(ElementIndex); - public int LevelElementIndex => DocumentModel.GetLevelElementIndex(LevelIndex); - public int RoomIndex => DocumentModel.GetElementRoomIndex(ElementIndex); - public int RoomElementIndex => DocumentModel.GetRoomElementIndex(RoomIndex); - public int BimDocumentIndex => DocumentModel.GetElementBimDocumentIndex(ElementIndex); - public int WorksetIndex => DocumentModel.GetElementWorksetIndex(ElementIndex); - public int FamilyInstanceElementIndex => DocumentModel.GetFamilyInstanceElementIndex(FamilyInstanceIndex); - public int FamilyTypeIndex => DocumentModel.GetFamilyInstanceFamilyTypeIndex(FamilyInstanceIndex); - public int FamilyTypeElementIndex => DocumentModel.GetFamilyTypeElementIndex(FamilyTypeIndex); - public int FamilyIndex => DocumentModel.GetFamilyTypeFamilyIndex(FamilyTypeIndex); - public int FamilyElementIndex => DocumentModel.GetFamilyElementIndex(FamilyIndex); - public int SystemElementIndex => DocumentModel.GetSystemElementIndex(SystemIndex); - - // Derived Object-Generating Properties - - public Element Element => DocumentModel.ElementList.ElementAtOrDefault(ElementIndex); - public Category Category => DocumentModel.CategoryList.ElementAtOrDefault(CategoryIndex); - public Level Level => DocumentModel.LevelList.ElementAtOrDefault(LevelIndex); - public Room Room => DocumentModel.RoomList.ElementAtOrDefault(RoomIndex); - public BimDocument BimDocument => DocumentModel.BimDocumentList.ElementAtOrDefault(BimDocumentIndex); - public Workset Workset => DocumentModel.WorksetList.ElementAtOrDefault(WorksetIndex); - public FamilyInstance FamilyInstance => DocumentModel.FamilyInstanceList.ElementAtOrDefault(FamilyInstanceIndex); - public FamilyType FamilyType => DocumentModel.FamilyTypeList.ElementAtOrDefault(FamilyTypeIndex); - public Element FamilyTypeElement => DocumentModel.ElementList.ElementAtOrDefault(FamilyTypeElementIndex); - public Family Family => DocumentModel.FamilyList.ElementAtOrDefault(FamilyIndex); - public System System => DocumentModel.SystemList.ElementAtOrDefault(SystemIndex); - public Element SystemElement => DocumentModel.ElementList.ElementAtOrDefault(SystemElementIndex); - public IEnumerable Parameters => DocumentModel.ParameterList.SelectByIndex(ParameterIndices).ToEnumerable(); - - [Flags] - public enum ParameterScope - { - None = 0, - FamilyInstance = 1, - FamilyType = 1 << 1, - Family = 1 << 2, - All = FamilyInstance | FamilyType | Family, - } - - public Dictionary> GetScopedParameters( - ParameterScope scope = ParameterScope.All) - { - var result = new Dictionary>(); - - if ((scope & ParameterScope.FamilyInstance) == ParameterScope.FamilyInstance && - FamilyInstanceElementIndex != EntityRelation.None) - { - result[ParameterScope.FamilyInstance] = DocumentModel.GetElementInfo(FamilyInstanceElementIndex).Parameters; - } - - if ((scope & ParameterScope.FamilyType) == ParameterScope.FamilyType && - FamilyTypeElementIndex != EntityRelation.None) - { - result[ParameterScope.FamilyType] = DocumentModel.GetElementInfo(FamilyTypeElementIndex).Parameters; - } - - if ((scope & ParameterScope.Family) == ParameterScope.Family && - FamilyElementIndex != EntityRelation.None) - { - result[ParameterScope.Family] = DocumentModel.GetElementInfo(FamilyElementIndex).Parameters; - } - - return result; - } - - // Commonly Accessed Properties - - public long ElementId => DocumentModel.GetElementId(ElementIndex, -1); - public string ElementUniqueId => DocumentModel.GetElementUniqueId(ElementIndex); - - public string ElementUniqueIdWithBimScopedElementIdFallback - { - get - { - var elementUniqueId = ElementUniqueId; - return !string.IsNullOrWhiteSpace(elementUniqueId) - ? elementUniqueId - : $"{BimDocumentFileName}::{ElementId}"; - } - } - - public string ElementName => DocumentModel.GetElementName(ElementIndex); - public string CategoryName => DocumentModel.GetCategoryName(CategoryIndex); - public string CategoryBuiltInName => DocumentModel.GetCategoryBuiltInCategory(CategoryIndex); - public string LevelName => DocumentModel.GetElementName(LevelElementIndex); - public string FamilyName => DocumentModel.GetElementName(FamilyElementIndex, DocumentModel.GetElementFamilyName(ElementIndex)); - public string FamilyTypeName => DocumentModel.GetElementName(FamilyTypeElementIndex); - public string WorksetName => DocumentModel.GetWorksetName(WorksetIndex); - public string BimDocumentPathName => DocumentModel.GetBimDocumentPathName(BimDocumentIndex); - public string BimDocumentFileName => DocumentModel.GetBimDocumentFileName(BimDocumentIndex); - - /// - /// Constructor. - /// - public ElementInfo(DocumentModel documentModel, int elementIndex) - { - DocumentModel = documentModel; - ElementIndex = elementIndex; - } - } -} diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs index 5cb3c619..7f1047d2 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs @@ -7,7 +7,7 @@ // ReSharper disable InconsistentNaming -namespace Vim.Format.ObjectModel +namespace Vim.Format { public static class SchemaVersion { @@ -192,11 +192,6 @@ public static class History public static SerializableVersion v4_0_0 => SerializableVersion.Parse(History.v4_0_0); } - public partial class DocumentModel - { - public readonly Document Document; - } - public enum G3dAttributeReferenceMultiplicity { OneToOne, OneToMany, @@ -251,7 +246,7 @@ public enum ElementKind // - Also create a new SQL vw_Element_v* view with new element kind mapping. } - public interface IElementKindTable : IEntityTable + public interface IElementKindTable : IVimEntityTable { int GetElementIndex(int entityIndex); } @@ -298,7 +293,6 @@ public static ulong CombineAsStorageKey(this Relation relation1, Relati public partial class Entity { public int Index; - public Document Document; public virtual bool FieldsAreEqual(object obj) => throw new NotImplementedException(); @@ -309,7 +303,7 @@ public virtual bool FieldsAreEqual(object obj) /// public static class EntityRelation { - public const int None = VimConstants.NoEntityRelation; + public const int None = VimEntityTableConstants.NoEntityRelation; public static int IndexOrDefault(this Entity entity) => entity?.Index ?? None; @@ -358,7 +352,7 @@ public int GetElementIndexOrNone() /// /// Represents an Asset buffer in the VIM file. /// - [TableName(TableNames.Asset)] + [TableName(VimEntityTableNames.Asset)] public partial class Asset : Entity { /// @@ -370,7 +364,7 @@ public partial class Asset : Entity /// /// Defines the display units of a ParameterDefinition /// - [TableName(TableNames.DisplayUnit)] + [TableName(VimEntityTableNames.DisplayUnit)] public partial class DisplayUnit : Entity, IStorageKey { /// @@ -426,7 +420,7 @@ public enum ParameterDescriptorStorageType /// /// Represents a parameter descriptor. /// - [TableName(TableNames.ParameterDescriptor)] + [TableName(VimEntityTableNames.ParameterDescriptor)] public partial class ParameterDescriptor : Entity, IStorageKey { /// @@ -538,8 +532,7 @@ public ParameterDescriptorStorageType GetParameterDescriptorStorageType() /// /// Represents a parameter associated to an Element. An Element can contain 0..* Parameters. /// - [TableName(TableNames.Parameter)] - [CascadeElementRemap] + [TableName(VimEntityTableNames.Parameter)] public partial class Parameter : EntityWithElement { /// @@ -643,7 +636,7 @@ public bool TryParseNativeValueAsBoolean(ParameterDescriptor desc, out bool resu /// /// Represents an object which can be associated to a collection of Parameters. /// - [TableName(TableNames.Element)] + [TableName(VimEntityTableNames.Element)] public partial class Element : Entity { [EntityColumnLoader("int:Id", typeof(int), SchemaVersion.History.v4_6_0)] @@ -686,7 +679,7 @@ public Vector3 Location /// /// Represents a named collection of Elements used for organizational purposes. /// - [TableName(TableNames.Workset)] + [TableName(VimEntityTableNames.Workset)] public partial class Workset : Entity { public int Id; @@ -699,7 +692,7 @@ public partial class Workset : Entity public Relation _BimDocument; } - [TableName(TableNames.AssemblyInstance)] + [TableName(VimEntityTableNames.AssemblyInstance)] [ElementKind(ElementKind.AssemblyInstance)] public partial class AssemblyInstance : EntityWithElement { @@ -714,8 +707,7 @@ public Vector3 Position } } - [TableName(TableNames.Group)] - [CascadeElementRemap] // Groups can be family instances + [TableName(VimEntityTableNames.Group)] [ElementKind(ElementKind.Group)] public partial class Group : EntityWithElement { @@ -730,7 +722,7 @@ public Vector3 Position } } - [TableName(TableNames.DesignOption)] + [TableName(VimEntityTableNames.DesignOption)] [ElementKind(ElementKind.DesignOption)] public partial class DesignOption : EntityWithElement { @@ -740,7 +732,7 @@ public partial class DesignOption : EntityWithElement /// /// Represents an XY plane at a specific Z coordinate in the model. /// - [TableName(TableNames.Level)] + [TableName(VimEntityTableNames.Level)] [ElementKind(ElementKind.Level)] public partial class Level : EntityWithElement { @@ -772,7 +764,7 @@ public partial class Level : EntityWithElement /// /// Represents a phase of construction. /// - [TableName(TableNames.Phase)] + [TableName(VimEntityTableNames.Phase)] [ElementKind(ElementKind.Phase)] public partial class Phase : EntityWithElement { } @@ -780,7 +772,7 @@ public partial class Phase : EntityWithElement /// /// Represents a room in the model. /// - [TableName(TableNames.Room)] + [TableName(VimEntityTableNames.Room)] [ElementKind(ElementKind.Room)] public partial class Room : EntityWithElement { @@ -797,7 +789,7 @@ public partial class Room : EntityWithElement /// /// Represents a source BIM document, for example: a Revit file, or an IFC file. /// - [TableName(TableNames.BimDocument)] + [TableName(VimEntityTableNames.BimDocument)] [ElementKind(ElementKind.BimDocument)] public partial class BimDocument : EntityWithElement { @@ -845,7 +837,7 @@ public partial class BimDocument : EntityWithElement /// /// An associative table used to list the DisplayUnits in a BimDocument. /// - [TableName(TableNames.DisplayUnitInBimDocument)] + [TableName(VimEntityTableNames.DisplayUnitInBimDocument)] public partial class DisplayUnitInBimDocument : Entity, IStorageKey { public Relation _DisplayUnit; @@ -858,7 +850,7 @@ public object GetStorageKey() /// /// An associative table used to order the Phases in a BimDocument. /// - [TableName(TableNames.PhaseOrderInBimDocument)] + [TableName(VimEntityTableNames.PhaseOrderInBimDocument)] public partial class PhaseOrderInBimDocument : Entity, IStorageKey { public int OrderIndex; @@ -873,7 +865,7 @@ public object GetStorageKey() /// /// Represents the category to which an Element may belong (ex: Door, Floor, Ceiling, etc...). /// - [TableName(TableNames.Category)] + [TableName(VimEntityTableNames.Category)] public partial class Category : Entity { public string Name; @@ -904,7 +896,7 @@ public DVector3 LineColor /// /// Represents a collection FamilyTypes, for example an 'I Beam' Family. /// - [TableName(TableNames.Family)] + [TableName(VimEntityTableNames.Family)] [ElementKind(ElementKind.Family)] public partial class Family : EntityWithElement { @@ -920,7 +912,7 @@ public partial class Family : EntityWithElement /// For example, a FamilyType of 'W14x32' is defined within the 'I Beam' Family. /// In the Revit API, the FamilyType closely correlates to the FamilySymbol class. /// - [TableName(TableNames.FamilyType)] + [TableName(VimEntityTableNames.FamilyType)] [ElementKind(ElementKind.FamilyType)] public partial class FamilyType : EntityWithElement { @@ -934,8 +926,7 @@ public partial class FamilyType : EntityWithElement /// For example, a FamilyInstance of the FamilyType 'W14x32' (which itself is defined in the 'I Beam' Family) /// may have a length of 12 feet, whereas another FamilyInstance may have a different length of 8 feet. /// - [TableName(TableNames.FamilyInstance)] - [CascadeElementRemap] + [TableName(VimEntityTableNames.FamilyInstance)] [ElementKind(ElementKind.FamilyInstance)] public partial class FamilyInstance : EntityWithElement { @@ -1011,7 +1002,7 @@ public Vector3 HandOrientation /// /// Represents a 3D or a 2D view. /// - [TableName(TableNames.View)] + [TableName(VimEntityTableNames.View)] [ElementKind(ElementKind.View)] public partial class View : EntityWithElement { @@ -1091,8 +1082,8 @@ public DAABox2D Outline /// /// An associative table binding an Element to a View. /// - [TableName(TableNames.ElementInView)] - [CascadeElementRemap] + [TableName(VimEntityTableNames.ElementInView)] + [JoiningTable] public partial class ElementInView : EntityWithElement, IStorageKey { public Relation _View; @@ -1104,7 +1095,8 @@ public object GetStorageKey() /// /// An associative table binding a Shape to a View. /// - [TableName(TableNames.ShapeInView)] + [TableName(VimEntityTableNames.ShapeInView)] + [JoiningTable] public partial class ShapeInView : Entity, IStorageKey { public Relation _Shape; @@ -1117,7 +1109,8 @@ public object GetStorageKey() /// /// An associative table binding an Asset to a View. /// - [TableName(TableNames.AssetInView)] + [TableName(VimEntityTableNames.AssetInView)] + [JoiningTable] public partial class AssetInView : Entity, IStorageKey { public Relation _Asset; @@ -1130,7 +1123,8 @@ public object GetStorageKey() /// /// An associative table binding an Asset to a ViewSheet. /// - [TableName(TableNames.AssetInViewSheet)] + [TableName(VimEntityTableNames.AssetInViewSheet)] + [JoiningTable] public partial class AssetInViewSheet : Entity, IStorageKey { public Relation _Asset; @@ -1143,7 +1137,8 @@ public object GetStorageKey() /// /// An associative table binding a Level to a View. /// - [TableName(TableNames.LevelInView)] + [TableName(VimEntityTableNames.LevelInView)] + [JoiningTable] public partial class LevelInView : Entity, IStorageKey { /// @@ -1176,7 +1171,7 @@ public object GetStorageKey() /// /// Represents the orthographic or perspective camera of a 3D view. /// - [TableName(TableNames.Camera)] + [TableName(VimEntityTableNames.Camera)] public partial class Camera : Entity { public int Id; @@ -1225,7 +1220,7 @@ public partial class Camera : Entity /// /// Represents a colored and textured material. /// - [TableName(TableNames.Material)] + [TableName(VimEntityTableNames.Material)] [G3dAttributeReference("g3d:material:color:0:float32:4", G3dAttributeReferenceMultiplicity.OneToOne)] [G3dAttributeReference("g3d:material:color:0:float32:4", G3dAttributeReferenceMultiplicity.OneToOne)] [G3dAttributeReference("g3d:material:glossiness:0:float32:1", G3dAttributeReferenceMultiplicity.OneToOne)] @@ -1321,13 +1316,43 @@ public DVector2 NormalUvOffset /// The transparency, defined in the domain [0..1] public double Transparency; + + public VimMaterial ToVimMaterial() + => ToVimMaterial(this); + + public static VimMaterial ToVimMaterial(Material m) + => ToVimMaterial( + m.Color.X, + m.Color.Y, + m.Color.Z, + m.Transparency, + m.Glossiness, + m.Smoothness); + + public static VimMaterial ToVimMaterial( + double colorX, + double colorY, + double colorZ, + double transparency, + double glossiness, + double smoothness) + => new VimMaterial() + { + Color = new Vector4( + (float) colorX, + (float) colorY, + (float) colorZ, + (float)(1 - transparency)), // TECH DEBT: rendered material value is 1.0f - transparency + Glossiness = (float) glossiness, + Smoothness = (float) smoothness + }; } /// /// An associative table binding a Material to an Element. /// - [TableName(TableNames.MaterialInElement)] - [CascadeElementRemap] + [TableName(VimEntityTableNames.MaterialInElement)] + [JoiningTable] public partial class MaterialInElement : EntityWithElement, IStorageKey { public double Area; @@ -1358,7 +1383,7 @@ public static class MaterialFunctionAssignment /// /// Represents a material layer within a CompoundStructure. /// - [TableName(TableNames.CompoundStructureLayer)] + [TableName(VimEntityTableNames.CompoundStructureLayer)] public partial class CompoundStructureLayer : Entity { public int OrderIndex; @@ -1372,7 +1397,7 @@ public partial class CompoundStructureLayer : Entity /// /// Represents the collection of material layers which compose walls, ceilings, floors, etc. /// - [TableName(TableNames.CompoundStructure)] + [TableName(VimEntityTableNames.CompoundStructure)] public partial class CompoundStructure : Entity { /// @@ -1396,7 +1421,7 @@ public partial class CompoundStructure : Entity /// The ordering and the number of Nodes matches the ordering and the number of instances in the G3D buffer. /// This serves to bridge the gap between the Element entities and their corresponding instance geometry. /// - [TableName(TableNames.Node)] + [TableName(VimEntityTableNames.Node)] [G3dAttributeReference("g3d:instance:transform:0:float32:16", G3dAttributeReferenceMultiplicity.OneToOne)] [G3dAttributeReference("g3d:instance:parent:0:int32:1", G3dAttributeReferenceMultiplicity.OneToOne)] [G3dAttributeReference("g3d:instance:mesh:0:int32:1", G3dAttributeReferenceMultiplicity.OneToOne)] @@ -1408,7 +1433,7 @@ public partial class Node : EntityWithElement /// /// Represents a mesh in the G3D buffer of the VIM file. /// - [TableName(TableNames.Geometry)] + [TableName(VimEntityTableNames.Geometry)] [G3dAttributeReference("g3d:mesh:submeshoffset:0:int32:1", G3dAttributeReferenceMultiplicity.OneToOne)] public partial class Geometry : Entity { @@ -1436,7 +1461,7 @@ public AABox Box /// Represents a sequence of Vector3 points in world space. /// The ordering and number of Shapes matches the ordering and number of shapes in the G3D buffer. /// - [TableName(TableNames.Shape)] + [TableName(VimEntityTableNames.Shape)] [G3dAttributeReference("g3d:shape:vertexoffset:0:int32:1", G3dAttributeReferenceMultiplicity.OneToOne, true)] [G3dAttributeReference("g3d:shape:color:0:float32:4", G3dAttributeReferenceMultiplicity.OneToOne, true)] [G3dAttributeReference("g3d:shape:width:0:float32:1", G3dAttributeReferenceMultiplicity.OneToOne, true)] @@ -1449,7 +1474,7 @@ public partial class Shape : EntityWithElement /// Currently, these define the shapes representing the curve loops on a face on an element; /// faces may have a number of curve loops which may designate the contour of the face and its holes. /// - [TableName(TableNames.ShapeCollection)] + [TableName(VimEntityTableNames.ShapeCollection)] [G3dAttributeReference("g3d:shape:vertexoffset:0:int32:1", G3dAttributeReferenceMultiplicity.OneToMany, true)] [G3dAttributeReference("g3d:shape:color:0:float32:4", G3dAttributeReferenceMultiplicity.OneToMany, true)] [G3dAttributeReference("g3d:shape:width:0:float32:1", G3dAttributeReferenceMultiplicity.OneToMany, true)] @@ -1460,7 +1485,8 @@ public partial class ShapeCollection : EntityWithElement /// /// An associative table binding a Shape to a ShapeCollection. /// - [TableName(TableNames.ShapeInShapeCollection)] + [TableName(VimEntityTableNames.ShapeInShapeCollection)] + [JoiningTable] public partial class ShapeInShapeCollection : Entity, IStorageKey { public Relation _Shape; @@ -1492,7 +1518,7 @@ public enum SystemType /// /// Represents a collection of Elements which compose a System. These may be mechanical systems, piping systems, electrical systems, curtain walls, stairs, etc. /// - [TableName(TableNames.System)] + [TableName(VimEntityTableNames.System)] [ElementKind(ElementKind.System)] public partial class System : EntityWithElement { @@ -1536,8 +1562,8 @@ public enum ElementInSystemRole /// /// An associative table binding an Element to a System. /// - [TableName(TableNames.ElementInSystem)] - [CascadeElementRemap] + [TableName(VimEntityTableNames.ElementInSystem)] + [JoiningTable] public partial class ElementInSystem : EntityWithElement, IStorageKey { /// @@ -1573,7 +1599,7 @@ public ElementInSystemRole GetRoles() /// Represents a textual Warning in a BimDocument. Warnings designate whether there are any problematic /// authoring issues among Elements in a BimDocument. /// - [TableName(TableNames.Warning)] + [TableName(VimEntityTableNames.Warning)] public partial class Warning : Entity { public string Guid; @@ -1585,8 +1611,8 @@ public partial class Warning : Entity /// /// An associative table binding an Element to a Warning. /// - [TableName(TableNames.ElementInWarning)] - [CascadeElementRemap] + [TableName(VimEntityTableNames.ElementInWarning)] + [JoiningTable] public partial class ElementInWarning : EntityWithElement, IStorageKey { public Relation _Warning; @@ -1599,7 +1625,7 @@ public object GetStorageKey() /// Represents the project base point or the document's current survey point if IsShared is set to true. /// BasePoints are only exported in Revit 2021+ /// - [TableName(TableNames.BasePoint)] + [TableName(VimEntityTableNames.BasePoint)] [ElementKind(ElementKind.BasePoint)] public partial class BasePoint : EntityWithElement { @@ -1660,7 +1686,7 @@ public enum PhaseStatusPresentation /// /// Represents a row in the Phase Filters view in Revit. /// - [TableName(TableNames.PhaseFilter)] + [TableName(VimEntityTableNames.PhaseFilter)] [ElementKind(ElementKind.PhaseFilter)] public partial class PhaseFilter : EntityWithElement { @@ -1715,7 +1741,7 @@ public static string PhaseStatusPresentationToString(int phaseStatusPresentation /// /// Represents a vertical plane (or a vertical cylindrical segment when curved). /// - [TableName(TableNames.Grid)] + [TableName(VimEntityTableNames.Grid)] [ElementKind(ElementKind.Grid)] public partial class Grid : EntityWithElement { @@ -1777,7 +1803,7 @@ public DAABox Extents /// /// Represents a planar region which can be used to represent places like parking spots. /// - [TableName(TableNames.Area)] + [TableName(VimEntityTableNames.Area)] [ElementKind(ElementKind.Area)] public partial class Area : EntityWithElement { @@ -1810,7 +1836,7 @@ public partial class Area : EntityWithElement /// /// Represents an area categorization, for example to differentiate between parking areas and waste/dump areas. /// - [TableName(TableNames.AreaScheme)] + [TableName(VimEntityTableNames.AreaScheme)] [ElementKind(ElementKind.AreaScheme)] public partial class AreaScheme : EntityWithElement { @@ -1823,7 +1849,7 @@ public partial class AreaScheme : EntityWithElement /// /// Represents tabular data composed of named columns and cells containing string values. /// - [TableName(TableNames.Schedule)] + [TableName(VimEntityTableNames.Schedule)] [ElementKind(ElementKind.Schedule)] public partial class Schedule : EntityWithElement @@ -1832,7 +1858,8 @@ public partial class Schedule : EntityWithElement /// /// Represents a column in a Schedule. /// - [TableName(TableNames.ScheduleColumn)] + [TableName(VimEntityTableNames.ScheduleColumn)] + [JoiningTable] public partial class ScheduleColumn : Entity { /// @@ -1854,7 +1881,8 @@ public partial class ScheduleColumn : Entity /// /// Represents a cell in a ScheduleColumn. /// - [TableName(TableNames.ScheduleCell)] + [TableName(VimEntityTableNames.ScheduleCell)] + [JoiningTable] public partial class ScheduleCell : Entity { /// @@ -1876,7 +1904,7 @@ public partial class ScheduleCell : Entity /// /// Represents a view sheet set, which is a collection of views and view sheets. /// - [TableName(TableNames.ViewSheetSet)] + [TableName(VimEntityTableNames.ViewSheetSet)] [ElementKind(ElementKind.ViewSheetSet)] public partial class ViewSheetSet : EntityWithElement { @@ -1885,7 +1913,7 @@ public partial class ViewSheetSet : EntityWithElement /// /// Represents a view sheet, which can contain multiple views. /// - [TableName(TableNames.ViewSheet)] + [TableName(VimEntityTableNames.ViewSheet)] [ElementKind(ElementKind.ViewSheet)] public partial class ViewSheet : EntityWithElement { @@ -1898,7 +1926,8 @@ public partial class ViewSheet : EntityWithElement /// /// An associative table binding a ViewSheet to a ViewSheetSet. /// - [TableName(TableNames.ViewSheetInViewSheetSet)] + [TableName(VimEntityTableNames.ViewSheetInViewSheetSet)] + [JoiningTable] public partial class ViewSheetInViewSheetSet : Entity, IStorageKey { public Relation _ViewSheet; @@ -1911,7 +1940,8 @@ public object GetStorageKey() /// /// An associative table binding a View to a ViewSheetSet. /// - [TableName(TableNames.ViewInViewSheetSet)] + [TableName(VimEntityTableNames.ViewInViewSheetSet)] + [JoiningTable] public partial class ViewInViewSheetSet : Entity, IStorageKey { public Relation _View; @@ -1924,7 +1954,8 @@ public object GetStorageKey() /// /// An associative table binding a View to a ViewSheet /// - [TableName(TableNames.ViewInViewSheet)] + [TableName(VimEntityTableNames.ViewInViewSheet)] + [JoiningTable] public partial class ViewInViewSheet : Entity, IStorageKey { public Relation _View; @@ -1934,7 +1965,7 @@ public object GetStorageKey() => _View.CombineAsStorageKey(_ViewSheet); } - [TableName(TableNames.Site)] + [TableName(VimEntityTableNames.Site)] [ElementKind(ElementKind.Site)] public partial class Site : EntityWithElement { @@ -1945,7 +1976,7 @@ public partial class Site : EntityWithElement public string Number; } - [TableName(TableNames.Building)] + [TableName(VimEntityTableNames.Building)] [ElementKind(ElementKind.Building)] public partial class Building : EntityWithElement { @@ -2004,33 +2035,5 @@ public static IEnumerable GetEntityTypes() where T : Entity public static IEnumerable GetEntityTypes() => GetEntityTypes().Where(IsEntityAndHasTableNameAttribute); - - public static object GetPropertyValue(this DocumentModel documentModel, string propertyName) - => documentModel.GetType().GetProperty(propertyName)?.GetValue(documentModel, null); - - public static VimSchema GetCurrentVimSchema() - { - var vimSchema = new VimSchema(VimFormatVersion.Current, SchemaVersion.Current); - - foreach (var entityType in GetEntityTypes()) - { - var entityTableSchema = vimSchema.AddEntityTableSchema(entityType.GetEntityTableName()); - - foreach (var fieldInfo in entityType.GetRelationFields()) - { - var (indexColumnName, _) = fieldInfo.GetIndexColumnInfo(); - entityTableSchema.AddColumn(indexColumnName); - } - - foreach (var fieldInfo in entityType.GetEntityFields()) - { - var loadingInfos = fieldInfo.GetEntityColumnLoadingInfo(); - - foreach (var li in loadingInfos) - entityTableSchema.AddColumn(li.EntityColumnAttribute.SerializedValueColumnName); - } - } - return vimSchema; - } } } diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelBuilder.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelBuilder.cs deleted file mode 100644 index ad2952d4..00000000 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelBuilder.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Vim.Format.ObjectModel -{ - /// - /// This class makes it easy to fill out the entity tables of a VIM, by allowing the user to specify a mapping - /// between objects in the source domain (e.g. Revit.Element) and entities. This allows a programmer to not - /// have to worry about adding the same element twice, and allows them to add entity objects to the document - /// builder in a single pass without worrying about lookup tables. - /// - public partial class ObjectModelBuilder - { - public DocumentBuilder ToDocumentBuilder(string generator, string versionString) - => AddEntityTableSets(new DocumentBuilder(generator, SchemaVersion.Current, versionString)); - } -} diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelExtensions.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelExtensions.cs index 75ed6734..aeb15353 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelExtensions.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelExtensions.cs @@ -3,90 +3,49 @@ using System.Data; using System.IO; using System.Linq; -using Vim.Format.Geometry; -using Vim.G3d; using Vim.Util; -using Vim.LinqArray; -using Vim.Math3d; -namespace Vim.Format.ObjectModel +namespace Vim.Format { public static class ObjectModelExtensions { - public static ElementInfo GetElementInfo(this DocumentModel documentModel, int elementIndex) - => new ElementInfo(documentModel, elementIndex); - - public static ElementInfo GetElementInfo(this DocumentModel documentModel, Element element) - => documentModel.GetElementInfo(element.Index); - - public static ElementInfo GetElementInfo(this DocumentModel documentModel, EntityWithElement entityWithElement) - => documentModel.GetElementInfo(entityWithElement._Element.Index); - - public static string GetUrn(this ElementInfo elementInfo) - => Urn.GetElementUrn(Urn.VimNID, elementInfo.Element); - public static string GetUrn(this BimDocument bd) => Urn.GetBimDocumentUrn(Urn.VimNID, bd); public static Element CreateSyntheticElement(string name, string type) => new Element { - Id = VimConstants.SyntheticElementId, + Id = VimEntityTableConstants.SyntheticElementId, Name = name, Type = type, UniqueId = $"{name}_{type}" // NOTE: we need to assign a UniqueId for merging purposes. }; public static Element CreateParameterHolderElement(string bimDocumentName) - => CreateSyntheticElement(bimDocumentName, VimConstants.BimDocumentParameterHolderElementType); + => CreateSyntheticElement(bimDocumentName, VimEntityTableConstants.BimDocumentParameterHolderElementType); public static Element CreateParameterHolderElement(this BimDocument bd) => CreateParameterHolderElement(bd.Name); - public static DictionaryOfLists GetAssetsInViewOrderedByViewIndex(this DocumentModel dm) - => dm.AssetInViewList.GroupBy(aiv => aiv.View.Index).ToDictionaryOfLists(); + public static DictionaryOfLists GetAssetsInViewOrderedByViewIndex(this VIM vim) + => vim.GetEntityTableSet().AssetInViewTable.GroupBy(aiv => aiv.View.Index).ToDictionaryOfLists(); - public static string GetBimDocumentFileName(this DocumentModel dm, int bimDocumentIndex) - => Path.GetFileName(dm.GetBimDocumentPathName(bimDocumentIndex)); + public static string GetBimDocumentFileName(this VIM vim, int bimDocumentIndex) + => Path.GetFileName(vim.GetEntityTableSet().BimDocumentTable.GetPathName(bimDocumentIndex)); - public static IArray GetBimDocumentDisplayUnits(this DocumentModel dm, BimDocument bd) - => dm.DisplayUnitInBimDocumentList + public static IEnumerable GetBimDocumentDisplayUnits(this VIM vim, BimDocument bd) + => vim.GetEntityTableSet().DisplayUnitInBimDocumentTable .Where(item => item.BimDocument.Index == bd.Index) - .Select(item => item.DisplayUnit) - .ToIArray(); + .Select(item => item.DisplayUnit); - public static IArray GetBimDocumentPhases(this DocumentModel dm, BimDocument bd) - => dm.PhaseOrderInBimDocumentList + public static IEnumerable GetBimDocumentPhases(this VIM vim, BimDocument bd) + => vim.GetEntityTableSet().PhaseOrderInBimDocumentTable .Where(item => item.BimDocument.Index == bd.Index) - .Select(item => item.Phase) - .ToIArray(); + .Select(item => item.Phase); public const string LengthSpecLegacyPrefix = "UT_Length"; public const string LengthSpecPrefix = "autodesk.spec.aec:length"; - public static DisplayUnit GetLengthDisplayUnit(this IArray displayUnits) - => displayUnits.FirstOrDefault(du => - { - var spec = du.Spec; - return spec.StartsWith(LengthSpecPrefix, StringComparison.InvariantCultureIgnoreCase) || - spec.StartsWith(LengthSpecLegacyPrefix, StringComparison.InvariantCultureIgnoreCase); - }); - - public static FamilyType GetFamilyType(this FamilyInstance fi) - => fi?.FamilyType; - - public static string GetFamilyTypeName(this FamilyInstance fi) - => fi?.FamilyType?.Element?.Name ?? ""; - - public static Family GetFamily(this FamilyType ft) - => ft?.Family; - - public static Family GetFamily(this FamilyInstance fi) - => fi?.GetFamilyType()?.GetFamily(); - - public static string GetFamilyName(this FamilyInstance fi) - => fi?.GetFamily()?.Element?.Name ?? ""; - /// /// Extension method using pre-allocated parser for improved performance. /// @@ -114,25 +73,6 @@ public static string GetParameterDisplayValueWithNativeValueFallback(this PipeSe } } - public static ElementInSystem[] GetElementsInSystem(this DocumentModel dm, System system) - { - if (system == null) - return Array.Empty(); - - return dm.ElementInSystemList.Where(eis => eis._System.Index == system.Index) - .ToArray(); - } - - public static Element[] GetElementsInWarning(this DocumentModel dm, Warning warning) - { - if (warning == null) - return Array.Empty(); - - return dm.ElementInWarningList.Where(eiw => eiw._Warning.Index == warning.Index) - .Select(eiw => eiw.Element) - .ToArray(); - } - // A helper class which defines cell data to be stored in a DataTable. private class CellData { @@ -148,13 +88,15 @@ public CellData(string value, int colIndex, int rowIndex) } } - public static DataTable GetScheduleAsDataTable(this DocumentModel dm, int scheduleIndex) + public static DataTable GetScheduleAsDataTable(this VIM vim, int scheduleIndex) { - var ei = dm.ScheduleElementIndex[scheduleIndex]; + var tableSet = vim.GetEntityTableSet(); + + var ei = tableSet.ScheduleTable.GetElementIndex(scheduleIndex); - var dataTable = new DataTable(dm.GetElementName(ei)); + var dataTable = new DataTable(tableSet.ElementTable.GetName(ei)); - var columns = dm.ScheduleColumnList + var columns = tableSet.ScheduleColumnTable .Where(c => c._Schedule.Index == scheduleIndex) .OrderBy(c => c.ColumnIndex) .ToArray(); @@ -162,12 +104,12 @@ public static DataTable GetScheduleAsDataTable(this DocumentModel dm, int schedu var columnSet = new HashSet(columns.Select(c => c.Index)); - var cellRecords = dm.ScheduleCellScheduleColumnIndex - .IndicesWhere((colIndex, _) => columnSet.Contains(colIndex)) + var cellRecords = tableSet.ScheduleCellTable.Column_ScheduleColumnIndex + .IndicesWhere((colIndex) => columnSet.Contains(colIndex)) .Select(cellIndex => new CellData( - dm.GetScheduleCellValue(cellIndex), - dm.GetScheduleCellScheduleColumnIndex(cellIndex), - dm.GetScheduleCellRowIndex(cellIndex))) + tableSet.ScheduleCellTable.GetValue(cellIndex), + tableSet.ScheduleCellTable.GetScheduleColumnIndex(cellIndex), + tableSet.ScheduleCellTable.GetRowIndex(cellIndex))) .GroupBy(c => c.RowIndex) .OrderBy(g => g.Key) .Select(g => g.OrderBy(t => t.ColIndex).Select(t => t.Value)); @@ -181,7 +123,7 @@ public static DataTable GetScheduleAsDataTable(this DocumentModel dm, int schedu /// /// Returns the list of parameter indices associated with the given element index. /// - public static List GetParameterIndicesFromElementIndex(this ElementIndexMaps elementIndexMaps, int elementIndex) + public static List GetParameterIndicesFromElementIndex(this VimElementIndexMaps elementIndexMaps, int elementIndex) { return elementIndexMaps.ParameterIndicesFromElementIndex.TryGetValue(elementIndex, out var parameterIndices) ? parameterIndices diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs deleted file mode 100644 index f3213ff8..00000000 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs +++ /dev/null @@ -1,10253 +0,0 @@ -// AUTO-GENERATED FILE, DO NOT MODIFY. -// ReSharper disable All -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using Vim.Math3d; -using Vim.LinqArray; -using Vim.Format.ObjectModel; -using Vim.Util; - -namespace Vim.Format.ObjectModel { - // AUTO-GENERATED - public partial class Asset - { - public Asset() - { - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Asset other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (BufferName == other.BufferName); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class DisplayUnit - { - public DisplayUnit() - { - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is DisplayUnit other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Spec == other.Spec) && - (Type == other.Type) && - (Label == other.Label); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ParameterDescriptor - { - public Vim.Format.ObjectModel.DisplayUnit DisplayUnit => _DisplayUnit?.Value; - public int DisplayUnitIndex => _DisplayUnit?.Index ?? EntityRelation.None; - public ParameterDescriptor() - { - _DisplayUnit = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ParameterDescriptor other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Name == other.Name) && - (Group == other.Group) && - (ParameterType == other.ParameterType) && - (IsInstance == other.IsInstance) && - (IsShared == other.IsShared) && - (IsReadOnly == other.IsReadOnly) && - (Flags == other.Flags) && - (Guid == other.Guid) && - (StorageType == other.StorageType) && - (_DisplayUnit?.Index == other._DisplayUnit?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Parameter - { - public Vim.Format.ObjectModel.ParameterDescriptor ParameterDescriptor => _ParameterDescriptor?.Value; - public int ParameterDescriptorIndex => _ParameterDescriptor?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Parameter() - { - _ParameterDescriptor = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Parameter other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Value == other.Value) && - (_ParameterDescriptor?.Index == other._ParameterDescriptor?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Element - { - public Vim.Format.ObjectModel.Level Level => _Level?.Value; - public int LevelIndex => _Level?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Phase PhaseCreated => _PhaseCreated?.Value; - public int PhaseCreatedIndex => _PhaseCreated?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Phase PhaseDemolished => _PhaseDemolished?.Value; - public int PhaseDemolishedIndex => _PhaseDemolished?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Category Category => _Category?.Value; - public int CategoryIndex => _Category?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Workset Workset => _Workset?.Value; - public int WorksetIndex => _Workset?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.DesignOption DesignOption => _DesignOption?.Value; - public int DesignOptionIndex => _DesignOption?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.View OwnerView => _OwnerView?.Value; - public int OwnerViewIndex => _OwnerView?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Group Group => _Group?.Value; - public int GroupIndex => _Group?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.AssemblyInstance AssemblyInstance => _AssemblyInstance?.Value; - public int AssemblyInstanceIndex => _AssemblyInstance?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.BimDocument BimDocument => _BimDocument?.Value; - public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Room Room => _Room?.Value; - public int RoomIndex => _Room?.Index ?? EntityRelation.None; - public Element() - { - _Level = new Relation(); - _PhaseCreated = new Relation(); - _PhaseDemolished = new Relation(); - _Category = new Relation(); - _Workset = new Relation(); - _DesignOption = new Relation(); - _OwnerView = new Relation(); - _Group = new Relation(); - _AssemblyInstance = new Relation(); - _BimDocument = new Relation(); - _Room = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Element other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Id == other.Id) && - (Type == other.Type) && - (Name == other.Name) && - (UniqueId == other.UniqueId) && - (Location_X == other.Location_X) && - (Location_Y == other.Location_Y) && - (Location_Z == other.Location_Z) && - (FamilyName == other.FamilyName) && - (IsPinned == other.IsPinned) && - (_Level?.Index == other._Level?.Index) && - (_PhaseCreated?.Index == other._PhaseCreated?.Index) && - (_PhaseDemolished?.Index == other._PhaseDemolished?.Index) && - (_Category?.Index == other._Category?.Index) && - (_Workset?.Index == other._Workset?.Index) && - (_DesignOption?.Index == other._DesignOption?.Index) && - (_OwnerView?.Index == other._OwnerView?.Index) && - (_Group?.Index == other._Group?.Index) && - (_AssemblyInstance?.Index == other._AssemblyInstance?.Index) && - (_BimDocument?.Index == other._BimDocument?.Index) && - (_Room?.Index == other._Room?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Workset - { - public Vim.Format.ObjectModel.BimDocument BimDocument => _BimDocument?.Value; - public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; - public Workset() - { - _BimDocument = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Workset other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Id == other.Id) && - (Name == other.Name) && - (Kind == other.Kind) && - (IsOpen == other.IsOpen) && - (IsEditable == other.IsEditable) && - (Owner == other.Owner) && - (UniqueId == other.UniqueId) && - (_BimDocument?.Index == other._BimDocument?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class AssemblyInstance - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public AssemblyInstance() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is AssemblyInstance other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (AssemblyTypeName == other.AssemblyTypeName) && - (Position_X == other.Position_X) && - (Position_Y == other.Position_Y) && - (Position_Z == other.Position_Z) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Group - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Group() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Group other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (GroupType == other.GroupType) && - (Position_X == other.Position_X) && - (Position_Y == other.Position_Y) && - (Position_Z == other.Position_Z) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class DesignOption - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public DesignOption() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is DesignOption other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (IsPrimary == other.IsPrimary) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Level - { - public Vim.Format.ObjectModel.FamilyType FamilyType => _FamilyType?.Value; - public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Building Building => _Building?.Value; - public int BuildingIndex => _Building?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Level() - { - _FamilyType = new Relation(); - _Building = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Level other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Elevation == other.Elevation) && - (ProjectElevation == other.ProjectElevation) && - (_FamilyType?.Index == other._FamilyType?.Index) && - (_Building?.Index == other._Building?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Phase - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Phase() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Phase other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Room - { - public Vim.Format.ObjectModel.Level UpperLimit => _UpperLimit?.Value; - public int UpperLimitIndex => _UpperLimit?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Room() - { - _UpperLimit = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Room other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (BaseOffset == other.BaseOffset) && - (LimitOffset == other.LimitOffset) && - (UnboundedHeight == other.UnboundedHeight) && - (Volume == other.Volume) && - (Perimeter == other.Perimeter) && - (Area == other.Area) && - (Number == other.Number) && - (_UpperLimit?.Index == other._UpperLimit?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class BimDocument - { - public Vim.Format.ObjectModel.View ActiveView => _ActiveView?.Value; - public int ActiveViewIndex => _ActiveView?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Family OwnerFamily => _OwnerFamily?.Value; - public int OwnerFamilyIndex => _OwnerFamily?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.BimDocument Parent => _Parent?.Value; - public int ParentIndex => _Parent?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public BimDocument() - { - _ActiveView = new Relation(); - _OwnerFamily = new Relation(); - _Parent = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is BimDocument other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Title == other.Title) && - (IsMetric == other.IsMetric) && - (NumSaves == other.NumSaves) && - (IsLinked == other.IsLinked) && - (IsDetached == other.IsDetached) && - (IsWorkshared == other.IsWorkshared) && - (PathName == other.PathName) && - (Latitude == other.Latitude) && - (Longitude == other.Longitude) && - (TimeZone == other.TimeZone) && - (PlaceName == other.PlaceName) && - (WeatherStationName == other.WeatherStationName) && - (Elevation == other.Elevation) && - (ProjectLocation == other.ProjectLocation) && - (IssueDate == other.IssueDate) && - (Status == other.Status) && - (ClientName == other.ClientName) && - (Address == other.Address) && - (Name == other.Name) && - (Number == other.Number) && - (Author == other.Author) && - (BuildingName == other.BuildingName) && - (OrganizationName == other.OrganizationName) && - (OrganizationDescription == other.OrganizationDescription) && - (Product == other.Product) && - (Version == other.Version) && - (User == other.User) && - (FileLength == other.FileLength) && - (_ActiveView?.Index == other._ActiveView?.Index) && - (_OwnerFamily?.Index == other._OwnerFamily?.Index) && - (_Parent?.Index == other._Parent?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class DisplayUnitInBimDocument - { - public Vim.Format.ObjectModel.DisplayUnit DisplayUnit => _DisplayUnit?.Value; - public int DisplayUnitIndex => _DisplayUnit?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.BimDocument BimDocument => _BimDocument?.Value; - public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; - public DisplayUnitInBimDocument() - { - _DisplayUnit = new Relation(); - _BimDocument = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is DisplayUnitInBimDocument other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_DisplayUnit?.Index == other._DisplayUnit?.Index) && - (_BimDocument?.Index == other._BimDocument?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class PhaseOrderInBimDocument - { - public Vim.Format.ObjectModel.Phase Phase => _Phase?.Value; - public int PhaseIndex => _Phase?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.BimDocument BimDocument => _BimDocument?.Value; - public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; - public PhaseOrderInBimDocument() - { - _Phase = new Relation(); - _BimDocument = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is PhaseOrderInBimDocument other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (OrderIndex == other.OrderIndex) && - (_Phase?.Index == other._Phase?.Index) && - (_BimDocument?.Index == other._BimDocument?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Category - { - public Vim.Format.ObjectModel.Category Parent => _Parent?.Value; - public int ParentIndex => _Parent?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Material Material => _Material?.Value; - public int MaterialIndex => _Material?.Index ?? EntityRelation.None; - public Category() - { - _Parent = new Relation(); - _Material = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Category other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Name == other.Name) && - (Id == other.Id) && - (CategoryType == other.CategoryType) && - (LineColor_X == other.LineColor_X) && - (LineColor_Y == other.LineColor_Y) && - (LineColor_Z == other.LineColor_Z) && - (BuiltInCategory == other.BuiltInCategory) && - (_Parent?.Index == other._Parent?.Index) && - (_Material?.Index == other._Material?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Family - { - public Vim.Format.ObjectModel.Category FamilyCategory => _FamilyCategory?.Value; - public int FamilyCategoryIndex => _FamilyCategory?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Family() - { - _FamilyCategory = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Family other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (StructuralMaterialType == other.StructuralMaterialType) && - (StructuralSectionShape == other.StructuralSectionShape) && - (IsSystemFamily == other.IsSystemFamily) && - (IsInPlace == other.IsInPlace) && - (_FamilyCategory?.Index == other._FamilyCategory?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class FamilyType - { - public Vim.Format.ObjectModel.Family Family => _Family?.Value; - public int FamilyIndex => _Family?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.CompoundStructure CompoundStructure => _CompoundStructure?.Value; - public int CompoundStructureIndex => _CompoundStructure?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public FamilyType() - { - _Family = new Relation(); - _CompoundStructure = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is FamilyType other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (IsSystemFamilyType == other.IsSystemFamilyType) && - (_Family?.Index == other._Family?.Index) && - (_CompoundStructure?.Index == other._CompoundStructure?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class FamilyInstance - { - public Vim.Format.ObjectModel.FamilyType FamilyType => _FamilyType?.Value; - public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Host => _Host?.Value; - public int HostIndex => _Host?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Room FromRoom => _FromRoom?.Value; - public int FromRoomIndex => _FromRoom?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Room ToRoom => _ToRoom?.Value; - public int ToRoomIndex => _ToRoom?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element SuperComponent => _SuperComponent?.Value; - public int SuperComponentIndex => _SuperComponent?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public FamilyInstance() - { - _FamilyType = new Relation(); - _Host = new Relation(); - _FromRoom = new Relation(); - _ToRoom = new Relation(); - _SuperComponent = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is FamilyInstance other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (FacingFlipped == other.FacingFlipped) && - (FacingOrientation_X == other.FacingOrientation_X) && - (FacingOrientation_Y == other.FacingOrientation_Y) && - (FacingOrientation_Z == other.FacingOrientation_Z) && - (HandFlipped == other.HandFlipped) && - (Mirrored == other.Mirrored) && - (HasModifiedGeometry == other.HasModifiedGeometry) && - (Scale == other.Scale) && - (BasisX_X == other.BasisX_X) && - (BasisX_Y == other.BasisX_Y) && - (BasisX_Z == other.BasisX_Z) && - (BasisY_X == other.BasisY_X) && - (BasisY_Y == other.BasisY_Y) && - (BasisY_Z == other.BasisY_Z) && - (BasisZ_X == other.BasisZ_X) && - (BasisZ_Y == other.BasisZ_Y) && - (BasisZ_Z == other.BasisZ_Z) && - (Translation_X == other.Translation_X) && - (Translation_Y == other.Translation_Y) && - (Translation_Z == other.Translation_Z) && - (HandOrientation_X == other.HandOrientation_X) && - (HandOrientation_Y == other.HandOrientation_Y) && - (HandOrientation_Z == other.HandOrientation_Z) && - (_FamilyType?.Index == other._FamilyType?.Index) && - (_Host?.Index == other._Host?.Index) && - (_FromRoom?.Index == other._FromRoom?.Index) && - (_ToRoom?.Index == other._ToRoom?.Index) && - (_SuperComponent?.Index == other._SuperComponent?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class View - { - public Vim.Format.ObjectModel.Camera Camera => _Camera?.Value; - public int CameraIndex => _Camera?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.FamilyType FamilyType => _FamilyType?.Value; - public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public View() - { - _Camera = new Relation(); - _FamilyType = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is View other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Title == other.Title) && - (ViewType == other.ViewType) && - (Up_X == other.Up_X) && - (Up_Y == other.Up_Y) && - (Up_Z == other.Up_Z) && - (Right_X == other.Right_X) && - (Right_Y == other.Right_Y) && - (Right_Z == other.Right_Z) && - (Origin_X == other.Origin_X) && - (Origin_Y == other.Origin_Y) && - (Origin_Z == other.Origin_Z) && - (ViewDirection_X == other.ViewDirection_X) && - (ViewDirection_Y == other.ViewDirection_Y) && - (ViewDirection_Z == other.ViewDirection_Z) && - (ViewPosition_X == other.ViewPosition_X) && - (ViewPosition_Y == other.ViewPosition_Y) && - (ViewPosition_Z == other.ViewPosition_Z) && - (Scale == other.Scale) && - (Outline_Min_X == other.Outline_Min_X) && - (Outline_Min_Y == other.Outline_Min_Y) && - (Outline_Max_X == other.Outline_Max_X) && - (Outline_Max_Y == other.Outline_Max_Y) && - (DetailLevel == other.DetailLevel) && - (_Camera?.Index == other._Camera?.Index) && - (_FamilyType?.Index == other._FamilyType?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ElementInView - { - public Vim.Format.ObjectModel.View View => _View?.Value; - public int ViewIndex => _View?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public ElementInView() - { - _View = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ElementInView other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_View?.Index == other._View?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ShapeInView - { - public Vim.Format.ObjectModel.Shape Shape => _Shape?.Value; - public int ShapeIndex => _Shape?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.View View => _View?.Value; - public int ViewIndex => _View?.Index ?? EntityRelation.None; - public ShapeInView() - { - _Shape = new Relation(); - _View = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ShapeInView other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Shape?.Index == other._Shape?.Index) && - (_View?.Index == other._View?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class AssetInView - { - public Vim.Format.ObjectModel.Asset Asset => _Asset?.Value; - public int AssetIndex => _Asset?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.View View => _View?.Value; - public int ViewIndex => _View?.Index ?? EntityRelation.None; - public AssetInView() - { - _Asset = new Relation(); - _View = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is AssetInView other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Asset?.Index == other._Asset?.Index) && - (_View?.Index == other._View?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class AssetInViewSheet - { - public Vim.Format.ObjectModel.Asset Asset => _Asset?.Value; - public int AssetIndex => _Asset?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.ViewSheet ViewSheet => _ViewSheet?.Value; - public int ViewSheetIndex => _ViewSheet?.Index ?? EntityRelation.None; - public AssetInViewSheet() - { - _Asset = new Relation(); - _ViewSheet = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is AssetInViewSheet other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Asset?.Index == other._Asset?.Index) && - (_ViewSheet?.Index == other._ViewSheet?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class LevelInView - { - public Vim.Format.ObjectModel.Level Level => _Level?.Value; - public int LevelIndex => _Level?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.View View => _View?.Value; - public int ViewIndex => _View?.Index ?? EntityRelation.None; - public LevelInView() - { - _Level = new Relation(); - _View = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is LevelInView other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Extents_Min_X == other.Extents_Min_X) && - (Extents_Min_Y == other.Extents_Min_Y) && - (Extents_Min_Z == other.Extents_Min_Z) && - (Extents_Max_X == other.Extents_Max_X) && - (Extents_Max_Y == other.Extents_Max_Y) && - (Extents_Max_Z == other.Extents_Max_Z) && - (_Level?.Index == other._Level?.Index) && - (_View?.Index == other._View?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Camera - { - public Camera() - { - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Camera other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Id == other.Id) && - (IsPerspective == other.IsPerspective) && - (VerticalExtent == other.VerticalExtent) && - (HorizontalExtent == other.HorizontalExtent) && - (FarDistance == other.FarDistance) && - (NearDistance == other.NearDistance) && - (TargetDistance == other.TargetDistance) && - (RightOffset == other.RightOffset) && - (UpOffset == other.UpOffset); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Material - { - public Vim.Format.ObjectModel.Asset ColorTextureFile => _ColorTextureFile?.Value; - public int ColorTextureFileIndex => _ColorTextureFile?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Asset NormalTextureFile => _NormalTextureFile?.Value; - public int NormalTextureFileIndex => _NormalTextureFile?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Material() - { - _ColorTextureFile = new Relation(); - _NormalTextureFile = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Material other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Name == other.Name) && - (MaterialCategory == other.MaterialCategory) && - (Color_X == other.Color_X) && - (Color_Y == other.Color_Y) && - (Color_Z == other.Color_Z) && - (ColorUvScaling_X == other.ColorUvScaling_X) && - (ColorUvScaling_Y == other.ColorUvScaling_Y) && - (ColorUvOffset_X == other.ColorUvOffset_X) && - (ColorUvOffset_Y == other.ColorUvOffset_Y) && - (NormalUvScaling_X == other.NormalUvScaling_X) && - (NormalUvScaling_Y == other.NormalUvScaling_Y) && - (NormalUvOffset_X == other.NormalUvOffset_X) && - (NormalUvOffset_Y == other.NormalUvOffset_Y) && - (NormalAmount == other.NormalAmount) && - (Glossiness == other.Glossiness) && - (Smoothness == other.Smoothness) && - (Transparency == other.Transparency) && - (_ColorTextureFile?.Index == other._ColorTextureFile?.Index) && - (_NormalTextureFile?.Index == other._NormalTextureFile?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class MaterialInElement - { - public Vim.Format.ObjectModel.Material Material => _Material?.Value; - public int MaterialIndex => _Material?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public MaterialInElement() - { - _Material = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is MaterialInElement other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Area == other.Area) && - (Volume == other.Volume) && - (IsPaint == other.IsPaint) && - (_Material?.Index == other._Material?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class CompoundStructureLayer - { - public Vim.Format.ObjectModel.Material Material => _Material?.Value; - public int MaterialIndex => _Material?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.CompoundStructure CompoundStructure => _CompoundStructure?.Value; - public int CompoundStructureIndex => _CompoundStructure?.Index ?? EntityRelation.None; - public CompoundStructureLayer() - { - _Material = new Relation(); - _CompoundStructure = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is CompoundStructureLayer other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (OrderIndex == other.OrderIndex) && - (Width == other.Width) && - (MaterialFunctionAssignment == other.MaterialFunctionAssignment) && - (_Material?.Index == other._Material?.Index) && - (_CompoundStructure?.Index == other._CompoundStructure?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class CompoundStructure - { - public Vim.Format.ObjectModel.CompoundStructureLayer StructuralLayer => _StructuralLayer?.Value; - public int StructuralLayerIndex => _StructuralLayer?.Index ?? EntityRelation.None; - public CompoundStructure() - { - _StructuralLayer = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is CompoundStructure other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Width == other.Width) && - (_StructuralLayer?.Index == other._StructuralLayer?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Node - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Node() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Node other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Geometry - { - public Geometry() - { - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Geometry other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Box_Min_X == other.Box_Min_X) && - (Box_Min_Y == other.Box_Min_Y) && - (Box_Min_Z == other.Box_Min_Z) && - (Box_Max_X == other.Box_Max_X) && - (Box_Max_Y == other.Box_Max_Y) && - (Box_Max_Z == other.Box_Max_Z) && - (VertexCount == other.VertexCount) && - (FaceCount == other.FaceCount); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Shape - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Shape() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Shape other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ShapeCollection - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public ShapeCollection() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ShapeCollection other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ShapeInShapeCollection - { - public Vim.Format.ObjectModel.Shape Shape => _Shape?.Value; - public int ShapeIndex => _Shape?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.ShapeCollection ShapeCollection => _ShapeCollection?.Value; - public int ShapeCollectionIndex => _ShapeCollection?.Index ?? EntityRelation.None; - public ShapeInShapeCollection() - { - _Shape = new Relation(); - _ShapeCollection = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ShapeInShapeCollection other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Shape?.Index == other._Shape?.Index) && - (_ShapeCollection?.Index == other._ShapeCollection?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class System - { - public Vim.Format.ObjectModel.FamilyType FamilyType => _FamilyType?.Value; - public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public System() - { - _FamilyType = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is System other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (SystemType == other.SystemType) && - (_FamilyType?.Index == other._FamilyType?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ElementInSystem - { - public Vim.Format.ObjectModel.System System => _System?.Value; - public int SystemIndex => _System?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public ElementInSystem() - { - _System = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ElementInSystem other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Roles == other.Roles) && - (_System?.Index == other._System?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Warning - { - public Vim.Format.ObjectModel.BimDocument BimDocument => _BimDocument?.Value; - public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; - public Warning() - { - _BimDocument = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Warning other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Guid == other.Guid) && - (Severity == other.Severity) && - (Description == other.Description) && - (_BimDocument?.Index == other._BimDocument?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ElementInWarning - { - public Vim.Format.ObjectModel.Warning Warning => _Warning?.Value; - public int WarningIndex => _Warning?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public ElementInWarning() - { - _Warning = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ElementInWarning other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Warning?.Index == other._Warning?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class BasePoint - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public BasePoint() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is BasePoint other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (IsSurveyPoint == other.IsSurveyPoint) && - (Position_X == other.Position_X) && - (Position_Y == other.Position_Y) && - (Position_Z == other.Position_Z) && - (SharedPosition_X == other.SharedPosition_X) && - (SharedPosition_Y == other.SharedPosition_Y) && - (SharedPosition_Z == other.SharedPosition_Z) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class PhaseFilter - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public PhaseFilter() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is PhaseFilter other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (New == other.New) && - (Existing == other.Existing) && - (Demolished == other.Demolished) && - (Temporary == other.Temporary) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Grid - { - public Vim.Format.ObjectModel.FamilyType FamilyType => _FamilyType?.Value; - public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Grid() - { - _FamilyType = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Grid other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (StartPoint_X == other.StartPoint_X) && - (StartPoint_Y == other.StartPoint_Y) && - (StartPoint_Z == other.StartPoint_Z) && - (EndPoint_X == other.EndPoint_X) && - (EndPoint_Y == other.EndPoint_Y) && - (EndPoint_Z == other.EndPoint_Z) && - (IsCurved == other.IsCurved) && - (Extents_Min_X == other.Extents_Min_X) && - (Extents_Min_Y == other.Extents_Min_Y) && - (Extents_Min_Z == other.Extents_Min_Z) && - (Extents_Max_X == other.Extents_Max_X) && - (Extents_Max_Y == other.Extents_Max_Y) && - (Extents_Max_Z == other.Extents_Max_Z) && - (_FamilyType?.Index == other._FamilyType?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Area - { - public Vim.Format.ObjectModel.AreaScheme AreaScheme => _AreaScheme?.Value; - public int AreaSchemeIndex => _AreaScheme?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Area() - { - _AreaScheme = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Area other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Value == other.Value) && - (Perimeter == other.Perimeter) && - (Number == other.Number) && - (IsGrossInterior == other.IsGrossInterior) && - (_AreaScheme?.Index == other._AreaScheme?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class AreaScheme - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public AreaScheme() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is AreaScheme other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (IsGrossBuildingArea == other.IsGrossBuildingArea) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Schedule - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Schedule() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Schedule other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ScheduleColumn - { - public Vim.Format.ObjectModel.Schedule Schedule => _Schedule?.Value; - public int ScheduleIndex => _Schedule?.Index ?? EntityRelation.None; - public ScheduleColumn() - { - _Schedule = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ScheduleColumn other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Name == other.Name) && - (ColumnIndex == other.ColumnIndex) && - (_Schedule?.Index == other._Schedule?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ScheduleCell - { - public Vim.Format.ObjectModel.ScheduleColumn ScheduleColumn => _ScheduleColumn?.Value; - public int ScheduleColumnIndex => _ScheduleColumn?.Index ?? EntityRelation.None; - public ScheduleCell() - { - _ScheduleColumn = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ScheduleCell other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Value == other.Value) && - (RowIndex == other.RowIndex) && - (_ScheduleColumn?.Index == other._ScheduleColumn?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ViewSheetSet - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public ViewSheetSet() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ViewSheetSet other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ViewSheet - { - public Vim.Format.ObjectModel.FamilyType FamilyType => _FamilyType?.Value; - public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public ViewSheet() - { - _FamilyType = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ViewSheet other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_FamilyType?.Index == other._FamilyType?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ViewSheetInViewSheetSet - { - public Vim.Format.ObjectModel.ViewSheet ViewSheet => _ViewSheet?.Value; - public int ViewSheetIndex => _ViewSheet?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.ViewSheetSet ViewSheetSet => _ViewSheetSet?.Value; - public int ViewSheetSetIndex => _ViewSheetSet?.Index ?? EntityRelation.None; - public ViewSheetInViewSheetSet() - { - _ViewSheet = new Relation(); - _ViewSheetSet = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ViewSheetInViewSheetSet other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_ViewSheet?.Index == other._ViewSheet?.Index) && - (_ViewSheetSet?.Index == other._ViewSheetSet?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ViewInViewSheetSet - { - public Vim.Format.ObjectModel.View View => _View?.Value; - public int ViewIndex => _View?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.ViewSheetSet ViewSheetSet => _ViewSheetSet?.Value; - public int ViewSheetSetIndex => _ViewSheetSet?.Index ?? EntityRelation.None; - public ViewInViewSheetSet() - { - _View = new Relation(); - _ViewSheetSet = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ViewInViewSheetSet other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_View?.Index == other._View?.Index) && - (_ViewSheetSet?.Index == other._ViewSheetSet?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class ViewInViewSheet - { - public Vim.Format.ObjectModel.View View => _View?.Value; - public int ViewIndex => _View?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.ViewSheet ViewSheet => _ViewSheet?.Value; - public int ViewSheetIndex => _ViewSheet?.Index ?? EntityRelation.None; - public ViewInViewSheet() - { - _View = new Relation(); - _ViewSheet = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is ViewInViewSheet other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (_View?.Index == other._View?.Index) && - (_ViewSheet?.Index == other._ViewSheet?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Site - { - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Site() - { - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Site other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Latitude == other.Latitude) && - (Longitude == other.Longitude) && - (Address == other.Address) && - (Elevation == other.Elevation) && - (Number == other.Number) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - // AUTO-GENERATED - public partial class Building - { - public Vim.Format.ObjectModel.Site Site => _Site?.Value; - public int SiteIndex => _Site?.Index ?? EntityRelation.None; - public Vim.Format.ObjectModel.Element Element => _Element?.Value; - public int ElementIndex => _Element?.Index ?? EntityRelation.None; - public Building() - { - _Site = new Relation(); - _Element = new Relation(); - } - - public override bool FieldsAreEqual(object obj) - { - if ((obj is Building other)) - { - var fieldsAreEqual = - (Index == other.Index) && - (Elevation == other.Elevation) && - (TerrainElevation == other.TerrainElevation) && - (Address == other.Address) && - (_Site?.Index == other._Site?.Index) && - (_Element?.Index == other._Element?.Index); - if (!fieldsAreEqual) - { - return false; - } - - return true; - } - return false; - } - - } // end of class - - public partial class DocumentModel - { - public ElementIndexMaps ElementIndexMaps { get; } - - // Asset - - public EntityTable AssetEntityTable { get; } - - public IArray AssetBufferName { get; } - public String GetAssetBufferName(int index, String defaultValue = "") => AssetBufferName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public int NumAsset => AssetEntityTable?.NumRows ?? 0; - public IArray AssetList { get; } - public Asset GetAsset(int n) - { - if (n < 0) return null; - var r = new Asset(); - r.Document = Document; - r.Index = n; - r.BufferName = AssetBufferName.ElementAtOrDefault(n); - return r; - } - - - // DisplayUnit - - public EntityTable DisplayUnitEntityTable { get; } - - public IArray DisplayUnitSpec { get; } - public String GetDisplayUnitSpec(int index, String defaultValue = "") => DisplayUnitSpec?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray DisplayUnitType { get; } - public String GetDisplayUnitType(int index, String defaultValue = "") => DisplayUnitType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray DisplayUnitLabel { get; } - public String GetDisplayUnitLabel(int index, String defaultValue = "") => DisplayUnitLabel?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public int NumDisplayUnit => DisplayUnitEntityTable?.NumRows ?? 0; - public IArray DisplayUnitList { get; } - public DisplayUnit GetDisplayUnit(int n) - { - if (n < 0) return null; - var r = new DisplayUnit(); - r.Document = Document; - r.Index = n; - r.Spec = DisplayUnitSpec.ElementAtOrDefault(n); - r.Type = DisplayUnitType.ElementAtOrDefault(n); - r.Label = DisplayUnitLabel.ElementAtOrDefault(n); - return r; - } - - - // ParameterDescriptor - - public EntityTable ParameterDescriptorEntityTable { get; } - - public IArray ParameterDescriptorName { get; } - public String GetParameterDescriptorName(int index, String defaultValue = "") => ParameterDescriptorName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorGroup { get; } - public String GetParameterDescriptorGroup(int index, String defaultValue = "") => ParameterDescriptorGroup?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorParameterType { get; } - public String GetParameterDescriptorParameterType(int index, String defaultValue = "") => ParameterDescriptorParameterType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorIsInstance { get; } - public Boolean GetParameterDescriptorIsInstance(int index, Boolean defaultValue = default) => ParameterDescriptorIsInstance?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorIsShared { get; } - public Boolean GetParameterDescriptorIsShared(int index, Boolean defaultValue = default) => ParameterDescriptorIsShared?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorIsReadOnly { get; } - public Boolean GetParameterDescriptorIsReadOnly(int index, Boolean defaultValue = default) => ParameterDescriptorIsReadOnly?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorFlags { get; } - public Int32 GetParameterDescriptorFlags(int index, Int32 defaultValue = default) => ParameterDescriptorFlags?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorGuid { get; } - public String GetParameterDescriptorGuid(int index, String defaultValue = "") => ParameterDescriptorGuid?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorStorageType { get; } - public Int32 GetParameterDescriptorStorageType(int index, Int32 defaultValue = default) => ParameterDescriptorStorageType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterDescriptorDisplayUnitIndex { get; } - public int GetParameterDescriptorDisplayUnitIndex(int index) => ParameterDescriptorDisplayUnitIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumParameterDescriptor => ParameterDescriptorEntityTable?.NumRows ?? 0; - public IArray ParameterDescriptorList { get; } - public ParameterDescriptor GetParameterDescriptor(int n) - { - if (n < 0) return null; - var r = new ParameterDescriptor(); - r.Document = Document; - r.Index = n; - r.Name = ParameterDescriptorName.ElementAtOrDefault(n); - r.Group = ParameterDescriptorGroup.ElementAtOrDefault(n); - r.ParameterType = ParameterDescriptorParameterType.ElementAtOrDefault(n); - r.IsInstance = ParameterDescriptorIsInstance.ElementAtOrDefault(n); - r.IsShared = ParameterDescriptorIsShared.ElementAtOrDefault(n); - r.IsReadOnly = ParameterDescriptorIsReadOnly.ElementAtOrDefault(n); - r.Flags = ParameterDescriptorFlags.ElementAtOrDefault(n); - r.Guid = ParameterDescriptorGuid.ElementAtOrDefault(n); - r.StorageType = ParameterDescriptorStorageType.ElementAtOrDefault(n); - r._DisplayUnit = new Relation(GetParameterDescriptorDisplayUnitIndex(n), GetDisplayUnit); - return r; - } - - - // Parameter - - public EntityTable ParameterEntityTable { get; } - - public IArray ParameterValue { get; } - public String GetParameterValue(int index, String defaultValue = "") => ParameterValue?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ParameterParameterDescriptorIndex { get; } - public int GetParameterParameterDescriptorIndex(int index) => ParameterParameterDescriptorIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ParameterElementIndex { get; } - public int GetParameterElementIndex(int index) => ParameterElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumParameter => ParameterEntityTable?.NumRows ?? 0; - public IArray ParameterList { get; } - public Parameter GetParameter(int n) - { - if (n < 0) return null; - var r = new Parameter(); - r.Document = Document; - r.Index = n; - r.Value = ParameterValue.ElementAtOrDefault(n); - r._ParameterDescriptor = new Relation(GetParameterParameterDescriptorIndex(n), GetParameterDescriptor); - r._Element = new Relation(GetParameterElementIndex(n), GetElement); - return r; - } - - - // Element - - public EntityTable ElementEntityTable { get; } - - public IArray ElementId { get; } - public Int64 GetElementId(int index, Int64 defaultValue = default) => ElementId?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementType { get; } - public String GetElementType(int index, String defaultValue = "") => ElementType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementName { get; } - public String GetElementName(int index, String defaultValue = "") => ElementName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementUniqueId { get; } - public String GetElementUniqueId(int index, String defaultValue = "") => ElementUniqueId?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementLocation_X { get; } - public Single GetElementLocation_X(int index, Single defaultValue = default) => ElementLocation_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementLocation_Y { get; } - public Single GetElementLocation_Y(int index, Single defaultValue = default) => ElementLocation_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementLocation_Z { get; } - public Single GetElementLocation_Z(int index, Single defaultValue = default) => ElementLocation_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementFamilyName { get; } - public String GetElementFamilyName(int index, String defaultValue = "") => ElementFamilyName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementIsPinned { get; } - public Boolean GetElementIsPinned(int index, Boolean defaultValue = default) => ElementIsPinned?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementLevelIndex { get; } - public int GetElementLevelIndex(int index) => ElementLevelIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementPhaseCreatedIndex { get; } - public int GetElementPhaseCreatedIndex(int index) => ElementPhaseCreatedIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementPhaseDemolishedIndex { get; } - public int GetElementPhaseDemolishedIndex(int index) => ElementPhaseDemolishedIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementCategoryIndex { get; } - public int GetElementCategoryIndex(int index) => ElementCategoryIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementWorksetIndex { get; } - public int GetElementWorksetIndex(int index) => ElementWorksetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementDesignOptionIndex { get; } - public int GetElementDesignOptionIndex(int index) => ElementDesignOptionIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementOwnerViewIndex { get; } - public int GetElementOwnerViewIndex(int index) => ElementOwnerViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementGroupIndex { get; } - public int GetElementGroupIndex(int index) => ElementGroupIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementAssemblyInstanceIndex { get; } - public int GetElementAssemblyInstanceIndex(int index) => ElementAssemblyInstanceIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementBimDocumentIndex { get; } - public int GetElementBimDocumentIndex(int index) => ElementBimDocumentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementRoomIndex { get; } - public int GetElementRoomIndex(int index) => ElementRoomIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumElement => ElementEntityTable?.NumRows ?? 0; - public IArray ElementList { get; } - public Element GetElement(int n) - { - if (n < 0) return null; - var r = new Element(); - r.Document = Document; - r.Index = n; - r.Id = ElementId.ElementAtOrDefault(n); - r.Type = ElementType.ElementAtOrDefault(n); - r.Name = ElementName.ElementAtOrDefault(n); - r.UniqueId = ElementUniqueId.ElementAtOrDefault(n); - r.Location_X = ElementLocation_X.ElementAtOrDefault(n); - r.Location_Y = ElementLocation_Y.ElementAtOrDefault(n); - r.Location_Z = ElementLocation_Z.ElementAtOrDefault(n); - r.FamilyName = ElementFamilyName.ElementAtOrDefault(n); - r.IsPinned = ElementIsPinned.ElementAtOrDefault(n); - r._Level = new Relation(GetElementLevelIndex(n), GetLevel); - r._PhaseCreated = new Relation(GetElementPhaseCreatedIndex(n), GetPhase); - r._PhaseDemolished = new Relation(GetElementPhaseDemolishedIndex(n), GetPhase); - r._Category = new Relation(GetElementCategoryIndex(n), GetCategory); - r._Workset = new Relation(GetElementWorksetIndex(n), GetWorkset); - r._DesignOption = new Relation(GetElementDesignOptionIndex(n), GetDesignOption); - r._OwnerView = new Relation(GetElementOwnerViewIndex(n), GetView); - r._Group = new Relation(GetElementGroupIndex(n), GetGroup); - r._AssemblyInstance = new Relation(GetElementAssemblyInstanceIndex(n), GetAssemblyInstance); - r._BimDocument = new Relation(GetElementBimDocumentIndex(n), GetBimDocument); - r._Room = new Relation(GetElementRoomIndex(n), GetRoom); - return r; - } - - - // Workset - - public EntityTable WorksetEntityTable { get; } - - public IArray WorksetId { get; } - public Int32 GetWorksetId(int index, Int32 defaultValue = default) => WorksetId?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetName { get; } - public String GetWorksetName(int index, String defaultValue = "") => WorksetName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetKind { get; } - public String GetWorksetKind(int index, String defaultValue = "") => WorksetKind?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetIsOpen { get; } - public Boolean GetWorksetIsOpen(int index, Boolean defaultValue = default) => WorksetIsOpen?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetIsEditable { get; } - public Boolean GetWorksetIsEditable(int index, Boolean defaultValue = default) => WorksetIsEditable?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetOwner { get; } - public String GetWorksetOwner(int index, String defaultValue = "") => WorksetOwner?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetUniqueId { get; } - public String GetWorksetUniqueId(int index, String defaultValue = "") => WorksetUniqueId?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WorksetBimDocumentIndex { get; } - public int GetWorksetBimDocumentIndex(int index) => WorksetBimDocumentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumWorkset => WorksetEntityTable?.NumRows ?? 0; - public IArray WorksetList { get; } - public Workset GetWorkset(int n) - { - if (n < 0) return null; - var r = new Workset(); - r.Document = Document; - r.Index = n; - r.Id = WorksetId.ElementAtOrDefault(n); - r.Name = WorksetName.ElementAtOrDefault(n); - r.Kind = WorksetKind.ElementAtOrDefault(n); - r.IsOpen = WorksetIsOpen.ElementAtOrDefault(n); - r.IsEditable = WorksetIsEditable.ElementAtOrDefault(n); - r.Owner = WorksetOwner.ElementAtOrDefault(n); - r.UniqueId = WorksetUniqueId.ElementAtOrDefault(n); - r._BimDocument = new Relation(GetWorksetBimDocumentIndex(n), GetBimDocument); - return r; - } - - - // AssemblyInstance - - public EntityTable AssemblyInstanceEntityTable { get; } - - public IArray AssemblyInstanceAssemblyTypeName { get; } - public String GetAssemblyInstanceAssemblyTypeName(int index, String defaultValue = "") => AssemblyInstanceAssemblyTypeName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AssemblyInstancePosition_X { get; } - public Single GetAssemblyInstancePosition_X(int index, Single defaultValue = default) => AssemblyInstancePosition_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AssemblyInstancePosition_Y { get; } - public Single GetAssemblyInstancePosition_Y(int index, Single defaultValue = default) => AssemblyInstancePosition_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AssemblyInstancePosition_Z { get; } - public Single GetAssemblyInstancePosition_Z(int index, Single defaultValue = default) => AssemblyInstancePosition_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AssemblyInstanceElementIndex { get; } - public int GetAssemblyInstanceElementIndex(int index) => AssemblyInstanceElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumAssemblyInstance => AssemblyInstanceEntityTable?.NumRows ?? 0; - public IArray AssemblyInstanceList { get; } - public AssemblyInstance GetAssemblyInstance(int n) - { - if (n < 0) return null; - var r = new AssemblyInstance(); - r.Document = Document; - r.Index = n; - r.AssemblyTypeName = AssemblyInstanceAssemblyTypeName.ElementAtOrDefault(n); - r.Position_X = AssemblyInstancePosition_X.ElementAtOrDefault(n); - r.Position_Y = AssemblyInstancePosition_Y.ElementAtOrDefault(n); - r.Position_Z = AssemblyInstancePosition_Z.ElementAtOrDefault(n); - r._Element = new Relation(GetAssemblyInstanceElementIndex(n), GetElement); - return r; - } - - - // Group - - public EntityTable GroupEntityTable { get; } - - public IArray GroupGroupType { get; } - public String GetGroupGroupType(int index, String defaultValue = "") => GroupGroupType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GroupPosition_X { get; } - public Single GetGroupPosition_X(int index, Single defaultValue = default) => GroupPosition_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GroupPosition_Y { get; } - public Single GetGroupPosition_Y(int index, Single defaultValue = default) => GroupPosition_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GroupPosition_Z { get; } - public Single GetGroupPosition_Z(int index, Single defaultValue = default) => GroupPosition_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GroupElementIndex { get; } - public int GetGroupElementIndex(int index) => GroupElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumGroup => GroupEntityTable?.NumRows ?? 0; - public IArray GroupList { get; } - public Group GetGroup(int n) - { - if (n < 0) return null; - var r = new Group(); - r.Document = Document; - r.Index = n; - r.GroupType = GroupGroupType.ElementAtOrDefault(n); - r.Position_X = GroupPosition_X.ElementAtOrDefault(n); - r.Position_Y = GroupPosition_Y.ElementAtOrDefault(n); - r.Position_Z = GroupPosition_Z.ElementAtOrDefault(n); - r._Element = new Relation(GetGroupElementIndex(n), GetElement); - return r; - } - - - // DesignOption - - public EntityTable DesignOptionEntityTable { get; } - - public IArray DesignOptionIsPrimary { get; } - public Boolean GetDesignOptionIsPrimary(int index, Boolean defaultValue = default) => DesignOptionIsPrimary?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray DesignOptionElementIndex { get; } - public int GetDesignOptionElementIndex(int index) => DesignOptionElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumDesignOption => DesignOptionEntityTable?.NumRows ?? 0; - public IArray DesignOptionList { get; } - public DesignOption GetDesignOption(int n) - { - if (n < 0) return null; - var r = new DesignOption(); - r.Document = Document; - r.Index = n; - r.IsPrimary = DesignOptionIsPrimary.ElementAtOrDefault(n); - r._Element = new Relation(GetDesignOptionElementIndex(n), GetElement); - return r; - } - - - // Level - - public EntityTable LevelEntityTable { get; } - - public IArray LevelElevation { get; } - public Double GetLevelElevation(int index, Double defaultValue = default) => LevelElevation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelProjectElevation { get; } - public Double GetLevelProjectElevation(int index, Double defaultValue = default) => LevelProjectElevation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelFamilyTypeIndex { get; } - public int GetLevelFamilyTypeIndex(int index) => LevelFamilyTypeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray LevelBuildingIndex { get; } - public int GetLevelBuildingIndex(int index) => LevelBuildingIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray LevelElementIndex { get; } - public int GetLevelElementIndex(int index) => LevelElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumLevel => LevelEntityTable?.NumRows ?? 0; - public IArray LevelList { get; } - public Level GetLevel(int n) - { - if (n < 0) return null; - var r = new Level(); - r.Document = Document; - r.Index = n; - r.Elevation = LevelElevation.ElementAtOrDefault(n); - r.ProjectElevation = LevelProjectElevation.ElementAtOrDefault(n); - r._FamilyType = new Relation(GetLevelFamilyTypeIndex(n), GetFamilyType); - r._Building = new Relation(GetLevelBuildingIndex(n), GetBuilding); - r._Element = new Relation(GetLevelElementIndex(n), GetElement); - return r; - } - - - // Phase - - public EntityTable PhaseEntityTable { get; } - - public IArray PhaseElementIndex { get; } - public int GetPhaseElementIndex(int index) => PhaseElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumPhase => PhaseEntityTable?.NumRows ?? 0; - public IArray PhaseList { get; } - public Phase GetPhase(int n) - { - if (n < 0) return null; - var r = new Phase(); - r.Document = Document; - r.Index = n; - r._Element = new Relation(GetPhaseElementIndex(n), GetElement); - return r; - } - - - // Room - - public EntityTable RoomEntityTable { get; } - - public IArray RoomBaseOffset { get; } - public Double GetRoomBaseOffset(int index, Double defaultValue = default) => RoomBaseOffset?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomLimitOffset { get; } - public Double GetRoomLimitOffset(int index, Double defaultValue = default) => RoomLimitOffset?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomUnboundedHeight { get; } - public Double GetRoomUnboundedHeight(int index, Double defaultValue = default) => RoomUnboundedHeight?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomVolume { get; } - public Double GetRoomVolume(int index, Double defaultValue = default) => RoomVolume?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomPerimeter { get; } - public Double GetRoomPerimeter(int index, Double defaultValue = default) => RoomPerimeter?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomArea { get; } - public Double GetRoomArea(int index, Double defaultValue = default) => RoomArea?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomNumber { get; } - public String GetRoomNumber(int index, String defaultValue = "") => RoomNumber?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray RoomUpperLimitIndex { get; } - public int GetRoomUpperLimitIndex(int index) => RoomUpperLimitIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray RoomElementIndex { get; } - public int GetRoomElementIndex(int index) => RoomElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumRoom => RoomEntityTable?.NumRows ?? 0; - public IArray RoomList { get; } - public Room GetRoom(int n) - { - if (n < 0) return null; - var r = new Room(); - r.Document = Document; - r.Index = n; - r.BaseOffset = RoomBaseOffset.ElementAtOrDefault(n); - r.LimitOffset = RoomLimitOffset.ElementAtOrDefault(n); - r.UnboundedHeight = RoomUnboundedHeight.ElementAtOrDefault(n); - r.Volume = RoomVolume.ElementAtOrDefault(n); - r.Perimeter = RoomPerimeter.ElementAtOrDefault(n); - r.Area = RoomArea.ElementAtOrDefault(n); - r.Number = RoomNumber.ElementAtOrDefault(n); - r._UpperLimit = new Relation(GetRoomUpperLimitIndex(n), GetLevel); - r._Element = new Relation(GetRoomElementIndex(n), GetElement); - return r; - } - - - // BimDocument - - public EntityTable BimDocumentEntityTable { get; } - - public IArray BimDocumentTitle { get; } - public String GetBimDocumentTitle(int index, String defaultValue = "") => BimDocumentTitle?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentIsMetric { get; } - public Boolean GetBimDocumentIsMetric(int index, Boolean defaultValue = default) => BimDocumentIsMetric?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentGuid { get; } - public String GetBimDocumentGuid(int index, String defaultValue = "") => BimDocumentGuid?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentNumSaves { get; } - public Int32 GetBimDocumentNumSaves(int index, Int32 defaultValue = default) => BimDocumentNumSaves?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentIsLinked { get; } - public Boolean GetBimDocumentIsLinked(int index, Boolean defaultValue = default) => BimDocumentIsLinked?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentIsDetached { get; } - public Boolean GetBimDocumentIsDetached(int index, Boolean defaultValue = default) => BimDocumentIsDetached?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentIsWorkshared { get; } - public Boolean GetBimDocumentIsWorkshared(int index, Boolean defaultValue = default) => BimDocumentIsWorkshared?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentPathName { get; } - public String GetBimDocumentPathName(int index, String defaultValue = "") => BimDocumentPathName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentLatitude { get; } - public Double GetBimDocumentLatitude(int index, Double defaultValue = default) => BimDocumentLatitude?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentLongitude { get; } - public Double GetBimDocumentLongitude(int index, Double defaultValue = default) => BimDocumentLongitude?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentTimeZone { get; } - public Double GetBimDocumentTimeZone(int index, Double defaultValue = default) => BimDocumentTimeZone?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentPlaceName { get; } - public String GetBimDocumentPlaceName(int index, String defaultValue = "") => BimDocumentPlaceName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentWeatherStationName { get; } - public String GetBimDocumentWeatherStationName(int index, String defaultValue = "") => BimDocumentWeatherStationName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentElevation { get; } - public Double GetBimDocumentElevation(int index, Double defaultValue = default) => BimDocumentElevation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentProjectLocation { get; } - public String GetBimDocumentProjectLocation(int index, String defaultValue = "") => BimDocumentProjectLocation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentIssueDate { get; } - public String GetBimDocumentIssueDate(int index, String defaultValue = "") => BimDocumentIssueDate?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentStatus { get; } - public String GetBimDocumentStatus(int index, String defaultValue = "") => BimDocumentStatus?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentClientName { get; } - public String GetBimDocumentClientName(int index, String defaultValue = "") => BimDocumentClientName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentAddress { get; } - public String GetBimDocumentAddress(int index, String defaultValue = "") => BimDocumentAddress?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentName { get; } - public String GetBimDocumentName(int index, String defaultValue = "") => BimDocumentName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentNumber { get; } - public String GetBimDocumentNumber(int index, String defaultValue = "") => BimDocumentNumber?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentAuthor { get; } - public String GetBimDocumentAuthor(int index, String defaultValue = "") => BimDocumentAuthor?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentBuildingName { get; } - public String GetBimDocumentBuildingName(int index, String defaultValue = "") => BimDocumentBuildingName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentOrganizationName { get; } - public String GetBimDocumentOrganizationName(int index, String defaultValue = "") => BimDocumentOrganizationName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentOrganizationDescription { get; } - public String GetBimDocumentOrganizationDescription(int index, String defaultValue = "") => BimDocumentOrganizationDescription?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentProduct { get; } - public String GetBimDocumentProduct(int index, String defaultValue = "") => BimDocumentProduct?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentVersion { get; } - public String GetBimDocumentVersion(int index, String defaultValue = "") => BimDocumentVersion?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentUser { get; } - public String GetBimDocumentUser(int index, String defaultValue = "") => BimDocumentUser?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentFileLength { get; } - public Int64 GetBimDocumentFileLength(int index, Int64 defaultValue = default) => BimDocumentFileLength?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BimDocumentActiveViewIndex { get; } - public int GetBimDocumentActiveViewIndex(int index) => BimDocumentActiveViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray BimDocumentOwnerFamilyIndex { get; } - public int GetBimDocumentOwnerFamilyIndex(int index) => BimDocumentOwnerFamilyIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray BimDocumentParentIndex { get; } - public int GetBimDocumentParentIndex(int index) => BimDocumentParentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray BimDocumentElementIndex { get; } - public int GetBimDocumentElementIndex(int index) => BimDocumentElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumBimDocument => BimDocumentEntityTable?.NumRows ?? 0; - public IArray BimDocumentList { get; } - public BimDocument GetBimDocument(int n) - { - if (n < 0) return null; - var r = new BimDocument(); - r.Document = Document; - r.Index = n; - r.Title = BimDocumentTitle.ElementAtOrDefault(n); - r.IsMetric = BimDocumentIsMetric.ElementAtOrDefault(n); - r.Guid = BimDocumentGuid.ElementAtOrDefault(n); - r.NumSaves = BimDocumentNumSaves.ElementAtOrDefault(n); - r.IsLinked = BimDocumentIsLinked.ElementAtOrDefault(n); - r.IsDetached = BimDocumentIsDetached.ElementAtOrDefault(n); - r.IsWorkshared = BimDocumentIsWorkshared.ElementAtOrDefault(n); - r.PathName = BimDocumentPathName.ElementAtOrDefault(n); - r.Latitude = BimDocumentLatitude.ElementAtOrDefault(n); - r.Longitude = BimDocumentLongitude.ElementAtOrDefault(n); - r.TimeZone = BimDocumentTimeZone.ElementAtOrDefault(n); - r.PlaceName = BimDocumentPlaceName.ElementAtOrDefault(n); - r.WeatherStationName = BimDocumentWeatherStationName.ElementAtOrDefault(n); - r.Elevation = BimDocumentElevation.ElementAtOrDefault(n); - r.ProjectLocation = BimDocumentProjectLocation.ElementAtOrDefault(n); - r.IssueDate = BimDocumentIssueDate.ElementAtOrDefault(n); - r.Status = BimDocumentStatus.ElementAtOrDefault(n); - r.ClientName = BimDocumentClientName.ElementAtOrDefault(n); - r.Address = BimDocumentAddress.ElementAtOrDefault(n); - r.Name = BimDocumentName.ElementAtOrDefault(n); - r.Number = BimDocumentNumber.ElementAtOrDefault(n); - r.Author = BimDocumentAuthor.ElementAtOrDefault(n); - r.BuildingName = BimDocumentBuildingName.ElementAtOrDefault(n); - r.OrganizationName = BimDocumentOrganizationName.ElementAtOrDefault(n); - r.OrganizationDescription = BimDocumentOrganizationDescription.ElementAtOrDefault(n); - r.Product = BimDocumentProduct.ElementAtOrDefault(n); - r.Version = BimDocumentVersion.ElementAtOrDefault(n); - r.User = BimDocumentUser.ElementAtOrDefault(n); - r.FileLength = BimDocumentFileLength.ElementAtOrDefault(n); - r._ActiveView = new Relation(GetBimDocumentActiveViewIndex(n), GetView); - r._OwnerFamily = new Relation(GetBimDocumentOwnerFamilyIndex(n), GetFamily); - r._Parent = new Relation(GetBimDocumentParentIndex(n), GetBimDocument); - r._Element = new Relation(GetBimDocumentElementIndex(n), GetElement); - return r; - } - - - // DisplayUnitInBimDocument - - public EntityTable DisplayUnitInBimDocumentEntityTable { get; } - - public IArray DisplayUnitInBimDocumentDisplayUnitIndex { get; } - public int GetDisplayUnitInBimDocumentDisplayUnitIndex(int index) => DisplayUnitInBimDocumentDisplayUnitIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray DisplayUnitInBimDocumentBimDocumentIndex { get; } - public int GetDisplayUnitInBimDocumentBimDocumentIndex(int index) => DisplayUnitInBimDocumentBimDocumentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumDisplayUnitInBimDocument => DisplayUnitInBimDocumentEntityTable?.NumRows ?? 0; - public IArray DisplayUnitInBimDocumentList { get; } - public DisplayUnitInBimDocument GetDisplayUnitInBimDocument(int n) - { - if (n < 0) return null; - var r = new DisplayUnitInBimDocument(); - r.Document = Document; - r.Index = n; - r._DisplayUnit = new Relation(GetDisplayUnitInBimDocumentDisplayUnitIndex(n), GetDisplayUnit); - r._BimDocument = new Relation(GetDisplayUnitInBimDocumentBimDocumentIndex(n), GetBimDocument); - return r; - } - - - // PhaseOrderInBimDocument - - public EntityTable PhaseOrderInBimDocumentEntityTable { get; } - - public IArray PhaseOrderInBimDocumentOrderIndex { get; } - public Int32 GetPhaseOrderInBimDocumentOrderIndex(int index, Int32 defaultValue = default) => PhaseOrderInBimDocumentOrderIndex?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray PhaseOrderInBimDocumentPhaseIndex { get; } - public int GetPhaseOrderInBimDocumentPhaseIndex(int index) => PhaseOrderInBimDocumentPhaseIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray PhaseOrderInBimDocumentBimDocumentIndex { get; } - public int GetPhaseOrderInBimDocumentBimDocumentIndex(int index) => PhaseOrderInBimDocumentBimDocumentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumPhaseOrderInBimDocument => PhaseOrderInBimDocumentEntityTable?.NumRows ?? 0; - public IArray PhaseOrderInBimDocumentList { get; } - public PhaseOrderInBimDocument GetPhaseOrderInBimDocument(int n) - { - if (n < 0) return null; - var r = new PhaseOrderInBimDocument(); - r.Document = Document; - r.Index = n; - r.OrderIndex = PhaseOrderInBimDocumentOrderIndex.ElementAtOrDefault(n); - r._Phase = new Relation(GetPhaseOrderInBimDocumentPhaseIndex(n), GetPhase); - r._BimDocument = new Relation(GetPhaseOrderInBimDocumentBimDocumentIndex(n), GetBimDocument); - return r; - } - - - // Category - - public EntityTable CategoryEntityTable { get; } - - public IArray CategoryName { get; } - public String GetCategoryName(int index, String defaultValue = "") => CategoryName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryId { get; } - public Int64 GetCategoryId(int index, Int64 defaultValue = default) => CategoryId?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryCategoryType { get; } - public String GetCategoryCategoryType(int index, String defaultValue = "") => CategoryCategoryType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryLineColor_X { get; } - public Double GetCategoryLineColor_X(int index, Double defaultValue = default) => CategoryLineColor_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryLineColor_Y { get; } - public Double GetCategoryLineColor_Y(int index, Double defaultValue = default) => CategoryLineColor_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryLineColor_Z { get; } - public Double GetCategoryLineColor_Z(int index, Double defaultValue = default) => CategoryLineColor_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryBuiltInCategory { get; } - public String GetCategoryBuiltInCategory(int index, String defaultValue = "") => CategoryBuiltInCategory?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CategoryParentIndex { get; } - public int GetCategoryParentIndex(int index) => CategoryParentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray CategoryMaterialIndex { get; } - public int GetCategoryMaterialIndex(int index) => CategoryMaterialIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumCategory => CategoryEntityTable?.NumRows ?? 0; - public IArray CategoryList { get; } - public Category GetCategory(int n) - { - if (n < 0) return null; - var r = new Category(); - r.Document = Document; - r.Index = n; - r.Name = CategoryName.ElementAtOrDefault(n); - r.Id = CategoryId.ElementAtOrDefault(n); - r.CategoryType = CategoryCategoryType.ElementAtOrDefault(n); - r.LineColor_X = CategoryLineColor_X.ElementAtOrDefault(n); - r.LineColor_Y = CategoryLineColor_Y.ElementAtOrDefault(n); - r.LineColor_Z = CategoryLineColor_Z.ElementAtOrDefault(n); - r.BuiltInCategory = CategoryBuiltInCategory.ElementAtOrDefault(n); - r._Parent = new Relation(GetCategoryParentIndex(n), GetCategory); - r._Material = new Relation(GetCategoryMaterialIndex(n), GetMaterial); - return r; - } - - - // Family - - public EntityTable FamilyEntityTable { get; } - - public IArray FamilyStructuralMaterialType { get; } - public String GetFamilyStructuralMaterialType(int index, String defaultValue = "") => FamilyStructuralMaterialType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyStructuralSectionShape { get; } - public String GetFamilyStructuralSectionShape(int index, String defaultValue = "") => FamilyStructuralSectionShape?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyIsSystemFamily { get; } - public Boolean GetFamilyIsSystemFamily(int index, Boolean defaultValue = default) => FamilyIsSystemFamily?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyIsInPlace { get; } - public Boolean GetFamilyIsInPlace(int index, Boolean defaultValue = default) => FamilyIsInPlace?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyFamilyCategoryIndex { get; } - public int GetFamilyFamilyCategoryIndex(int index) => FamilyFamilyCategoryIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyElementIndex { get; } - public int GetFamilyElementIndex(int index) => FamilyElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumFamily => FamilyEntityTable?.NumRows ?? 0; - public IArray FamilyList { get; } - public Family GetFamily(int n) - { - if (n < 0) return null; - var r = new Family(); - r.Document = Document; - r.Index = n; - r.StructuralMaterialType = FamilyStructuralMaterialType.ElementAtOrDefault(n); - r.StructuralSectionShape = FamilyStructuralSectionShape.ElementAtOrDefault(n); - r.IsSystemFamily = FamilyIsSystemFamily.ElementAtOrDefault(n); - r.IsInPlace = FamilyIsInPlace.ElementAtOrDefault(n); - r._FamilyCategory = new Relation(GetFamilyFamilyCategoryIndex(n), GetCategory); - r._Element = new Relation(GetFamilyElementIndex(n), GetElement); - return r; - } - - - // FamilyType - - public EntityTable FamilyTypeEntityTable { get; } - - public IArray FamilyTypeIsSystemFamilyType { get; } - public Boolean GetFamilyTypeIsSystemFamilyType(int index, Boolean defaultValue = default) => FamilyTypeIsSystemFamilyType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyTypeFamilyIndex { get; } - public int GetFamilyTypeFamilyIndex(int index) => FamilyTypeFamilyIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyTypeCompoundStructureIndex { get; } - public int GetFamilyTypeCompoundStructureIndex(int index) => FamilyTypeCompoundStructureIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyTypeElementIndex { get; } - public int GetFamilyTypeElementIndex(int index) => FamilyTypeElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumFamilyType => FamilyTypeEntityTable?.NumRows ?? 0; - public IArray FamilyTypeList { get; } - public FamilyType GetFamilyType(int n) - { - if (n < 0) return null; - var r = new FamilyType(); - r.Document = Document; - r.Index = n; - r.IsSystemFamilyType = FamilyTypeIsSystemFamilyType.ElementAtOrDefault(n); - r._Family = new Relation(GetFamilyTypeFamilyIndex(n), GetFamily); - r._CompoundStructure = new Relation(GetFamilyTypeCompoundStructureIndex(n), GetCompoundStructure); - r._Element = new Relation(GetFamilyTypeElementIndex(n), GetElement); - return r; - } - - - // FamilyInstance - - public EntityTable FamilyInstanceEntityTable { get; } - - public IArray FamilyInstanceFacingFlipped { get; } - public Boolean GetFamilyInstanceFacingFlipped(int index, Boolean defaultValue = default) => FamilyInstanceFacingFlipped?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceFacingOrientation_X { get; } - public Single GetFamilyInstanceFacingOrientation_X(int index, Single defaultValue = default) => FamilyInstanceFacingOrientation_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceFacingOrientation_Y { get; } - public Single GetFamilyInstanceFacingOrientation_Y(int index, Single defaultValue = default) => FamilyInstanceFacingOrientation_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceFacingOrientation_Z { get; } - public Single GetFamilyInstanceFacingOrientation_Z(int index, Single defaultValue = default) => FamilyInstanceFacingOrientation_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceHandFlipped { get; } - public Boolean GetFamilyInstanceHandFlipped(int index, Boolean defaultValue = default) => FamilyInstanceHandFlipped?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceMirrored { get; } - public Boolean GetFamilyInstanceMirrored(int index, Boolean defaultValue = default) => FamilyInstanceMirrored?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceHasModifiedGeometry { get; } - public Boolean GetFamilyInstanceHasModifiedGeometry(int index, Boolean defaultValue = default) => FamilyInstanceHasModifiedGeometry?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceScale { get; } - public Single GetFamilyInstanceScale(int index, Single defaultValue = default) => FamilyInstanceScale?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisX_X { get; } - public Single GetFamilyInstanceBasisX_X(int index, Single defaultValue = default) => FamilyInstanceBasisX_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisX_Y { get; } - public Single GetFamilyInstanceBasisX_Y(int index, Single defaultValue = default) => FamilyInstanceBasisX_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisX_Z { get; } - public Single GetFamilyInstanceBasisX_Z(int index, Single defaultValue = default) => FamilyInstanceBasisX_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisY_X { get; } - public Single GetFamilyInstanceBasisY_X(int index, Single defaultValue = default) => FamilyInstanceBasisY_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisY_Y { get; } - public Single GetFamilyInstanceBasisY_Y(int index, Single defaultValue = default) => FamilyInstanceBasisY_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisY_Z { get; } - public Single GetFamilyInstanceBasisY_Z(int index, Single defaultValue = default) => FamilyInstanceBasisY_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisZ_X { get; } - public Single GetFamilyInstanceBasisZ_X(int index, Single defaultValue = default) => FamilyInstanceBasisZ_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisZ_Y { get; } - public Single GetFamilyInstanceBasisZ_Y(int index, Single defaultValue = default) => FamilyInstanceBasisZ_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceBasisZ_Z { get; } - public Single GetFamilyInstanceBasisZ_Z(int index, Single defaultValue = default) => FamilyInstanceBasisZ_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceTranslation_X { get; } - public Single GetFamilyInstanceTranslation_X(int index, Single defaultValue = default) => FamilyInstanceTranslation_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceTranslation_Y { get; } - public Single GetFamilyInstanceTranslation_Y(int index, Single defaultValue = default) => FamilyInstanceTranslation_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceTranslation_Z { get; } - public Single GetFamilyInstanceTranslation_Z(int index, Single defaultValue = default) => FamilyInstanceTranslation_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceHandOrientation_X { get; } - public Single GetFamilyInstanceHandOrientation_X(int index, Single defaultValue = default) => FamilyInstanceHandOrientation_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceHandOrientation_Y { get; } - public Single GetFamilyInstanceHandOrientation_Y(int index, Single defaultValue = default) => FamilyInstanceHandOrientation_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceHandOrientation_Z { get; } - public Single GetFamilyInstanceHandOrientation_Z(int index, Single defaultValue = default) => FamilyInstanceHandOrientation_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray FamilyInstanceFamilyTypeIndex { get; } - public int GetFamilyInstanceFamilyTypeIndex(int index) => FamilyInstanceFamilyTypeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyInstanceHostIndex { get; } - public int GetFamilyInstanceHostIndex(int index) => FamilyInstanceHostIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyInstanceFromRoomIndex { get; } - public int GetFamilyInstanceFromRoomIndex(int index) => FamilyInstanceFromRoomIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyInstanceToRoomIndex { get; } - public int GetFamilyInstanceToRoomIndex(int index) => FamilyInstanceToRoomIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyInstanceSuperComponentIndex { get; } - public int GetFamilyInstanceSuperComponentIndex(int index) => FamilyInstanceSuperComponentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray FamilyInstanceElementIndex { get; } - public int GetFamilyInstanceElementIndex(int index) => FamilyInstanceElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumFamilyInstance => FamilyInstanceEntityTable?.NumRows ?? 0; - public IArray FamilyInstanceList { get; } - public FamilyInstance GetFamilyInstance(int n) - { - if (n < 0) return null; - var r = new FamilyInstance(); - r.Document = Document; - r.Index = n; - r.FacingFlipped = FamilyInstanceFacingFlipped.ElementAtOrDefault(n); - r.FacingOrientation_X = FamilyInstanceFacingOrientation_X.ElementAtOrDefault(n); - r.FacingOrientation_Y = FamilyInstanceFacingOrientation_Y.ElementAtOrDefault(n); - r.FacingOrientation_Z = FamilyInstanceFacingOrientation_Z.ElementAtOrDefault(n); - r.HandFlipped = FamilyInstanceHandFlipped.ElementAtOrDefault(n); - r.Mirrored = FamilyInstanceMirrored.ElementAtOrDefault(n); - r.HasModifiedGeometry = FamilyInstanceHasModifiedGeometry.ElementAtOrDefault(n); - r.Scale = FamilyInstanceScale.ElementAtOrDefault(n); - r.BasisX_X = FamilyInstanceBasisX_X.ElementAtOrDefault(n); - r.BasisX_Y = FamilyInstanceBasisX_Y.ElementAtOrDefault(n); - r.BasisX_Z = FamilyInstanceBasisX_Z.ElementAtOrDefault(n); - r.BasisY_X = FamilyInstanceBasisY_X.ElementAtOrDefault(n); - r.BasisY_Y = FamilyInstanceBasisY_Y.ElementAtOrDefault(n); - r.BasisY_Z = FamilyInstanceBasisY_Z.ElementAtOrDefault(n); - r.BasisZ_X = FamilyInstanceBasisZ_X.ElementAtOrDefault(n); - r.BasisZ_Y = FamilyInstanceBasisZ_Y.ElementAtOrDefault(n); - r.BasisZ_Z = FamilyInstanceBasisZ_Z.ElementAtOrDefault(n); - r.Translation_X = FamilyInstanceTranslation_X.ElementAtOrDefault(n); - r.Translation_Y = FamilyInstanceTranslation_Y.ElementAtOrDefault(n); - r.Translation_Z = FamilyInstanceTranslation_Z.ElementAtOrDefault(n); - r.HandOrientation_X = FamilyInstanceHandOrientation_X.ElementAtOrDefault(n); - r.HandOrientation_Y = FamilyInstanceHandOrientation_Y.ElementAtOrDefault(n); - r.HandOrientation_Z = FamilyInstanceHandOrientation_Z.ElementAtOrDefault(n); - r._FamilyType = new Relation(GetFamilyInstanceFamilyTypeIndex(n), GetFamilyType); - r._Host = new Relation(GetFamilyInstanceHostIndex(n), GetElement); - r._FromRoom = new Relation(GetFamilyInstanceFromRoomIndex(n), GetRoom); - r._ToRoom = new Relation(GetFamilyInstanceToRoomIndex(n), GetRoom); - r._SuperComponent = new Relation(GetFamilyInstanceSuperComponentIndex(n), GetElement); - r._Element = new Relation(GetFamilyInstanceElementIndex(n), GetElement); - return r; - } - - - // View - - public EntityTable ViewEntityTable { get; } - - public IArray ViewTitle { get; } - public String GetViewTitle(int index, String defaultValue = "") => ViewTitle?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewType { get; } - public String GetViewViewType(int index, String defaultValue = "") => ViewViewType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewUp_X { get; } - public Double GetViewUp_X(int index, Double defaultValue = default) => ViewUp_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewUp_Y { get; } - public Double GetViewUp_Y(int index, Double defaultValue = default) => ViewUp_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewUp_Z { get; } - public Double GetViewUp_Z(int index, Double defaultValue = default) => ViewUp_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewRight_X { get; } - public Double GetViewRight_X(int index, Double defaultValue = default) => ViewRight_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewRight_Y { get; } - public Double GetViewRight_Y(int index, Double defaultValue = default) => ViewRight_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewRight_Z { get; } - public Double GetViewRight_Z(int index, Double defaultValue = default) => ViewRight_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOrigin_X { get; } - public Double GetViewOrigin_X(int index, Double defaultValue = default) => ViewOrigin_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOrigin_Y { get; } - public Double GetViewOrigin_Y(int index, Double defaultValue = default) => ViewOrigin_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOrigin_Z { get; } - public Double GetViewOrigin_Z(int index, Double defaultValue = default) => ViewOrigin_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewDirection_X { get; } - public Double GetViewViewDirection_X(int index, Double defaultValue = default) => ViewViewDirection_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewDirection_Y { get; } - public Double GetViewViewDirection_Y(int index, Double defaultValue = default) => ViewViewDirection_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewDirection_Z { get; } - public Double GetViewViewDirection_Z(int index, Double defaultValue = default) => ViewViewDirection_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewPosition_X { get; } - public Double GetViewViewPosition_X(int index, Double defaultValue = default) => ViewViewPosition_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewPosition_Y { get; } - public Double GetViewViewPosition_Y(int index, Double defaultValue = default) => ViewViewPosition_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewViewPosition_Z { get; } - public Double GetViewViewPosition_Z(int index, Double defaultValue = default) => ViewViewPosition_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewScale { get; } - public Double GetViewScale(int index, Double defaultValue = default) => ViewScale?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOutline_Min_X { get; } - public Double GetViewOutline_Min_X(int index, Double defaultValue = default) => ViewOutline_Min_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOutline_Min_Y { get; } - public Double GetViewOutline_Min_Y(int index, Double defaultValue = default) => ViewOutline_Min_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOutline_Max_X { get; } - public Double GetViewOutline_Max_X(int index, Double defaultValue = default) => ViewOutline_Max_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewOutline_Max_Y { get; } - public Double GetViewOutline_Max_Y(int index, Double defaultValue = default) => ViewOutline_Max_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewDetailLevel { get; } - public Int32 GetViewDetailLevel(int index, Int32 defaultValue = default) => ViewDetailLevel?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ViewCameraIndex { get; } - public int GetViewCameraIndex(int index) => ViewCameraIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ViewFamilyTypeIndex { get; } - public int GetViewFamilyTypeIndex(int index) => ViewFamilyTypeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ViewElementIndex { get; } - public int GetViewElementIndex(int index) => ViewElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumView => ViewEntityTable?.NumRows ?? 0; - public IArray ViewList { get; } - public View GetView(int n) - { - if (n < 0) return null; - var r = new View(); - r.Document = Document; - r.Index = n; - r.Title = ViewTitle.ElementAtOrDefault(n); - r.ViewType = ViewViewType.ElementAtOrDefault(n); - r.Up_X = ViewUp_X.ElementAtOrDefault(n); - r.Up_Y = ViewUp_Y.ElementAtOrDefault(n); - r.Up_Z = ViewUp_Z.ElementAtOrDefault(n); - r.Right_X = ViewRight_X.ElementAtOrDefault(n); - r.Right_Y = ViewRight_Y.ElementAtOrDefault(n); - r.Right_Z = ViewRight_Z.ElementAtOrDefault(n); - r.Origin_X = ViewOrigin_X.ElementAtOrDefault(n); - r.Origin_Y = ViewOrigin_Y.ElementAtOrDefault(n); - r.Origin_Z = ViewOrigin_Z.ElementAtOrDefault(n); - r.ViewDirection_X = ViewViewDirection_X.ElementAtOrDefault(n); - r.ViewDirection_Y = ViewViewDirection_Y.ElementAtOrDefault(n); - r.ViewDirection_Z = ViewViewDirection_Z.ElementAtOrDefault(n); - r.ViewPosition_X = ViewViewPosition_X.ElementAtOrDefault(n); - r.ViewPosition_Y = ViewViewPosition_Y.ElementAtOrDefault(n); - r.ViewPosition_Z = ViewViewPosition_Z.ElementAtOrDefault(n); - r.Scale = ViewScale.ElementAtOrDefault(n); - r.Outline_Min_X = ViewOutline_Min_X.ElementAtOrDefault(n); - r.Outline_Min_Y = ViewOutline_Min_Y.ElementAtOrDefault(n); - r.Outline_Max_X = ViewOutline_Max_X.ElementAtOrDefault(n); - r.Outline_Max_Y = ViewOutline_Max_Y.ElementAtOrDefault(n); - r.DetailLevel = ViewDetailLevel.ElementAtOrDefault(n); - r._Camera = new Relation(GetViewCameraIndex(n), GetCamera); - r._FamilyType = new Relation(GetViewFamilyTypeIndex(n), GetFamilyType); - r._Element = new Relation(GetViewElementIndex(n), GetElement); - return r; - } - - - // ElementInView - - public EntityTable ElementInViewEntityTable { get; } - - public IArray ElementInViewViewIndex { get; } - public int GetElementInViewViewIndex(int index) => ElementInViewViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementInViewElementIndex { get; } - public int GetElementInViewElementIndex(int index) => ElementInViewElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumElementInView => ElementInViewEntityTable?.NumRows ?? 0; - public IArray ElementInViewList { get; } - public ElementInView GetElementInView(int n) - { - if (n < 0) return null; - var r = new ElementInView(); - r.Document = Document; - r.Index = n; - r._View = new Relation(GetElementInViewViewIndex(n), GetView); - r._Element = new Relation(GetElementInViewElementIndex(n), GetElement); - return r; - } - - - // ShapeInView - - public EntityTable ShapeInViewEntityTable { get; } - - public IArray ShapeInViewShapeIndex { get; } - public int GetShapeInViewShapeIndex(int index) => ShapeInViewShapeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ShapeInViewViewIndex { get; } - public int GetShapeInViewViewIndex(int index) => ShapeInViewViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumShapeInView => ShapeInViewEntityTable?.NumRows ?? 0; - public IArray ShapeInViewList { get; } - public ShapeInView GetShapeInView(int n) - { - if (n < 0) return null; - var r = new ShapeInView(); - r.Document = Document; - r.Index = n; - r._Shape = new Relation(GetShapeInViewShapeIndex(n), GetShape); - r._View = new Relation(GetShapeInViewViewIndex(n), GetView); - return r; - } - - - // AssetInView - - public EntityTable AssetInViewEntityTable { get; } - - public IArray AssetInViewAssetIndex { get; } - public int GetAssetInViewAssetIndex(int index) => AssetInViewAssetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray AssetInViewViewIndex { get; } - public int GetAssetInViewViewIndex(int index) => AssetInViewViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumAssetInView => AssetInViewEntityTable?.NumRows ?? 0; - public IArray AssetInViewList { get; } - public AssetInView GetAssetInView(int n) - { - if (n < 0) return null; - var r = new AssetInView(); - r.Document = Document; - r.Index = n; - r._Asset = new Relation(GetAssetInViewAssetIndex(n), GetAsset); - r._View = new Relation(GetAssetInViewViewIndex(n), GetView); - return r; - } - - - // AssetInViewSheet - - public EntityTable AssetInViewSheetEntityTable { get; } - - public IArray AssetInViewSheetAssetIndex { get; } - public int GetAssetInViewSheetAssetIndex(int index) => AssetInViewSheetAssetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray AssetInViewSheetViewSheetIndex { get; } - public int GetAssetInViewSheetViewSheetIndex(int index) => AssetInViewSheetViewSheetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumAssetInViewSheet => AssetInViewSheetEntityTable?.NumRows ?? 0; - public IArray AssetInViewSheetList { get; } - public AssetInViewSheet GetAssetInViewSheet(int n) - { - if (n < 0) return null; - var r = new AssetInViewSheet(); - r.Document = Document; - r.Index = n; - r._Asset = new Relation(GetAssetInViewSheetAssetIndex(n), GetAsset); - r._ViewSheet = new Relation(GetAssetInViewSheetViewSheetIndex(n), GetViewSheet); - return r; - } - - - // LevelInView - - public EntityTable LevelInViewEntityTable { get; } - - public IArray LevelInViewExtents_Min_X { get; } - public Double GetLevelInViewExtents_Min_X(int index, Double defaultValue = default) => LevelInViewExtents_Min_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelInViewExtents_Min_Y { get; } - public Double GetLevelInViewExtents_Min_Y(int index, Double defaultValue = default) => LevelInViewExtents_Min_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelInViewExtents_Min_Z { get; } - public Double GetLevelInViewExtents_Min_Z(int index, Double defaultValue = default) => LevelInViewExtents_Min_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelInViewExtents_Max_X { get; } - public Double GetLevelInViewExtents_Max_X(int index, Double defaultValue = default) => LevelInViewExtents_Max_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelInViewExtents_Max_Y { get; } - public Double GetLevelInViewExtents_Max_Y(int index, Double defaultValue = default) => LevelInViewExtents_Max_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelInViewExtents_Max_Z { get; } - public Double GetLevelInViewExtents_Max_Z(int index, Double defaultValue = default) => LevelInViewExtents_Max_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray LevelInViewLevelIndex { get; } - public int GetLevelInViewLevelIndex(int index) => LevelInViewLevelIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray LevelInViewViewIndex { get; } - public int GetLevelInViewViewIndex(int index) => LevelInViewViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumLevelInView => LevelInViewEntityTable?.NumRows ?? 0; - public IArray LevelInViewList { get; } - public LevelInView GetLevelInView(int n) - { - if (n < 0) return null; - var r = new LevelInView(); - r.Document = Document; - r.Index = n; - r.Extents_Min_X = LevelInViewExtents_Min_X.ElementAtOrDefault(n); - r.Extents_Min_Y = LevelInViewExtents_Min_Y.ElementAtOrDefault(n); - r.Extents_Min_Z = LevelInViewExtents_Min_Z.ElementAtOrDefault(n); - r.Extents_Max_X = LevelInViewExtents_Max_X.ElementAtOrDefault(n); - r.Extents_Max_Y = LevelInViewExtents_Max_Y.ElementAtOrDefault(n); - r.Extents_Max_Z = LevelInViewExtents_Max_Z.ElementAtOrDefault(n); - r._Level = new Relation(GetLevelInViewLevelIndex(n), GetLevel); - r._View = new Relation(GetLevelInViewViewIndex(n), GetView); - return r; - } - - - // Camera - - public EntityTable CameraEntityTable { get; } - - public IArray CameraId { get; } - public Int32 GetCameraId(int index, Int32 defaultValue = default) => CameraId?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraIsPerspective { get; } - public Int32 GetCameraIsPerspective(int index, Int32 defaultValue = default) => CameraIsPerspective?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraVerticalExtent { get; } - public Double GetCameraVerticalExtent(int index, Double defaultValue = default) => CameraVerticalExtent?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraHorizontalExtent { get; } - public Double GetCameraHorizontalExtent(int index, Double defaultValue = default) => CameraHorizontalExtent?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraFarDistance { get; } - public Double GetCameraFarDistance(int index, Double defaultValue = default) => CameraFarDistance?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraNearDistance { get; } - public Double GetCameraNearDistance(int index, Double defaultValue = default) => CameraNearDistance?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraTargetDistance { get; } - public Double GetCameraTargetDistance(int index, Double defaultValue = default) => CameraTargetDistance?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraRightOffset { get; } - public Double GetCameraRightOffset(int index, Double defaultValue = default) => CameraRightOffset?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CameraUpOffset { get; } - public Double GetCameraUpOffset(int index, Double defaultValue = default) => CameraUpOffset?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public int NumCamera => CameraEntityTable?.NumRows ?? 0; - public IArray CameraList { get; } - public Camera GetCamera(int n) - { - if (n < 0) return null; - var r = new Camera(); - r.Document = Document; - r.Index = n; - r.Id = CameraId.ElementAtOrDefault(n); - r.IsPerspective = CameraIsPerspective.ElementAtOrDefault(n); - r.VerticalExtent = CameraVerticalExtent.ElementAtOrDefault(n); - r.HorizontalExtent = CameraHorizontalExtent.ElementAtOrDefault(n); - r.FarDistance = CameraFarDistance.ElementAtOrDefault(n); - r.NearDistance = CameraNearDistance.ElementAtOrDefault(n); - r.TargetDistance = CameraTargetDistance.ElementAtOrDefault(n); - r.RightOffset = CameraRightOffset.ElementAtOrDefault(n); - r.UpOffset = CameraUpOffset.ElementAtOrDefault(n); - return r; - } - - - // Material - - public EntityTable MaterialEntityTable { get; } - - public IArray MaterialName { get; } - public String GetMaterialName(int index, String defaultValue = "") => MaterialName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialMaterialCategory { get; } - public String GetMaterialMaterialCategory(int index, String defaultValue = "") => MaterialMaterialCategory?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColor_X { get; } - public Double GetMaterialColor_X(int index, Double defaultValue = default) => MaterialColor_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColor_Y { get; } - public Double GetMaterialColor_Y(int index, Double defaultValue = default) => MaterialColor_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColor_Z { get; } - public Double GetMaterialColor_Z(int index, Double defaultValue = default) => MaterialColor_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColorUvScaling_X { get; } - public Double GetMaterialColorUvScaling_X(int index, Double defaultValue = default) => MaterialColorUvScaling_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColorUvScaling_Y { get; } - public Double GetMaterialColorUvScaling_Y(int index, Double defaultValue = default) => MaterialColorUvScaling_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColorUvOffset_X { get; } - public Double GetMaterialColorUvOffset_X(int index, Double defaultValue = default) => MaterialColorUvOffset_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColorUvOffset_Y { get; } - public Double GetMaterialColorUvOffset_Y(int index, Double defaultValue = default) => MaterialColorUvOffset_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialNormalUvScaling_X { get; } - public Double GetMaterialNormalUvScaling_X(int index, Double defaultValue = default) => MaterialNormalUvScaling_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialNormalUvScaling_Y { get; } - public Double GetMaterialNormalUvScaling_Y(int index, Double defaultValue = default) => MaterialNormalUvScaling_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialNormalUvOffset_X { get; } - public Double GetMaterialNormalUvOffset_X(int index, Double defaultValue = default) => MaterialNormalUvOffset_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialNormalUvOffset_Y { get; } - public Double GetMaterialNormalUvOffset_Y(int index, Double defaultValue = default) => MaterialNormalUvOffset_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialNormalAmount { get; } - public Double GetMaterialNormalAmount(int index, Double defaultValue = default) => MaterialNormalAmount?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialGlossiness { get; } - public Double GetMaterialGlossiness(int index, Double defaultValue = default) => MaterialGlossiness?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialSmoothness { get; } - public Double GetMaterialSmoothness(int index, Double defaultValue = default) => MaterialSmoothness?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialTransparency { get; } - public Double GetMaterialTransparency(int index, Double defaultValue = default) => MaterialTransparency?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialColorTextureFileIndex { get; } - public int GetMaterialColorTextureFileIndex(int index) => MaterialColorTextureFileIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray MaterialNormalTextureFileIndex { get; } - public int GetMaterialNormalTextureFileIndex(int index) => MaterialNormalTextureFileIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray MaterialElementIndex { get; } - public int GetMaterialElementIndex(int index) => MaterialElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumMaterial => MaterialEntityTable?.NumRows ?? 0; - public IArray MaterialList { get; } - public Material GetMaterial(int n) - { - if (n < 0) return null; - var r = new Material(); - r.Document = Document; - r.Index = n; - r.Name = MaterialName.ElementAtOrDefault(n); - r.MaterialCategory = MaterialMaterialCategory.ElementAtOrDefault(n); - r.Color_X = MaterialColor_X.ElementAtOrDefault(n); - r.Color_Y = MaterialColor_Y.ElementAtOrDefault(n); - r.Color_Z = MaterialColor_Z.ElementAtOrDefault(n); - r.ColorUvScaling_X = MaterialColorUvScaling_X.ElementAtOrDefault(n); - r.ColorUvScaling_Y = MaterialColorUvScaling_Y.ElementAtOrDefault(n); - r.ColorUvOffset_X = MaterialColorUvOffset_X.ElementAtOrDefault(n); - r.ColorUvOffset_Y = MaterialColorUvOffset_Y.ElementAtOrDefault(n); - r.NormalUvScaling_X = MaterialNormalUvScaling_X.ElementAtOrDefault(n); - r.NormalUvScaling_Y = MaterialNormalUvScaling_Y.ElementAtOrDefault(n); - r.NormalUvOffset_X = MaterialNormalUvOffset_X.ElementAtOrDefault(n); - r.NormalUvOffset_Y = MaterialNormalUvOffset_Y.ElementAtOrDefault(n); - r.NormalAmount = MaterialNormalAmount.ElementAtOrDefault(n); - r.Glossiness = MaterialGlossiness.ElementAtOrDefault(n); - r.Smoothness = MaterialSmoothness.ElementAtOrDefault(n); - r.Transparency = MaterialTransparency.ElementAtOrDefault(n); - r._ColorTextureFile = new Relation(GetMaterialColorTextureFileIndex(n), GetAsset); - r._NormalTextureFile = new Relation(GetMaterialNormalTextureFileIndex(n), GetAsset); - r._Element = new Relation(GetMaterialElementIndex(n), GetElement); - return r; - } - - - // MaterialInElement - - public EntityTable MaterialInElementEntityTable { get; } - - public IArray MaterialInElementArea { get; } - public Double GetMaterialInElementArea(int index, Double defaultValue = default) => MaterialInElementArea?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialInElementVolume { get; } - public Double GetMaterialInElementVolume(int index, Double defaultValue = default) => MaterialInElementVolume?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialInElementIsPaint { get; } - public Boolean GetMaterialInElementIsPaint(int index, Boolean defaultValue = default) => MaterialInElementIsPaint?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray MaterialInElementMaterialIndex { get; } - public int GetMaterialInElementMaterialIndex(int index) => MaterialInElementMaterialIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray MaterialInElementElementIndex { get; } - public int GetMaterialInElementElementIndex(int index) => MaterialInElementElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumMaterialInElement => MaterialInElementEntityTable?.NumRows ?? 0; - public IArray MaterialInElementList { get; } - public MaterialInElement GetMaterialInElement(int n) - { - if (n < 0) return null; - var r = new MaterialInElement(); - r.Document = Document; - r.Index = n; - r.Area = MaterialInElementArea.ElementAtOrDefault(n); - r.Volume = MaterialInElementVolume.ElementAtOrDefault(n); - r.IsPaint = MaterialInElementIsPaint.ElementAtOrDefault(n); - r._Material = new Relation(GetMaterialInElementMaterialIndex(n), GetMaterial); - r._Element = new Relation(GetMaterialInElementElementIndex(n), GetElement); - return r; - } - - - // CompoundStructureLayer - - public EntityTable CompoundStructureLayerEntityTable { get; } - - public IArray CompoundStructureLayerOrderIndex { get; } - public Int32 GetCompoundStructureLayerOrderIndex(int index, Int32 defaultValue = default) => CompoundStructureLayerOrderIndex?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CompoundStructureLayerWidth { get; } - public Double GetCompoundStructureLayerWidth(int index, Double defaultValue = default) => CompoundStructureLayerWidth?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CompoundStructureLayerMaterialFunctionAssignment { get; } - public String GetCompoundStructureLayerMaterialFunctionAssignment(int index, String defaultValue = "") => CompoundStructureLayerMaterialFunctionAssignment?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CompoundStructureLayerMaterialIndex { get; } - public int GetCompoundStructureLayerMaterialIndex(int index) => CompoundStructureLayerMaterialIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray CompoundStructureLayerCompoundStructureIndex { get; } - public int GetCompoundStructureLayerCompoundStructureIndex(int index) => CompoundStructureLayerCompoundStructureIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumCompoundStructureLayer => CompoundStructureLayerEntityTable?.NumRows ?? 0; - public IArray CompoundStructureLayerList { get; } - public CompoundStructureLayer GetCompoundStructureLayer(int n) - { - if (n < 0) return null; - var r = new CompoundStructureLayer(); - r.Document = Document; - r.Index = n; - r.OrderIndex = CompoundStructureLayerOrderIndex.ElementAtOrDefault(n); - r.Width = CompoundStructureLayerWidth.ElementAtOrDefault(n); - r.MaterialFunctionAssignment = CompoundStructureLayerMaterialFunctionAssignment.ElementAtOrDefault(n); - r._Material = new Relation(GetCompoundStructureLayerMaterialIndex(n), GetMaterial); - r._CompoundStructure = new Relation(GetCompoundStructureLayerCompoundStructureIndex(n), GetCompoundStructure); - return r; - } - - - // CompoundStructure - - public EntityTable CompoundStructureEntityTable { get; } - - public IArray CompoundStructureWidth { get; } - public Double GetCompoundStructureWidth(int index, Double defaultValue = default) => CompoundStructureWidth?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray CompoundStructureStructuralLayerIndex { get; } - public int GetCompoundStructureStructuralLayerIndex(int index) => CompoundStructureStructuralLayerIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumCompoundStructure => CompoundStructureEntityTable?.NumRows ?? 0; - public IArray CompoundStructureList { get; } - public CompoundStructure GetCompoundStructure(int n) - { - if (n < 0) return null; - var r = new CompoundStructure(); - r.Document = Document; - r.Index = n; - r.Width = CompoundStructureWidth.ElementAtOrDefault(n); - r._StructuralLayer = new Relation(GetCompoundStructureStructuralLayerIndex(n), GetCompoundStructureLayer); - return r; - } - - - // Node - - public EntityTable NodeEntityTable { get; } - - public IArray NodeElementIndex { get; } - public int GetNodeElementIndex(int index) => NodeElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumNode => NodeEntityTable?.NumRows ?? 0; - public IArray NodeList { get; } - public Node GetNode(int n) - { - if (n < 0) return null; - var r = new Node(); - r.Document = Document; - r.Index = n; - r._Element = new Relation(GetNodeElementIndex(n), GetElement); - return r; - } - - - // Geometry - - public EntityTable GeometryEntityTable { get; } - - public IArray GeometryBox_Min_X { get; } - public Single GetGeometryBox_Min_X(int index, Single defaultValue = default) => GeometryBox_Min_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryBox_Min_Y { get; } - public Single GetGeometryBox_Min_Y(int index, Single defaultValue = default) => GeometryBox_Min_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryBox_Min_Z { get; } - public Single GetGeometryBox_Min_Z(int index, Single defaultValue = default) => GeometryBox_Min_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryBox_Max_X { get; } - public Single GetGeometryBox_Max_X(int index, Single defaultValue = default) => GeometryBox_Max_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryBox_Max_Y { get; } - public Single GetGeometryBox_Max_Y(int index, Single defaultValue = default) => GeometryBox_Max_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryBox_Max_Z { get; } - public Single GetGeometryBox_Max_Z(int index, Single defaultValue = default) => GeometryBox_Max_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryVertexCount { get; } - public Int32 GetGeometryVertexCount(int index, Int32 defaultValue = default) => GeometryVertexCount?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GeometryFaceCount { get; } - public Int32 GetGeometryFaceCount(int index, Int32 defaultValue = default) => GeometryFaceCount?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public int NumGeometry => GeometryEntityTable?.NumRows ?? 0; - public IArray GeometryList { get; } - public Geometry GetGeometry(int n) - { - if (n < 0) return null; - var r = new Geometry(); - r.Document = Document; - r.Index = n; - r.Box_Min_X = GeometryBox_Min_X.ElementAtOrDefault(n); - r.Box_Min_Y = GeometryBox_Min_Y.ElementAtOrDefault(n); - r.Box_Min_Z = GeometryBox_Min_Z.ElementAtOrDefault(n); - r.Box_Max_X = GeometryBox_Max_X.ElementAtOrDefault(n); - r.Box_Max_Y = GeometryBox_Max_Y.ElementAtOrDefault(n); - r.Box_Max_Z = GeometryBox_Max_Z.ElementAtOrDefault(n); - r.VertexCount = GeometryVertexCount.ElementAtOrDefault(n); - r.FaceCount = GeometryFaceCount.ElementAtOrDefault(n); - return r; - } - - - // Shape - - public EntityTable ShapeEntityTable { get; } - - public IArray ShapeElementIndex { get; } - public int GetShapeElementIndex(int index) => ShapeElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumShape => ShapeEntityTable?.NumRows ?? 0; - public IArray ShapeList { get; } - public Shape GetShape(int n) - { - if (n < 0) return null; - var r = new Shape(); - r.Document = Document; - r.Index = n; - r._Element = new Relation(GetShapeElementIndex(n), GetElement); - return r; - } - - - // ShapeCollection - - public EntityTable ShapeCollectionEntityTable { get; } - - public IArray ShapeCollectionElementIndex { get; } - public int GetShapeCollectionElementIndex(int index) => ShapeCollectionElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumShapeCollection => ShapeCollectionEntityTable?.NumRows ?? 0; - public IArray ShapeCollectionList { get; } - public ShapeCollection GetShapeCollection(int n) - { - if (n < 0) return null; - var r = new ShapeCollection(); - r.Document = Document; - r.Index = n; - r._Element = new Relation(GetShapeCollectionElementIndex(n), GetElement); - return r; - } - - - // ShapeInShapeCollection - - public EntityTable ShapeInShapeCollectionEntityTable { get; } - - public IArray ShapeInShapeCollectionShapeIndex { get; } - public int GetShapeInShapeCollectionShapeIndex(int index) => ShapeInShapeCollectionShapeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ShapeInShapeCollectionShapeCollectionIndex { get; } - public int GetShapeInShapeCollectionShapeCollectionIndex(int index) => ShapeInShapeCollectionShapeCollectionIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumShapeInShapeCollection => ShapeInShapeCollectionEntityTable?.NumRows ?? 0; - public IArray ShapeInShapeCollectionList { get; } - public ShapeInShapeCollection GetShapeInShapeCollection(int n) - { - if (n < 0) return null; - var r = new ShapeInShapeCollection(); - r.Document = Document; - r.Index = n; - r._Shape = new Relation(GetShapeInShapeCollectionShapeIndex(n), GetShape); - r._ShapeCollection = new Relation(GetShapeInShapeCollectionShapeCollectionIndex(n), GetShapeCollection); - return r; - } - - - // System - - public EntityTable SystemEntityTable { get; } - - public IArray SystemSystemType { get; } - public Int32 GetSystemSystemType(int index, Int32 defaultValue = default) => SystemSystemType?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray SystemFamilyTypeIndex { get; } - public int GetSystemFamilyTypeIndex(int index) => SystemFamilyTypeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray SystemElementIndex { get; } - public int GetSystemElementIndex(int index) => SystemElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumSystem => SystemEntityTable?.NumRows ?? 0; - public IArray SystemList { get; } - public System GetSystem(int n) - { - if (n < 0) return null; - var r = new System(); - r.Document = Document; - r.Index = n; - r.SystemType = SystemSystemType.ElementAtOrDefault(n); - r._FamilyType = new Relation(GetSystemFamilyTypeIndex(n), GetFamilyType); - r._Element = new Relation(GetSystemElementIndex(n), GetElement); - return r; - } - - - // ElementInSystem - - public EntityTable ElementInSystemEntityTable { get; } - - public IArray ElementInSystemRoles { get; } - public Int32 GetElementInSystemRoles(int index, Int32 defaultValue = default) => ElementInSystemRoles?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ElementInSystemSystemIndex { get; } - public int GetElementInSystemSystemIndex(int index) => ElementInSystemSystemIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementInSystemElementIndex { get; } - public int GetElementInSystemElementIndex(int index) => ElementInSystemElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumElementInSystem => ElementInSystemEntityTable?.NumRows ?? 0; - public IArray ElementInSystemList { get; } - public ElementInSystem GetElementInSystem(int n) - { - if (n < 0) return null; - var r = new ElementInSystem(); - r.Document = Document; - r.Index = n; - r.Roles = ElementInSystemRoles.ElementAtOrDefault(n); - r._System = new Relation(GetElementInSystemSystemIndex(n), GetSystem); - r._Element = new Relation(GetElementInSystemElementIndex(n), GetElement); - return r; - } - - - // Warning - - public EntityTable WarningEntityTable { get; } - - public IArray WarningGuid { get; } - public String GetWarningGuid(int index, String defaultValue = "") => WarningGuid?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WarningSeverity { get; } - public String GetWarningSeverity(int index, String defaultValue = "") => WarningSeverity?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WarningDescription { get; } - public String GetWarningDescription(int index, String defaultValue = "") => WarningDescription?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray WarningBimDocumentIndex { get; } - public int GetWarningBimDocumentIndex(int index) => WarningBimDocumentIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumWarning => WarningEntityTable?.NumRows ?? 0; - public IArray WarningList { get; } - public Warning GetWarning(int n) - { - if (n < 0) return null; - var r = new Warning(); - r.Document = Document; - r.Index = n; - r.Guid = WarningGuid.ElementAtOrDefault(n); - r.Severity = WarningSeverity.ElementAtOrDefault(n); - r.Description = WarningDescription.ElementAtOrDefault(n); - r._BimDocument = new Relation(GetWarningBimDocumentIndex(n), GetBimDocument); - return r; - } - - - // ElementInWarning - - public EntityTable ElementInWarningEntityTable { get; } - - public IArray ElementInWarningWarningIndex { get; } - public int GetElementInWarningWarningIndex(int index) => ElementInWarningWarningIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ElementInWarningElementIndex { get; } - public int GetElementInWarningElementIndex(int index) => ElementInWarningElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumElementInWarning => ElementInWarningEntityTable?.NumRows ?? 0; - public IArray ElementInWarningList { get; } - public ElementInWarning GetElementInWarning(int n) - { - if (n < 0) return null; - var r = new ElementInWarning(); - r.Document = Document; - r.Index = n; - r._Warning = new Relation(GetElementInWarningWarningIndex(n), GetWarning); - r._Element = new Relation(GetElementInWarningElementIndex(n), GetElement); - return r; - } - - - // BasePoint - - public EntityTable BasePointEntityTable { get; } - - public IArray BasePointIsSurveyPoint { get; } - public Boolean GetBasePointIsSurveyPoint(int index, Boolean defaultValue = default) => BasePointIsSurveyPoint?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointPosition_X { get; } - public Double GetBasePointPosition_X(int index, Double defaultValue = default) => BasePointPosition_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointPosition_Y { get; } - public Double GetBasePointPosition_Y(int index, Double defaultValue = default) => BasePointPosition_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointPosition_Z { get; } - public Double GetBasePointPosition_Z(int index, Double defaultValue = default) => BasePointPosition_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointSharedPosition_X { get; } - public Double GetBasePointSharedPosition_X(int index, Double defaultValue = default) => BasePointSharedPosition_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointSharedPosition_Y { get; } - public Double GetBasePointSharedPosition_Y(int index, Double defaultValue = default) => BasePointSharedPosition_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointSharedPosition_Z { get; } - public Double GetBasePointSharedPosition_Z(int index, Double defaultValue = default) => BasePointSharedPosition_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BasePointElementIndex { get; } - public int GetBasePointElementIndex(int index) => BasePointElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumBasePoint => BasePointEntityTable?.NumRows ?? 0; - public IArray BasePointList { get; } - public BasePoint GetBasePoint(int n) - { - if (n < 0) return null; - var r = new BasePoint(); - r.Document = Document; - r.Index = n; - r.IsSurveyPoint = BasePointIsSurveyPoint.ElementAtOrDefault(n); - r.Position_X = BasePointPosition_X.ElementAtOrDefault(n); - r.Position_Y = BasePointPosition_Y.ElementAtOrDefault(n); - r.Position_Z = BasePointPosition_Z.ElementAtOrDefault(n); - r.SharedPosition_X = BasePointSharedPosition_X.ElementAtOrDefault(n); - r.SharedPosition_Y = BasePointSharedPosition_Y.ElementAtOrDefault(n); - r.SharedPosition_Z = BasePointSharedPosition_Z.ElementAtOrDefault(n); - r._Element = new Relation(GetBasePointElementIndex(n), GetElement); - return r; - } - - - // PhaseFilter - - public EntityTable PhaseFilterEntityTable { get; } - - public IArray PhaseFilterNew { get; } - public Int32 GetPhaseFilterNew(int index, Int32 defaultValue = default) => PhaseFilterNew?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray PhaseFilterExisting { get; } - public Int32 GetPhaseFilterExisting(int index, Int32 defaultValue = default) => PhaseFilterExisting?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray PhaseFilterDemolished { get; } - public Int32 GetPhaseFilterDemolished(int index, Int32 defaultValue = default) => PhaseFilterDemolished?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray PhaseFilterTemporary { get; } - public Int32 GetPhaseFilterTemporary(int index, Int32 defaultValue = default) => PhaseFilterTemporary?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray PhaseFilterElementIndex { get; } - public int GetPhaseFilterElementIndex(int index) => PhaseFilterElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumPhaseFilter => PhaseFilterEntityTable?.NumRows ?? 0; - public IArray PhaseFilterList { get; } - public PhaseFilter GetPhaseFilter(int n) - { - if (n < 0) return null; - var r = new PhaseFilter(); - r.Document = Document; - r.Index = n; - r.New = PhaseFilterNew.ElementAtOrDefault(n); - r.Existing = PhaseFilterExisting.ElementAtOrDefault(n); - r.Demolished = PhaseFilterDemolished.ElementAtOrDefault(n); - r.Temporary = PhaseFilterTemporary.ElementAtOrDefault(n); - r._Element = new Relation(GetPhaseFilterElementIndex(n), GetElement); - return r; - } - - - // Grid - - public EntityTable GridEntityTable { get; } - - public IArray GridStartPoint_X { get; } - public Double GetGridStartPoint_X(int index, Double defaultValue = default) => GridStartPoint_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridStartPoint_Y { get; } - public Double GetGridStartPoint_Y(int index, Double defaultValue = default) => GridStartPoint_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridStartPoint_Z { get; } - public Double GetGridStartPoint_Z(int index, Double defaultValue = default) => GridStartPoint_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridEndPoint_X { get; } - public Double GetGridEndPoint_X(int index, Double defaultValue = default) => GridEndPoint_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridEndPoint_Y { get; } - public Double GetGridEndPoint_Y(int index, Double defaultValue = default) => GridEndPoint_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridEndPoint_Z { get; } - public Double GetGridEndPoint_Z(int index, Double defaultValue = default) => GridEndPoint_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridIsCurved { get; } - public Boolean GetGridIsCurved(int index, Boolean defaultValue = default) => GridIsCurved?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridExtents_Min_X { get; } - public Double GetGridExtents_Min_X(int index, Double defaultValue = default) => GridExtents_Min_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridExtents_Min_Y { get; } - public Double GetGridExtents_Min_Y(int index, Double defaultValue = default) => GridExtents_Min_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridExtents_Min_Z { get; } - public Double GetGridExtents_Min_Z(int index, Double defaultValue = default) => GridExtents_Min_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridExtents_Max_X { get; } - public Double GetGridExtents_Max_X(int index, Double defaultValue = default) => GridExtents_Max_X?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridExtents_Max_Y { get; } - public Double GetGridExtents_Max_Y(int index, Double defaultValue = default) => GridExtents_Max_Y?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridExtents_Max_Z { get; } - public Double GetGridExtents_Max_Z(int index, Double defaultValue = default) => GridExtents_Max_Z?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray GridFamilyTypeIndex { get; } - public int GetGridFamilyTypeIndex(int index) => GridFamilyTypeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray GridElementIndex { get; } - public int GetGridElementIndex(int index) => GridElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumGrid => GridEntityTable?.NumRows ?? 0; - public IArray GridList { get; } - public Grid GetGrid(int n) - { - if (n < 0) return null; - var r = new Grid(); - r.Document = Document; - r.Index = n; - r.StartPoint_X = GridStartPoint_X.ElementAtOrDefault(n); - r.StartPoint_Y = GridStartPoint_Y.ElementAtOrDefault(n); - r.StartPoint_Z = GridStartPoint_Z.ElementAtOrDefault(n); - r.EndPoint_X = GridEndPoint_X.ElementAtOrDefault(n); - r.EndPoint_Y = GridEndPoint_Y.ElementAtOrDefault(n); - r.EndPoint_Z = GridEndPoint_Z.ElementAtOrDefault(n); - r.IsCurved = GridIsCurved.ElementAtOrDefault(n); - r.Extents_Min_X = GridExtents_Min_X.ElementAtOrDefault(n); - r.Extents_Min_Y = GridExtents_Min_Y.ElementAtOrDefault(n); - r.Extents_Min_Z = GridExtents_Min_Z.ElementAtOrDefault(n); - r.Extents_Max_X = GridExtents_Max_X.ElementAtOrDefault(n); - r.Extents_Max_Y = GridExtents_Max_Y.ElementAtOrDefault(n); - r.Extents_Max_Z = GridExtents_Max_Z.ElementAtOrDefault(n); - r._FamilyType = new Relation(GetGridFamilyTypeIndex(n), GetFamilyType); - r._Element = new Relation(GetGridElementIndex(n), GetElement); - return r; - } - - - // Area - - public EntityTable AreaEntityTable { get; } - - public IArray AreaValue { get; } - public Double GetAreaValue(int index, Double defaultValue = default) => AreaValue?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AreaPerimeter { get; } - public Double GetAreaPerimeter(int index, Double defaultValue = default) => AreaPerimeter?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AreaNumber { get; } - public String GetAreaNumber(int index, String defaultValue = "") => AreaNumber?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AreaIsGrossInterior { get; } - public Boolean GetAreaIsGrossInterior(int index, Boolean defaultValue = default) => AreaIsGrossInterior?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AreaAreaSchemeIndex { get; } - public int GetAreaAreaSchemeIndex(int index) => AreaAreaSchemeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray AreaElementIndex { get; } - public int GetAreaElementIndex(int index) => AreaElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumArea => AreaEntityTable?.NumRows ?? 0; - public IArray AreaList { get; } - public Area GetArea(int n) - { - if (n < 0) return null; - var r = new Area(); - r.Document = Document; - r.Index = n; - r.Value = AreaValue.ElementAtOrDefault(n); - r.Perimeter = AreaPerimeter.ElementAtOrDefault(n); - r.Number = AreaNumber.ElementAtOrDefault(n); - r.IsGrossInterior = AreaIsGrossInterior.ElementAtOrDefault(n); - r._AreaScheme = new Relation(GetAreaAreaSchemeIndex(n), GetAreaScheme); - r._Element = new Relation(GetAreaElementIndex(n), GetElement); - return r; - } - - - // AreaScheme - - public EntityTable AreaSchemeEntityTable { get; } - - public IArray AreaSchemeIsGrossBuildingArea { get; } - public Boolean GetAreaSchemeIsGrossBuildingArea(int index, Boolean defaultValue = default) => AreaSchemeIsGrossBuildingArea?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray AreaSchemeElementIndex { get; } - public int GetAreaSchemeElementIndex(int index) => AreaSchemeElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumAreaScheme => AreaSchemeEntityTable?.NumRows ?? 0; - public IArray AreaSchemeList { get; } - public AreaScheme GetAreaScheme(int n) - { - if (n < 0) return null; - var r = new AreaScheme(); - r.Document = Document; - r.Index = n; - r.IsGrossBuildingArea = AreaSchemeIsGrossBuildingArea.ElementAtOrDefault(n); - r._Element = new Relation(GetAreaSchemeElementIndex(n), GetElement); - return r; - } - - - // Schedule - - public EntityTable ScheduleEntityTable { get; } - - public IArray ScheduleElementIndex { get; } - public int GetScheduleElementIndex(int index) => ScheduleElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumSchedule => ScheduleEntityTable?.NumRows ?? 0; - public IArray ScheduleList { get; } - public Schedule GetSchedule(int n) - { - if (n < 0) return null; - var r = new Schedule(); - r.Document = Document; - r.Index = n; - r._Element = new Relation(GetScheduleElementIndex(n), GetElement); - return r; - } - - - // ScheduleColumn - - public EntityTable ScheduleColumnEntityTable { get; } - - public IArray ScheduleColumnName { get; } - public String GetScheduleColumnName(int index, String defaultValue = "") => ScheduleColumnName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ScheduleColumnColumnIndex { get; } - public Int32 GetScheduleColumnColumnIndex(int index, Int32 defaultValue = default) => ScheduleColumnColumnIndex?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ScheduleColumnScheduleIndex { get; } - public int GetScheduleColumnScheduleIndex(int index) => ScheduleColumnScheduleIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumScheduleColumn => ScheduleColumnEntityTable?.NumRows ?? 0; - public IArray ScheduleColumnList { get; } - public ScheduleColumn GetScheduleColumn(int n) - { - if (n < 0) return null; - var r = new ScheduleColumn(); - r.Document = Document; - r.Index = n; - r.Name = ScheduleColumnName.ElementAtOrDefault(n); - r.ColumnIndex = ScheduleColumnColumnIndex.ElementAtOrDefault(n); - r._Schedule = new Relation(GetScheduleColumnScheduleIndex(n), GetSchedule); - return r; - } - - - // ScheduleCell - - public EntityTable ScheduleCellEntityTable { get; } - - public IArray ScheduleCellValue { get; } - public String GetScheduleCellValue(int index, String defaultValue = "") => ScheduleCellValue?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ScheduleCellRowIndex { get; } - public Int32 GetScheduleCellRowIndex(int index, Int32 defaultValue = default) => ScheduleCellRowIndex?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray ScheduleCellScheduleColumnIndex { get; } - public int GetScheduleCellScheduleColumnIndex(int index) => ScheduleCellScheduleColumnIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumScheduleCell => ScheduleCellEntityTable?.NumRows ?? 0; - public IArray ScheduleCellList { get; } - public ScheduleCell GetScheduleCell(int n) - { - if (n < 0) return null; - var r = new ScheduleCell(); - r.Document = Document; - r.Index = n; - r.Value = ScheduleCellValue.ElementAtOrDefault(n); - r.RowIndex = ScheduleCellRowIndex.ElementAtOrDefault(n); - r._ScheduleColumn = new Relation(GetScheduleCellScheduleColumnIndex(n), GetScheduleColumn); - return r; - } - - - // ViewSheetSet - - public EntityTable ViewSheetSetEntityTable { get; } - - public IArray ViewSheetSetElementIndex { get; } - public int GetViewSheetSetElementIndex(int index) => ViewSheetSetElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumViewSheetSet => ViewSheetSetEntityTable?.NumRows ?? 0; - public IArray ViewSheetSetList { get; } - public ViewSheetSet GetViewSheetSet(int n) - { - if (n < 0) return null; - var r = new ViewSheetSet(); - r.Document = Document; - r.Index = n; - r._Element = new Relation(GetViewSheetSetElementIndex(n), GetElement); - return r; - } - - - // ViewSheet - - public EntityTable ViewSheetEntityTable { get; } - - public IArray ViewSheetFamilyTypeIndex { get; } - public int GetViewSheetFamilyTypeIndex(int index) => ViewSheetFamilyTypeIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ViewSheetElementIndex { get; } - public int GetViewSheetElementIndex(int index) => ViewSheetElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumViewSheet => ViewSheetEntityTable?.NumRows ?? 0; - public IArray ViewSheetList { get; } - public ViewSheet GetViewSheet(int n) - { - if (n < 0) return null; - var r = new ViewSheet(); - r.Document = Document; - r.Index = n; - r._FamilyType = new Relation(GetViewSheetFamilyTypeIndex(n), GetFamilyType); - r._Element = new Relation(GetViewSheetElementIndex(n), GetElement); - return r; - } - - - // ViewSheetInViewSheetSet - - public EntityTable ViewSheetInViewSheetSetEntityTable { get; } - - public IArray ViewSheetInViewSheetSetViewSheetIndex { get; } - public int GetViewSheetInViewSheetSetViewSheetIndex(int index) => ViewSheetInViewSheetSetViewSheetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ViewSheetInViewSheetSetViewSheetSetIndex { get; } - public int GetViewSheetInViewSheetSetViewSheetSetIndex(int index) => ViewSheetInViewSheetSetViewSheetSetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumViewSheetInViewSheetSet => ViewSheetInViewSheetSetEntityTable?.NumRows ?? 0; - public IArray ViewSheetInViewSheetSetList { get; } - public ViewSheetInViewSheetSet GetViewSheetInViewSheetSet(int n) - { - if (n < 0) return null; - var r = new ViewSheetInViewSheetSet(); - r.Document = Document; - r.Index = n; - r._ViewSheet = new Relation(GetViewSheetInViewSheetSetViewSheetIndex(n), GetViewSheet); - r._ViewSheetSet = new Relation(GetViewSheetInViewSheetSetViewSheetSetIndex(n), GetViewSheetSet); - return r; - } - - - // ViewInViewSheetSet - - public EntityTable ViewInViewSheetSetEntityTable { get; } - - public IArray ViewInViewSheetSetViewIndex { get; } - public int GetViewInViewSheetSetViewIndex(int index) => ViewInViewSheetSetViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ViewInViewSheetSetViewSheetSetIndex { get; } - public int GetViewInViewSheetSetViewSheetSetIndex(int index) => ViewInViewSheetSetViewSheetSetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumViewInViewSheetSet => ViewInViewSheetSetEntityTable?.NumRows ?? 0; - public IArray ViewInViewSheetSetList { get; } - public ViewInViewSheetSet GetViewInViewSheetSet(int n) - { - if (n < 0) return null; - var r = new ViewInViewSheetSet(); - r.Document = Document; - r.Index = n; - r._View = new Relation(GetViewInViewSheetSetViewIndex(n), GetView); - r._ViewSheetSet = new Relation(GetViewInViewSheetSetViewSheetSetIndex(n), GetViewSheetSet); - return r; - } - - - // ViewInViewSheet - - public EntityTable ViewInViewSheetEntityTable { get; } - - public IArray ViewInViewSheetViewIndex { get; } - public int GetViewInViewSheetViewIndex(int index) => ViewInViewSheetViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray ViewInViewSheetViewSheetIndex { get; } - public int GetViewInViewSheetViewSheetIndex(int index) => ViewInViewSheetViewSheetIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumViewInViewSheet => ViewInViewSheetEntityTable?.NumRows ?? 0; - public IArray ViewInViewSheetList { get; } - public ViewInViewSheet GetViewInViewSheet(int n) - { - if (n < 0) return null; - var r = new ViewInViewSheet(); - r.Document = Document; - r.Index = n; - r._View = new Relation(GetViewInViewSheetViewIndex(n), GetView); - r._ViewSheet = new Relation(GetViewInViewSheetViewSheetIndex(n), GetViewSheet); - return r; - } - - - // Site - - public EntityTable SiteEntityTable { get; } - - public IArray SiteLatitude { get; } - public Double GetSiteLatitude(int index, Double defaultValue = default) => SiteLatitude?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray SiteLongitude { get; } - public Double GetSiteLongitude(int index, Double defaultValue = default) => SiteLongitude?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray SiteAddress { get; } - public String GetSiteAddress(int index, String defaultValue = "") => SiteAddress?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray SiteElevation { get; } - public Double GetSiteElevation(int index, Double defaultValue = default) => SiteElevation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray SiteNumber { get; } - public String GetSiteNumber(int index, String defaultValue = "") => SiteNumber?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray SiteElementIndex { get; } - public int GetSiteElementIndex(int index) => SiteElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumSite => SiteEntityTable?.NumRows ?? 0; - public IArray SiteList { get; } - public Site GetSite(int n) - { - if (n < 0) return null; - var r = new Site(); - r.Document = Document; - r.Index = n; - r.Latitude = SiteLatitude.ElementAtOrDefault(n); - r.Longitude = SiteLongitude.ElementAtOrDefault(n); - r.Address = SiteAddress.ElementAtOrDefault(n); - r.Elevation = SiteElevation.ElementAtOrDefault(n); - r.Number = SiteNumber.ElementAtOrDefault(n); - r._Element = new Relation(GetSiteElementIndex(n), GetElement); - return r; - } - - - // Building - - public EntityTable BuildingEntityTable { get; } - - public IArray BuildingElevation { get; } - public Double GetBuildingElevation(int index, Double defaultValue = default) => BuildingElevation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BuildingTerrainElevation { get; } - public Double GetBuildingTerrainElevation(int index, Double defaultValue = default) => BuildingTerrainElevation?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BuildingAddress { get; } - public String GetBuildingAddress(int index, String defaultValue = "") => BuildingAddress?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; - public IArray BuildingSiteIndex { get; } - public int GetBuildingSiteIndex(int index) => BuildingSiteIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public IArray BuildingElementIndex { get; } - public int GetBuildingElementIndex(int index) => BuildingElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; - public int NumBuilding => BuildingEntityTable?.NumRows ?? 0; - public IArray BuildingList { get; } - public Building GetBuilding(int n) - { - if (n < 0) return null; - var r = new Building(); - r.Document = Document; - r.Index = n; - r.Elevation = BuildingElevation.ElementAtOrDefault(n); - r.TerrainElevation = BuildingTerrainElevation.ElementAtOrDefault(n); - r.Address = BuildingAddress.ElementAtOrDefault(n); - r._Site = new Relation(GetBuildingSiteIndex(n), GetSite); - r._Element = new Relation(GetBuildingElementIndex(n), GetElement); - return r; - } - - // All entity collections - public Dictionary> AllEntities => new Dictionary>() { - {"Vim.Asset", AssetList.ToEnumerable()}, - {"Vim.DisplayUnit", DisplayUnitList.ToEnumerable()}, - {"Vim.ParameterDescriptor", ParameterDescriptorList.ToEnumerable()}, - {"Vim.Parameter", ParameterList.ToEnumerable()}, - {"Vim.Element", ElementList.ToEnumerable()}, - {"Vim.Workset", WorksetList.ToEnumerable()}, - {"Vim.AssemblyInstance", AssemblyInstanceList.ToEnumerable()}, - {"Vim.Group", GroupList.ToEnumerable()}, - {"Vim.DesignOption", DesignOptionList.ToEnumerable()}, - {"Vim.Level", LevelList.ToEnumerable()}, - {"Vim.Phase", PhaseList.ToEnumerable()}, - {"Vim.Room", RoomList.ToEnumerable()}, - {"Vim.BimDocument", BimDocumentList.ToEnumerable()}, - {"Vim.DisplayUnitInBimDocument", DisplayUnitInBimDocumentList.ToEnumerable()}, - {"Vim.PhaseOrderInBimDocument", PhaseOrderInBimDocumentList.ToEnumerable()}, - {"Vim.Category", CategoryList.ToEnumerable()}, - {"Vim.Family", FamilyList.ToEnumerable()}, - {"Vim.FamilyType", FamilyTypeList.ToEnumerable()}, - {"Vim.FamilyInstance", FamilyInstanceList.ToEnumerable()}, - {"Vim.View", ViewList.ToEnumerable()}, - {"Vim.ElementInView", ElementInViewList.ToEnumerable()}, - {"Vim.ShapeInView", ShapeInViewList.ToEnumerable()}, - {"Vim.AssetInView", AssetInViewList.ToEnumerable()}, - {"Vim.AssetInViewSheet", AssetInViewSheetList.ToEnumerable()}, - {"Vim.LevelInView", LevelInViewList.ToEnumerable()}, - {"Vim.Camera", CameraList.ToEnumerable()}, - {"Vim.Material", MaterialList.ToEnumerable()}, - {"Vim.MaterialInElement", MaterialInElementList.ToEnumerable()}, - {"Vim.CompoundStructureLayer", CompoundStructureLayerList.ToEnumerable()}, - {"Vim.CompoundStructure", CompoundStructureList.ToEnumerable()}, - {"Vim.Node", NodeList.ToEnumerable()}, - {"Vim.Geometry", GeometryList.ToEnumerable()}, - {"Vim.Shape", ShapeList.ToEnumerable()}, - {"Vim.ShapeCollection", ShapeCollectionList.ToEnumerable()}, - {"Vim.ShapeInShapeCollection", ShapeInShapeCollectionList.ToEnumerable()}, - {"Vim.System", SystemList.ToEnumerable()}, - {"Vim.ElementInSystem", ElementInSystemList.ToEnumerable()}, - {"Vim.Warning", WarningList.ToEnumerable()}, - {"Vim.ElementInWarning", ElementInWarningList.ToEnumerable()}, - {"Vim.BasePoint", BasePointList.ToEnumerable()}, - {"Vim.PhaseFilter", PhaseFilterList.ToEnumerable()}, - {"Vim.Grid", GridList.ToEnumerable()}, - {"Vim.Area", AreaList.ToEnumerable()}, - {"Vim.AreaScheme", AreaSchemeList.ToEnumerable()}, - {"Vim.Schedule", ScheduleList.ToEnumerable()}, - {"Vim.ScheduleColumn", ScheduleColumnList.ToEnumerable()}, - {"Vim.ScheduleCell", ScheduleCellList.ToEnumerable()}, - {"Vim.ViewSheetSet", ViewSheetSetList.ToEnumerable()}, - {"Vim.ViewSheet", ViewSheetList.ToEnumerable()}, - {"Vim.ViewSheetInViewSheetSet", ViewSheetInViewSheetSetList.ToEnumerable()}, - {"Vim.ViewInViewSheetSet", ViewInViewSheetSetList.ToEnumerable()}, - {"Vim.ViewInViewSheet", ViewInViewSheetList.ToEnumerable()}, - {"Vim.Site", SiteList.ToEnumerable()}, - {"Vim.Building", BuildingList.ToEnumerable()}, - }; - - // Entity types from table names - public Dictionary EntityTypes => new Dictionary() { - {"Vim.Asset", typeof(Asset)}, - {"Vim.DisplayUnit", typeof(DisplayUnit)}, - {"Vim.ParameterDescriptor", typeof(ParameterDescriptor)}, - {"Vim.Parameter", typeof(Parameter)}, - {"Vim.Element", typeof(Element)}, - {"Vim.Workset", typeof(Workset)}, - {"Vim.AssemblyInstance", typeof(AssemblyInstance)}, - {"Vim.Group", typeof(Group)}, - {"Vim.DesignOption", typeof(DesignOption)}, - {"Vim.Level", typeof(Level)}, - {"Vim.Phase", typeof(Phase)}, - {"Vim.Room", typeof(Room)}, - {"Vim.BimDocument", typeof(BimDocument)}, - {"Vim.DisplayUnitInBimDocument", typeof(DisplayUnitInBimDocument)}, - {"Vim.PhaseOrderInBimDocument", typeof(PhaseOrderInBimDocument)}, - {"Vim.Category", typeof(Category)}, - {"Vim.Family", typeof(Family)}, - {"Vim.FamilyType", typeof(FamilyType)}, - {"Vim.FamilyInstance", typeof(FamilyInstance)}, - {"Vim.View", typeof(View)}, - {"Vim.ElementInView", typeof(ElementInView)}, - {"Vim.ShapeInView", typeof(ShapeInView)}, - {"Vim.AssetInView", typeof(AssetInView)}, - {"Vim.AssetInViewSheet", typeof(AssetInViewSheet)}, - {"Vim.LevelInView", typeof(LevelInView)}, - {"Vim.Camera", typeof(Camera)}, - {"Vim.Material", typeof(Material)}, - {"Vim.MaterialInElement", typeof(MaterialInElement)}, - {"Vim.CompoundStructureLayer", typeof(CompoundStructureLayer)}, - {"Vim.CompoundStructure", typeof(CompoundStructure)}, - {"Vim.Node", typeof(Node)}, - {"Vim.Geometry", typeof(Geometry)}, - {"Vim.Shape", typeof(Shape)}, - {"Vim.ShapeCollection", typeof(ShapeCollection)}, - {"Vim.ShapeInShapeCollection", typeof(ShapeInShapeCollection)}, - {"Vim.System", typeof(System)}, - {"Vim.ElementInSystem", typeof(ElementInSystem)}, - {"Vim.Warning", typeof(Warning)}, - {"Vim.ElementInWarning", typeof(ElementInWarning)}, - {"Vim.BasePoint", typeof(BasePoint)}, - {"Vim.PhaseFilter", typeof(PhaseFilter)}, - {"Vim.Grid", typeof(Grid)}, - {"Vim.Area", typeof(Area)}, - {"Vim.AreaScheme", typeof(AreaScheme)}, - {"Vim.Schedule", typeof(Schedule)}, - {"Vim.ScheduleColumn", typeof(ScheduleColumn)}, - {"Vim.ScheduleCell", typeof(ScheduleCell)}, - {"Vim.ViewSheetSet", typeof(ViewSheetSet)}, - {"Vim.ViewSheet", typeof(ViewSheet)}, - {"Vim.ViewSheetInViewSheetSet", typeof(ViewSheetInViewSheetSet)}, - {"Vim.ViewInViewSheetSet", typeof(ViewInViewSheetSet)}, - {"Vim.ViewInViewSheet", typeof(ViewInViewSheet)}, - {"Vim.Site", typeof(Site)}, - {"Vim.Building", typeof(Building)}, - }; - public DocumentModel(Document d, bool inParallel = true) - { - Document = d; - - // Initialize entity tables - AssetEntityTable = Document.GetTable("Vim.Asset"); - DisplayUnitEntityTable = Document.GetTable("Vim.DisplayUnit"); - ParameterDescriptorEntityTable = Document.GetTable("Vim.ParameterDescriptor"); - ParameterEntityTable = Document.GetTable("Vim.Parameter"); - ElementEntityTable = Document.GetTable("Vim.Element"); - WorksetEntityTable = Document.GetTable("Vim.Workset"); - AssemblyInstanceEntityTable = Document.GetTable("Vim.AssemblyInstance"); - GroupEntityTable = Document.GetTable("Vim.Group"); - DesignOptionEntityTable = Document.GetTable("Vim.DesignOption"); - LevelEntityTable = Document.GetTable("Vim.Level"); - PhaseEntityTable = Document.GetTable("Vim.Phase"); - RoomEntityTable = Document.GetTable("Vim.Room"); - BimDocumentEntityTable = Document.GetTable("Vim.BimDocument"); - DisplayUnitInBimDocumentEntityTable = Document.GetTable("Vim.DisplayUnitInBimDocument"); - PhaseOrderInBimDocumentEntityTable = Document.GetTable("Vim.PhaseOrderInBimDocument"); - CategoryEntityTable = Document.GetTable("Vim.Category"); - FamilyEntityTable = Document.GetTable("Vim.Family"); - FamilyTypeEntityTable = Document.GetTable("Vim.FamilyType"); - FamilyInstanceEntityTable = Document.GetTable("Vim.FamilyInstance"); - ViewEntityTable = Document.GetTable("Vim.View"); - ElementInViewEntityTable = Document.GetTable("Vim.ElementInView"); - ShapeInViewEntityTable = Document.GetTable("Vim.ShapeInView"); - AssetInViewEntityTable = Document.GetTable("Vim.AssetInView"); - AssetInViewSheetEntityTable = Document.GetTable("Vim.AssetInViewSheet"); - LevelInViewEntityTable = Document.GetTable("Vim.LevelInView"); - CameraEntityTable = Document.GetTable("Vim.Camera"); - MaterialEntityTable = Document.GetTable("Vim.Material"); - MaterialInElementEntityTable = Document.GetTable("Vim.MaterialInElement"); - CompoundStructureLayerEntityTable = Document.GetTable("Vim.CompoundStructureLayer"); - CompoundStructureEntityTable = Document.GetTable("Vim.CompoundStructure"); - NodeEntityTable = Document.GetTable("Vim.Node"); - GeometryEntityTable = Document.GetTable("Vim.Geometry"); - ShapeEntityTable = Document.GetTable("Vim.Shape"); - ShapeCollectionEntityTable = Document.GetTable("Vim.ShapeCollection"); - ShapeInShapeCollectionEntityTable = Document.GetTable("Vim.ShapeInShapeCollection"); - SystemEntityTable = Document.GetTable("Vim.System"); - ElementInSystemEntityTable = Document.GetTable("Vim.ElementInSystem"); - WarningEntityTable = Document.GetTable("Vim.Warning"); - ElementInWarningEntityTable = Document.GetTable("Vim.ElementInWarning"); - BasePointEntityTable = Document.GetTable("Vim.BasePoint"); - PhaseFilterEntityTable = Document.GetTable("Vim.PhaseFilter"); - GridEntityTable = Document.GetTable("Vim.Grid"); - AreaEntityTable = Document.GetTable("Vim.Area"); - AreaSchemeEntityTable = Document.GetTable("Vim.AreaScheme"); - ScheduleEntityTable = Document.GetTable("Vim.Schedule"); - ScheduleColumnEntityTable = Document.GetTable("Vim.ScheduleColumn"); - ScheduleCellEntityTable = Document.GetTable("Vim.ScheduleCell"); - ViewSheetSetEntityTable = Document.GetTable("Vim.ViewSheetSet"); - ViewSheetEntityTable = Document.GetTable("Vim.ViewSheet"); - ViewSheetInViewSheetSetEntityTable = Document.GetTable("Vim.ViewSheetInViewSheetSet"); - ViewInViewSheetSetEntityTable = Document.GetTable("Vim.ViewInViewSheetSet"); - ViewInViewSheetEntityTable = Document.GetTable("Vim.ViewInViewSheet"); - SiteEntityTable = Document.GetTable("Vim.Site"); - BuildingEntityTable = Document.GetTable("Vim.Building"); - - // Initialize entity arrays - AssetBufferName = AssetEntityTable?.GetStringColumnValues("string:BufferName") ?? Array.Empty().ToIArray(); - DisplayUnitSpec = DisplayUnitEntityTable?.GetStringColumnValues("string:Spec") ?? Array.Empty().ToIArray(); - DisplayUnitType = DisplayUnitEntityTable?.GetStringColumnValues("string:Type") ?? Array.Empty().ToIArray(); - DisplayUnitLabel = DisplayUnitEntityTable?.GetStringColumnValues("string:Label") ?? Array.Empty().ToIArray(); - ParameterDescriptorName = ParameterDescriptorEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - ParameterDescriptorGroup = ParameterDescriptorEntityTable?.GetStringColumnValues("string:Group") ?? Array.Empty().ToIArray(); - ParameterDescriptorParameterType = ParameterDescriptorEntityTable?.GetStringColumnValues("string:ParameterType") ?? Array.Empty().ToIArray(); - ParameterDescriptorIsInstance = ParameterDescriptorEntityTable?.GetDataColumnValues("byte:IsInstance") ?? Array.Empty().ToIArray(); - ParameterDescriptorIsShared = ParameterDescriptorEntityTable?.GetDataColumnValues("byte:IsShared") ?? Array.Empty().ToIArray(); - ParameterDescriptorIsReadOnly = ParameterDescriptorEntityTable?.GetDataColumnValues("byte:IsReadOnly") ?? Array.Empty().ToIArray(); - ParameterDescriptorFlags = ParameterDescriptorEntityTable?.GetDataColumnValues("int:Flags") ?? Array.Empty().ToIArray(); - ParameterDescriptorGuid = ParameterDescriptorEntityTable?.GetStringColumnValues("string:Guid") ?? Array.Empty().ToIArray(); - ParameterDescriptorStorageType = ParameterDescriptorEntityTable?.GetDataColumnValues("int:StorageType") ?? Array.Empty().ToIArray(); - ParameterValue = ParameterEntityTable?.GetStringColumnValues("string:Value") ?? Array.Empty().ToIArray(); - ElementId = (ElementEntityTable?.GetDataColumnValues("long:Id") ?? ElementEntityTable?.GetDataColumnValues("int:Id")?.Select(v => (Int64) v)) ?? Array.Empty().ToIArray(); - ElementType = ElementEntityTable?.GetStringColumnValues("string:Type") ?? Array.Empty().ToIArray(); - ElementName = ElementEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - ElementUniqueId = ElementEntityTable?.GetStringColumnValues("string:UniqueId") ?? Array.Empty().ToIArray(); - ElementLocation_X = ElementEntityTable?.GetDataColumnValues("float:Location.X") ?? Array.Empty().ToIArray(); - ElementLocation_Y = ElementEntityTable?.GetDataColumnValues("float:Location.Y") ?? Array.Empty().ToIArray(); - ElementLocation_Z = ElementEntityTable?.GetDataColumnValues("float:Location.Z") ?? Array.Empty().ToIArray(); - ElementFamilyName = ElementEntityTable?.GetStringColumnValues("string:FamilyName") ?? Array.Empty().ToIArray(); - ElementIsPinned = ElementEntityTable?.GetDataColumnValues("byte:IsPinned") ?? Array.Empty().ToIArray(); - WorksetId = WorksetEntityTable?.GetDataColumnValues("int:Id") ?? Array.Empty().ToIArray(); - WorksetName = WorksetEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - WorksetKind = WorksetEntityTable?.GetStringColumnValues("string:Kind") ?? Array.Empty().ToIArray(); - WorksetIsOpen = WorksetEntityTable?.GetDataColumnValues("byte:IsOpen") ?? Array.Empty().ToIArray(); - WorksetIsEditable = WorksetEntityTable?.GetDataColumnValues("byte:IsEditable") ?? Array.Empty().ToIArray(); - WorksetOwner = WorksetEntityTable?.GetStringColumnValues("string:Owner") ?? Array.Empty().ToIArray(); - WorksetUniqueId = WorksetEntityTable?.GetStringColumnValues("string:UniqueId") ?? Array.Empty().ToIArray(); - AssemblyInstanceAssemblyTypeName = AssemblyInstanceEntityTable?.GetStringColumnValues("string:AssemblyTypeName") ?? Array.Empty().ToIArray(); - AssemblyInstancePosition_X = AssemblyInstanceEntityTable?.GetDataColumnValues("float:Position.X") ?? Array.Empty().ToIArray(); - AssemblyInstancePosition_Y = AssemblyInstanceEntityTable?.GetDataColumnValues("float:Position.Y") ?? Array.Empty().ToIArray(); - AssemblyInstancePosition_Z = AssemblyInstanceEntityTable?.GetDataColumnValues("float:Position.Z") ?? Array.Empty().ToIArray(); - GroupGroupType = GroupEntityTable?.GetStringColumnValues("string:GroupType") ?? Array.Empty().ToIArray(); - GroupPosition_X = GroupEntityTable?.GetDataColumnValues("float:Position.X") ?? Array.Empty().ToIArray(); - GroupPosition_Y = GroupEntityTable?.GetDataColumnValues("float:Position.Y") ?? Array.Empty().ToIArray(); - GroupPosition_Z = GroupEntityTable?.GetDataColumnValues("float:Position.Z") ?? Array.Empty().ToIArray(); - DesignOptionIsPrimary = DesignOptionEntityTable?.GetDataColumnValues("byte:IsPrimary") ?? Array.Empty().ToIArray(); - LevelElevation = LevelEntityTable?.GetDataColumnValues("double:Elevation") ?? Array.Empty().ToIArray(); - LevelProjectElevation = LevelEntityTable?.GetDataColumnValues("double:ProjectElevation") ?? Array.Empty().ToIArray(); - RoomBaseOffset = RoomEntityTable?.GetDataColumnValues("double:BaseOffset") ?? Array.Empty().ToIArray(); - RoomLimitOffset = RoomEntityTable?.GetDataColumnValues("double:LimitOffset") ?? Array.Empty().ToIArray(); - RoomUnboundedHeight = RoomEntityTable?.GetDataColumnValues("double:UnboundedHeight") ?? Array.Empty().ToIArray(); - RoomVolume = RoomEntityTable?.GetDataColumnValues("double:Volume") ?? Array.Empty().ToIArray(); - RoomPerimeter = RoomEntityTable?.GetDataColumnValues("double:Perimeter") ?? Array.Empty().ToIArray(); - RoomArea = RoomEntityTable?.GetDataColumnValues("double:Area") ?? Array.Empty().ToIArray(); - RoomNumber = RoomEntityTable?.GetStringColumnValues("string:Number") ?? Array.Empty().ToIArray(); - BimDocumentTitle = BimDocumentEntityTable?.GetStringColumnValues("string:Title") ?? Array.Empty().ToIArray(); - BimDocumentIsMetric = BimDocumentEntityTable?.GetDataColumnValues("byte:IsMetric") ?? Array.Empty().ToIArray(); - BimDocumentGuid = BimDocumentEntityTable?.GetStringColumnValues("string:Guid") ?? Array.Empty().ToIArray(); - BimDocumentNumSaves = BimDocumentEntityTable?.GetDataColumnValues("int:NumSaves") ?? Array.Empty().ToIArray(); - BimDocumentIsLinked = BimDocumentEntityTable?.GetDataColumnValues("byte:IsLinked") ?? Array.Empty().ToIArray(); - BimDocumentIsDetached = BimDocumentEntityTable?.GetDataColumnValues("byte:IsDetached") ?? Array.Empty().ToIArray(); - BimDocumentIsWorkshared = BimDocumentEntityTable?.GetDataColumnValues("byte:IsWorkshared") ?? Array.Empty().ToIArray(); - BimDocumentPathName = BimDocumentEntityTable?.GetStringColumnValues("string:PathName") ?? Array.Empty().ToIArray(); - BimDocumentLatitude = BimDocumentEntityTable?.GetDataColumnValues("double:Latitude") ?? Array.Empty().ToIArray(); - BimDocumentLongitude = BimDocumentEntityTable?.GetDataColumnValues("double:Longitude") ?? Array.Empty().ToIArray(); - BimDocumentTimeZone = BimDocumentEntityTable?.GetDataColumnValues("double:TimeZone") ?? Array.Empty().ToIArray(); - BimDocumentPlaceName = BimDocumentEntityTable?.GetStringColumnValues("string:PlaceName") ?? Array.Empty().ToIArray(); - BimDocumentWeatherStationName = BimDocumentEntityTable?.GetStringColumnValues("string:WeatherStationName") ?? Array.Empty().ToIArray(); - BimDocumentElevation = BimDocumentEntityTable?.GetDataColumnValues("double:Elevation") ?? Array.Empty().ToIArray(); - BimDocumentProjectLocation = BimDocumentEntityTable?.GetStringColumnValues("string:ProjectLocation") ?? Array.Empty().ToIArray(); - BimDocumentIssueDate = BimDocumentEntityTable?.GetStringColumnValues("string:IssueDate") ?? Array.Empty().ToIArray(); - BimDocumentStatus = BimDocumentEntityTable?.GetStringColumnValues("string:Status") ?? Array.Empty().ToIArray(); - BimDocumentClientName = BimDocumentEntityTable?.GetStringColumnValues("string:ClientName") ?? Array.Empty().ToIArray(); - BimDocumentAddress = BimDocumentEntityTable?.GetStringColumnValues("string:Address") ?? Array.Empty().ToIArray(); - BimDocumentName = BimDocumentEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - BimDocumentNumber = BimDocumentEntityTable?.GetStringColumnValues("string:Number") ?? Array.Empty().ToIArray(); - BimDocumentAuthor = BimDocumentEntityTable?.GetStringColumnValues("string:Author") ?? Array.Empty().ToIArray(); - BimDocumentBuildingName = BimDocumentEntityTable?.GetStringColumnValues("string:BuildingName") ?? Array.Empty().ToIArray(); - BimDocumentOrganizationName = BimDocumentEntityTable?.GetStringColumnValues("string:OrganizationName") ?? Array.Empty().ToIArray(); - BimDocumentOrganizationDescription = BimDocumentEntityTable?.GetStringColumnValues("string:OrganizationDescription") ?? Array.Empty().ToIArray(); - BimDocumentProduct = BimDocumentEntityTable?.GetStringColumnValues("string:Product") ?? Array.Empty().ToIArray(); - BimDocumentVersion = BimDocumentEntityTable?.GetStringColumnValues("string:Version") ?? Array.Empty().ToIArray(); - BimDocumentUser = BimDocumentEntityTable?.GetStringColumnValues("string:User") ?? Array.Empty().ToIArray(); - BimDocumentFileLength = BimDocumentEntityTable?.GetDataColumnValues("long:FileLength") ?? Array.Empty().ToIArray(); - PhaseOrderInBimDocumentOrderIndex = PhaseOrderInBimDocumentEntityTable?.GetDataColumnValues("int:OrderIndex") ?? Array.Empty().ToIArray(); - CategoryName = CategoryEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - CategoryId = (CategoryEntityTable?.GetDataColumnValues("long:Id") ?? CategoryEntityTable?.GetDataColumnValues("int:Id")?.Select(v => (Int64) v)) ?? Array.Empty().ToIArray(); - CategoryCategoryType = CategoryEntityTable?.GetStringColumnValues("string:CategoryType") ?? Array.Empty().ToIArray(); - CategoryLineColor_X = CategoryEntityTable?.GetDataColumnValues("double:LineColor.X") ?? Array.Empty().ToIArray(); - CategoryLineColor_Y = CategoryEntityTable?.GetDataColumnValues("double:LineColor.Y") ?? Array.Empty().ToIArray(); - CategoryLineColor_Z = CategoryEntityTable?.GetDataColumnValues("double:LineColor.Z") ?? Array.Empty().ToIArray(); - CategoryBuiltInCategory = CategoryEntityTable?.GetStringColumnValues("string:BuiltInCategory") ?? Array.Empty().ToIArray(); - FamilyStructuralMaterialType = FamilyEntityTable?.GetStringColumnValues("string:StructuralMaterialType") ?? Array.Empty().ToIArray(); - FamilyStructuralSectionShape = FamilyEntityTable?.GetStringColumnValues("string:StructuralSectionShape") ?? Array.Empty().ToIArray(); - FamilyIsSystemFamily = FamilyEntityTable?.GetDataColumnValues("byte:IsSystemFamily") ?? Array.Empty().ToIArray(); - FamilyIsInPlace = FamilyEntityTable?.GetDataColumnValues("byte:IsInPlace") ?? Array.Empty().ToIArray(); - FamilyTypeIsSystemFamilyType = FamilyTypeEntityTable?.GetDataColumnValues("byte:IsSystemFamilyType") ?? Array.Empty().ToIArray(); - FamilyInstanceFacingFlipped = FamilyInstanceEntityTable?.GetDataColumnValues("byte:FacingFlipped") ?? Array.Empty().ToIArray(); - FamilyInstanceFacingOrientation_X = FamilyInstanceEntityTable?.GetDataColumnValues("float:FacingOrientation.X") ?? Array.Empty().ToIArray(); - FamilyInstanceFacingOrientation_Y = FamilyInstanceEntityTable?.GetDataColumnValues("float:FacingOrientation.Y") ?? Array.Empty().ToIArray(); - FamilyInstanceFacingOrientation_Z = FamilyInstanceEntityTable?.GetDataColumnValues("float:FacingOrientation.Z") ?? Array.Empty().ToIArray(); - FamilyInstanceHandFlipped = FamilyInstanceEntityTable?.GetDataColumnValues("byte:HandFlipped") ?? Array.Empty().ToIArray(); - FamilyInstanceMirrored = FamilyInstanceEntityTable?.GetDataColumnValues("byte:Mirrored") ?? Array.Empty().ToIArray(); - FamilyInstanceHasModifiedGeometry = FamilyInstanceEntityTable?.GetDataColumnValues("byte:HasModifiedGeometry") ?? Array.Empty().ToIArray(); - FamilyInstanceScale = FamilyInstanceEntityTable?.GetDataColumnValues("float:Scale") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisX_X = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisX.X") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisX_Y = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisX.Y") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisX_Z = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisX.Z") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisY_X = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisY.X") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisY_Y = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisY.Y") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisY_Z = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisY.Z") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisZ_X = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisZ.X") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisZ_Y = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisZ.Y") ?? Array.Empty().ToIArray(); - FamilyInstanceBasisZ_Z = FamilyInstanceEntityTable?.GetDataColumnValues("float:BasisZ.Z") ?? Array.Empty().ToIArray(); - FamilyInstanceTranslation_X = FamilyInstanceEntityTable?.GetDataColumnValues("float:Translation.X") ?? Array.Empty().ToIArray(); - FamilyInstanceTranslation_Y = FamilyInstanceEntityTable?.GetDataColumnValues("float:Translation.Y") ?? Array.Empty().ToIArray(); - FamilyInstanceTranslation_Z = FamilyInstanceEntityTable?.GetDataColumnValues("float:Translation.Z") ?? Array.Empty().ToIArray(); - FamilyInstanceHandOrientation_X = FamilyInstanceEntityTable?.GetDataColumnValues("float:HandOrientation.X") ?? Array.Empty().ToIArray(); - FamilyInstanceHandOrientation_Y = FamilyInstanceEntityTable?.GetDataColumnValues("float:HandOrientation.Y") ?? Array.Empty().ToIArray(); - FamilyInstanceHandOrientation_Z = FamilyInstanceEntityTable?.GetDataColumnValues("float:HandOrientation.Z") ?? Array.Empty().ToIArray(); - ViewTitle = ViewEntityTable?.GetStringColumnValues("string:Title") ?? Array.Empty().ToIArray(); - ViewViewType = ViewEntityTable?.GetStringColumnValues("string:ViewType") ?? Array.Empty().ToIArray(); - ViewUp_X = ViewEntityTable?.GetDataColumnValues("double:Up.X") ?? Array.Empty().ToIArray(); - ViewUp_Y = ViewEntityTable?.GetDataColumnValues("double:Up.Y") ?? Array.Empty().ToIArray(); - ViewUp_Z = ViewEntityTable?.GetDataColumnValues("double:Up.Z") ?? Array.Empty().ToIArray(); - ViewRight_X = ViewEntityTable?.GetDataColumnValues("double:Right.X") ?? Array.Empty().ToIArray(); - ViewRight_Y = ViewEntityTable?.GetDataColumnValues("double:Right.Y") ?? Array.Empty().ToIArray(); - ViewRight_Z = ViewEntityTable?.GetDataColumnValues("double:Right.Z") ?? Array.Empty().ToIArray(); - ViewOrigin_X = ViewEntityTable?.GetDataColumnValues("double:Origin.X") ?? Array.Empty().ToIArray(); - ViewOrigin_Y = ViewEntityTable?.GetDataColumnValues("double:Origin.Y") ?? Array.Empty().ToIArray(); - ViewOrigin_Z = ViewEntityTable?.GetDataColumnValues("double:Origin.Z") ?? Array.Empty().ToIArray(); - ViewViewDirection_X = ViewEntityTable?.GetDataColumnValues("double:ViewDirection.X") ?? Array.Empty().ToIArray(); - ViewViewDirection_Y = ViewEntityTable?.GetDataColumnValues("double:ViewDirection.Y") ?? Array.Empty().ToIArray(); - ViewViewDirection_Z = ViewEntityTable?.GetDataColumnValues("double:ViewDirection.Z") ?? Array.Empty().ToIArray(); - ViewViewPosition_X = ViewEntityTable?.GetDataColumnValues("double:ViewPosition.X") ?? Array.Empty().ToIArray(); - ViewViewPosition_Y = ViewEntityTable?.GetDataColumnValues("double:ViewPosition.Y") ?? Array.Empty().ToIArray(); - ViewViewPosition_Z = ViewEntityTable?.GetDataColumnValues("double:ViewPosition.Z") ?? Array.Empty().ToIArray(); - ViewScale = ViewEntityTable?.GetDataColumnValues("double:Scale") ?? Array.Empty().ToIArray(); - ViewOutline_Min_X = ViewEntityTable?.GetDataColumnValues("double:Outline.Min.X") ?? Array.Empty().ToIArray(); - ViewOutline_Min_Y = ViewEntityTable?.GetDataColumnValues("double:Outline.Min.Y") ?? Array.Empty().ToIArray(); - ViewOutline_Max_X = ViewEntityTable?.GetDataColumnValues("double:Outline.Max.X") ?? Array.Empty().ToIArray(); - ViewOutline_Max_Y = ViewEntityTable?.GetDataColumnValues("double:Outline.Max.Y") ?? Array.Empty().ToIArray(); - ViewDetailLevel = ViewEntityTable?.GetDataColumnValues("int:DetailLevel") ?? Array.Empty().ToIArray(); - LevelInViewExtents_Min_X = LevelInViewEntityTable?.GetDataColumnValues("double:Extents.Min.X") ?? Array.Empty().ToIArray(); - LevelInViewExtents_Min_Y = LevelInViewEntityTable?.GetDataColumnValues("double:Extents.Min.Y") ?? Array.Empty().ToIArray(); - LevelInViewExtents_Min_Z = LevelInViewEntityTable?.GetDataColumnValues("double:Extents.Min.Z") ?? Array.Empty().ToIArray(); - LevelInViewExtents_Max_X = LevelInViewEntityTable?.GetDataColumnValues("double:Extents.Max.X") ?? Array.Empty().ToIArray(); - LevelInViewExtents_Max_Y = LevelInViewEntityTable?.GetDataColumnValues("double:Extents.Max.Y") ?? Array.Empty().ToIArray(); - LevelInViewExtents_Max_Z = LevelInViewEntityTable?.GetDataColumnValues("double:Extents.Max.Z") ?? Array.Empty().ToIArray(); - CameraId = CameraEntityTable?.GetDataColumnValues("int:Id") ?? Array.Empty().ToIArray(); - CameraIsPerspective = CameraEntityTable?.GetDataColumnValues("int:IsPerspective") ?? Array.Empty().ToIArray(); - CameraVerticalExtent = CameraEntityTable?.GetDataColumnValues("double:VerticalExtent") ?? Array.Empty().ToIArray(); - CameraHorizontalExtent = CameraEntityTable?.GetDataColumnValues("double:HorizontalExtent") ?? Array.Empty().ToIArray(); - CameraFarDistance = CameraEntityTable?.GetDataColumnValues("double:FarDistance") ?? Array.Empty().ToIArray(); - CameraNearDistance = CameraEntityTable?.GetDataColumnValues("double:NearDistance") ?? Array.Empty().ToIArray(); - CameraTargetDistance = CameraEntityTable?.GetDataColumnValues("double:TargetDistance") ?? Array.Empty().ToIArray(); - CameraRightOffset = CameraEntityTable?.GetDataColumnValues("double:RightOffset") ?? Array.Empty().ToIArray(); - CameraUpOffset = CameraEntityTable?.GetDataColumnValues("double:UpOffset") ?? Array.Empty().ToIArray(); - MaterialName = MaterialEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - MaterialMaterialCategory = MaterialEntityTable?.GetStringColumnValues("string:MaterialCategory") ?? Array.Empty().ToIArray(); - MaterialColor_X = MaterialEntityTable?.GetDataColumnValues("double:Color.X") ?? Array.Empty().ToIArray(); - MaterialColor_Y = MaterialEntityTable?.GetDataColumnValues("double:Color.Y") ?? Array.Empty().ToIArray(); - MaterialColor_Z = MaterialEntityTable?.GetDataColumnValues("double:Color.Z") ?? Array.Empty().ToIArray(); - MaterialColorUvScaling_X = MaterialEntityTable?.GetDataColumnValues("double:ColorUvScaling.X") ?? Array.Empty().ToIArray(); - MaterialColorUvScaling_Y = MaterialEntityTable?.GetDataColumnValues("double:ColorUvScaling.Y") ?? Array.Empty().ToIArray(); - MaterialColorUvOffset_X = MaterialEntityTable?.GetDataColumnValues("double:ColorUvOffset.X") ?? Array.Empty().ToIArray(); - MaterialColorUvOffset_Y = MaterialEntityTable?.GetDataColumnValues("double:ColorUvOffset.Y") ?? Array.Empty().ToIArray(); - MaterialNormalUvScaling_X = MaterialEntityTable?.GetDataColumnValues("double:NormalUvScaling.X") ?? Array.Empty().ToIArray(); - MaterialNormalUvScaling_Y = MaterialEntityTable?.GetDataColumnValues("double:NormalUvScaling.Y") ?? Array.Empty().ToIArray(); - MaterialNormalUvOffset_X = MaterialEntityTable?.GetDataColumnValues("double:NormalUvOffset.X") ?? Array.Empty().ToIArray(); - MaterialNormalUvOffset_Y = MaterialEntityTable?.GetDataColumnValues("double:NormalUvOffset.Y") ?? Array.Empty().ToIArray(); - MaterialNormalAmount = MaterialEntityTable?.GetDataColumnValues("double:NormalAmount") ?? Array.Empty().ToIArray(); - MaterialGlossiness = MaterialEntityTable?.GetDataColumnValues("double:Glossiness") ?? Array.Empty().ToIArray(); - MaterialSmoothness = MaterialEntityTable?.GetDataColumnValues("double:Smoothness") ?? Array.Empty().ToIArray(); - MaterialTransparency = MaterialEntityTable?.GetDataColumnValues("double:Transparency") ?? Array.Empty().ToIArray(); - MaterialInElementArea = MaterialInElementEntityTable?.GetDataColumnValues("double:Area") ?? Array.Empty().ToIArray(); - MaterialInElementVolume = MaterialInElementEntityTable?.GetDataColumnValues("double:Volume") ?? Array.Empty().ToIArray(); - MaterialInElementIsPaint = MaterialInElementEntityTable?.GetDataColumnValues("byte:IsPaint") ?? Array.Empty().ToIArray(); - CompoundStructureLayerOrderIndex = CompoundStructureLayerEntityTable?.GetDataColumnValues("int:OrderIndex") ?? Array.Empty().ToIArray(); - CompoundStructureLayerWidth = CompoundStructureLayerEntityTable?.GetDataColumnValues("double:Width") ?? Array.Empty().ToIArray(); - CompoundStructureLayerMaterialFunctionAssignment = CompoundStructureLayerEntityTable?.GetStringColumnValues("string:MaterialFunctionAssignment") ?? Array.Empty().ToIArray(); - CompoundStructureWidth = CompoundStructureEntityTable?.GetDataColumnValues("double:Width") ?? Array.Empty().ToIArray(); - GeometryBox_Min_X = GeometryEntityTable?.GetDataColumnValues("float:Box.Min.X") ?? Array.Empty().ToIArray(); - GeometryBox_Min_Y = GeometryEntityTable?.GetDataColumnValues("float:Box.Min.Y") ?? Array.Empty().ToIArray(); - GeometryBox_Min_Z = GeometryEntityTable?.GetDataColumnValues("float:Box.Min.Z") ?? Array.Empty().ToIArray(); - GeometryBox_Max_X = GeometryEntityTable?.GetDataColumnValues("float:Box.Max.X") ?? Array.Empty().ToIArray(); - GeometryBox_Max_Y = GeometryEntityTable?.GetDataColumnValues("float:Box.Max.Y") ?? Array.Empty().ToIArray(); - GeometryBox_Max_Z = GeometryEntityTable?.GetDataColumnValues("float:Box.Max.Z") ?? Array.Empty().ToIArray(); - GeometryVertexCount = GeometryEntityTable?.GetDataColumnValues("int:VertexCount") ?? Array.Empty().ToIArray(); - GeometryFaceCount = GeometryEntityTable?.GetDataColumnValues("int:FaceCount") ?? Array.Empty().ToIArray(); - SystemSystemType = SystemEntityTable?.GetDataColumnValues("int:SystemType") ?? Array.Empty().ToIArray(); - ElementInSystemRoles = ElementInSystemEntityTable?.GetDataColumnValues("int:Roles") ?? Array.Empty().ToIArray(); - WarningGuid = WarningEntityTable?.GetStringColumnValues("string:Guid") ?? Array.Empty().ToIArray(); - WarningSeverity = WarningEntityTable?.GetStringColumnValues("string:Severity") ?? Array.Empty().ToIArray(); - WarningDescription = WarningEntityTable?.GetStringColumnValues("string:Description") ?? Array.Empty().ToIArray(); - BasePointIsSurveyPoint = BasePointEntityTable?.GetDataColumnValues("byte:IsSurveyPoint") ?? Array.Empty().ToIArray(); - BasePointPosition_X = BasePointEntityTable?.GetDataColumnValues("double:Position.X") ?? Array.Empty().ToIArray(); - BasePointPosition_Y = BasePointEntityTable?.GetDataColumnValues("double:Position.Y") ?? Array.Empty().ToIArray(); - BasePointPosition_Z = BasePointEntityTable?.GetDataColumnValues("double:Position.Z") ?? Array.Empty().ToIArray(); - BasePointSharedPosition_X = BasePointEntityTable?.GetDataColumnValues("double:SharedPosition.X") ?? Array.Empty().ToIArray(); - BasePointSharedPosition_Y = BasePointEntityTable?.GetDataColumnValues("double:SharedPosition.Y") ?? Array.Empty().ToIArray(); - BasePointSharedPosition_Z = BasePointEntityTable?.GetDataColumnValues("double:SharedPosition.Z") ?? Array.Empty().ToIArray(); - PhaseFilterNew = PhaseFilterEntityTable?.GetDataColumnValues("int:New") ?? Array.Empty().ToIArray(); - PhaseFilterExisting = PhaseFilterEntityTable?.GetDataColumnValues("int:Existing") ?? Array.Empty().ToIArray(); - PhaseFilterDemolished = PhaseFilterEntityTable?.GetDataColumnValues("int:Demolished") ?? Array.Empty().ToIArray(); - PhaseFilterTemporary = PhaseFilterEntityTable?.GetDataColumnValues("int:Temporary") ?? Array.Empty().ToIArray(); - GridStartPoint_X = GridEntityTable?.GetDataColumnValues("double:StartPoint.X") ?? Array.Empty().ToIArray(); - GridStartPoint_Y = GridEntityTable?.GetDataColumnValues("double:StartPoint.Y") ?? Array.Empty().ToIArray(); - GridStartPoint_Z = GridEntityTable?.GetDataColumnValues("double:StartPoint.Z") ?? Array.Empty().ToIArray(); - GridEndPoint_X = GridEntityTable?.GetDataColumnValues("double:EndPoint.X") ?? Array.Empty().ToIArray(); - GridEndPoint_Y = GridEntityTable?.GetDataColumnValues("double:EndPoint.Y") ?? Array.Empty().ToIArray(); - GridEndPoint_Z = GridEntityTable?.GetDataColumnValues("double:EndPoint.Z") ?? Array.Empty().ToIArray(); - GridIsCurved = GridEntityTable?.GetDataColumnValues("byte:IsCurved") ?? Array.Empty().ToIArray(); - GridExtents_Min_X = GridEntityTable?.GetDataColumnValues("double:Extents.Min.X") ?? Array.Empty().ToIArray(); - GridExtents_Min_Y = GridEntityTable?.GetDataColumnValues("double:Extents.Min.Y") ?? Array.Empty().ToIArray(); - GridExtents_Min_Z = GridEntityTable?.GetDataColumnValues("double:Extents.Min.Z") ?? Array.Empty().ToIArray(); - GridExtents_Max_X = GridEntityTable?.GetDataColumnValues("double:Extents.Max.X") ?? Array.Empty().ToIArray(); - GridExtents_Max_Y = GridEntityTable?.GetDataColumnValues("double:Extents.Max.Y") ?? Array.Empty().ToIArray(); - GridExtents_Max_Z = GridEntityTable?.GetDataColumnValues("double:Extents.Max.Z") ?? Array.Empty().ToIArray(); - AreaValue = AreaEntityTable?.GetDataColumnValues("double:Value") ?? Array.Empty().ToIArray(); - AreaPerimeter = AreaEntityTable?.GetDataColumnValues("double:Perimeter") ?? Array.Empty().ToIArray(); - AreaNumber = AreaEntityTable?.GetStringColumnValues("string:Number") ?? Array.Empty().ToIArray(); - AreaIsGrossInterior = AreaEntityTable?.GetDataColumnValues("byte:IsGrossInterior") ?? Array.Empty().ToIArray(); - AreaSchemeIsGrossBuildingArea = AreaSchemeEntityTable?.GetDataColumnValues("byte:IsGrossBuildingArea") ?? Array.Empty().ToIArray(); - ScheduleColumnName = ScheduleColumnEntityTable?.GetStringColumnValues("string:Name") ?? Array.Empty().ToIArray(); - ScheduleColumnColumnIndex = ScheduleColumnEntityTable?.GetDataColumnValues("int:ColumnIndex") ?? Array.Empty().ToIArray(); - ScheduleCellValue = ScheduleCellEntityTable?.GetStringColumnValues("string:Value") ?? Array.Empty().ToIArray(); - ScheduleCellRowIndex = ScheduleCellEntityTable?.GetDataColumnValues("int:RowIndex") ?? Array.Empty().ToIArray(); - SiteLatitude = SiteEntityTable?.GetDataColumnValues("double:Latitude") ?? Array.Empty().ToIArray(); - SiteLongitude = SiteEntityTable?.GetDataColumnValues("double:Longitude") ?? Array.Empty().ToIArray(); - SiteAddress = SiteEntityTable?.GetStringColumnValues("string:Address") ?? Array.Empty().ToIArray(); - SiteElevation = SiteEntityTable?.GetDataColumnValues("double:Elevation") ?? Array.Empty().ToIArray(); - SiteNumber = SiteEntityTable?.GetStringColumnValues("string:Number") ?? Array.Empty().ToIArray(); - BuildingElevation = BuildingEntityTable?.GetDataColumnValues("double:Elevation") ?? Array.Empty().ToIArray(); - BuildingTerrainElevation = BuildingEntityTable?.GetDataColumnValues("double:TerrainElevation") ?? Array.Empty().ToIArray(); - BuildingAddress = BuildingEntityTable?.GetStringColumnValues("string:Address") ?? Array.Empty().ToIArray(); - - // Initialize entity relational columns - ParameterDescriptorDisplayUnitIndex = ParameterDescriptorEntityTable?.GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty().ToIArray(); - ParameterParameterDescriptorIndex = ParameterEntityTable?.GetIndexColumnValues("index:Vim.ParameterDescriptor:ParameterDescriptor") ?? Array.Empty().ToIArray(); - ParameterElementIndex = ParameterEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ElementLevelIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Level:Level") ?? Array.Empty().ToIArray(); - ElementPhaseCreatedIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Phase:PhaseCreated") ?? Array.Empty().ToIArray(); - ElementPhaseDemolishedIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Phase:PhaseDemolished") ?? Array.Empty().ToIArray(); - ElementCategoryIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Category:Category") ?? Array.Empty().ToIArray(); - ElementWorksetIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Workset:Workset") ?? Array.Empty().ToIArray(); - ElementDesignOptionIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.DesignOption:DesignOption") ?? Array.Empty().ToIArray(); - ElementOwnerViewIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.View:OwnerView") ?? Array.Empty().ToIArray(); - ElementGroupIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Group:Group") ?? Array.Empty().ToIArray(); - ElementAssemblyInstanceIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.AssemblyInstance:AssemblyInstance") ?? Array.Empty().ToIArray(); - ElementBimDocumentIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty().ToIArray(); - ElementRoomIndex = ElementEntityTable?.GetIndexColumnValues("index:Vim.Room:Room") ?? Array.Empty().ToIArray(); - WorksetBimDocumentIndex = WorksetEntityTable?.GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty().ToIArray(); - AssemblyInstanceElementIndex = AssemblyInstanceEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - GroupElementIndex = GroupEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - DesignOptionElementIndex = DesignOptionEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - LevelFamilyTypeIndex = LevelEntityTable?.GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty().ToIArray(); - LevelBuildingIndex = LevelEntityTable?.GetIndexColumnValues("index:Vim.Building:Building") ?? Array.Empty().ToIArray(); - LevelElementIndex = LevelEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - PhaseElementIndex = PhaseEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - RoomUpperLimitIndex = RoomEntityTable?.GetIndexColumnValues("index:Vim.Level:UpperLimit") ?? Array.Empty().ToIArray(); - RoomElementIndex = RoomEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - BimDocumentActiveViewIndex = BimDocumentEntityTable?.GetIndexColumnValues("index:Vim.View:ActiveView") ?? Array.Empty().ToIArray(); - BimDocumentOwnerFamilyIndex = BimDocumentEntityTable?.GetIndexColumnValues("index:Vim.Family:OwnerFamily") ?? Array.Empty().ToIArray(); - BimDocumentParentIndex = BimDocumentEntityTable?.GetIndexColumnValues("index:Vim.BimDocument:Parent") ?? Array.Empty().ToIArray(); - BimDocumentElementIndex = BimDocumentEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - DisplayUnitInBimDocumentDisplayUnitIndex = DisplayUnitInBimDocumentEntityTable?.GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty().ToIArray(); - DisplayUnitInBimDocumentBimDocumentIndex = DisplayUnitInBimDocumentEntityTable?.GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty().ToIArray(); - PhaseOrderInBimDocumentPhaseIndex = PhaseOrderInBimDocumentEntityTable?.GetIndexColumnValues("index:Vim.Phase:Phase") ?? Array.Empty().ToIArray(); - PhaseOrderInBimDocumentBimDocumentIndex = PhaseOrderInBimDocumentEntityTable?.GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty().ToIArray(); - CategoryParentIndex = CategoryEntityTable?.GetIndexColumnValues("index:Vim.Category:Parent") ?? Array.Empty().ToIArray(); - CategoryMaterialIndex = CategoryEntityTable?.GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty().ToIArray(); - FamilyFamilyCategoryIndex = FamilyEntityTable?.GetIndexColumnValues("index:Vim.Category:FamilyCategory") ?? Array.Empty().ToIArray(); - FamilyElementIndex = FamilyEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - FamilyTypeFamilyIndex = FamilyTypeEntityTable?.GetIndexColumnValues("index:Vim.Family:Family") ?? Array.Empty().ToIArray(); - FamilyTypeCompoundStructureIndex = FamilyTypeEntityTable?.GetIndexColumnValues("index:Vim.CompoundStructure:CompoundStructure") ?? Array.Empty().ToIArray(); - FamilyTypeElementIndex = FamilyTypeEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - FamilyInstanceFamilyTypeIndex = FamilyInstanceEntityTable?.GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty().ToIArray(); - FamilyInstanceHostIndex = FamilyInstanceEntityTable?.GetIndexColumnValues("index:Vim.Element:Host") ?? Array.Empty().ToIArray(); - FamilyInstanceFromRoomIndex = FamilyInstanceEntityTable?.GetIndexColumnValues("index:Vim.Room:FromRoom") ?? Array.Empty().ToIArray(); - FamilyInstanceToRoomIndex = FamilyInstanceEntityTable?.GetIndexColumnValues("index:Vim.Room:ToRoom") ?? Array.Empty().ToIArray(); - FamilyInstanceSuperComponentIndex = FamilyInstanceEntityTable?.GetIndexColumnValues("index:Vim.Element:SuperComponent") ?? Array.Empty().ToIArray(); - FamilyInstanceElementIndex = FamilyInstanceEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ViewCameraIndex = ViewEntityTable?.GetIndexColumnValues("index:Vim.Camera:Camera") ?? Array.Empty().ToIArray(); - ViewFamilyTypeIndex = ViewEntityTable?.GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty().ToIArray(); - ViewElementIndex = ViewEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ElementInViewViewIndex = ElementInViewEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); - ElementInViewElementIndex = ElementInViewEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ShapeInViewShapeIndex = ShapeInViewEntityTable?.GetIndexColumnValues("index:Vim.Shape:Shape") ?? Array.Empty().ToIArray(); - ShapeInViewViewIndex = ShapeInViewEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); - AssetInViewAssetIndex = AssetInViewEntityTable?.GetIndexColumnValues("index:Vim.Asset:Asset") ?? Array.Empty().ToIArray(); - AssetInViewViewIndex = AssetInViewEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); - AssetInViewSheetAssetIndex = AssetInViewSheetEntityTable?.GetIndexColumnValues("index:Vim.Asset:Asset") ?? Array.Empty().ToIArray(); - AssetInViewSheetViewSheetIndex = AssetInViewSheetEntityTable?.GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty().ToIArray(); - LevelInViewLevelIndex = LevelInViewEntityTable?.GetIndexColumnValues("index:Vim.Level:Level") ?? Array.Empty().ToIArray(); - LevelInViewViewIndex = LevelInViewEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); - MaterialColorTextureFileIndex = MaterialEntityTable?.GetIndexColumnValues("index:Vim.Asset:ColorTextureFile") ?? Array.Empty().ToIArray(); - MaterialNormalTextureFileIndex = MaterialEntityTable?.GetIndexColumnValues("index:Vim.Asset:NormalTextureFile") ?? Array.Empty().ToIArray(); - MaterialElementIndex = MaterialEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - MaterialInElementMaterialIndex = MaterialInElementEntityTable?.GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty().ToIArray(); - MaterialInElementElementIndex = MaterialInElementEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - CompoundStructureLayerMaterialIndex = CompoundStructureLayerEntityTable?.GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty().ToIArray(); - CompoundStructureLayerCompoundStructureIndex = CompoundStructureLayerEntityTable?.GetIndexColumnValues("index:Vim.CompoundStructure:CompoundStructure") ?? Array.Empty().ToIArray(); - CompoundStructureStructuralLayerIndex = CompoundStructureEntityTable?.GetIndexColumnValues("index:Vim.CompoundStructureLayer:StructuralLayer") ?? Array.Empty().ToIArray(); - NodeElementIndex = NodeEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ShapeElementIndex = ShapeEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ShapeCollectionElementIndex = ShapeCollectionEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ShapeInShapeCollectionShapeIndex = ShapeInShapeCollectionEntityTable?.GetIndexColumnValues("index:Vim.Shape:Shape") ?? Array.Empty().ToIArray(); - ShapeInShapeCollectionShapeCollectionIndex = ShapeInShapeCollectionEntityTable?.GetIndexColumnValues("index:Vim.ShapeCollection:ShapeCollection") ?? Array.Empty().ToIArray(); - SystemFamilyTypeIndex = SystemEntityTable?.GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty().ToIArray(); - SystemElementIndex = SystemEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ElementInSystemSystemIndex = ElementInSystemEntityTable?.GetIndexColumnValues("index:Vim.System:System") ?? Array.Empty().ToIArray(); - ElementInSystemElementIndex = ElementInSystemEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - WarningBimDocumentIndex = WarningEntityTable?.GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty().ToIArray(); - ElementInWarningWarningIndex = ElementInWarningEntityTable?.GetIndexColumnValues("index:Vim.Warning:Warning") ?? Array.Empty().ToIArray(); - ElementInWarningElementIndex = ElementInWarningEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - BasePointElementIndex = BasePointEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - PhaseFilterElementIndex = PhaseFilterEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - GridFamilyTypeIndex = GridEntityTable?.GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty().ToIArray(); - GridElementIndex = GridEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - AreaAreaSchemeIndex = AreaEntityTable?.GetIndexColumnValues("index:Vim.AreaScheme:AreaScheme") ?? Array.Empty().ToIArray(); - AreaElementIndex = AreaEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - AreaSchemeElementIndex = AreaSchemeEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ScheduleElementIndex = ScheduleEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ScheduleColumnScheduleIndex = ScheduleColumnEntityTable?.GetIndexColumnValues("index:Vim.Schedule:Schedule") ?? Array.Empty().ToIArray(); - ScheduleCellScheduleColumnIndex = ScheduleCellEntityTable?.GetIndexColumnValues("index:Vim.ScheduleColumn:ScheduleColumn") ?? Array.Empty().ToIArray(); - ViewSheetSetElementIndex = ViewSheetSetEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ViewSheetFamilyTypeIndex = ViewSheetEntityTable?.GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty().ToIArray(); - ViewSheetElementIndex = ViewSheetEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - ViewSheetInViewSheetSetViewSheetIndex = ViewSheetInViewSheetSetEntityTable?.GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty().ToIArray(); - ViewSheetInViewSheetSetViewSheetSetIndex = ViewSheetInViewSheetSetEntityTable?.GetIndexColumnValues("index:Vim.ViewSheetSet:ViewSheetSet") ?? Array.Empty().ToIArray(); - ViewInViewSheetSetViewIndex = ViewInViewSheetSetEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); - ViewInViewSheetSetViewSheetSetIndex = ViewInViewSheetSetEntityTable?.GetIndexColumnValues("index:Vim.ViewSheetSet:ViewSheetSet") ?? Array.Empty().ToIArray(); - ViewInViewSheetViewIndex = ViewInViewSheetEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); - ViewInViewSheetViewSheetIndex = ViewInViewSheetEntityTable?.GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty().ToIArray(); - SiteElementIndex = SiteEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - BuildingSiteIndex = BuildingEntityTable?.GetIndexColumnValues("index:Vim.Site:Site") ?? Array.Empty().ToIArray(); - BuildingElementIndex = BuildingEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); - - // Initialize entity collections - AssetList = NumAsset.Select(i => GetAsset(i)); - DisplayUnitList = NumDisplayUnit.Select(i => GetDisplayUnit(i)); - ParameterDescriptorList = NumParameterDescriptor.Select(i => GetParameterDescriptor(i)); - ParameterList = NumParameter.Select(i => GetParameter(i)); - ElementList = NumElement.Select(i => GetElement(i)); - WorksetList = NumWorkset.Select(i => GetWorkset(i)); - AssemblyInstanceList = NumAssemblyInstance.Select(i => GetAssemblyInstance(i)); - GroupList = NumGroup.Select(i => GetGroup(i)); - DesignOptionList = NumDesignOption.Select(i => GetDesignOption(i)); - LevelList = NumLevel.Select(i => GetLevel(i)); - PhaseList = NumPhase.Select(i => GetPhase(i)); - RoomList = NumRoom.Select(i => GetRoom(i)); - BimDocumentList = NumBimDocument.Select(i => GetBimDocument(i)); - DisplayUnitInBimDocumentList = NumDisplayUnitInBimDocument.Select(i => GetDisplayUnitInBimDocument(i)); - PhaseOrderInBimDocumentList = NumPhaseOrderInBimDocument.Select(i => GetPhaseOrderInBimDocument(i)); - CategoryList = NumCategory.Select(i => GetCategory(i)); - FamilyList = NumFamily.Select(i => GetFamily(i)); - FamilyTypeList = NumFamilyType.Select(i => GetFamilyType(i)); - FamilyInstanceList = NumFamilyInstance.Select(i => GetFamilyInstance(i)); - ViewList = NumView.Select(i => GetView(i)); - ElementInViewList = NumElementInView.Select(i => GetElementInView(i)); - ShapeInViewList = NumShapeInView.Select(i => GetShapeInView(i)); - AssetInViewList = NumAssetInView.Select(i => GetAssetInView(i)); - AssetInViewSheetList = NumAssetInViewSheet.Select(i => GetAssetInViewSheet(i)); - LevelInViewList = NumLevelInView.Select(i => GetLevelInView(i)); - CameraList = NumCamera.Select(i => GetCamera(i)); - MaterialList = NumMaterial.Select(i => GetMaterial(i)); - MaterialInElementList = NumMaterialInElement.Select(i => GetMaterialInElement(i)); - CompoundStructureLayerList = NumCompoundStructureLayer.Select(i => GetCompoundStructureLayer(i)); - CompoundStructureList = NumCompoundStructure.Select(i => GetCompoundStructure(i)); - NodeList = NumNode.Select(i => GetNode(i)); - GeometryList = NumGeometry.Select(i => GetGeometry(i)); - ShapeList = NumShape.Select(i => GetShape(i)); - ShapeCollectionList = NumShapeCollection.Select(i => GetShapeCollection(i)); - ShapeInShapeCollectionList = NumShapeInShapeCollection.Select(i => GetShapeInShapeCollection(i)); - SystemList = NumSystem.Select(i => GetSystem(i)); - ElementInSystemList = NumElementInSystem.Select(i => GetElementInSystem(i)); - WarningList = NumWarning.Select(i => GetWarning(i)); - ElementInWarningList = NumElementInWarning.Select(i => GetElementInWarning(i)); - BasePointList = NumBasePoint.Select(i => GetBasePoint(i)); - PhaseFilterList = NumPhaseFilter.Select(i => GetPhaseFilter(i)); - GridList = NumGrid.Select(i => GetGrid(i)); - AreaList = NumArea.Select(i => GetArea(i)); - AreaSchemeList = NumAreaScheme.Select(i => GetAreaScheme(i)); - ScheduleList = NumSchedule.Select(i => GetSchedule(i)); - ScheduleColumnList = NumScheduleColumn.Select(i => GetScheduleColumn(i)); - ScheduleCellList = NumScheduleCell.Select(i => GetScheduleCell(i)); - ViewSheetSetList = NumViewSheetSet.Select(i => GetViewSheetSet(i)); - ViewSheetList = NumViewSheet.Select(i => GetViewSheet(i)); - ViewSheetInViewSheetSetList = NumViewSheetInViewSheetSet.Select(i => GetViewSheetInViewSheetSet(i)); - ViewInViewSheetSetList = NumViewInViewSheetSet.Select(i => GetViewInViewSheetSet(i)); - ViewInViewSheetList = NumViewInViewSheet.Select(i => GetViewInViewSheet(i)); - SiteList = NumSite.Select(i => GetSite(i)); - BuildingList = NumBuilding.Select(i => GetBuilding(i)); - - // Initialize element index maps - ElementIndexMaps = new ElementIndexMaps(this, inParallel); - } - } // Document class - - public partial class EntityTableSet - { - public string[] StringTable { get; } - - public Dictionary RawTableMap { get; } = new Dictionary(); - - public Dictionary Tables { get; } = new Dictionary(); - - public SerializableEntityTable GetSerializableTableOrEmpty(string tableName) - => RawTableMap.TryGetValue(tableName, out var result) ? result : new SerializableEntityTable { Name = tableName }; - - public ElementIndexMaps ElementIndexMaps { get; } - - public EntityTableSet(SerializableEntityTable[] rawTables, string[] stringTable, bool inParallel = true) - { - StringTable = stringTable; - - foreach (var rawTable in rawTables) - RawTableMap[rawTable.Name] = rawTable; - - // Populate the entity tables. - Tables[TableNames.Asset] = AssetTable = new AssetTable(GetSerializableTableOrEmpty(TableNames.Asset), stringTable, this); - Tables[TableNames.DisplayUnit] = DisplayUnitTable = new DisplayUnitTable(GetSerializableTableOrEmpty(TableNames.DisplayUnit), stringTable, this); - Tables[TableNames.ParameterDescriptor] = ParameterDescriptorTable = new ParameterDescriptorTable(GetSerializableTableOrEmpty(TableNames.ParameterDescriptor), stringTable, this); - Tables[TableNames.Parameter] = ParameterTable = new ParameterTable(GetSerializableTableOrEmpty(TableNames.Parameter), stringTable, this); - Tables[TableNames.Element] = ElementTable = new ElementTable(GetSerializableTableOrEmpty(TableNames.Element), stringTable, this); - Tables[TableNames.Workset] = WorksetTable = new WorksetTable(GetSerializableTableOrEmpty(TableNames.Workset), stringTable, this); - Tables[TableNames.AssemblyInstance] = AssemblyInstanceTable = new AssemblyInstanceTable(GetSerializableTableOrEmpty(TableNames.AssemblyInstance), stringTable, this); - Tables[TableNames.Group] = GroupTable = new GroupTable(GetSerializableTableOrEmpty(TableNames.Group), stringTable, this); - Tables[TableNames.DesignOption] = DesignOptionTable = new DesignOptionTable(GetSerializableTableOrEmpty(TableNames.DesignOption), stringTable, this); - Tables[TableNames.Level] = LevelTable = new LevelTable(GetSerializableTableOrEmpty(TableNames.Level), stringTable, this); - Tables[TableNames.Phase] = PhaseTable = new PhaseTable(GetSerializableTableOrEmpty(TableNames.Phase), stringTable, this); - Tables[TableNames.Room] = RoomTable = new RoomTable(GetSerializableTableOrEmpty(TableNames.Room), stringTable, this); - Tables[TableNames.BimDocument] = BimDocumentTable = new BimDocumentTable(GetSerializableTableOrEmpty(TableNames.BimDocument), stringTable, this); - Tables[TableNames.DisplayUnitInBimDocument] = DisplayUnitInBimDocumentTable = new DisplayUnitInBimDocumentTable(GetSerializableTableOrEmpty(TableNames.DisplayUnitInBimDocument), stringTable, this); - Tables[TableNames.PhaseOrderInBimDocument] = PhaseOrderInBimDocumentTable = new PhaseOrderInBimDocumentTable(GetSerializableTableOrEmpty(TableNames.PhaseOrderInBimDocument), stringTable, this); - Tables[TableNames.Category] = CategoryTable = new CategoryTable(GetSerializableTableOrEmpty(TableNames.Category), stringTable, this); - Tables[TableNames.Family] = FamilyTable = new FamilyTable(GetSerializableTableOrEmpty(TableNames.Family), stringTable, this); - Tables[TableNames.FamilyType] = FamilyTypeTable = new FamilyTypeTable(GetSerializableTableOrEmpty(TableNames.FamilyType), stringTable, this); - Tables[TableNames.FamilyInstance] = FamilyInstanceTable = new FamilyInstanceTable(GetSerializableTableOrEmpty(TableNames.FamilyInstance), stringTable, this); - Tables[TableNames.View] = ViewTable = new ViewTable(GetSerializableTableOrEmpty(TableNames.View), stringTable, this); - Tables[TableNames.ElementInView] = ElementInViewTable = new ElementInViewTable(GetSerializableTableOrEmpty(TableNames.ElementInView), stringTable, this); - Tables[TableNames.ShapeInView] = ShapeInViewTable = new ShapeInViewTable(GetSerializableTableOrEmpty(TableNames.ShapeInView), stringTable, this); - Tables[TableNames.AssetInView] = AssetInViewTable = new AssetInViewTable(GetSerializableTableOrEmpty(TableNames.AssetInView), stringTable, this); - Tables[TableNames.AssetInViewSheet] = AssetInViewSheetTable = new AssetInViewSheetTable(GetSerializableTableOrEmpty(TableNames.AssetInViewSheet), stringTable, this); - Tables[TableNames.LevelInView] = LevelInViewTable = new LevelInViewTable(GetSerializableTableOrEmpty(TableNames.LevelInView), stringTable, this); - Tables[TableNames.Camera] = CameraTable = new CameraTable(GetSerializableTableOrEmpty(TableNames.Camera), stringTable, this); - Tables[TableNames.Material] = MaterialTable = new MaterialTable(GetSerializableTableOrEmpty(TableNames.Material), stringTable, this); - Tables[TableNames.MaterialInElement] = MaterialInElementTable = new MaterialInElementTable(GetSerializableTableOrEmpty(TableNames.MaterialInElement), stringTable, this); - Tables[TableNames.CompoundStructureLayer] = CompoundStructureLayerTable = new CompoundStructureLayerTable(GetSerializableTableOrEmpty(TableNames.CompoundStructureLayer), stringTable, this); - Tables[TableNames.CompoundStructure] = CompoundStructureTable = new CompoundStructureTable(GetSerializableTableOrEmpty(TableNames.CompoundStructure), stringTable, this); - Tables[TableNames.Node] = NodeTable = new NodeTable(GetSerializableTableOrEmpty(TableNames.Node), stringTable, this); - Tables[TableNames.Geometry] = GeometryTable = new GeometryTable(GetSerializableTableOrEmpty(TableNames.Geometry), stringTable, this); - Tables[TableNames.Shape] = ShapeTable = new ShapeTable(GetSerializableTableOrEmpty(TableNames.Shape), stringTable, this); - Tables[TableNames.ShapeCollection] = ShapeCollectionTable = new ShapeCollectionTable(GetSerializableTableOrEmpty(TableNames.ShapeCollection), stringTable, this); - Tables[TableNames.ShapeInShapeCollection] = ShapeInShapeCollectionTable = new ShapeInShapeCollectionTable(GetSerializableTableOrEmpty(TableNames.ShapeInShapeCollection), stringTable, this); - Tables[TableNames.System] = SystemTable = new SystemTable(GetSerializableTableOrEmpty(TableNames.System), stringTable, this); - Tables[TableNames.ElementInSystem] = ElementInSystemTable = new ElementInSystemTable(GetSerializableTableOrEmpty(TableNames.ElementInSystem), stringTable, this); - Tables[TableNames.Warning] = WarningTable = new WarningTable(GetSerializableTableOrEmpty(TableNames.Warning), stringTable, this); - Tables[TableNames.ElementInWarning] = ElementInWarningTable = new ElementInWarningTable(GetSerializableTableOrEmpty(TableNames.ElementInWarning), stringTable, this); - Tables[TableNames.BasePoint] = BasePointTable = new BasePointTable(GetSerializableTableOrEmpty(TableNames.BasePoint), stringTable, this); - Tables[TableNames.PhaseFilter] = PhaseFilterTable = new PhaseFilterTable(GetSerializableTableOrEmpty(TableNames.PhaseFilter), stringTable, this); - Tables[TableNames.Grid] = GridTable = new GridTable(GetSerializableTableOrEmpty(TableNames.Grid), stringTable, this); - Tables[TableNames.Area] = AreaTable = new AreaTable(GetSerializableTableOrEmpty(TableNames.Area), stringTable, this); - Tables[TableNames.AreaScheme] = AreaSchemeTable = new AreaSchemeTable(GetSerializableTableOrEmpty(TableNames.AreaScheme), stringTable, this); - Tables[TableNames.Schedule] = ScheduleTable = new ScheduleTable(GetSerializableTableOrEmpty(TableNames.Schedule), stringTable, this); - Tables[TableNames.ScheduleColumn] = ScheduleColumnTable = new ScheduleColumnTable(GetSerializableTableOrEmpty(TableNames.ScheduleColumn), stringTable, this); - Tables[TableNames.ScheduleCell] = ScheduleCellTable = new ScheduleCellTable(GetSerializableTableOrEmpty(TableNames.ScheduleCell), stringTable, this); - Tables[TableNames.ViewSheetSet] = ViewSheetSetTable = new ViewSheetSetTable(GetSerializableTableOrEmpty(TableNames.ViewSheetSet), stringTable, this); - Tables[TableNames.ViewSheet] = ViewSheetTable = new ViewSheetTable(GetSerializableTableOrEmpty(TableNames.ViewSheet), stringTable, this); - Tables[TableNames.ViewSheetInViewSheetSet] = ViewSheetInViewSheetSetTable = new ViewSheetInViewSheetSetTable(GetSerializableTableOrEmpty(TableNames.ViewSheetInViewSheetSet), stringTable, this); - Tables[TableNames.ViewInViewSheetSet] = ViewInViewSheetSetTable = new ViewInViewSheetSetTable(GetSerializableTableOrEmpty(TableNames.ViewInViewSheetSet), stringTable, this); - Tables[TableNames.ViewInViewSheet] = ViewInViewSheetTable = new ViewInViewSheetTable(GetSerializableTableOrEmpty(TableNames.ViewInViewSheet), stringTable, this); - Tables[TableNames.Site] = SiteTable = new SiteTable(GetSerializableTableOrEmpty(TableNames.Site), stringTable, this); - Tables[TableNames.Building] = BuildingTable = new BuildingTable(GetSerializableTableOrEmpty(TableNames.Building), stringTable, this); - - // Initialize element index maps - ElementIndexMaps = new ElementIndexMaps(this, inParallel); - - } // EntityTableSet constructor - - public AssetTable AssetTable { get; } // can be null - public Asset GetAsset(int index) => AssetTable?.Get(index); - public DisplayUnitTable DisplayUnitTable { get; } // can be null - public DisplayUnit GetDisplayUnit(int index) => DisplayUnitTable?.Get(index); - public ParameterDescriptorTable ParameterDescriptorTable { get; } // can be null - public ParameterDescriptor GetParameterDescriptor(int index) => ParameterDescriptorTable?.Get(index); - public ParameterTable ParameterTable { get; } // can be null - public Parameter GetParameter(int index) => ParameterTable?.Get(index); - public ElementTable ElementTable { get; } // can be null - public Element GetElement(int index) => ElementTable?.Get(index); - public WorksetTable WorksetTable { get; } // can be null - public Workset GetWorkset(int index) => WorksetTable?.Get(index); - public AssemblyInstanceTable AssemblyInstanceTable { get; } // can be null - public AssemblyInstance GetAssemblyInstance(int index) => AssemblyInstanceTable?.Get(index); - public GroupTable GroupTable { get; } // can be null - public Group GetGroup(int index) => GroupTable?.Get(index); - public DesignOptionTable DesignOptionTable { get; } // can be null - public DesignOption GetDesignOption(int index) => DesignOptionTable?.Get(index); - public LevelTable LevelTable { get; } // can be null - public Level GetLevel(int index) => LevelTable?.Get(index); - public PhaseTable PhaseTable { get; } // can be null - public Phase GetPhase(int index) => PhaseTable?.Get(index); - public RoomTable RoomTable { get; } // can be null - public Room GetRoom(int index) => RoomTable?.Get(index); - public BimDocumentTable BimDocumentTable { get; } // can be null - public BimDocument GetBimDocument(int index) => BimDocumentTable?.Get(index); - public DisplayUnitInBimDocumentTable DisplayUnitInBimDocumentTable { get; } // can be null - public DisplayUnitInBimDocument GetDisplayUnitInBimDocument(int index) => DisplayUnitInBimDocumentTable?.Get(index); - public PhaseOrderInBimDocumentTable PhaseOrderInBimDocumentTable { get; } // can be null - public PhaseOrderInBimDocument GetPhaseOrderInBimDocument(int index) => PhaseOrderInBimDocumentTable?.Get(index); - public CategoryTable CategoryTable { get; } // can be null - public Category GetCategory(int index) => CategoryTable?.Get(index); - public FamilyTable FamilyTable { get; } // can be null - public Family GetFamily(int index) => FamilyTable?.Get(index); - public FamilyTypeTable FamilyTypeTable { get; } // can be null - public FamilyType GetFamilyType(int index) => FamilyTypeTable?.Get(index); - public FamilyInstanceTable FamilyInstanceTable { get; } // can be null - public FamilyInstance GetFamilyInstance(int index) => FamilyInstanceTable?.Get(index); - public ViewTable ViewTable { get; } // can be null - public View GetView(int index) => ViewTable?.Get(index); - public ElementInViewTable ElementInViewTable { get; } // can be null - public ElementInView GetElementInView(int index) => ElementInViewTable?.Get(index); - public ShapeInViewTable ShapeInViewTable { get; } // can be null - public ShapeInView GetShapeInView(int index) => ShapeInViewTable?.Get(index); - public AssetInViewTable AssetInViewTable { get; } // can be null - public AssetInView GetAssetInView(int index) => AssetInViewTable?.Get(index); - public AssetInViewSheetTable AssetInViewSheetTable { get; } // can be null - public AssetInViewSheet GetAssetInViewSheet(int index) => AssetInViewSheetTable?.Get(index); - public LevelInViewTable LevelInViewTable { get; } // can be null - public LevelInView GetLevelInView(int index) => LevelInViewTable?.Get(index); - public CameraTable CameraTable { get; } // can be null - public Camera GetCamera(int index) => CameraTable?.Get(index); - public MaterialTable MaterialTable { get; } // can be null - public Material GetMaterial(int index) => MaterialTable?.Get(index); - public MaterialInElementTable MaterialInElementTable { get; } // can be null - public MaterialInElement GetMaterialInElement(int index) => MaterialInElementTable?.Get(index); - public CompoundStructureLayerTable CompoundStructureLayerTable { get; } // can be null - public CompoundStructureLayer GetCompoundStructureLayer(int index) => CompoundStructureLayerTable?.Get(index); - public CompoundStructureTable CompoundStructureTable { get; } // can be null - public CompoundStructure GetCompoundStructure(int index) => CompoundStructureTable?.Get(index); - public NodeTable NodeTable { get; } // can be null - public Node GetNode(int index) => NodeTable?.Get(index); - public GeometryTable GeometryTable { get; } // can be null - public Geometry GetGeometry(int index) => GeometryTable?.Get(index); - public ShapeTable ShapeTable { get; } // can be null - public Shape GetShape(int index) => ShapeTable?.Get(index); - public ShapeCollectionTable ShapeCollectionTable { get; } // can be null - public ShapeCollection GetShapeCollection(int index) => ShapeCollectionTable?.Get(index); - public ShapeInShapeCollectionTable ShapeInShapeCollectionTable { get; } // can be null - public ShapeInShapeCollection GetShapeInShapeCollection(int index) => ShapeInShapeCollectionTable?.Get(index); - public SystemTable SystemTable { get; } // can be null - public System GetSystem(int index) => SystemTable?.Get(index); - public ElementInSystemTable ElementInSystemTable { get; } // can be null - public ElementInSystem GetElementInSystem(int index) => ElementInSystemTable?.Get(index); - public WarningTable WarningTable { get; } // can be null - public Warning GetWarning(int index) => WarningTable?.Get(index); - public ElementInWarningTable ElementInWarningTable { get; } // can be null - public ElementInWarning GetElementInWarning(int index) => ElementInWarningTable?.Get(index); - public BasePointTable BasePointTable { get; } // can be null - public BasePoint GetBasePoint(int index) => BasePointTable?.Get(index); - public PhaseFilterTable PhaseFilterTable { get; } // can be null - public PhaseFilter GetPhaseFilter(int index) => PhaseFilterTable?.Get(index); - public GridTable GridTable { get; } // can be null - public Grid GetGrid(int index) => GridTable?.Get(index); - public AreaTable AreaTable { get; } // can be null - public Area GetArea(int index) => AreaTable?.Get(index); - public AreaSchemeTable AreaSchemeTable { get; } // can be null - public AreaScheme GetAreaScheme(int index) => AreaSchemeTable?.Get(index); - public ScheduleTable ScheduleTable { get; } // can be null - public Schedule GetSchedule(int index) => ScheduleTable?.Get(index); - public ScheduleColumnTable ScheduleColumnTable { get; } // can be null - public ScheduleColumn GetScheduleColumn(int index) => ScheduleColumnTable?.Get(index); - public ScheduleCellTable ScheduleCellTable { get; } // can be null - public ScheduleCell GetScheduleCell(int index) => ScheduleCellTable?.Get(index); - public ViewSheetSetTable ViewSheetSetTable { get; } // can be null - public ViewSheetSet GetViewSheetSet(int index) => ViewSheetSetTable?.Get(index); - public ViewSheetTable ViewSheetTable { get; } // can be null - public ViewSheet GetViewSheet(int index) => ViewSheetTable?.Get(index); - public ViewSheetInViewSheetSetTable ViewSheetInViewSheetSetTable { get; } // can be null - public ViewSheetInViewSheetSet GetViewSheetInViewSheetSet(int index) => ViewSheetInViewSheetSetTable?.Get(index); - public ViewInViewSheetSetTable ViewInViewSheetSetTable { get; } // can be null - public ViewInViewSheetSet GetViewInViewSheetSet(int index) => ViewInViewSheetSetTable?.Get(index); - public ViewInViewSheetTable ViewInViewSheetTable { get; } // can be null - public ViewInViewSheet GetViewInViewSheet(int index) => ViewInViewSheetTable?.Get(index); - public SiteTable SiteTable { get; } // can be null - public Site GetSite(int index) => SiteTable?.Get(index); - public BuildingTable BuildingTable { get; } // can be null - public Building GetBuilding(int index) => BuildingTable?.Get(index); - - public static HashSet GetElementKindTableNames() - => new HashSet() - { - TableNames.AssemblyInstance, - TableNames.Group, - TableNames.DesignOption, - TableNames.Level, - TableNames.Phase, - TableNames.Room, - TableNames.BimDocument, - TableNames.Family, - TableNames.FamilyType, - TableNames.FamilyInstance, - TableNames.View, - TableNames.Material, - TableNames.System, - TableNames.BasePoint, - TableNames.PhaseFilter, - TableNames.Grid, - TableNames.Area, - TableNames.AreaScheme, - TableNames.Schedule, - TableNames.ViewSheetSet, - TableNames.ViewSheet, - TableNames.Site, - TableNames.Building, - }; - - // Returns an array defining a 1:1 association of Element to its ElementKind - public ElementKind[] GetElementKinds() - { - var elementKinds = new ElementKind[ElementTable?.RowCount ?? 0]; - - if (elementKinds.Length == 0) return elementKinds; - - // Initialize all element kinds to unknown - for (var i = 0; i < elementKinds.Length; ++i) { elementKinds[i] = ElementKind.Unknown; } - - // Populate the element kinds from the relevant entity tables - for (var i = 0; i < (AssemblyInstanceTable?.RowCount ?? 0); ++i) - { - var elementIndex = AssemblyInstanceTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.AssemblyInstance; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (GroupTable?.RowCount ?? 0); ++i) - { - var elementIndex = GroupTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Group; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (DesignOptionTable?.RowCount ?? 0); ++i) - { - var elementIndex = DesignOptionTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.DesignOption; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (LevelTable?.RowCount ?? 0); ++i) - { - var elementIndex = LevelTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Level; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (PhaseTable?.RowCount ?? 0); ++i) - { - var elementIndex = PhaseTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Phase; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (RoomTable?.RowCount ?? 0); ++i) - { - var elementIndex = RoomTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Room; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (BimDocumentTable?.RowCount ?? 0); ++i) - { - var elementIndex = BimDocumentTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.BimDocument; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (FamilyTable?.RowCount ?? 0); ++i) - { - var elementIndex = FamilyTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Family; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (FamilyTypeTable?.RowCount ?? 0); ++i) - { - var elementIndex = FamilyTypeTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.FamilyType; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (FamilyInstanceTable?.RowCount ?? 0); ++i) - { - var elementIndex = FamilyInstanceTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.FamilyInstance; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (ViewTable?.RowCount ?? 0); ++i) - { - var elementIndex = ViewTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.View; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (MaterialTable?.RowCount ?? 0); ++i) - { - var elementIndex = MaterialTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Material; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (SystemTable?.RowCount ?? 0); ++i) - { - var elementIndex = SystemTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.System; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (BasePointTable?.RowCount ?? 0); ++i) - { - var elementIndex = BasePointTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.BasePoint; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (PhaseFilterTable?.RowCount ?? 0); ++i) - { - var elementIndex = PhaseFilterTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.PhaseFilter; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (GridTable?.RowCount ?? 0); ++i) - { - var elementIndex = GridTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Grid; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (AreaTable?.RowCount ?? 0); ++i) - { - var elementIndex = AreaTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Area; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (AreaSchemeTable?.RowCount ?? 0); ++i) - { - var elementIndex = AreaSchemeTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.AreaScheme; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (ScheduleTable?.RowCount ?? 0); ++i) - { - var elementIndex = ScheduleTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Schedule; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (ViewSheetSetTable?.RowCount ?? 0); ++i) - { - var elementIndex = ViewSheetSetTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.ViewSheetSet; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (ViewSheetTable?.RowCount ?? 0); ++i) - { - var elementIndex = ViewSheetTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.ViewSheet; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (SiteTable?.RowCount ?? 0); ++i) - { - var elementIndex = SiteTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Site; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - for (var i = 0; i < (BuildingTable?.RowCount ?? 0); ++i) - { - var elementIndex = BuildingTable?.Column_ElementIndex[i] ?? EntityRelation.None; - if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; - - var currentElementKind = elementKinds[elementIndex]; - var candidateElementKind = ElementKind.Building; - - // Only update the element kind if it is unknown or if it is less than the current kind. - if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; - - elementKinds[elementIndex] = candidateElementKind; - } - - return elementKinds; - } // GetElementKinds() - } // class EntityTableSet - - public partial class AssetTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Asset; - - public EntityTableSet ParentTableSet { get; } // can be null - - public AssetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_BufferName = GetStringColumnValues("string:BufferName") ?? Array.Empty(); - } - - public String[] Column_BufferName { get; } - public String GetBufferName(int index, String @default = "") => Column_BufferName.ElementAtOrDefault(index, @default); - // Object Getter - public Asset Get(int index) - { - if (index < 0) return null; - var r = new Asset(); - r.Index = index; - r.BufferName = GetBufferName(index); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class AssetTable - - public partial class DisplayUnitTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.DisplayUnit; - - public EntityTableSet ParentTableSet { get; } // can be null - - public DisplayUnitTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Spec = GetStringColumnValues("string:Spec") ?? Array.Empty(); - Column_Type = GetStringColumnValues("string:Type") ?? Array.Empty(); - Column_Label = GetStringColumnValues("string:Label") ?? Array.Empty(); - } - - public String[] Column_Spec { get; } - public String GetSpec(int index, String @default = "") => Column_Spec.ElementAtOrDefault(index, @default); - public String[] Column_Type { get; } - public String GetType(int index, String @default = "") => Column_Type.ElementAtOrDefault(index, @default); - public String[] Column_Label { get; } - public String GetLabel(int index, String @default = "") => Column_Label.ElementAtOrDefault(index, @default); - // Object Getter - public DisplayUnit Get(int index) - { - if (index < 0) return null; - var r = new DisplayUnit(); - r.Index = index; - r.Spec = GetSpec(index); - r.Type = GetType(index); - r.Label = GetLabel(index); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class DisplayUnitTable - - public partial class ParameterDescriptorTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ParameterDescriptor; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ParameterDescriptorTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_Group = GetStringColumnValues("string:Group") ?? Array.Empty(); - Column_ParameterType = GetStringColumnValues("string:ParameterType") ?? Array.Empty(); - Column_IsInstance = GetDataColumnValues("byte:IsInstance") ?? Array.Empty(); - Column_IsShared = GetDataColumnValues("byte:IsShared") ?? Array.Empty(); - Column_IsReadOnly = GetDataColumnValues("byte:IsReadOnly") ?? Array.Empty(); - Column_Flags = GetDataColumnValues("int:Flags") ?? Array.Empty(); - Column_Guid = GetStringColumnValues("string:Guid") ?? Array.Empty(); - Column_StorageType = GetDataColumnValues("int:StorageType") ?? Array.Empty(); - Column_DisplayUnitIndex = GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty(); - } - - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public String[] Column_Group { get; } - public String GetGroup(int index, String @default = "") => Column_Group.ElementAtOrDefault(index, @default); - public String[] Column_ParameterType { get; } - public String GetParameterType(int index, String @default = "") => Column_ParameterType.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsInstance { get; } - public Boolean GetIsInstance(int index, Boolean @default = default) => Column_IsInstance.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsShared { get; } - public Boolean GetIsShared(int index, Boolean @default = default) => Column_IsShared.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsReadOnly { get; } - public Boolean GetIsReadOnly(int index, Boolean @default = default) => Column_IsReadOnly.ElementAtOrDefault(index, @default); - public Int32[] Column_Flags { get; } - public Int32 GetFlags(int index, Int32 @default = default) => Column_Flags.ElementAtOrDefault(index, @default); - public String[] Column_Guid { get; } - public String GetGuid(int index, String @default = "") => Column_Guid.ElementAtOrDefault(index, @default); - public Int32[] Column_StorageType { get; } - public Int32 GetStorageType(int index, Int32 @default = default) => Column_StorageType.ElementAtOrDefault(index, @default); - public int[] Column_DisplayUnitIndex { get; } - public int GetDisplayUnitIndex(int index) => Column_DisplayUnitIndex.ElementAtOrDefault(index, EntityRelation.None); - public DisplayUnit GetDisplayUnit(int index) => _GetReferencedDisplayUnit(GetDisplayUnitIndex(index)); - private DisplayUnit _GetReferencedDisplayUnit(int referencedIndex) => ParentTableSet.GetDisplayUnit(referencedIndex); - // Object Getter - public ParameterDescriptor Get(int index) - { - if (index < 0) return null; - var r = new ParameterDescriptor(); - r.Index = index; - r.Name = GetName(index); - r.Group = GetGroup(index); - r.ParameterType = GetParameterType(index); - r.IsInstance = GetIsInstance(index); - r.IsShared = GetIsShared(index); - r.IsReadOnly = GetIsReadOnly(index); - r.Flags = GetFlags(index); - r.Guid = GetGuid(index); - r.StorageType = GetStorageType(index); - r._DisplayUnit = new Relation(GetDisplayUnitIndex(index), _GetReferencedDisplayUnit); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ParameterDescriptorTable - - public partial class ParameterTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Parameter; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ParameterTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Value = GetStringColumnValues("string:Value") ?? Array.Empty(); - Column_ParameterDescriptorIndex = GetIndexColumnValues("index:Vim.ParameterDescriptor:ParameterDescriptor") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_Value { get; } - public String GetValue(int index, String @default = "") => Column_Value.ElementAtOrDefault(index, @default); - public int[] Column_ParameterDescriptorIndex { get; } - public int GetParameterDescriptorIndex(int index) => Column_ParameterDescriptorIndex.ElementAtOrDefault(index, EntityRelation.None); - public ParameterDescriptor GetParameterDescriptor(int index) => _GetReferencedParameterDescriptor(GetParameterDescriptorIndex(index)); - private ParameterDescriptor _GetReferencedParameterDescriptor(int referencedIndex) => ParentTableSet.GetParameterDescriptor(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Parameter Get(int index) - { - if (index < 0) return null; - var r = new Parameter(); - r.Index = index; - r.Value = GetValue(index); - r._ParameterDescriptor = new Relation(GetParameterDescriptorIndex(index), _GetReferencedParameterDescriptor); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ParameterTable - - public partial class ElementTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Element; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ElementTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Id = (GetDataColumnValues("long:Id") ?? GetDataColumnValues("int:Id")?.Select(v => (Int64) v).ToArray()) ?? Array.Empty(); - Column_Type = GetStringColumnValues("string:Type") ?? Array.Empty(); - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_UniqueId = GetStringColumnValues("string:UniqueId") ?? Array.Empty(); - Column_Location_X = GetDataColumnValues("float:Location.X") ?? Array.Empty(); - Column_Location_Y = GetDataColumnValues("float:Location.Y") ?? Array.Empty(); - Column_Location_Z = GetDataColumnValues("float:Location.Z") ?? Array.Empty(); - Column_FamilyName = GetStringColumnValues("string:FamilyName") ?? Array.Empty(); - Column_IsPinned = GetDataColumnValues("byte:IsPinned") ?? Array.Empty(); - Column_LevelIndex = GetIndexColumnValues("index:Vim.Level:Level") ?? Array.Empty(); - Column_PhaseCreatedIndex = GetIndexColumnValues("index:Vim.Phase:PhaseCreated") ?? Array.Empty(); - Column_PhaseDemolishedIndex = GetIndexColumnValues("index:Vim.Phase:PhaseDemolished") ?? Array.Empty(); - Column_CategoryIndex = GetIndexColumnValues("index:Vim.Category:Category") ?? Array.Empty(); - Column_WorksetIndex = GetIndexColumnValues("index:Vim.Workset:Workset") ?? Array.Empty(); - Column_DesignOptionIndex = GetIndexColumnValues("index:Vim.DesignOption:DesignOption") ?? Array.Empty(); - Column_OwnerViewIndex = GetIndexColumnValues("index:Vim.View:OwnerView") ?? Array.Empty(); - Column_GroupIndex = GetIndexColumnValues("index:Vim.Group:Group") ?? Array.Empty(); - Column_AssemblyInstanceIndex = GetIndexColumnValues("index:Vim.AssemblyInstance:AssemblyInstance") ?? Array.Empty(); - Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); - Column_RoomIndex = GetIndexColumnValues("index:Vim.Room:Room") ?? Array.Empty(); - } - - public Int64[] Column_Id { get; } - public Int64 GetId(int index, Int64 @default = default) => Column_Id.ElementAtOrDefault(index, @default); - public String[] Column_Type { get; } - public String GetType(int index, String @default = "") => Column_Type.ElementAtOrDefault(index, @default); - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public String[] Column_UniqueId { get; } - public String GetUniqueId(int index, String @default = "") => Column_UniqueId.ElementAtOrDefault(index, @default); - public Single[] Column_Location_X { get; } - public Single GetLocation_X(int index, Single @default = default) => Column_Location_X.ElementAtOrDefault(index, @default); - public Single[] Column_Location_Y { get; } - public Single GetLocation_Y(int index, Single @default = default) => Column_Location_Y.ElementAtOrDefault(index, @default); - public Single[] Column_Location_Z { get; } - public Single GetLocation_Z(int index, Single @default = default) => Column_Location_Z.ElementAtOrDefault(index, @default); - public String[] Column_FamilyName { get; } - public String GetFamilyName(int index, String @default = "") => Column_FamilyName.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsPinned { get; } - public Boolean GetIsPinned(int index, Boolean @default = default) => Column_IsPinned.ElementAtOrDefault(index, @default); - public int[] Column_LevelIndex { get; } - public int GetLevelIndex(int index) => Column_LevelIndex.ElementAtOrDefault(index, EntityRelation.None); - public Level GetLevel(int index) => _GetReferencedLevel(GetLevelIndex(index)); - private Level _GetReferencedLevel(int referencedIndex) => ParentTableSet.GetLevel(referencedIndex); - public int[] Column_PhaseCreatedIndex { get; } - public int GetPhaseCreatedIndex(int index) => Column_PhaseCreatedIndex.ElementAtOrDefault(index, EntityRelation.None); - public Phase GetPhaseCreated(int index) => _GetReferencedPhaseCreated(GetPhaseCreatedIndex(index)); - private Phase _GetReferencedPhaseCreated(int referencedIndex) => ParentTableSet.GetPhase(referencedIndex); - public int[] Column_PhaseDemolishedIndex { get; } - public int GetPhaseDemolishedIndex(int index) => Column_PhaseDemolishedIndex.ElementAtOrDefault(index, EntityRelation.None); - public Phase GetPhaseDemolished(int index) => _GetReferencedPhaseDemolished(GetPhaseDemolishedIndex(index)); - private Phase _GetReferencedPhaseDemolished(int referencedIndex) => ParentTableSet.GetPhase(referencedIndex); - public int[] Column_CategoryIndex { get; } - public int GetCategoryIndex(int index) => Column_CategoryIndex.ElementAtOrDefault(index, EntityRelation.None); - public Category GetCategory(int index) => _GetReferencedCategory(GetCategoryIndex(index)); - private Category _GetReferencedCategory(int referencedIndex) => ParentTableSet.GetCategory(referencedIndex); - public int[] Column_WorksetIndex { get; } - public int GetWorksetIndex(int index) => Column_WorksetIndex.ElementAtOrDefault(index, EntityRelation.None); - public Workset GetWorkset(int index) => _GetReferencedWorkset(GetWorksetIndex(index)); - private Workset _GetReferencedWorkset(int referencedIndex) => ParentTableSet.GetWorkset(referencedIndex); - public int[] Column_DesignOptionIndex { get; } - public int GetDesignOptionIndex(int index) => Column_DesignOptionIndex.ElementAtOrDefault(index, EntityRelation.None); - public DesignOption GetDesignOption(int index) => _GetReferencedDesignOption(GetDesignOptionIndex(index)); - private DesignOption _GetReferencedDesignOption(int referencedIndex) => ParentTableSet.GetDesignOption(referencedIndex); - public int[] Column_OwnerViewIndex { get; } - public int GetOwnerViewIndex(int index) => Column_OwnerViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetOwnerView(int index) => _GetReferencedOwnerView(GetOwnerViewIndex(index)); - private View _GetReferencedOwnerView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - public int[] Column_GroupIndex { get; } - public int GetGroupIndex(int index) => Column_GroupIndex.ElementAtOrDefault(index, EntityRelation.None); - public Group GetGroup(int index) => _GetReferencedGroup(GetGroupIndex(index)); - private Group _GetReferencedGroup(int referencedIndex) => ParentTableSet.GetGroup(referencedIndex); - public int[] Column_AssemblyInstanceIndex { get; } - public int GetAssemblyInstanceIndex(int index) => Column_AssemblyInstanceIndex.ElementAtOrDefault(index, EntityRelation.None); - public AssemblyInstance GetAssemblyInstance(int index) => _GetReferencedAssemblyInstance(GetAssemblyInstanceIndex(index)); - private AssemblyInstance _GetReferencedAssemblyInstance(int referencedIndex) => ParentTableSet.GetAssemblyInstance(referencedIndex); - public int[] Column_BimDocumentIndex { get; } - public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); - public BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); - private BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); - public int[] Column_RoomIndex { get; } - public int GetRoomIndex(int index) => Column_RoomIndex.ElementAtOrDefault(index, EntityRelation.None); - public Room GetRoom(int index) => _GetReferencedRoom(GetRoomIndex(index)); - private Room _GetReferencedRoom(int referencedIndex) => ParentTableSet.GetRoom(referencedIndex); - // Object Getter - public Element Get(int index) - { - if (index < 0) return null; - var r = new Element(); - r.Index = index; - r.Id = GetId(index); - r.Type = GetType(index); - r.Name = GetName(index); - r.UniqueId = GetUniqueId(index); - r.Location_X = GetLocation_X(index); - r.Location_Y = GetLocation_Y(index); - r.Location_Z = GetLocation_Z(index); - r.FamilyName = GetFamilyName(index); - r.IsPinned = GetIsPinned(index); - r._Level = new Relation(GetLevelIndex(index), _GetReferencedLevel); - r._PhaseCreated = new Relation(GetPhaseCreatedIndex(index), _GetReferencedPhaseCreated); - r._PhaseDemolished = new Relation(GetPhaseDemolishedIndex(index), _GetReferencedPhaseDemolished); - r._Category = new Relation(GetCategoryIndex(index), _GetReferencedCategory); - r._Workset = new Relation(GetWorksetIndex(index), _GetReferencedWorkset); - r._DesignOption = new Relation(GetDesignOptionIndex(index), _GetReferencedDesignOption); - r._OwnerView = new Relation(GetOwnerViewIndex(index), _GetReferencedOwnerView); - r._Group = new Relation(GetGroupIndex(index), _GetReferencedGroup); - r._AssemblyInstance = new Relation(GetAssemblyInstanceIndex(index), _GetReferencedAssemblyInstance); - r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); - r._Room = new Relation(GetRoomIndex(index), _GetReferencedRoom); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ElementTable - - public partial class WorksetTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Workset; - - public EntityTableSet ParentTableSet { get; } // can be null - - public WorksetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Id = GetDataColumnValues("int:Id") ?? Array.Empty(); - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_Kind = GetStringColumnValues("string:Kind") ?? Array.Empty(); - Column_IsOpen = GetDataColumnValues("byte:IsOpen") ?? Array.Empty(); - Column_IsEditable = GetDataColumnValues("byte:IsEditable") ?? Array.Empty(); - Column_Owner = GetStringColumnValues("string:Owner") ?? Array.Empty(); - Column_UniqueId = GetStringColumnValues("string:UniqueId") ?? Array.Empty(); - Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); - } - - public Int32[] Column_Id { get; } - public Int32 GetId(int index, Int32 @default = default) => Column_Id.ElementAtOrDefault(index, @default); - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public String[] Column_Kind { get; } - public String GetKind(int index, String @default = "") => Column_Kind.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsOpen { get; } - public Boolean GetIsOpen(int index, Boolean @default = default) => Column_IsOpen.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsEditable { get; } - public Boolean GetIsEditable(int index, Boolean @default = default) => Column_IsEditable.ElementAtOrDefault(index, @default); - public String[] Column_Owner { get; } - public String GetOwner(int index, String @default = "") => Column_Owner.ElementAtOrDefault(index, @default); - public String[] Column_UniqueId { get; } - public String GetUniqueId(int index, String @default = "") => Column_UniqueId.ElementAtOrDefault(index, @default); - public int[] Column_BimDocumentIndex { get; } - public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); - public BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); - private BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); - // Object Getter - public Workset Get(int index) - { - if (index < 0) return null; - var r = new Workset(); - r.Index = index; - r.Id = GetId(index); - r.Name = GetName(index); - r.Kind = GetKind(index); - r.IsOpen = GetIsOpen(index); - r.IsEditable = GetIsEditable(index); - r.Owner = GetOwner(index); - r.UniqueId = GetUniqueId(index); - r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class WorksetTable - - public partial class AssemblyInstanceTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.AssemblyInstance; - - public EntityTableSet ParentTableSet { get; } // can be null - - public AssemblyInstanceTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_AssemblyTypeName = GetStringColumnValues("string:AssemblyTypeName") ?? Array.Empty(); - Column_Position_X = GetDataColumnValues("float:Position.X") ?? Array.Empty(); - Column_Position_Y = GetDataColumnValues("float:Position.Y") ?? Array.Empty(); - Column_Position_Z = GetDataColumnValues("float:Position.Z") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_AssemblyTypeName { get; } - public String GetAssemblyTypeName(int index, String @default = "") => Column_AssemblyTypeName.ElementAtOrDefault(index, @default); - public Single[] Column_Position_X { get; } - public Single GetPosition_X(int index, Single @default = default) => Column_Position_X.ElementAtOrDefault(index, @default); - public Single[] Column_Position_Y { get; } - public Single GetPosition_Y(int index, Single @default = default) => Column_Position_Y.ElementAtOrDefault(index, @default); - public Single[] Column_Position_Z { get; } - public Single GetPosition_Z(int index, Single @default = default) => Column_Position_Z.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public AssemblyInstance Get(int index) - { - if (index < 0) return null; - var r = new AssemblyInstance(); - r.Index = index; - r.AssemblyTypeName = GetAssemblyTypeName(index); - r.Position_X = GetPosition_X(index); - r.Position_Y = GetPosition_Y(index); - r.Position_Z = GetPosition_Z(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class AssemblyInstanceTable - - public partial class GroupTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Group; - - public EntityTableSet ParentTableSet { get; } // can be null - - public GroupTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_GroupType = GetStringColumnValues("string:GroupType") ?? Array.Empty(); - Column_Position_X = GetDataColumnValues("float:Position.X") ?? Array.Empty(); - Column_Position_Y = GetDataColumnValues("float:Position.Y") ?? Array.Empty(); - Column_Position_Z = GetDataColumnValues("float:Position.Z") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_GroupType { get; } - public String GetGroupType(int index, String @default = "") => Column_GroupType.ElementAtOrDefault(index, @default); - public Single[] Column_Position_X { get; } - public Single GetPosition_X(int index, Single @default = default) => Column_Position_X.ElementAtOrDefault(index, @default); - public Single[] Column_Position_Y { get; } - public Single GetPosition_Y(int index, Single @default = default) => Column_Position_Y.ElementAtOrDefault(index, @default); - public Single[] Column_Position_Z { get; } - public Single GetPosition_Z(int index, Single @default = default) => Column_Position_Z.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Group Get(int index) - { - if (index < 0) return null; - var r = new Group(); - r.Index = index; - r.GroupType = GetGroupType(index); - r.Position_X = GetPosition_X(index); - r.Position_Y = GetPosition_Y(index); - r.Position_Z = GetPosition_Z(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class GroupTable - - public partial class DesignOptionTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.DesignOption; - - public EntityTableSet ParentTableSet { get; } // can be null - - public DesignOptionTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_IsPrimary = GetDataColumnValues("byte:IsPrimary") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Boolean[] Column_IsPrimary { get; } - public Boolean GetIsPrimary(int index, Boolean @default = default) => Column_IsPrimary.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public DesignOption Get(int index) - { - if (index < 0) return null; - var r = new DesignOption(); - r.Index = index; - r.IsPrimary = GetIsPrimary(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class DesignOptionTable - - public partial class LevelTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Level; - - public EntityTableSet ParentTableSet { get; } // can be null - - public LevelTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); - Column_ProjectElevation = GetDataColumnValues("double:ProjectElevation") ?? Array.Empty(); - Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); - Column_BuildingIndex = GetIndexColumnValues("index:Vim.Building:Building") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_Elevation { get; } - public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); - public Double[] Column_ProjectElevation { get; } - public Double GetProjectElevation(int index, Double @default = default) => Column_ProjectElevation.ElementAtOrDefault(index, @default); - public int[] Column_FamilyTypeIndex { get; } - public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); - public FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); - private FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); - public int[] Column_BuildingIndex { get; } - public int GetBuildingIndex(int index) => Column_BuildingIndex.ElementAtOrDefault(index, EntityRelation.None); - public Building GetBuilding(int index) => _GetReferencedBuilding(GetBuildingIndex(index)); - private Building _GetReferencedBuilding(int referencedIndex) => ParentTableSet.GetBuilding(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Level Get(int index) - { - if (index < 0) return null; - var r = new Level(); - r.Index = index; - r.Elevation = GetElevation(index); - r.ProjectElevation = GetProjectElevation(index); - r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); - r._Building = new Relation(GetBuildingIndex(index), _GetReferencedBuilding); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class LevelTable - - public partial class PhaseTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Phase; - - public EntityTableSet ParentTableSet { get; } // can be null - - public PhaseTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Phase Get(int index) - { - if (index < 0) return null; - var r = new Phase(); - r.Index = index; - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class PhaseTable - - public partial class RoomTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Room; - - public EntityTableSet ParentTableSet { get; } // can be null - - public RoomTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_BaseOffset = GetDataColumnValues("double:BaseOffset") ?? Array.Empty(); - Column_LimitOffset = GetDataColumnValues("double:LimitOffset") ?? Array.Empty(); - Column_UnboundedHeight = GetDataColumnValues("double:UnboundedHeight") ?? Array.Empty(); - Column_Volume = GetDataColumnValues("double:Volume") ?? Array.Empty(); - Column_Perimeter = GetDataColumnValues("double:Perimeter") ?? Array.Empty(); - Column_Area = GetDataColumnValues("double:Area") ?? Array.Empty(); - Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); - Column_UpperLimitIndex = GetIndexColumnValues("index:Vim.Level:UpperLimit") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_BaseOffset { get; } - public Double GetBaseOffset(int index, Double @default = default) => Column_BaseOffset.ElementAtOrDefault(index, @default); - public Double[] Column_LimitOffset { get; } - public Double GetLimitOffset(int index, Double @default = default) => Column_LimitOffset.ElementAtOrDefault(index, @default); - public Double[] Column_UnboundedHeight { get; } - public Double GetUnboundedHeight(int index, Double @default = default) => Column_UnboundedHeight.ElementAtOrDefault(index, @default); - public Double[] Column_Volume { get; } - public Double GetVolume(int index, Double @default = default) => Column_Volume.ElementAtOrDefault(index, @default); - public Double[] Column_Perimeter { get; } - public Double GetPerimeter(int index, Double @default = default) => Column_Perimeter.ElementAtOrDefault(index, @default); - public Double[] Column_Area { get; } - public Double GetArea(int index, Double @default = default) => Column_Area.ElementAtOrDefault(index, @default); - public String[] Column_Number { get; } - public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); - public int[] Column_UpperLimitIndex { get; } - public int GetUpperLimitIndex(int index) => Column_UpperLimitIndex.ElementAtOrDefault(index, EntityRelation.None); - public Level GetUpperLimit(int index) => _GetReferencedUpperLimit(GetUpperLimitIndex(index)); - private Level _GetReferencedUpperLimit(int referencedIndex) => ParentTableSet.GetLevel(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Room Get(int index) - { - if (index < 0) return null; - var r = new Room(); - r.Index = index; - r.BaseOffset = GetBaseOffset(index); - r.LimitOffset = GetLimitOffset(index); - r.UnboundedHeight = GetUnboundedHeight(index); - r.Volume = GetVolume(index); - r.Perimeter = GetPerimeter(index); - r.Area = GetArea(index); - r.Number = GetNumber(index); - r._UpperLimit = new Relation(GetUpperLimitIndex(index), _GetReferencedUpperLimit); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class RoomTable - - public partial class BimDocumentTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.BimDocument; - - public EntityTableSet ParentTableSet { get; } // can be null - - public BimDocumentTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Title = GetStringColumnValues("string:Title") ?? Array.Empty(); - Column_IsMetric = GetDataColumnValues("byte:IsMetric") ?? Array.Empty(); - Column_Guid = GetStringColumnValues("string:Guid") ?? Array.Empty(); - Column_NumSaves = GetDataColumnValues("int:NumSaves") ?? Array.Empty(); - Column_IsLinked = GetDataColumnValues("byte:IsLinked") ?? Array.Empty(); - Column_IsDetached = GetDataColumnValues("byte:IsDetached") ?? Array.Empty(); - Column_IsWorkshared = GetDataColumnValues("byte:IsWorkshared") ?? Array.Empty(); - Column_PathName = GetStringColumnValues("string:PathName") ?? Array.Empty(); - Column_Latitude = GetDataColumnValues("double:Latitude") ?? Array.Empty(); - Column_Longitude = GetDataColumnValues("double:Longitude") ?? Array.Empty(); - Column_TimeZone = GetDataColumnValues("double:TimeZone") ?? Array.Empty(); - Column_PlaceName = GetStringColumnValues("string:PlaceName") ?? Array.Empty(); - Column_WeatherStationName = GetStringColumnValues("string:WeatherStationName") ?? Array.Empty(); - Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); - Column_ProjectLocation = GetStringColumnValues("string:ProjectLocation") ?? Array.Empty(); - Column_IssueDate = GetStringColumnValues("string:IssueDate") ?? Array.Empty(); - Column_Status = GetStringColumnValues("string:Status") ?? Array.Empty(); - Column_ClientName = GetStringColumnValues("string:ClientName") ?? Array.Empty(); - Column_Address = GetStringColumnValues("string:Address") ?? Array.Empty(); - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); - Column_Author = GetStringColumnValues("string:Author") ?? Array.Empty(); - Column_BuildingName = GetStringColumnValues("string:BuildingName") ?? Array.Empty(); - Column_OrganizationName = GetStringColumnValues("string:OrganizationName") ?? Array.Empty(); - Column_OrganizationDescription = GetStringColumnValues("string:OrganizationDescription") ?? Array.Empty(); - Column_Product = GetStringColumnValues("string:Product") ?? Array.Empty(); - Column_Version = GetStringColumnValues("string:Version") ?? Array.Empty(); - Column_User = GetStringColumnValues("string:User") ?? Array.Empty(); - Column_FileLength = GetDataColumnValues("long:FileLength") ?? Array.Empty(); - Column_ActiveViewIndex = GetIndexColumnValues("index:Vim.View:ActiveView") ?? Array.Empty(); - Column_OwnerFamilyIndex = GetIndexColumnValues("index:Vim.Family:OwnerFamily") ?? Array.Empty(); - Column_ParentIndex = GetIndexColumnValues("index:Vim.BimDocument:Parent") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_Title { get; } - public String GetTitle(int index, String @default = "") => Column_Title.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsMetric { get; } - public Boolean GetIsMetric(int index, Boolean @default = default) => Column_IsMetric.ElementAtOrDefault(index, @default); - public String[] Column_Guid { get; } - public String GetGuid(int index, String @default = "") => Column_Guid.ElementAtOrDefault(index, @default); - public Int32[] Column_NumSaves { get; } - public Int32 GetNumSaves(int index, Int32 @default = default) => Column_NumSaves.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsLinked { get; } - public Boolean GetIsLinked(int index, Boolean @default = default) => Column_IsLinked.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsDetached { get; } - public Boolean GetIsDetached(int index, Boolean @default = default) => Column_IsDetached.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsWorkshared { get; } - public Boolean GetIsWorkshared(int index, Boolean @default = default) => Column_IsWorkshared.ElementAtOrDefault(index, @default); - public String[] Column_PathName { get; } - public String GetPathName(int index, String @default = "") => Column_PathName.ElementAtOrDefault(index, @default); - public Double[] Column_Latitude { get; } - public Double GetLatitude(int index, Double @default = default) => Column_Latitude.ElementAtOrDefault(index, @default); - public Double[] Column_Longitude { get; } - public Double GetLongitude(int index, Double @default = default) => Column_Longitude.ElementAtOrDefault(index, @default); - public Double[] Column_TimeZone { get; } - public Double GetTimeZone(int index, Double @default = default) => Column_TimeZone.ElementAtOrDefault(index, @default); - public String[] Column_PlaceName { get; } - public String GetPlaceName(int index, String @default = "") => Column_PlaceName.ElementAtOrDefault(index, @default); - public String[] Column_WeatherStationName { get; } - public String GetWeatherStationName(int index, String @default = "") => Column_WeatherStationName.ElementAtOrDefault(index, @default); - public Double[] Column_Elevation { get; } - public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); - public String[] Column_ProjectLocation { get; } - public String GetProjectLocation(int index, String @default = "") => Column_ProjectLocation.ElementAtOrDefault(index, @default); - public String[] Column_IssueDate { get; } - public String GetIssueDate(int index, String @default = "") => Column_IssueDate.ElementAtOrDefault(index, @default); - public String[] Column_Status { get; } - public String GetStatus(int index, String @default = "") => Column_Status.ElementAtOrDefault(index, @default); - public String[] Column_ClientName { get; } - public String GetClientName(int index, String @default = "") => Column_ClientName.ElementAtOrDefault(index, @default); - public String[] Column_Address { get; } - public String GetAddress(int index, String @default = "") => Column_Address.ElementAtOrDefault(index, @default); - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public String[] Column_Number { get; } - public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); - public String[] Column_Author { get; } - public String GetAuthor(int index, String @default = "") => Column_Author.ElementAtOrDefault(index, @default); - public String[] Column_BuildingName { get; } - public String GetBuildingName(int index, String @default = "") => Column_BuildingName.ElementAtOrDefault(index, @default); - public String[] Column_OrganizationName { get; } - public String GetOrganizationName(int index, String @default = "") => Column_OrganizationName.ElementAtOrDefault(index, @default); - public String[] Column_OrganizationDescription { get; } - public String GetOrganizationDescription(int index, String @default = "") => Column_OrganizationDescription.ElementAtOrDefault(index, @default); - public String[] Column_Product { get; } - public String GetProduct(int index, String @default = "") => Column_Product.ElementAtOrDefault(index, @default); - public String[] Column_Version { get; } - public String GetVersion(int index, String @default = "") => Column_Version.ElementAtOrDefault(index, @default); - public String[] Column_User { get; } - public String GetUser(int index, String @default = "") => Column_User.ElementAtOrDefault(index, @default); - public Int64[] Column_FileLength { get; } - public Int64 GetFileLength(int index, Int64 @default = default) => Column_FileLength.ElementAtOrDefault(index, @default); - public int[] Column_ActiveViewIndex { get; } - public int GetActiveViewIndex(int index) => Column_ActiveViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetActiveView(int index) => _GetReferencedActiveView(GetActiveViewIndex(index)); - private View _GetReferencedActiveView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - public int[] Column_OwnerFamilyIndex { get; } - public int GetOwnerFamilyIndex(int index) => Column_OwnerFamilyIndex.ElementAtOrDefault(index, EntityRelation.None); - public Family GetOwnerFamily(int index) => _GetReferencedOwnerFamily(GetOwnerFamilyIndex(index)); - private Family _GetReferencedOwnerFamily(int referencedIndex) => ParentTableSet.GetFamily(referencedIndex); - public int[] Column_ParentIndex { get; } - public int GetParentIndex(int index) => Column_ParentIndex.ElementAtOrDefault(index, EntityRelation.None); - public BimDocument GetParent(int index) => _GetReferencedParent(GetParentIndex(index)); - private BimDocument _GetReferencedParent(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public BimDocument Get(int index) - { - if (index < 0) return null; - var r = new BimDocument(); - r.Index = index; - r.Title = GetTitle(index); - r.IsMetric = GetIsMetric(index); - r.Guid = GetGuid(index); - r.NumSaves = GetNumSaves(index); - r.IsLinked = GetIsLinked(index); - r.IsDetached = GetIsDetached(index); - r.IsWorkshared = GetIsWorkshared(index); - r.PathName = GetPathName(index); - r.Latitude = GetLatitude(index); - r.Longitude = GetLongitude(index); - r.TimeZone = GetTimeZone(index); - r.PlaceName = GetPlaceName(index); - r.WeatherStationName = GetWeatherStationName(index); - r.Elevation = GetElevation(index); - r.ProjectLocation = GetProjectLocation(index); - r.IssueDate = GetIssueDate(index); - r.Status = GetStatus(index); - r.ClientName = GetClientName(index); - r.Address = GetAddress(index); - r.Name = GetName(index); - r.Number = GetNumber(index); - r.Author = GetAuthor(index); - r.BuildingName = GetBuildingName(index); - r.OrganizationName = GetOrganizationName(index); - r.OrganizationDescription = GetOrganizationDescription(index); - r.Product = GetProduct(index); - r.Version = GetVersion(index); - r.User = GetUser(index); - r.FileLength = GetFileLength(index); - r._ActiveView = new Relation(GetActiveViewIndex(index), _GetReferencedActiveView); - r._OwnerFamily = new Relation(GetOwnerFamilyIndex(index), _GetReferencedOwnerFamily); - r._Parent = new Relation(GetParentIndex(index), _GetReferencedParent); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class BimDocumentTable - - public partial class DisplayUnitInBimDocumentTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.DisplayUnitInBimDocument; - - public EntityTableSet ParentTableSet { get; } // can be null - - public DisplayUnitInBimDocumentTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_DisplayUnitIndex = GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty(); - Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); - } - - public int[] Column_DisplayUnitIndex { get; } - public int GetDisplayUnitIndex(int index) => Column_DisplayUnitIndex.ElementAtOrDefault(index, EntityRelation.None); - public DisplayUnit GetDisplayUnit(int index) => _GetReferencedDisplayUnit(GetDisplayUnitIndex(index)); - private DisplayUnit _GetReferencedDisplayUnit(int referencedIndex) => ParentTableSet.GetDisplayUnit(referencedIndex); - public int[] Column_BimDocumentIndex { get; } - public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); - public BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); - private BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); - // Object Getter - public DisplayUnitInBimDocument Get(int index) - { - if (index < 0) return null; - var r = new DisplayUnitInBimDocument(); - r.Index = index; - r._DisplayUnit = new Relation(GetDisplayUnitIndex(index), _GetReferencedDisplayUnit); - r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class DisplayUnitInBimDocumentTable - - public partial class PhaseOrderInBimDocumentTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.PhaseOrderInBimDocument; - - public EntityTableSet ParentTableSet { get; } // can be null - - public PhaseOrderInBimDocumentTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_OrderIndex = GetDataColumnValues("int:OrderIndex") ?? Array.Empty(); - Column_PhaseIndex = GetIndexColumnValues("index:Vim.Phase:Phase") ?? Array.Empty(); - Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); - } - - public Int32[] Column_OrderIndex { get; } - public Int32 GetOrderIndex(int index, Int32 @default = default) => Column_OrderIndex.ElementAtOrDefault(index, @default); - public int[] Column_PhaseIndex { get; } - public int GetPhaseIndex(int index) => Column_PhaseIndex.ElementAtOrDefault(index, EntityRelation.None); - public Phase GetPhase(int index) => _GetReferencedPhase(GetPhaseIndex(index)); - private Phase _GetReferencedPhase(int referencedIndex) => ParentTableSet.GetPhase(referencedIndex); - public int[] Column_BimDocumentIndex { get; } - public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); - public BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); - private BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); - // Object Getter - public PhaseOrderInBimDocument Get(int index) - { - if (index < 0) return null; - var r = new PhaseOrderInBimDocument(); - r.Index = index; - r.OrderIndex = GetOrderIndex(index); - r._Phase = new Relation(GetPhaseIndex(index), _GetReferencedPhase); - r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class PhaseOrderInBimDocumentTable - - public partial class CategoryTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Category; - - public EntityTableSet ParentTableSet { get; } // can be null - - public CategoryTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_Id = (GetDataColumnValues("long:Id") ?? GetDataColumnValues("int:Id")?.Select(v => (Int64) v).ToArray()) ?? Array.Empty(); - Column_CategoryType = GetStringColumnValues("string:CategoryType") ?? Array.Empty(); - Column_LineColor_X = GetDataColumnValues("double:LineColor.X") ?? Array.Empty(); - Column_LineColor_Y = GetDataColumnValues("double:LineColor.Y") ?? Array.Empty(); - Column_LineColor_Z = GetDataColumnValues("double:LineColor.Z") ?? Array.Empty(); - Column_BuiltInCategory = GetStringColumnValues("string:BuiltInCategory") ?? Array.Empty(); - Column_ParentIndex = GetIndexColumnValues("index:Vim.Category:Parent") ?? Array.Empty(); - Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); - } - - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public Int64[] Column_Id { get; } - public Int64 GetId(int index, Int64 @default = default) => Column_Id.ElementAtOrDefault(index, @default); - public String[] Column_CategoryType { get; } - public String GetCategoryType(int index, String @default = "") => Column_CategoryType.ElementAtOrDefault(index, @default); - public Double[] Column_LineColor_X { get; } - public Double GetLineColor_X(int index, Double @default = default) => Column_LineColor_X.ElementAtOrDefault(index, @default); - public Double[] Column_LineColor_Y { get; } - public Double GetLineColor_Y(int index, Double @default = default) => Column_LineColor_Y.ElementAtOrDefault(index, @default); - public Double[] Column_LineColor_Z { get; } - public Double GetLineColor_Z(int index, Double @default = default) => Column_LineColor_Z.ElementAtOrDefault(index, @default); - public String[] Column_BuiltInCategory { get; } - public String GetBuiltInCategory(int index, String @default = "") => Column_BuiltInCategory.ElementAtOrDefault(index, @default); - public int[] Column_ParentIndex { get; } - public int GetParentIndex(int index) => Column_ParentIndex.ElementAtOrDefault(index, EntityRelation.None); - public Category GetParent(int index) => _GetReferencedParent(GetParentIndex(index)); - private Category _GetReferencedParent(int referencedIndex) => ParentTableSet.GetCategory(referencedIndex); - public int[] Column_MaterialIndex { get; } - public int GetMaterialIndex(int index) => Column_MaterialIndex.ElementAtOrDefault(index, EntityRelation.None); - public Material GetMaterial(int index) => _GetReferencedMaterial(GetMaterialIndex(index)); - private Material _GetReferencedMaterial(int referencedIndex) => ParentTableSet.GetMaterial(referencedIndex); - // Object Getter - public Category Get(int index) - { - if (index < 0) return null; - var r = new Category(); - r.Index = index; - r.Name = GetName(index); - r.Id = GetId(index); - r.CategoryType = GetCategoryType(index); - r.LineColor_X = GetLineColor_X(index); - r.LineColor_Y = GetLineColor_Y(index); - r.LineColor_Z = GetLineColor_Z(index); - r.BuiltInCategory = GetBuiltInCategory(index); - r._Parent = new Relation(GetParentIndex(index), _GetReferencedParent); - r._Material = new Relation(GetMaterialIndex(index), _GetReferencedMaterial); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class CategoryTable - - public partial class FamilyTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Family; - - public EntityTableSet ParentTableSet { get; } // can be null - - public FamilyTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_StructuralMaterialType = GetStringColumnValues("string:StructuralMaterialType") ?? Array.Empty(); - Column_StructuralSectionShape = GetStringColumnValues("string:StructuralSectionShape") ?? Array.Empty(); - Column_IsSystemFamily = GetDataColumnValues("byte:IsSystemFamily") ?? Array.Empty(); - Column_IsInPlace = GetDataColumnValues("byte:IsInPlace") ?? Array.Empty(); - Column_FamilyCategoryIndex = GetIndexColumnValues("index:Vim.Category:FamilyCategory") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_StructuralMaterialType { get; } - public String GetStructuralMaterialType(int index, String @default = "") => Column_StructuralMaterialType.ElementAtOrDefault(index, @default); - public String[] Column_StructuralSectionShape { get; } - public String GetStructuralSectionShape(int index, String @default = "") => Column_StructuralSectionShape.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsSystemFamily { get; } - public Boolean GetIsSystemFamily(int index, Boolean @default = default) => Column_IsSystemFamily.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsInPlace { get; } - public Boolean GetIsInPlace(int index, Boolean @default = default) => Column_IsInPlace.ElementAtOrDefault(index, @default); - public int[] Column_FamilyCategoryIndex { get; } - public int GetFamilyCategoryIndex(int index) => Column_FamilyCategoryIndex.ElementAtOrDefault(index, EntityRelation.None); - public Category GetFamilyCategory(int index) => _GetReferencedFamilyCategory(GetFamilyCategoryIndex(index)); - private Category _GetReferencedFamilyCategory(int referencedIndex) => ParentTableSet.GetCategory(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Family Get(int index) - { - if (index < 0) return null; - var r = new Family(); - r.Index = index; - r.StructuralMaterialType = GetStructuralMaterialType(index); - r.StructuralSectionShape = GetStructuralSectionShape(index); - r.IsSystemFamily = GetIsSystemFamily(index); - r.IsInPlace = GetIsInPlace(index); - r._FamilyCategory = new Relation(GetFamilyCategoryIndex(index), _GetReferencedFamilyCategory); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class FamilyTable - - public partial class FamilyTypeTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.FamilyType; - - public EntityTableSet ParentTableSet { get; } // can be null - - public FamilyTypeTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_IsSystemFamilyType = GetDataColumnValues("byte:IsSystemFamilyType") ?? Array.Empty(); - Column_FamilyIndex = GetIndexColumnValues("index:Vim.Family:Family") ?? Array.Empty(); - Column_CompoundStructureIndex = GetIndexColumnValues("index:Vim.CompoundStructure:CompoundStructure") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Boolean[] Column_IsSystemFamilyType { get; } - public Boolean GetIsSystemFamilyType(int index, Boolean @default = default) => Column_IsSystemFamilyType.ElementAtOrDefault(index, @default); - public int[] Column_FamilyIndex { get; } - public int GetFamilyIndex(int index) => Column_FamilyIndex.ElementAtOrDefault(index, EntityRelation.None); - public Family GetFamily(int index) => _GetReferencedFamily(GetFamilyIndex(index)); - private Family _GetReferencedFamily(int referencedIndex) => ParentTableSet.GetFamily(referencedIndex); - public int[] Column_CompoundStructureIndex { get; } - public int GetCompoundStructureIndex(int index) => Column_CompoundStructureIndex.ElementAtOrDefault(index, EntityRelation.None); - public CompoundStructure GetCompoundStructure(int index) => _GetReferencedCompoundStructure(GetCompoundStructureIndex(index)); - private CompoundStructure _GetReferencedCompoundStructure(int referencedIndex) => ParentTableSet.GetCompoundStructure(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public FamilyType Get(int index) - { - if (index < 0) return null; - var r = new FamilyType(); - r.Index = index; - r.IsSystemFamilyType = GetIsSystemFamilyType(index); - r._Family = new Relation(GetFamilyIndex(index), _GetReferencedFamily); - r._CompoundStructure = new Relation(GetCompoundStructureIndex(index), _GetReferencedCompoundStructure); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class FamilyTypeTable - - public partial class FamilyInstanceTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.FamilyInstance; - - public EntityTableSet ParentTableSet { get; } // can be null - - public FamilyInstanceTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_FacingFlipped = GetDataColumnValues("byte:FacingFlipped") ?? Array.Empty(); - Column_FacingOrientation_X = GetDataColumnValues("float:FacingOrientation.X") ?? Array.Empty(); - Column_FacingOrientation_Y = GetDataColumnValues("float:FacingOrientation.Y") ?? Array.Empty(); - Column_FacingOrientation_Z = GetDataColumnValues("float:FacingOrientation.Z") ?? Array.Empty(); - Column_HandFlipped = GetDataColumnValues("byte:HandFlipped") ?? Array.Empty(); - Column_Mirrored = GetDataColumnValues("byte:Mirrored") ?? Array.Empty(); - Column_HasModifiedGeometry = GetDataColumnValues("byte:HasModifiedGeometry") ?? Array.Empty(); - Column_Scale = GetDataColumnValues("float:Scale") ?? Array.Empty(); - Column_BasisX_X = GetDataColumnValues("float:BasisX.X") ?? Array.Empty(); - Column_BasisX_Y = GetDataColumnValues("float:BasisX.Y") ?? Array.Empty(); - Column_BasisX_Z = GetDataColumnValues("float:BasisX.Z") ?? Array.Empty(); - Column_BasisY_X = GetDataColumnValues("float:BasisY.X") ?? Array.Empty(); - Column_BasisY_Y = GetDataColumnValues("float:BasisY.Y") ?? Array.Empty(); - Column_BasisY_Z = GetDataColumnValues("float:BasisY.Z") ?? Array.Empty(); - Column_BasisZ_X = GetDataColumnValues("float:BasisZ.X") ?? Array.Empty(); - Column_BasisZ_Y = GetDataColumnValues("float:BasisZ.Y") ?? Array.Empty(); - Column_BasisZ_Z = GetDataColumnValues("float:BasisZ.Z") ?? Array.Empty(); - Column_Translation_X = GetDataColumnValues("float:Translation.X") ?? Array.Empty(); - Column_Translation_Y = GetDataColumnValues("float:Translation.Y") ?? Array.Empty(); - Column_Translation_Z = GetDataColumnValues("float:Translation.Z") ?? Array.Empty(); - Column_HandOrientation_X = GetDataColumnValues("float:HandOrientation.X") ?? Array.Empty(); - Column_HandOrientation_Y = GetDataColumnValues("float:HandOrientation.Y") ?? Array.Empty(); - Column_HandOrientation_Z = GetDataColumnValues("float:HandOrientation.Z") ?? Array.Empty(); - Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); - Column_HostIndex = GetIndexColumnValues("index:Vim.Element:Host") ?? Array.Empty(); - Column_FromRoomIndex = GetIndexColumnValues("index:Vim.Room:FromRoom") ?? Array.Empty(); - Column_ToRoomIndex = GetIndexColumnValues("index:Vim.Room:ToRoom") ?? Array.Empty(); - Column_SuperComponentIndex = GetIndexColumnValues("index:Vim.Element:SuperComponent") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Boolean[] Column_FacingFlipped { get; } - public Boolean GetFacingFlipped(int index, Boolean @default = default) => Column_FacingFlipped.ElementAtOrDefault(index, @default); - public Single[] Column_FacingOrientation_X { get; } - public Single GetFacingOrientation_X(int index, Single @default = default) => Column_FacingOrientation_X.ElementAtOrDefault(index, @default); - public Single[] Column_FacingOrientation_Y { get; } - public Single GetFacingOrientation_Y(int index, Single @default = default) => Column_FacingOrientation_Y.ElementAtOrDefault(index, @default); - public Single[] Column_FacingOrientation_Z { get; } - public Single GetFacingOrientation_Z(int index, Single @default = default) => Column_FacingOrientation_Z.ElementAtOrDefault(index, @default); - public Boolean[] Column_HandFlipped { get; } - public Boolean GetHandFlipped(int index, Boolean @default = default) => Column_HandFlipped.ElementAtOrDefault(index, @default); - public Boolean[] Column_Mirrored { get; } - public Boolean GetMirrored(int index, Boolean @default = default) => Column_Mirrored.ElementAtOrDefault(index, @default); - public Boolean[] Column_HasModifiedGeometry { get; } - public Boolean GetHasModifiedGeometry(int index, Boolean @default = default) => Column_HasModifiedGeometry.ElementAtOrDefault(index, @default); - public Single[] Column_Scale { get; } - public Single GetScale(int index, Single @default = default) => Column_Scale.ElementAtOrDefault(index, @default); - public Single[] Column_BasisX_X { get; } - public Single GetBasisX_X(int index, Single @default = default) => Column_BasisX_X.ElementAtOrDefault(index, @default); - public Single[] Column_BasisX_Y { get; } - public Single GetBasisX_Y(int index, Single @default = default) => Column_BasisX_Y.ElementAtOrDefault(index, @default); - public Single[] Column_BasisX_Z { get; } - public Single GetBasisX_Z(int index, Single @default = default) => Column_BasisX_Z.ElementAtOrDefault(index, @default); - public Single[] Column_BasisY_X { get; } - public Single GetBasisY_X(int index, Single @default = default) => Column_BasisY_X.ElementAtOrDefault(index, @default); - public Single[] Column_BasisY_Y { get; } - public Single GetBasisY_Y(int index, Single @default = default) => Column_BasisY_Y.ElementAtOrDefault(index, @default); - public Single[] Column_BasisY_Z { get; } - public Single GetBasisY_Z(int index, Single @default = default) => Column_BasisY_Z.ElementAtOrDefault(index, @default); - public Single[] Column_BasisZ_X { get; } - public Single GetBasisZ_X(int index, Single @default = default) => Column_BasisZ_X.ElementAtOrDefault(index, @default); - public Single[] Column_BasisZ_Y { get; } - public Single GetBasisZ_Y(int index, Single @default = default) => Column_BasisZ_Y.ElementAtOrDefault(index, @default); - public Single[] Column_BasisZ_Z { get; } - public Single GetBasisZ_Z(int index, Single @default = default) => Column_BasisZ_Z.ElementAtOrDefault(index, @default); - public Single[] Column_Translation_X { get; } - public Single GetTranslation_X(int index, Single @default = default) => Column_Translation_X.ElementAtOrDefault(index, @default); - public Single[] Column_Translation_Y { get; } - public Single GetTranslation_Y(int index, Single @default = default) => Column_Translation_Y.ElementAtOrDefault(index, @default); - public Single[] Column_Translation_Z { get; } - public Single GetTranslation_Z(int index, Single @default = default) => Column_Translation_Z.ElementAtOrDefault(index, @default); - public Single[] Column_HandOrientation_X { get; } - public Single GetHandOrientation_X(int index, Single @default = default) => Column_HandOrientation_X.ElementAtOrDefault(index, @default); - public Single[] Column_HandOrientation_Y { get; } - public Single GetHandOrientation_Y(int index, Single @default = default) => Column_HandOrientation_Y.ElementAtOrDefault(index, @default); - public Single[] Column_HandOrientation_Z { get; } - public Single GetHandOrientation_Z(int index, Single @default = default) => Column_HandOrientation_Z.ElementAtOrDefault(index, @default); - public int[] Column_FamilyTypeIndex { get; } - public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); - public FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); - private FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); - public int[] Column_HostIndex { get; } - public int GetHostIndex(int index) => Column_HostIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetHost(int index) => _GetReferencedHost(GetHostIndex(index)); - private Element _GetReferencedHost(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - public int[] Column_FromRoomIndex { get; } - public int GetFromRoomIndex(int index) => Column_FromRoomIndex.ElementAtOrDefault(index, EntityRelation.None); - public Room GetFromRoom(int index) => _GetReferencedFromRoom(GetFromRoomIndex(index)); - private Room _GetReferencedFromRoom(int referencedIndex) => ParentTableSet.GetRoom(referencedIndex); - public int[] Column_ToRoomIndex { get; } - public int GetToRoomIndex(int index) => Column_ToRoomIndex.ElementAtOrDefault(index, EntityRelation.None); - public Room GetToRoom(int index) => _GetReferencedToRoom(GetToRoomIndex(index)); - private Room _GetReferencedToRoom(int referencedIndex) => ParentTableSet.GetRoom(referencedIndex); - public int[] Column_SuperComponentIndex { get; } - public int GetSuperComponentIndex(int index) => Column_SuperComponentIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetSuperComponent(int index) => _GetReferencedSuperComponent(GetSuperComponentIndex(index)); - private Element _GetReferencedSuperComponent(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public FamilyInstance Get(int index) - { - if (index < 0) return null; - var r = new FamilyInstance(); - r.Index = index; - r.FacingFlipped = GetFacingFlipped(index); - r.FacingOrientation_X = GetFacingOrientation_X(index); - r.FacingOrientation_Y = GetFacingOrientation_Y(index); - r.FacingOrientation_Z = GetFacingOrientation_Z(index); - r.HandFlipped = GetHandFlipped(index); - r.Mirrored = GetMirrored(index); - r.HasModifiedGeometry = GetHasModifiedGeometry(index); - r.Scale = GetScale(index); - r.BasisX_X = GetBasisX_X(index); - r.BasisX_Y = GetBasisX_Y(index); - r.BasisX_Z = GetBasisX_Z(index); - r.BasisY_X = GetBasisY_X(index); - r.BasisY_Y = GetBasisY_Y(index); - r.BasisY_Z = GetBasisY_Z(index); - r.BasisZ_X = GetBasisZ_X(index); - r.BasisZ_Y = GetBasisZ_Y(index); - r.BasisZ_Z = GetBasisZ_Z(index); - r.Translation_X = GetTranslation_X(index); - r.Translation_Y = GetTranslation_Y(index); - r.Translation_Z = GetTranslation_Z(index); - r.HandOrientation_X = GetHandOrientation_X(index); - r.HandOrientation_Y = GetHandOrientation_Y(index); - r.HandOrientation_Z = GetHandOrientation_Z(index); - r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); - r._Host = new Relation(GetHostIndex(index), _GetReferencedHost); - r._FromRoom = new Relation(GetFromRoomIndex(index), _GetReferencedFromRoom); - r._ToRoom = new Relation(GetToRoomIndex(index), _GetReferencedToRoom); - r._SuperComponent = new Relation(GetSuperComponentIndex(index), _GetReferencedSuperComponent); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class FamilyInstanceTable - - public partial class ViewTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.View; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ViewTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Title = GetStringColumnValues("string:Title") ?? Array.Empty(); - Column_ViewType = GetStringColumnValues("string:ViewType") ?? Array.Empty(); - Column_Up_X = GetDataColumnValues("double:Up.X") ?? Array.Empty(); - Column_Up_Y = GetDataColumnValues("double:Up.Y") ?? Array.Empty(); - Column_Up_Z = GetDataColumnValues("double:Up.Z") ?? Array.Empty(); - Column_Right_X = GetDataColumnValues("double:Right.X") ?? Array.Empty(); - Column_Right_Y = GetDataColumnValues("double:Right.Y") ?? Array.Empty(); - Column_Right_Z = GetDataColumnValues("double:Right.Z") ?? Array.Empty(); - Column_Origin_X = GetDataColumnValues("double:Origin.X") ?? Array.Empty(); - Column_Origin_Y = GetDataColumnValues("double:Origin.Y") ?? Array.Empty(); - Column_Origin_Z = GetDataColumnValues("double:Origin.Z") ?? Array.Empty(); - Column_ViewDirection_X = GetDataColumnValues("double:ViewDirection.X") ?? Array.Empty(); - Column_ViewDirection_Y = GetDataColumnValues("double:ViewDirection.Y") ?? Array.Empty(); - Column_ViewDirection_Z = GetDataColumnValues("double:ViewDirection.Z") ?? Array.Empty(); - Column_ViewPosition_X = GetDataColumnValues("double:ViewPosition.X") ?? Array.Empty(); - Column_ViewPosition_Y = GetDataColumnValues("double:ViewPosition.Y") ?? Array.Empty(); - Column_ViewPosition_Z = GetDataColumnValues("double:ViewPosition.Z") ?? Array.Empty(); - Column_Scale = GetDataColumnValues("double:Scale") ?? Array.Empty(); - Column_Outline_Min_X = GetDataColumnValues("double:Outline.Min.X") ?? Array.Empty(); - Column_Outline_Min_Y = GetDataColumnValues("double:Outline.Min.Y") ?? Array.Empty(); - Column_Outline_Max_X = GetDataColumnValues("double:Outline.Max.X") ?? Array.Empty(); - Column_Outline_Max_Y = GetDataColumnValues("double:Outline.Max.Y") ?? Array.Empty(); - Column_DetailLevel = GetDataColumnValues("int:DetailLevel") ?? Array.Empty(); - Column_CameraIndex = GetIndexColumnValues("index:Vim.Camera:Camera") ?? Array.Empty(); - Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_Title { get; } - public String GetTitle(int index, String @default = "") => Column_Title.ElementAtOrDefault(index, @default); - public String[] Column_ViewType { get; } - public String GetViewType(int index, String @default = "") => Column_ViewType.ElementAtOrDefault(index, @default); - public Double[] Column_Up_X { get; } - public Double GetUp_X(int index, Double @default = default) => Column_Up_X.ElementAtOrDefault(index, @default); - public Double[] Column_Up_Y { get; } - public Double GetUp_Y(int index, Double @default = default) => Column_Up_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Up_Z { get; } - public Double GetUp_Z(int index, Double @default = default) => Column_Up_Z.ElementAtOrDefault(index, @default); - public Double[] Column_Right_X { get; } - public Double GetRight_X(int index, Double @default = default) => Column_Right_X.ElementAtOrDefault(index, @default); - public Double[] Column_Right_Y { get; } - public Double GetRight_Y(int index, Double @default = default) => Column_Right_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Right_Z { get; } - public Double GetRight_Z(int index, Double @default = default) => Column_Right_Z.ElementAtOrDefault(index, @default); - public Double[] Column_Origin_X { get; } - public Double GetOrigin_X(int index, Double @default = default) => Column_Origin_X.ElementAtOrDefault(index, @default); - public Double[] Column_Origin_Y { get; } - public Double GetOrigin_Y(int index, Double @default = default) => Column_Origin_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Origin_Z { get; } - public Double GetOrigin_Z(int index, Double @default = default) => Column_Origin_Z.ElementAtOrDefault(index, @default); - public Double[] Column_ViewDirection_X { get; } - public Double GetViewDirection_X(int index, Double @default = default) => Column_ViewDirection_X.ElementAtOrDefault(index, @default); - public Double[] Column_ViewDirection_Y { get; } - public Double GetViewDirection_Y(int index, Double @default = default) => Column_ViewDirection_Y.ElementAtOrDefault(index, @default); - public Double[] Column_ViewDirection_Z { get; } - public Double GetViewDirection_Z(int index, Double @default = default) => Column_ViewDirection_Z.ElementAtOrDefault(index, @default); - public Double[] Column_ViewPosition_X { get; } - public Double GetViewPosition_X(int index, Double @default = default) => Column_ViewPosition_X.ElementAtOrDefault(index, @default); - public Double[] Column_ViewPosition_Y { get; } - public Double GetViewPosition_Y(int index, Double @default = default) => Column_ViewPosition_Y.ElementAtOrDefault(index, @default); - public Double[] Column_ViewPosition_Z { get; } - public Double GetViewPosition_Z(int index, Double @default = default) => Column_ViewPosition_Z.ElementAtOrDefault(index, @default); - public Double[] Column_Scale { get; } - public Double GetScale(int index, Double @default = default) => Column_Scale.ElementAtOrDefault(index, @default); - public Double[] Column_Outline_Min_X { get; } - public Double GetOutline_Min_X(int index, Double @default = default) => Column_Outline_Min_X.ElementAtOrDefault(index, @default); - public Double[] Column_Outline_Min_Y { get; } - public Double GetOutline_Min_Y(int index, Double @default = default) => Column_Outline_Min_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Outline_Max_X { get; } - public Double GetOutline_Max_X(int index, Double @default = default) => Column_Outline_Max_X.ElementAtOrDefault(index, @default); - public Double[] Column_Outline_Max_Y { get; } - public Double GetOutline_Max_Y(int index, Double @default = default) => Column_Outline_Max_Y.ElementAtOrDefault(index, @default); - public Int32[] Column_DetailLevel { get; } - public Int32 GetDetailLevel(int index, Int32 @default = default) => Column_DetailLevel.ElementAtOrDefault(index, @default); - public int[] Column_CameraIndex { get; } - public int GetCameraIndex(int index) => Column_CameraIndex.ElementAtOrDefault(index, EntityRelation.None); - public Camera GetCamera(int index) => _GetReferencedCamera(GetCameraIndex(index)); - private Camera _GetReferencedCamera(int referencedIndex) => ParentTableSet.GetCamera(referencedIndex); - public int[] Column_FamilyTypeIndex { get; } - public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); - public FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); - private FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public View Get(int index) - { - if (index < 0) return null; - var r = new View(); - r.Index = index; - r.Title = GetTitle(index); - r.ViewType = GetViewType(index); - r.Up_X = GetUp_X(index); - r.Up_Y = GetUp_Y(index); - r.Up_Z = GetUp_Z(index); - r.Right_X = GetRight_X(index); - r.Right_Y = GetRight_Y(index); - r.Right_Z = GetRight_Z(index); - r.Origin_X = GetOrigin_X(index); - r.Origin_Y = GetOrigin_Y(index); - r.Origin_Z = GetOrigin_Z(index); - r.ViewDirection_X = GetViewDirection_X(index); - r.ViewDirection_Y = GetViewDirection_Y(index); - r.ViewDirection_Z = GetViewDirection_Z(index); - r.ViewPosition_X = GetViewPosition_X(index); - r.ViewPosition_Y = GetViewPosition_Y(index); - r.ViewPosition_Z = GetViewPosition_Z(index); - r.Scale = GetScale(index); - r.Outline_Min_X = GetOutline_Min_X(index); - r.Outline_Min_Y = GetOutline_Min_Y(index); - r.Outline_Max_X = GetOutline_Max_X(index); - r.Outline_Max_Y = GetOutline_Max_Y(index); - r.DetailLevel = GetDetailLevel(index); - r._Camera = new Relation(GetCameraIndex(index), _GetReferencedCamera); - r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ViewTable - - public partial class ElementInViewTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ElementInView; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ElementInViewTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ViewIndex { get; } - public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetView(int index) => _GetReferencedView(GetViewIndex(index)); - private View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public ElementInView Get(int index) - { - if (index < 0) return null; - var r = new ElementInView(); - r.Index = index; - r._View = new Relation(GetViewIndex(index), _GetReferencedView); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ElementInViewTable - - public partial class ShapeInViewTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ShapeInView; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ShapeInViewTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ShapeIndex = GetIndexColumnValues("index:Vim.Shape:Shape") ?? Array.Empty(); - Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); - } - - public int[] Column_ShapeIndex { get; } - public int GetShapeIndex(int index) => Column_ShapeIndex.ElementAtOrDefault(index, EntityRelation.None); - public Shape GetShape(int index) => _GetReferencedShape(GetShapeIndex(index)); - private Shape _GetReferencedShape(int referencedIndex) => ParentTableSet.GetShape(referencedIndex); - public int[] Column_ViewIndex { get; } - public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetView(int index) => _GetReferencedView(GetViewIndex(index)); - private View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - // Object Getter - public ShapeInView Get(int index) - { - if (index < 0) return null; - var r = new ShapeInView(); - r.Index = index; - r._Shape = new Relation(GetShapeIndex(index), _GetReferencedShape); - r._View = new Relation(GetViewIndex(index), _GetReferencedView); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ShapeInViewTable - - public partial class AssetInViewTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.AssetInView; - - public EntityTableSet ParentTableSet { get; } // can be null - - public AssetInViewTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_AssetIndex = GetIndexColumnValues("index:Vim.Asset:Asset") ?? Array.Empty(); - Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); - } - - public int[] Column_AssetIndex { get; } - public int GetAssetIndex(int index) => Column_AssetIndex.ElementAtOrDefault(index, EntityRelation.None); - public Asset GetAsset(int index) => _GetReferencedAsset(GetAssetIndex(index)); - private Asset _GetReferencedAsset(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); - public int[] Column_ViewIndex { get; } - public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetView(int index) => _GetReferencedView(GetViewIndex(index)); - private View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - // Object Getter - public AssetInView Get(int index) - { - if (index < 0) return null; - var r = new AssetInView(); - r.Index = index; - r._Asset = new Relation(GetAssetIndex(index), _GetReferencedAsset); - r._View = new Relation(GetViewIndex(index), _GetReferencedView); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class AssetInViewTable - - public partial class AssetInViewSheetTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.AssetInViewSheet; - - public EntityTableSet ParentTableSet { get; } // can be null - - public AssetInViewSheetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_AssetIndex = GetIndexColumnValues("index:Vim.Asset:Asset") ?? Array.Empty(); - Column_ViewSheetIndex = GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty(); - } - - public int[] Column_AssetIndex { get; } - public int GetAssetIndex(int index) => Column_AssetIndex.ElementAtOrDefault(index, EntityRelation.None); - public Asset GetAsset(int index) => _GetReferencedAsset(GetAssetIndex(index)); - private Asset _GetReferencedAsset(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); - public int[] Column_ViewSheetIndex { get; } - public int GetViewSheetIndex(int index) => Column_ViewSheetIndex.ElementAtOrDefault(index, EntityRelation.None); - public ViewSheet GetViewSheet(int index) => _GetReferencedViewSheet(GetViewSheetIndex(index)); - private ViewSheet _GetReferencedViewSheet(int referencedIndex) => ParentTableSet.GetViewSheet(referencedIndex); - // Object Getter - public AssetInViewSheet Get(int index) - { - if (index < 0) return null; - var r = new AssetInViewSheet(); - r.Index = index; - r._Asset = new Relation(GetAssetIndex(index), _GetReferencedAsset); - r._ViewSheet = new Relation(GetViewSheetIndex(index), _GetReferencedViewSheet); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class AssetInViewSheetTable - - public partial class LevelInViewTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.LevelInView; - - public EntityTableSet ParentTableSet { get; } // can be null - - public LevelInViewTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Extents_Min_X = GetDataColumnValues("double:Extents.Min.X") ?? Array.Empty(); - Column_Extents_Min_Y = GetDataColumnValues("double:Extents.Min.Y") ?? Array.Empty(); - Column_Extents_Min_Z = GetDataColumnValues("double:Extents.Min.Z") ?? Array.Empty(); - Column_Extents_Max_X = GetDataColumnValues("double:Extents.Max.X") ?? Array.Empty(); - Column_Extents_Max_Y = GetDataColumnValues("double:Extents.Max.Y") ?? Array.Empty(); - Column_Extents_Max_Z = GetDataColumnValues("double:Extents.Max.Z") ?? Array.Empty(); - Column_LevelIndex = GetIndexColumnValues("index:Vim.Level:Level") ?? Array.Empty(); - Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); - } - - public Double[] Column_Extents_Min_X { get; } - public Double GetExtents_Min_X(int index, Double @default = default) => Column_Extents_Min_X.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Min_Y { get; } - public Double GetExtents_Min_Y(int index, Double @default = default) => Column_Extents_Min_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Min_Z { get; } - public Double GetExtents_Min_Z(int index, Double @default = default) => Column_Extents_Min_Z.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Max_X { get; } - public Double GetExtents_Max_X(int index, Double @default = default) => Column_Extents_Max_X.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Max_Y { get; } - public Double GetExtents_Max_Y(int index, Double @default = default) => Column_Extents_Max_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Max_Z { get; } - public Double GetExtents_Max_Z(int index, Double @default = default) => Column_Extents_Max_Z.ElementAtOrDefault(index, @default); - public int[] Column_LevelIndex { get; } - public int GetLevelIndex(int index) => Column_LevelIndex.ElementAtOrDefault(index, EntityRelation.None); - public Level GetLevel(int index) => _GetReferencedLevel(GetLevelIndex(index)); - private Level _GetReferencedLevel(int referencedIndex) => ParentTableSet.GetLevel(referencedIndex); - public int[] Column_ViewIndex { get; } - public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetView(int index) => _GetReferencedView(GetViewIndex(index)); - private View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - // Object Getter - public LevelInView Get(int index) - { - if (index < 0) return null; - var r = new LevelInView(); - r.Index = index; - r.Extents_Min_X = GetExtents_Min_X(index); - r.Extents_Min_Y = GetExtents_Min_Y(index); - r.Extents_Min_Z = GetExtents_Min_Z(index); - r.Extents_Max_X = GetExtents_Max_X(index); - r.Extents_Max_Y = GetExtents_Max_Y(index); - r.Extents_Max_Z = GetExtents_Max_Z(index); - r._Level = new Relation(GetLevelIndex(index), _GetReferencedLevel); - r._View = new Relation(GetViewIndex(index), _GetReferencedView); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class LevelInViewTable - - public partial class CameraTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Camera; - - public EntityTableSet ParentTableSet { get; } // can be null - - public CameraTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Id = GetDataColumnValues("int:Id") ?? Array.Empty(); - Column_IsPerspective = GetDataColumnValues("int:IsPerspective") ?? Array.Empty(); - Column_VerticalExtent = GetDataColumnValues("double:VerticalExtent") ?? Array.Empty(); - Column_HorizontalExtent = GetDataColumnValues("double:HorizontalExtent") ?? Array.Empty(); - Column_FarDistance = GetDataColumnValues("double:FarDistance") ?? Array.Empty(); - Column_NearDistance = GetDataColumnValues("double:NearDistance") ?? Array.Empty(); - Column_TargetDistance = GetDataColumnValues("double:TargetDistance") ?? Array.Empty(); - Column_RightOffset = GetDataColumnValues("double:RightOffset") ?? Array.Empty(); - Column_UpOffset = GetDataColumnValues("double:UpOffset") ?? Array.Empty(); - } - - public Int32[] Column_Id { get; } - public Int32 GetId(int index, Int32 @default = default) => Column_Id.ElementAtOrDefault(index, @default); - public Int32[] Column_IsPerspective { get; } - public Int32 GetIsPerspective(int index, Int32 @default = default) => Column_IsPerspective.ElementAtOrDefault(index, @default); - public Double[] Column_VerticalExtent { get; } - public Double GetVerticalExtent(int index, Double @default = default) => Column_VerticalExtent.ElementAtOrDefault(index, @default); - public Double[] Column_HorizontalExtent { get; } - public Double GetHorizontalExtent(int index, Double @default = default) => Column_HorizontalExtent.ElementAtOrDefault(index, @default); - public Double[] Column_FarDistance { get; } - public Double GetFarDistance(int index, Double @default = default) => Column_FarDistance.ElementAtOrDefault(index, @default); - public Double[] Column_NearDistance { get; } - public Double GetNearDistance(int index, Double @default = default) => Column_NearDistance.ElementAtOrDefault(index, @default); - public Double[] Column_TargetDistance { get; } - public Double GetTargetDistance(int index, Double @default = default) => Column_TargetDistance.ElementAtOrDefault(index, @default); - public Double[] Column_RightOffset { get; } - public Double GetRightOffset(int index, Double @default = default) => Column_RightOffset.ElementAtOrDefault(index, @default); - public Double[] Column_UpOffset { get; } - public Double GetUpOffset(int index, Double @default = default) => Column_UpOffset.ElementAtOrDefault(index, @default); - // Object Getter - public Camera Get(int index) - { - if (index < 0) return null; - var r = new Camera(); - r.Index = index; - r.Id = GetId(index); - r.IsPerspective = GetIsPerspective(index); - r.VerticalExtent = GetVerticalExtent(index); - r.HorizontalExtent = GetHorizontalExtent(index); - r.FarDistance = GetFarDistance(index); - r.NearDistance = GetNearDistance(index); - r.TargetDistance = GetTargetDistance(index); - r.RightOffset = GetRightOffset(index); - r.UpOffset = GetUpOffset(index); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class CameraTable - - public partial class MaterialTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Material; - - public EntityTableSet ParentTableSet { get; } // can be null - - public MaterialTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_MaterialCategory = GetStringColumnValues("string:MaterialCategory") ?? Array.Empty(); - Column_Color_X = GetDataColumnValues("double:Color.X") ?? Array.Empty(); - Column_Color_Y = GetDataColumnValues("double:Color.Y") ?? Array.Empty(); - Column_Color_Z = GetDataColumnValues("double:Color.Z") ?? Array.Empty(); - Column_ColorUvScaling_X = GetDataColumnValues("double:ColorUvScaling.X") ?? Array.Empty(); - Column_ColorUvScaling_Y = GetDataColumnValues("double:ColorUvScaling.Y") ?? Array.Empty(); - Column_ColorUvOffset_X = GetDataColumnValues("double:ColorUvOffset.X") ?? Array.Empty(); - Column_ColorUvOffset_Y = GetDataColumnValues("double:ColorUvOffset.Y") ?? Array.Empty(); - Column_NormalUvScaling_X = GetDataColumnValues("double:NormalUvScaling.X") ?? Array.Empty(); - Column_NormalUvScaling_Y = GetDataColumnValues("double:NormalUvScaling.Y") ?? Array.Empty(); - Column_NormalUvOffset_X = GetDataColumnValues("double:NormalUvOffset.X") ?? Array.Empty(); - Column_NormalUvOffset_Y = GetDataColumnValues("double:NormalUvOffset.Y") ?? Array.Empty(); - Column_NormalAmount = GetDataColumnValues("double:NormalAmount") ?? Array.Empty(); - Column_Glossiness = GetDataColumnValues("double:Glossiness") ?? Array.Empty(); - Column_Smoothness = GetDataColumnValues("double:Smoothness") ?? Array.Empty(); - Column_Transparency = GetDataColumnValues("double:Transparency") ?? Array.Empty(); - Column_ColorTextureFileIndex = GetIndexColumnValues("index:Vim.Asset:ColorTextureFile") ?? Array.Empty(); - Column_NormalTextureFileIndex = GetIndexColumnValues("index:Vim.Asset:NormalTextureFile") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public String[] Column_MaterialCategory { get; } - public String GetMaterialCategory(int index, String @default = "") => Column_MaterialCategory.ElementAtOrDefault(index, @default); - public Double[] Column_Color_X { get; } - public Double GetColor_X(int index, Double @default = default) => Column_Color_X.ElementAtOrDefault(index, @default); - public Double[] Column_Color_Y { get; } - public Double GetColor_Y(int index, Double @default = default) => Column_Color_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Color_Z { get; } - public Double GetColor_Z(int index, Double @default = default) => Column_Color_Z.ElementAtOrDefault(index, @default); - public Double[] Column_ColorUvScaling_X { get; } - public Double GetColorUvScaling_X(int index, Double @default = default) => Column_ColorUvScaling_X.ElementAtOrDefault(index, @default); - public Double[] Column_ColorUvScaling_Y { get; } - public Double GetColorUvScaling_Y(int index, Double @default = default) => Column_ColorUvScaling_Y.ElementAtOrDefault(index, @default); - public Double[] Column_ColorUvOffset_X { get; } - public Double GetColorUvOffset_X(int index, Double @default = default) => Column_ColorUvOffset_X.ElementAtOrDefault(index, @default); - public Double[] Column_ColorUvOffset_Y { get; } - public Double GetColorUvOffset_Y(int index, Double @default = default) => Column_ColorUvOffset_Y.ElementAtOrDefault(index, @default); - public Double[] Column_NormalUvScaling_X { get; } - public Double GetNormalUvScaling_X(int index, Double @default = default) => Column_NormalUvScaling_X.ElementAtOrDefault(index, @default); - public Double[] Column_NormalUvScaling_Y { get; } - public Double GetNormalUvScaling_Y(int index, Double @default = default) => Column_NormalUvScaling_Y.ElementAtOrDefault(index, @default); - public Double[] Column_NormalUvOffset_X { get; } - public Double GetNormalUvOffset_X(int index, Double @default = default) => Column_NormalUvOffset_X.ElementAtOrDefault(index, @default); - public Double[] Column_NormalUvOffset_Y { get; } - public Double GetNormalUvOffset_Y(int index, Double @default = default) => Column_NormalUvOffset_Y.ElementAtOrDefault(index, @default); - public Double[] Column_NormalAmount { get; } - public Double GetNormalAmount(int index, Double @default = default) => Column_NormalAmount.ElementAtOrDefault(index, @default); - public Double[] Column_Glossiness { get; } - public Double GetGlossiness(int index, Double @default = default) => Column_Glossiness.ElementAtOrDefault(index, @default); - public Double[] Column_Smoothness { get; } - public Double GetSmoothness(int index, Double @default = default) => Column_Smoothness.ElementAtOrDefault(index, @default); - public Double[] Column_Transparency { get; } - public Double GetTransparency(int index, Double @default = default) => Column_Transparency.ElementAtOrDefault(index, @default); - public int[] Column_ColorTextureFileIndex { get; } - public int GetColorTextureFileIndex(int index) => Column_ColorTextureFileIndex.ElementAtOrDefault(index, EntityRelation.None); - public Asset GetColorTextureFile(int index) => _GetReferencedColorTextureFile(GetColorTextureFileIndex(index)); - private Asset _GetReferencedColorTextureFile(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); - public int[] Column_NormalTextureFileIndex { get; } - public int GetNormalTextureFileIndex(int index) => Column_NormalTextureFileIndex.ElementAtOrDefault(index, EntityRelation.None); - public Asset GetNormalTextureFile(int index) => _GetReferencedNormalTextureFile(GetNormalTextureFileIndex(index)); - private Asset _GetReferencedNormalTextureFile(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Material Get(int index) - { - if (index < 0) return null; - var r = new Material(); - r.Index = index; - r.Name = GetName(index); - r.MaterialCategory = GetMaterialCategory(index); - r.Color_X = GetColor_X(index); - r.Color_Y = GetColor_Y(index); - r.Color_Z = GetColor_Z(index); - r.ColorUvScaling_X = GetColorUvScaling_X(index); - r.ColorUvScaling_Y = GetColorUvScaling_Y(index); - r.ColorUvOffset_X = GetColorUvOffset_X(index); - r.ColorUvOffset_Y = GetColorUvOffset_Y(index); - r.NormalUvScaling_X = GetNormalUvScaling_X(index); - r.NormalUvScaling_Y = GetNormalUvScaling_Y(index); - r.NormalUvOffset_X = GetNormalUvOffset_X(index); - r.NormalUvOffset_Y = GetNormalUvOffset_Y(index); - r.NormalAmount = GetNormalAmount(index); - r.Glossiness = GetGlossiness(index); - r.Smoothness = GetSmoothness(index); - r.Transparency = GetTransparency(index); - r._ColorTextureFile = new Relation(GetColorTextureFileIndex(index), _GetReferencedColorTextureFile); - r._NormalTextureFile = new Relation(GetNormalTextureFileIndex(index), _GetReferencedNormalTextureFile); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class MaterialTable - - public partial class MaterialInElementTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.MaterialInElement; - - public EntityTableSet ParentTableSet { get; } // can be null - - public MaterialInElementTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Area = GetDataColumnValues("double:Area") ?? Array.Empty(); - Column_Volume = GetDataColumnValues("double:Volume") ?? Array.Empty(); - Column_IsPaint = GetDataColumnValues("byte:IsPaint") ?? Array.Empty(); - Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_Area { get; } - public Double GetArea(int index, Double @default = default) => Column_Area.ElementAtOrDefault(index, @default); - public Double[] Column_Volume { get; } - public Double GetVolume(int index, Double @default = default) => Column_Volume.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsPaint { get; } - public Boolean GetIsPaint(int index, Boolean @default = default) => Column_IsPaint.ElementAtOrDefault(index, @default); - public int[] Column_MaterialIndex { get; } - public int GetMaterialIndex(int index) => Column_MaterialIndex.ElementAtOrDefault(index, EntityRelation.None); - public Material GetMaterial(int index) => _GetReferencedMaterial(GetMaterialIndex(index)); - private Material _GetReferencedMaterial(int referencedIndex) => ParentTableSet.GetMaterial(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public MaterialInElement Get(int index) - { - if (index < 0) return null; - var r = new MaterialInElement(); - r.Index = index; - r.Area = GetArea(index); - r.Volume = GetVolume(index); - r.IsPaint = GetIsPaint(index); - r._Material = new Relation(GetMaterialIndex(index), _GetReferencedMaterial); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class MaterialInElementTable - - public partial class CompoundStructureLayerTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.CompoundStructureLayer; - - public EntityTableSet ParentTableSet { get; } // can be null - - public CompoundStructureLayerTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_OrderIndex = GetDataColumnValues("int:OrderIndex") ?? Array.Empty(); - Column_Width = GetDataColumnValues("double:Width") ?? Array.Empty(); - Column_MaterialFunctionAssignment = GetStringColumnValues("string:MaterialFunctionAssignment") ?? Array.Empty(); - Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); - Column_CompoundStructureIndex = GetIndexColumnValues("index:Vim.CompoundStructure:CompoundStructure") ?? Array.Empty(); - } - - public Int32[] Column_OrderIndex { get; } - public Int32 GetOrderIndex(int index, Int32 @default = default) => Column_OrderIndex.ElementAtOrDefault(index, @default); - public Double[] Column_Width { get; } - public Double GetWidth(int index, Double @default = default) => Column_Width.ElementAtOrDefault(index, @default); - public String[] Column_MaterialFunctionAssignment { get; } - public String GetMaterialFunctionAssignment(int index, String @default = "") => Column_MaterialFunctionAssignment.ElementAtOrDefault(index, @default); - public int[] Column_MaterialIndex { get; } - public int GetMaterialIndex(int index) => Column_MaterialIndex.ElementAtOrDefault(index, EntityRelation.None); - public Material GetMaterial(int index) => _GetReferencedMaterial(GetMaterialIndex(index)); - private Material _GetReferencedMaterial(int referencedIndex) => ParentTableSet.GetMaterial(referencedIndex); - public int[] Column_CompoundStructureIndex { get; } - public int GetCompoundStructureIndex(int index) => Column_CompoundStructureIndex.ElementAtOrDefault(index, EntityRelation.None); - public CompoundStructure GetCompoundStructure(int index) => _GetReferencedCompoundStructure(GetCompoundStructureIndex(index)); - private CompoundStructure _GetReferencedCompoundStructure(int referencedIndex) => ParentTableSet.GetCompoundStructure(referencedIndex); - // Object Getter - public CompoundStructureLayer Get(int index) - { - if (index < 0) return null; - var r = new CompoundStructureLayer(); - r.Index = index; - r.OrderIndex = GetOrderIndex(index); - r.Width = GetWidth(index); - r.MaterialFunctionAssignment = GetMaterialFunctionAssignment(index); - r._Material = new Relation(GetMaterialIndex(index), _GetReferencedMaterial); - r._CompoundStructure = new Relation(GetCompoundStructureIndex(index), _GetReferencedCompoundStructure); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class CompoundStructureLayerTable - - public partial class CompoundStructureTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.CompoundStructure; - - public EntityTableSet ParentTableSet { get; } // can be null - - public CompoundStructureTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Width = GetDataColumnValues("double:Width") ?? Array.Empty(); - Column_StructuralLayerIndex = GetIndexColumnValues("index:Vim.CompoundStructureLayer:StructuralLayer") ?? Array.Empty(); - } - - public Double[] Column_Width { get; } - public Double GetWidth(int index, Double @default = default) => Column_Width.ElementAtOrDefault(index, @default); - public int[] Column_StructuralLayerIndex { get; } - public int GetStructuralLayerIndex(int index) => Column_StructuralLayerIndex.ElementAtOrDefault(index, EntityRelation.None); - public CompoundStructureLayer GetStructuralLayer(int index) => _GetReferencedStructuralLayer(GetStructuralLayerIndex(index)); - private CompoundStructureLayer _GetReferencedStructuralLayer(int referencedIndex) => ParentTableSet.GetCompoundStructureLayer(referencedIndex); - // Object Getter - public CompoundStructure Get(int index) - { - if (index < 0) return null; - var r = new CompoundStructure(); - r.Index = index; - r.Width = GetWidth(index); - r._StructuralLayer = new Relation(GetStructuralLayerIndex(index), _GetReferencedStructuralLayer); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class CompoundStructureTable - - public partial class NodeTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Node; - - public EntityTableSet ParentTableSet { get; } // can be null - - public NodeTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Node Get(int index) - { - if (index < 0) return null; - var r = new Node(); - r.Index = index; - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class NodeTable - - public partial class GeometryTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Geometry; - - public EntityTableSet ParentTableSet { get; } // can be null - - public GeometryTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Box_Min_X = GetDataColumnValues("float:Box.Min.X") ?? Array.Empty(); - Column_Box_Min_Y = GetDataColumnValues("float:Box.Min.Y") ?? Array.Empty(); - Column_Box_Min_Z = GetDataColumnValues("float:Box.Min.Z") ?? Array.Empty(); - Column_Box_Max_X = GetDataColumnValues("float:Box.Max.X") ?? Array.Empty(); - Column_Box_Max_Y = GetDataColumnValues("float:Box.Max.Y") ?? Array.Empty(); - Column_Box_Max_Z = GetDataColumnValues("float:Box.Max.Z") ?? Array.Empty(); - Column_VertexCount = GetDataColumnValues("int:VertexCount") ?? Array.Empty(); - Column_FaceCount = GetDataColumnValues("int:FaceCount") ?? Array.Empty(); - } - - public Single[] Column_Box_Min_X { get; } - public Single GetBox_Min_X(int index, Single @default = default) => Column_Box_Min_X.ElementAtOrDefault(index, @default); - public Single[] Column_Box_Min_Y { get; } - public Single GetBox_Min_Y(int index, Single @default = default) => Column_Box_Min_Y.ElementAtOrDefault(index, @default); - public Single[] Column_Box_Min_Z { get; } - public Single GetBox_Min_Z(int index, Single @default = default) => Column_Box_Min_Z.ElementAtOrDefault(index, @default); - public Single[] Column_Box_Max_X { get; } - public Single GetBox_Max_X(int index, Single @default = default) => Column_Box_Max_X.ElementAtOrDefault(index, @default); - public Single[] Column_Box_Max_Y { get; } - public Single GetBox_Max_Y(int index, Single @default = default) => Column_Box_Max_Y.ElementAtOrDefault(index, @default); - public Single[] Column_Box_Max_Z { get; } - public Single GetBox_Max_Z(int index, Single @default = default) => Column_Box_Max_Z.ElementAtOrDefault(index, @default); - public Int32[] Column_VertexCount { get; } - public Int32 GetVertexCount(int index, Int32 @default = default) => Column_VertexCount.ElementAtOrDefault(index, @default); - public Int32[] Column_FaceCount { get; } - public Int32 GetFaceCount(int index, Int32 @default = default) => Column_FaceCount.ElementAtOrDefault(index, @default); - // Object Getter - public Geometry Get(int index) - { - if (index < 0) return null; - var r = new Geometry(); - r.Index = index; - r.Box_Min_X = GetBox_Min_X(index); - r.Box_Min_Y = GetBox_Min_Y(index); - r.Box_Min_Z = GetBox_Min_Z(index); - r.Box_Max_X = GetBox_Max_X(index); - r.Box_Max_Y = GetBox_Max_Y(index); - r.Box_Max_Z = GetBox_Max_Z(index); - r.VertexCount = GetVertexCount(index); - r.FaceCount = GetFaceCount(index); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class GeometryTable - - public partial class ShapeTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Shape; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ShapeTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Shape Get(int index) - { - if (index < 0) return null; - var r = new Shape(); - r.Index = index; - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ShapeTable - - public partial class ShapeCollectionTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ShapeCollection; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ShapeCollectionTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public ShapeCollection Get(int index) - { - if (index < 0) return null; - var r = new ShapeCollection(); - r.Index = index; - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ShapeCollectionTable - - public partial class ShapeInShapeCollectionTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ShapeInShapeCollection; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ShapeInShapeCollectionTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ShapeIndex = GetIndexColumnValues("index:Vim.Shape:Shape") ?? Array.Empty(); - Column_ShapeCollectionIndex = GetIndexColumnValues("index:Vim.ShapeCollection:ShapeCollection") ?? Array.Empty(); - } - - public int[] Column_ShapeIndex { get; } - public int GetShapeIndex(int index) => Column_ShapeIndex.ElementAtOrDefault(index, EntityRelation.None); - public Shape GetShape(int index) => _GetReferencedShape(GetShapeIndex(index)); - private Shape _GetReferencedShape(int referencedIndex) => ParentTableSet.GetShape(referencedIndex); - public int[] Column_ShapeCollectionIndex { get; } - public int GetShapeCollectionIndex(int index) => Column_ShapeCollectionIndex.ElementAtOrDefault(index, EntityRelation.None); - public ShapeCollection GetShapeCollection(int index) => _GetReferencedShapeCollection(GetShapeCollectionIndex(index)); - private ShapeCollection _GetReferencedShapeCollection(int referencedIndex) => ParentTableSet.GetShapeCollection(referencedIndex); - // Object Getter - public ShapeInShapeCollection Get(int index) - { - if (index < 0) return null; - var r = new ShapeInShapeCollection(); - r.Index = index; - r._Shape = new Relation(GetShapeIndex(index), _GetReferencedShape); - r._ShapeCollection = new Relation(GetShapeCollectionIndex(index), _GetReferencedShapeCollection); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ShapeInShapeCollectionTable - - public partial class SystemTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.System; - - public EntityTableSet ParentTableSet { get; } // can be null - - public SystemTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_SystemType = GetDataColumnValues("int:SystemType") ?? Array.Empty(); - Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Int32[] Column_SystemType { get; } - public Int32 GetSystemType(int index, Int32 @default = default) => Column_SystemType.ElementAtOrDefault(index, @default); - public int[] Column_FamilyTypeIndex { get; } - public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); - public FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); - private FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public System Get(int index) - { - if (index < 0) return null; - var r = new System(); - r.Index = index; - r.SystemType = GetSystemType(index); - r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class SystemTable - - public partial class ElementInSystemTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ElementInSystem; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ElementInSystemTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Roles = GetDataColumnValues("int:Roles") ?? Array.Empty(); - Column_SystemIndex = GetIndexColumnValues("index:Vim.System:System") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Int32[] Column_Roles { get; } - public Int32 GetRoles(int index, Int32 @default = default) => Column_Roles.ElementAtOrDefault(index, @default); - public int[] Column_SystemIndex { get; } - public int GetSystemIndex(int index) => Column_SystemIndex.ElementAtOrDefault(index, EntityRelation.None); - public System GetSystem(int index) => _GetReferencedSystem(GetSystemIndex(index)); - private System _GetReferencedSystem(int referencedIndex) => ParentTableSet.GetSystem(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public ElementInSystem Get(int index) - { - if (index < 0) return null; - var r = new ElementInSystem(); - r.Index = index; - r.Roles = GetRoles(index); - r._System = new Relation(GetSystemIndex(index), _GetReferencedSystem); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ElementInSystemTable - - public partial class WarningTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.Warning; - - public EntityTableSet ParentTableSet { get; } // can be null - - public WarningTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Guid = GetStringColumnValues("string:Guid") ?? Array.Empty(); - Column_Severity = GetStringColumnValues("string:Severity") ?? Array.Empty(); - Column_Description = GetStringColumnValues("string:Description") ?? Array.Empty(); - Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); - } - - public String[] Column_Guid { get; } - public String GetGuid(int index, String @default = "") => Column_Guid.ElementAtOrDefault(index, @default); - public String[] Column_Severity { get; } - public String GetSeverity(int index, String @default = "") => Column_Severity.ElementAtOrDefault(index, @default); - public String[] Column_Description { get; } - public String GetDescription(int index, String @default = "") => Column_Description.ElementAtOrDefault(index, @default); - public int[] Column_BimDocumentIndex { get; } - public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); - public BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); - private BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); - // Object Getter - public Warning Get(int index) - { - if (index < 0) return null; - var r = new Warning(); - r.Index = index; - r.Guid = GetGuid(index); - r.Severity = GetSeverity(index); - r.Description = GetDescription(index); - r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class WarningTable - - public partial class ElementInWarningTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ElementInWarning; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ElementInWarningTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_WarningIndex = GetIndexColumnValues("index:Vim.Warning:Warning") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_WarningIndex { get; } - public int GetWarningIndex(int index) => Column_WarningIndex.ElementAtOrDefault(index, EntityRelation.None); - public Warning GetWarning(int index) => _GetReferencedWarning(GetWarningIndex(index)); - private Warning _GetReferencedWarning(int referencedIndex) => ParentTableSet.GetWarning(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public ElementInWarning Get(int index) - { - if (index < 0) return null; - var r = new ElementInWarning(); - r.Index = index; - r._Warning = new Relation(GetWarningIndex(index), _GetReferencedWarning); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ElementInWarningTable - - public partial class BasePointTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.BasePoint; - - public EntityTableSet ParentTableSet { get; } // can be null - - public BasePointTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_IsSurveyPoint = GetDataColumnValues("byte:IsSurveyPoint") ?? Array.Empty(); - Column_Position_X = GetDataColumnValues("double:Position.X") ?? Array.Empty(); - Column_Position_Y = GetDataColumnValues("double:Position.Y") ?? Array.Empty(); - Column_Position_Z = GetDataColumnValues("double:Position.Z") ?? Array.Empty(); - Column_SharedPosition_X = GetDataColumnValues("double:SharedPosition.X") ?? Array.Empty(); - Column_SharedPosition_Y = GetDataColumnValues("double:SharedPosition.Y") ?? Array.Empty(); - Column_SharedPosition_Z = GetDataColumnValues("double:SharedPosition.Z") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Boolean[] Column_IsSurveyPoint { get; } - public Boolean GetIsSurveyPoint(int index, Boolean @default = default) => Column_IsSurveyPoint.ElementAtOrDefault(index, @default); - public Double[] Column_Position_X { get; } - public Double GetPosition_X(int index, Double @default = default) => Column_Position_X.ElementAtOrDefault(index, @default); - public Double[] Column_Position_Y { get; } - public Double GetPosition_Y(int index, Double @default = default) => Column_Position_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Position_Z { get; } - public Double GetPosition_Z(int index, Double @default = default) => Column_Position_Z.ElementAtOrDefault(index, @default); - public Double[] Column_SharedPosition_X { get; } - public Double GetSharedPosition_X(int index, Double @default = default) => Column_SharedPosition_X.ElementAtOrDefault(index, @default); - public Double[] Column_SharedPosition_Y { get; } - public Double GetSharedPosition_Y(int index, Double @default = default) => Column_SharedPosition_Y.ElementAtOrDefault(index, @default); - public Double[] Column_SharedPosition_Z { get; } - public Double GetSharedPosition_Z(int index, Double @default = default) => Column_SharedPosition_Z.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public BasePoint Get(int index) - { - if (index < 0) return null; - var r = new BasePoint(); - r.Index = index; - r.IsSurveyPoint = GetIsSurveyPoint(index); - r.Position_X = GetPosition_X(index); - r.Position_Y = GetPosition_Y(index); - r.Position_Z = GetPosition_Z(index); - r.SharedPosition_X = GetSharedPosition_X(index); - r.SharedPosition_Y = GetSharedPosition_Y(index); - r.SharedPosition_Z = GetSharedPosition_Z(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class BasePointTable - - public partial class PhaseFilterTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.PhaseFilter; - - public EntityTableSet ParentTableSet { get; } // can be null - - public PhaseFilterTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_New = GetDataColumnValues("int:New") ?? Array.Empty(); - Column_Existing = GetDataColumnValues("int:Existing") ?? Array.Empty(); - Column_Demolished = GetDataColumnValues("int:Demolished") ?? Array.Empty(); - Column_Temporary = GetDataColumnValues("int:Temporary") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Int32[] Column_New { get; } - public Int32 GetNew(int index, Int32 @default = default) => Column_New.ElementAtOrDefault(index, @default); - public Int32[] Column_Existing { get; } - public Int32 GetExisting(int index, Int32 @default = default) => Column_Existing.ElementAtOrDefault(index, @default); - public Int32[] Column_Demolished { get; } - public Int32 GetDemolished(int index, Int32 @default = default) => Column_Demolished.ElementAtOrDefault(index, @default); - public Int32[] Column_Temporary { get; } - public Int32 GetTemporary(int index, Int32 @default = default) => Column_Temporary.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public PhaseFilter Get(int index) - { - if (index < 0) return null; - var r = new PhaseFilter(); - r.Index = index; - r.New = GetNew(index); - r.Existing = GetExisting(index); - r.Demolished = GetDemolished(index); - r.Temporary = GetTemporary(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class PhaseFilterTable - - public partial class GridTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Grid; - - public EntityTableSet ParentTableSet { get; } // can be null - - public GridTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_StartPoint_X = GetDataColumnValues("double:StartPoint.X") ?? Array.Empty(); - Column_StartPoint_Y = GetDataColumnValues("double:StartPoint.Y") ?? Array.Empty(); - Column_StartPoint_Z = GetDataColumnValues("double:StartPoint.Z") ?? Array.Empty(); - Column_EndPoint_X = GetDataColumnValues("double:EndPoint.X") ?? Array.Empty(); - Column_EndPoint_Y = GetDataColumnValues("double:EndPoint.Y") ?? Array.Empty(); - Column_EndPoint_Z = GetDataColumnValues("double:EndPoint.Z") ?? Array.Empty(); - Column_IsCurved = GetDataColumnValues("byte:IsCurved") ?? Array.Empty(); - Column_Extents_Min_X = GetDataColumnValues("double:Extents.Min.X") ?? Array.Empty(); - Column_Extents_Min_Y = GetDataColumnValues("double:Extents.Min.Y") ?? Array.Empty(); - Column_Extents_Min_Z = GetDataColumnValues("double:Extents.Min.Z") ?? Array.Empty(); - Column_Extents_Max_X = GetDataColumnValues("double:Extents.Max.X") ?? Array.Empty(); - Column_Extents_Max_Y = GetDataColumnValues("double:Extents.Max.Y") ?? Array.Empty(); - Column_Extents_Max_Z = GetDataColumnValues("double:Extents.Max.Z") ?? Array.Empty(); - Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_StartPoint_X { get; } - public Double GetStartPoint_X(int index, Double @default = default) => Column_StartPoint_X.ElementAtOrDefault(index, @default); - public Double[] Column_StartPoint_Y { get; } - public Double GetStartPoint_Y(int index, Double @default = default) => Column_StartPoint_Y.ElementAtOrDefault(index, @default); - public Double[] Column_StartPoint_Z { get; } - public Double GetStartPoint_Z(int index, Double @default = default) => Column_StartPoint_Z.ElementAtOrDefault(index, @default); - public Double[] Column_EndPoint_X { get; } - public Double GetEndPoint_X(int index, Double @default = default) => Column_EndPoint_X.ElementAtOrDefault(index, @default); - public Double[] Column_EndPoint_Y { get; } - public Double GetEndPoint_Y(int index, Double @default = default) => Column_EndPoint_Y.ElementAtOrDefault(index, @default); - public Double[] Column_EndPoint_Z { get; } - public Double GetEndPoint_Z(int index, Double @default = default) => Column_EndPoint_Z.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsCurved { get; } - public Boolean GetIsCurved(int index, Boolean @default = default) => Column_IsCurved.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Min_X { get; } - public Double GetExtents_Min_X(int index, Double @default = default) => Column_Extents_Min_X.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Min_Y { get; } - public Double GetExtents_Min_Y(int index, Double @default = default) => Column_Extents_Min_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Min_Z { get; } - public Double GetExtents_Min_Z(int index, Double @default = default) => Column_Extents_Min_Z.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Max_X { get; } - public Double GetExtents_Max_X(int index, Double @default = default) => Column_Extents_Max_X.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Max_Y { get; } - public Double GetExtents_Max_Y(int index, Double @default = default) => Column_Extents_Max_Y.ElementAtOrDefault(index, @default); - public Double[] Column_Extents_Max_Z { get; } - public Double GetExtents_Max_Z(int index, Double @default = default) => Column_Extents_Max_Z.ElementAtOrDefault(index, @default); - public int[] Column_FamilyTypeIndex { get; } - public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); - public FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); - private FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Grid Get(int index) - { - if (index < 0) return null; - var r = new Grid(); - r.Index = index; - r.StartPoint_X = GetStartPoint_X(index); - r.StartPoint_Y = GetStartPoint_Y(index); - r.StartPoint_Z = GetStartPoint_Z(index); - r.EndPoint_X = GetEndPoint_X(index); - r.EndPoint_Y = GetEndPoint_Y(index); - r.EndPoint_Z = GetEndPoint_Z(index); - r.IsCurved = GetIsCurved(index); - r.Extents_Min_X = GetExtents_Min_X(index); - r.Extents_Min_Y = GetExtents_Min_Y(index); - r.Extents_Min_Z = GetExtents_Min_Z(index); - r.Extents_Max_X = GetExtents_Max_X(index); - r.Extents_Max_Y = GetExtents_Max_Y(index); - r.Extents_Max_Z = GetExtents_Max_Z(index); - r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class GridTable - - public partial class AreaTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Area; - - public EntityTableSet ParentTableSet { get; } // can be null - - public AreaTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Value = GetDataColumnValues("double:Value") ?? Array.Empty(); - Column_Perimeter = GetDataColumnValues("double:Perimeter") ?? Array.Empty(); - Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); - Column_IsGrossInterior = GetDataColumnValues("byte:IsGrossInterior") ?? Array.Empty(); - Column_AreaSchemeIndex = GetIndexColumnValues("index:Vim.AreaScheme:AreaScheme") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_Value { get; } - public Double GetValue(int index, Double @default = default) => Column_Value.ElementAtOrDefault(index, @default); - public Double[] Column_Perimeter { get; } - public Double GetPerimeter(int index, Double @default = default) => Column_Perimeter.ElementAtOrDefault(index, @default); - public String[] Column_Number { get; } - public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); - public Boolean[] Column_IsGrossInterior { get; } - public Boolean GetIsGrossInterior(int index, Boolean @default = default) => Column_IsGrossInterior.ElementAtOrDefault(index, @default); - public int[] Column_AreaSchemeIndex { get; } - public int GetAreaSchemeIndex(int index) => Column_AreaSchemeIndex.ElementAtOrDefault(index, EntityRelation.None); - public AreaScheme GetAreaScheme(int index) => _GetReferencedAreaScheme(GetAreaSchemeIndex(index)); - private AreaScheme _GetReferencedAreaScheme(int referencedIndex) => ParentTableSet.GetAreaScheme(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Area Get(int index) - { - if (index < 0) return null; - var r = new Area(); - r.Index = index; - r.Value = GetValue(index); - r.Perimeter = GetPerimeter(index); - r.Number = GetNumber(index); - r.IsGrossInterior = GetIsGrossInterior(index); - r._AreaScheme = new Relation(GetAreaSchemeIndex(index), _GetReferencedAreaScheme); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class AreaTable - - public partial class AreaSchemeTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.AreaScheme; - - public EntityTableSet ParentTableSet { get; } // can be null - - public AreaSchemeTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_IsGrossBuildingArea = GetDataColumnValues("byte:IsGrossBuildingArea") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Boolean[] Column_IsGrossBuildingArea { get; } - public Boolean GetIsGrossBuildingArea(int index, Boolean @default = default) => Column_IsGrossBuildingArea.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public AreaScheme Get(int index) - { - if (index < 0) return null; - var r = new AreaScheme(); - r.Index = index; - r.IsGrossBuildingArea = GetIsGrossBuildingArea(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class AreaSchemeTable - - public partial class ScheduleTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Schedule; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ScheduleTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Schedule Get(int index) - { - if (index < 0) return null; - var r = new Schedule(); - r.Index = index; - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ScheduleTable - - public partial class ScheduleColumnTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ScheduleColumn; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ScheduleColumnTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); - Column_ColumnIndex = GetDataColumnValues("int:ColumnIndex") ?? Array.Empty(); - Column_ScheduleIndex = GetIndexColumnValues("index:Vim.Schedule:Schedule") ?? Array.Empty(); - } - - public String[] Column_Name { get; } - public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); - public Int32[] Column_ColumnIndex { get; } - public Int32 GetColumnIndex(int index, Int32 @default = default) => Column_ColumnIndex.ElementAtOrDefault(index, @default); - public int[] Column_ScheduleIndex { get; } - public int GetScheduleIndex(int index) => Column_ScheduleIndex.ElementAtOrDefault(index, EntityRelation.None); - public Schedule GetSchedule(int index) => _GetReferencedSchedule(GetScheduleIndex(index)); - private Schedule _GetReferencedSchedule(int referencedIndex) => ParentTableSet.GetSchedule(referencedIndex); - // Object Getter - public ScheduleColumn Get(int index) - { - if (index < 0) return null; - var r = new ScheduleColumn(); - r.Index = index; - r.Name = GetName(index); - r.ColumnIndex = GetColumnIndex(index); - r._Schedule = new Relation(GetScheduleIndex(index), _GetReferencedSchedule); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ScheduleColumnTable - - public partial class ScheduleCellTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ScheduleCell; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ScheduleCellTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Value = GetStringColumnValues("string:Value") ?? Array.Empty(); - Column_RowIndex = GetDataColumnValues("int:RowIndex") ?? Array.Empty(); - Column_ScheduleColumnIndex = GetIndexColumnValues("index:Vim.ScheduleColumn:ScheduleColumn") ?? Array.Empty(); - } - - public String[] Column_Value { get; } - public String GetValue(int index, String @default = "") => Column_Value.ElementAtOrDefault(index, @default); - public Int32[] Column_RowIndex { get; } - public Int32 GetRowIndex(int index, Int32 @default = default) => Column_RowIndex.ElementAtOrDefault(index, @default); - public int[] Column_ScheduleColumnIndex { get; } - public int GetScheduleColumnIndex(int index) => Column_ScheduleColumnIndex.ElementAtOrDefault(index, EntityRelation.None); - public ScheduleColumn GetScheduleColumn(int index) => _GetReferencedScheduleColumn(GetScheduleColumnIndex(index)); - private ScheduleColumn _GetReferencedScheduleColumn(int referencedIndex) => ParentTableSet.GetScheduleColumn(referencedIndex); - // Object Getter - public ScheduleCell Get(int index) - { - if (index < 0) return null; - var r = new ScheduleCell(); - r.Index = index; - r.Value = GetValue(index); - r.RowIndex = GetRowIndex(index); - r._ScheduleColumn = new Relation(GetScheduleColumnIndex(index), _GetReferencedScheduleColumn); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ScheduleCellTable - - public partial class ViewSheetSetTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.ViewSheetSet; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ViewSheetSetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public ViewSheetSet Get(int index) - { - if (index < 0) return null; - var r = new ViewSheetSet(); - r.Index = index; - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ViewSheetSetTable - - public partial class ViewSheetTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.ViewSheet; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ViewSheetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public int[] Column_FamilyTypeIndex { get; } - public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); - public FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); - private FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public ViewSheet Get(int index) - { - if (index < 0) return null; - var r = new ViewSheet(); - r.Index = index; - r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ViewSheetTable - - public partial class ViewSheetInViewSheetSetTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ViewSheetInViewSheetSet; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ViewSheetInViewSheetSetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ViewSheetIndex = GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty(); - Column_ViewSheetSetIndex = GetIndexColumnValues("index:Vim.ViewSheetSet:ViewSheetSet") ?? Array.Empty(); - } - - public int[] Column_ViewSheetIndex { get; } - public int GetViewSheetIndex(int index) => Column_ViewSheetIndex.ElementAtOrDefault(index, EntityRelation.None); - public ViewSheet GetViewSheet(int index) => _GetReferencedViewSheet(GetViewSheetIndex(index)); - private ViewSheet _GetReferencedViewSheet(int referencedIndex) => ParentTableSet.GetViewSheet(referencedIndex); - public int[] Column_ViewSheetSetIndex { get; } - public int GetViewSheetSetIndex(int index) => Column_ViewSheetSetIndex.ElementAtOrDefault(index, EntityRelation.None); - public ViewSheetSet GetViewSheetSet(int index) => _GetReferencedViewSheetSet(GetViewSheetSetIndex(index)); - private ViewSheetSet _GetReferencedViewSheetSet(int referencedIndex) => ParentTableSet.GetViewSheetSet(referencedIndex); - // Object Getter - public ViewSheetInViewSheetSet Get(int index) - { - if (index < 0) return null; - var r = new ViewSheetInViewSheetSet(); - r.Index = index; - r._ViewSheet = new Relation(GetViewSheetIndex(index), _GetReferencedViewSheet); - r._ViewSheetSet = new Relation(GetViewSheetSetIndex(index), _GetReferencedViewSheetSet); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ViewSheetInViewSheetSetTable - - public partial class ViewInViewSheetSetTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ViewInViewSheetSet; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ViewInViewSheetSetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); - Column_ViewSheetSetIndex = GetIndexColumnValues("index:Vim.ViewSheetSet:ViewSheetSet") ?? Array.Empty(); - } - - public int[] Column_ViewIndex { get; } - public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetView(int index) => _GetReferencedView(GetViewIndex(index)); - private View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - public int[] Column_ViewSheetSetIndex { get; } - public int GetViewSheetSetIndex(int index) => Column_ViewSheetSetIndex.ElementAtOrDefault(index, EntityRelation.None); - public ViewSheetSet GetViewSheetSet(int index) => _GetReferencedViewSheetSet(GetViewSheetSetIndex(index)); - private ViewSheetSet _GetReferencedViewSheetSet(int referencedIndex) => ParentTableSet.GetViewSheetSet(referencedIndex); - // Object Getter - public ViewInViewSheetSet Get(int index) - { - if (index < 0) return null; - var r = new ViewInViewSheetSet(); - r.Index = index; - r._View = new Relation(GetViewIndex(index), _GetReferencedView); - r._ViewSheetSet = new Relation(GetViewSheetSetIndex(index), _GetReferencedViewSheetSet); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ViewInViewSheetSetTable - - public partial class ViewInViewSheetTable : EntityTable_v2, IEnumerable - { - - public const string TableName = TableNames.ViewInViewSheet; - - public EntityTableSet ParentTableSet { get; } // can be null - - public ViewInViewSheetTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); - Column_ViewSheetIndex = GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty(); - } - - public int[] Column_ViewIndex { get; } - public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); - public View GetView(int index) => _GetReferencedView(GetViewIndex(index)); - private View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); - public int[] Column_ViewSheetIndex { get; } - public int GetViewSheetIndex(int index) => Column_ViewSheetIndex.ElementAtOrDefault(index, EntityRelation.None); - public ViewSheet GetViewSheet(int index) => _GetReferencedViewSheet(GetViewSheetIndex(index)); - private ViewSheet _GetReferencedViewSheet(int referencedIndex) => ParentTableSet.GetViewSheet(referencedIndex); - // Object Getter - public ViewInViewSheet Get(int index) - { - if (index < 0) return null; - var r = new ViewInViewSheet(); - r.Index = index; - r._View = new Relation(GetViewIndex(index), _GetReferencedView); - r._ViewSheet = new Relation(GetViewSheetIndex(index), _GetReferencedViewSheet); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class ViewInViewSheetTable - - public partial class SiteTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Site; - - public EntityTableSet ParentTableSet { get; } // can be null - - public SiteTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Latitude = GetDataColumnValues("double:Latitude") ?? Array.Empty(); - Column_Longitude = GetDataColumnValues("double:Longitude") ?? Array.Empty(); - Column_Address = GetStringColumnValues("string:Address") ?? Array.Empty(); - Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); - Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_Latitude { get; } - public Double GetLatitude(int index, Double @default = default) => Column_Latitude.ElementAtOrDefault(index, @default); - public Double[] Column_Longitude { get; } - public Double GetLongitude(int index, Double @default = default) => Column_Longitude.ElementAtOrDefault(index, @default); - public String[] Column_Address { get; } - public String GetAddress(int index, String @default = "") => Column_Address.ElementAtOrDefault(index, @default); - public Double[] Column_Elevation { get; } - public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); - public String[] Column_Number { get; } - public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Site Get(int index) - { - if (index < 0) return null; - var r = new Site(); - r.Index = index; - r.Latitude = GetLatitude(index); - r.Longitude = GetLongitude(index); - r.Address = GetAddress(index); - r.Elevation = GetElevation(index); - r.Number = GetNumber(index); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class SiteTable - - public partial class BuildingTable : EntityTable_v2, IEnumerable , IElementKindTable - { - - public const string TableName = TableNames.Building; - - public EntityTableSet ParentTableSet { get; } // can be null - - public BuildingTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) - { - ParentTableSet = parentTableSet; - Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); - Column_TerrainElevation = GetDataColumnValues("double:TerrainElevation") ?? Array.Empty(); - Column_Address = GetStringColumnValues("string:Address") ?? Array.Empty(); - Column_SiteIndex = GetIndexColumnValues("index:Vim.Site:Site") ?? Array.Empty(); - Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); - } - - public Double[] Column_Elevation { get; } - public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); - public Double[] Column_TerrainElevation { get; } - public Double GetTerrainElevation(int index, Double @default = default) => Column_TerrainElevation.ElementAtOrDefault(index, @default); - public String[] Column_Address { get; } - public String GetAddress(int index, String @default = "") => Column_Address.ElementAtOrDefault(index, @default); - public int[] Column_SiteIndex { get; } - public int GetSiteIndex(int index) => Column_SiteIndex.ElementAtOrDefault(index, EntityRelation.None); - public Site GetSite(int index) => _GetReferencedSite(GetSiteIndex(index)); - private Site _GetReferencedSite(int referencedIndex) => ParentTableSet.GetSite(referencedIndex); - public int[] Column_ElementIndex { get; } - public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); - public Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); - private Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); - // Object Getter - public Building Get(int index) - { - if (index < 0) return null; - var r = new Building(); - r.Index = index; - r.Elevation = GetElevation(index); - r.TerrainElevation = GetTerrainElevation(index); - r.Address = GetAddress(index); - r._Site = new Relation(GetSiteIndex(index), _GetReferencedSite); - r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); - return r; - } - // Enumerator - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - for (var i = 0; i < RowCount; ++i) - yield return Get(i); - } - } // class BuildingTable - - public static class DocumentBuilderExtensions - { - public static EntityTableBuilder ToAssetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Asset); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BufferName; } - tb.AddStringColumn("string:BufferName", columnData); - } - return tb; - } - public static EntityTableBuilder ToDisplayUnitTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.DisplayUnit); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Spec; } - tb.AddStringColumn("string:Spec", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Type; } - tb.AddStringColumn("string:Type", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Label; } - tb.AddStringColumn("string:Label", columnData); - } - return tb; - } - public static EntityTableBuilder ToParameterDescriptorTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ParameterDescriptor); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Group; } - tb.AddStringColumn("string:Group", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ParameterType; } - tb.AddStringColumn("string:ParameterType", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsInstance; } - tb.AddDataColumn("byte:IsInstance", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsShared; } - tb.AddDataColumn("byte:IsShared", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsReadOnly; } - tb.AddDataColumn("byte:IsReadOnly", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Flags; } - tb.AddDataColumn("int:Flags", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Guid; } - tb.AddStringColumn("string:Guid", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StorageType; } - tb.AddDataColumn("int:StorageType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._DisplayUnit?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.DisplayUnit:DisplayUnit", columnData); - } - return tb; - } - public static EntityTableBuilder ToParameterTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Parameter); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Value; } - tb.AddStringColumn("string:Value", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ParameterDescriptor?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ParameterDescriptor:ParameterDescriptor", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToElementTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Element); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int64[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } - tb.AddDataColumn("long:Id", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Type; } - tb.AddStringColumn("string:Type", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UniqueId; } - tb.AddStringColumn("string:UniqueId", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Location_X; } - tb.AddDataColumn("float:Location.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Location_Y; } - tb.AddDataColumn("float:Location.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Location_Z; } - tb.AddDataColumn("float:Location.Z", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FamilyName; } - tb.AddStringColumn("string:FamilyName", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPinned; } - tb.AddDataColumn("byte:IsPinned", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Level?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Level:Level", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._PhaseCreated?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Phase:PhaseCreated", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._PhaseDemolished?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Phase:PhaseDemolished", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Category?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Category:Category", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Workset?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Workset:Workset", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._DesignOption?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.DesignOption:DesignOption", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._OwnerView?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:OwnerView", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Group?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Group:Group", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._AssemblyInstance?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.AssemblyInstance:AssemblyInstance", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Room?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Room:Room", columnData); - } - return tb; - } - public static EntityTableBuilder ToWorksetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Workset); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } - tb.AddDataColumn("int:Id", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Kind; } - tb.AddStringColumn("string:Kind", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsOpen; } - tb.AddDataColumn("byte:IsOpen", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsEditable; } - tb.AddDataColumn("byte:IsEditable", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Owner; } - tb.AddStringColumn("string:Owner", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UniqueId; } - tb.AddStringColumn("string:UniqueId", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); - } - return tb; - } - public static EntityTableBuilder ToAssemblyInstanceTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.AssemblyInstance); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].AssemblyTypeName; } - tb.AddStringColumn("string:AssemblyTypeName", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_X; } - tb.AddDataColumn("float:Position.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Y; } - tb.AddDataColumn("float:Position.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Z; } - tb.AddDataColumn("float:Position.Z", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToGroupTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Group); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].GroupType; } - tb.AddStringColumn("string:GroupType", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_X; } - tb.AddDataColumn("float:Position.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Y; } - tb.AddDataColumn("float:Position.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Z; } - tb.AddDataColumn("float:Position.Z", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToDesignOptionTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.DesignOption); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPrimary; } - tb.AddDataColumn("byte:IsPrimary", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToLevelTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Level); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } - tb.AddDataColumn("double:Elevation", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ProjectElevation; } - tb.AddDataColumn("double:ProjectElevation", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Building?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Building:Building", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToPhaseTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Phase); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToRoomTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Room); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BaseOffset; } - tb.AddDataColumn("double:BaseOffset", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LimitOffset; } - tb.AddDataColumn("double:LimitOffset", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UnboundedHeight; } - tb.AddDataColumn("double:UnboundedHeight", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Volume; } - tb.AddDataColumn("double:Volume", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Perimeter; } - tb.AddDataColumn("double:Perimeter", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Area; } - tb.AddDataColumn("double:Area", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } - tb.AddStringColumn("string:Number", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._UpperLimit?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Level:UpperLimit", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToBimDocumentTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.BimDocument); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Title; } - tb.AddStringColumn("string:Title", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsMetric; } - tb.AddDataColumn("byte:IsMetric", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Guid; } - tb.AddStringColumn("string:Guid", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NumSaves; } - tb.AddDataColumn("int:NumSaves", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsLinked; } - tb.AddDataColumn("byte:IsLinked", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsDetached; } - tb.AddDataColumn("byte:IsDetached", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsWorkshared; } - tb.AddDataColumn("byte:IsWorkshared", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].PathName; } - tb.AddStringColumn("string:PathName", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Latitude; } - tb.AddDataColumn("double:Latitude", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Longitude; } - tb.AddDataColumn("double:Longitude", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].TimeZone; } - tb.AddDataColumn("double:TimeZone", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].PlaceName; } - tb.AddStringColumn("string:PlaceName", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].WeatherStationName; } - tb.AddStringColumn("string:WeatherStationName", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } - tb.AddDataColumn("double:Elevation", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ProjectLocation; } - tb.AddStringColumn("string:ProjectLocation", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IssueDate; } - tb.AddStringColumn("string:IssueDate", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Status; } - tb.AddStringColumn("string:Status", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ClientName; } - tb.AddStringColumn("string:ClientName", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Address; } - tb.AddStringColumn("string:Address", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } - tb.AddStringColumn("string:Number", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Author; } - tb.AddStringColumn("string:Author", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BuildingName; } - tb.AddStringColumn("string:BuildingName", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrganizationName; } - tb.AddStringColumn("string:OrganizationName", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrganizationDescription; } - tb.AddStringColumn("string:OrganizationDescription", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Product; } - tb.AddStringColumn("string:Product", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Version; } - tb.AddStringColumn("string:Version", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].User; } - tb.AddStringColumn("string:User", columnData); - } - { - var columnData = new Int64[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FileLength; } - tb.AddDataColumn("long:FileLength", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ActiveView?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:ActiveView", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._OwnerFamily?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Family:OwnerFamily", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Parent?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.BimDocument:Parent", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToDisplayUnitInBimDocumentTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.DisplayUnitInBimDocument); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._DisplayUnit?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.DisplayUnit:DisplayUnit", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); - } - return tb; - } - public static EntityTableBuilder ToPhaseOrderInBimDocumentTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.PhaseOrderInBimDocument); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrderIndex; } - tb.AddDataColumn("int:OrderIndex", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Phase?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Phase:Phase", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); - } - return tb; - } - public static EntityTableBuilder ToCategoryTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Category); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new Int64[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } - tb.AddDataColumn("long:Id", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].CategoryType; } - tb.AddStringColumn("string:CategoryType", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LineColor_X; } - tb.AddDataColumn("double:LineColor.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LineColor_Y; } - tb.AddDataColumn("double:LineColor.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LineColor_Z; } - tb.AddDataColumn("double:LineColor.Z", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BuiltInCategory; } - tb.AddStringColumn("string:BuiltInCategory", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Parent?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Category:Parent", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Material?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Material:Material", columnData); - } - return tb; - } - public static EntityTableBuilder ToFamilyTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Family); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StructuralMaterialType; } - tb.AddStringColumn("string:StructuralMaterialType", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StructuralSectionShape; } - tb.AddStringColumn("string:StructuralSectionShape", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsSystemFamily; } - tb.AddDataColumn("byte:IsSystemFamily", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsInPlace; } - tb.AddDataColumn("byte:IsInPlace", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyCategory?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Category:FamilyCategory", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToFamilyTypeTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.FamilyType); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsSystemFamilyType; } - tb.AddDataColumn("byte:IsSystemFamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Family?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Family:Family", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._CompoundStructure?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.CompoundStructure:CompoundStructure", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToFamilyInstanceTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.FamilyInstance); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingFlipped; } - tb.AddDataColumn("byte:FacingFlipped", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingOrientation_X; } - tb.AddDataColumn("float:FacingOrientation.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingOrientation_Y; } - tb.AddDataColumn("float:FacingOrientation.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingOrientation_Z; } - tb.AddDataColumn("float:FacingOrientation.Z", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandFlipped; } - tb.AddDataColumn("byte:HandFlipped", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Mirrored; } - tb.AddDataColumn("byte:Mirrored", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HasModifiedGeometry; } - tb.AddDataColumn("byte:HasModifiedGeometry", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Scale; } - tb.AddDataColumn("float:Scale", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisX_X; } - tb.AddDataColumn("float:BasisX.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisX_Y; } - tb.AddDataColumn("float:BasisX.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisX_Z; } - tb.AddDataColumn("float:BasisX.Z", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisY_X; } - tb.AddDataColumn("float:BasisY.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisY_Y; } - tb.AddDataColumn("float:BasisY.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisY_Z; } - tb.AddDataColumn("float:BasisY.Z", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisZ_X; } - tb.AddDataColumn("float:BasisZ.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisZ_Y; } - tb.AddDataColumn("float:BasisZ.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisZ_Z; } - tb.AddDataColumn("float:BasisZ.Z", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Translation_X; } - tb.AddDataColumn("float:Translation.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Translation_Y; } - tb.AddDataColumn("float:Translation.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Translation_Z; } - tb.AddDataColumn("float:Translation.Z", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandOrientation_X; } - tb.AddDataColumn("float:HandOrientation.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandOrientation_Y; } - tb.AddDataColumn("float:HandOrientation.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandOrientation_Z; } - tb.AddDataColumn("float:HandOrientation.Z", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Host?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Host", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FromRoom?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Room:FromRoom", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ToRoom?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Room:ToRoom", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._SuperComponent?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:SuperComponent", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToViewTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.View); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Title; } - tb.AddStringColumn("string:Title", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewType; } - tb.AddStringColumn("string:ViewType", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Up_X; } - tb.AddDataColumn("double:Up.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Up_Y; } - tb.AddDataColumn("double:Up.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Up_Z; } - tb.AddDataColumn("double:Up.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Right_X; } - tb.AddDataColumn("double:Right.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Right_Y; } - tb.AddDataColumn("double:Right.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Right_Z; } - tb.AddDataColumn("double:Right.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Origin_X; } - tb.AddDataColumn("double:Origin.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Origin_Y; } - tb.AddDataColumn("double:Origin.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Origin_Z; } - tb.AddDataColumn("double:Origin.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewDirection_X; } - tb.AddDataColumn("double:ViewDirection.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewDirection_Y; } - tb.AddDataColumn("double:ViewDirection.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewDirection_Z; } - tb.AddDataColumn("double:ViewDirection.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewPosition_X; } - tb.AddDataColumn("double:ViewPosition.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewPosition_Y; } - tb.AddDataColumn("double:ViewPosition.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewPosition_Z; } - tb.AddDataColumn("double:ViewPosition.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Scale; } - tb.AddDataColumn("double:Scale", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Min_X; } - tb.AddDataColumn("double:Outline.Min.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Min_Y; } - tb.AddDataColumn("double:Outline.Min.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Max_X; } - tb.AddDataColumn("double:Outline.Max.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Max_Y; } - tb.AddDataColumn("double:Outline.Max.Y", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].DetailLevel; } - tb.AddDataColumn("int:DetailLevel", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Camera?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Camera:Camera", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToElementInViewTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ElementInView); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:View", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToShapeInViewTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ShapeInView); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Shape?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Shape:Shape", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:View", columnData); - } - return tb; - } - public static EntityTableBuilder ToAssetInViewTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.AssetInView); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Asset?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Asset:Asset", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:View", columnData); - } - return tb; - } - public static EntityTableBuilder ToAssetInViewSheetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.AssetInViewSheet); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Asset?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Asset:Asset", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheet?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ViewSheet:ViewSheet", columnData); - } - return tb; - } - public static EntityTableBuilder ToLevelInViewTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.LevelInView); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_X; } - tb.AddDataColumn("double:Extents.Min.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Y; } - tb.AddDataColumn("double:Extents.Min.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Z; } - tb.AddDataColumn("double:Extents.Min.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_X; } - tb.AddDataColumn("double:Extents.Max.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Y; } - tb.AddDataColumn("double:Extents.Max.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Z; } - tb.AddDataColumn("double:Extents.Max.Z", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Level?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Level:Level", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:View", columnData); - } - return tb; - } - public static EntityTableBuilder ToCameraTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Camera); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } - tb.AddDataColumn("int:Id", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPerspective; } - tb.AddDataColumn("int:IsPerspective", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].VerticalExtent; } - tb.AddDataColumn("double:VerticalExtent", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HorizontalExtent; } - tb.AddDataColumn("double:HorizontalExtent", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FarDistance; } - tb.AddDataColumn("double:FarDistance", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NearDistance; } - tb.AddDataColumn("double:NearDistance", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].TargetDistance; } - tb.AddDataColumn("double:TargetDistance", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].RightOffset; } - tb.AddDataColumn("double:RightOffset", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UpOffset; } - tb.AddDataColumn("double:UpOffset", columnData); - } - return tb; - } - public static EntityTableBuilder ToMaterialTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Material); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].MaterialCategory; } - tb.AddStringColumn("string:MaterialCategory", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Color_X; } - tb.AddDataColumn("double:Color.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Color_Y; } - tb.AddDataColumn("double:Color.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Color_Z; } - tb.AddDataColumn("double:Color.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvScaling_X; } - tb.AddDataColumn("double:ColorUvScaling.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvScaling_Y; } - tb.AddDataColumn("double:ColorUvScaling.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvOffset_X; } - tb.AddDataColumn("double:ColorUvOffset.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvOffset_Y; } - tb.AddDataColumn("double:ColorUvOffset.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvScaling_X; } - tb.AddDataColumn("double:NormalUvScaling.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvScaling_Y; } - tb.AddDataColumn("double:NormalUvScaling.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvOffset_X; } - tb.AddDataColumn("double:NormalUvOffset.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvOffset_Y; } - tb.AddDataColumn("double:NormalUvOffset.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalAmount; } - tb.AddDataColumn("double:NormalAmount", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Glossiness; } - tb.AddDataColumn("double:Glossiness", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Smoothness; } - tb.AddDataColumn("double:Smoothness", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Transparency; } - tb.AddDataColumn("double:Transparency", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ColorTextureFile?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Asset:ColorTextureFile", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._NormalTextureFile?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Asset:NormalTextureFile", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToMaterialInElementTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.MaterialInElement); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Area; } - tb.AddDataColumn("double:Area", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Volume; } - tb.AddDataColumn("double:Volume", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPaint; } - tb.AddDataColumn("byte:IsPaint", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Material?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Material:Material", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToCompoundStructureLayerTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.CompoundStructureLayer); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrderIndex; } - tb.AddDataColumn("int:OrderIndex", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Width; } - tb.AddDataColumn("double:Width", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].MaterialFunctionAssignment; } - tb.AddStringColumn("string:MaterialFunctionAssignment", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Material?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Material:Material", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._CompoundStructure?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.CompoundStructure:CompoundStructure", columnData); - } - return tb; - } - public static EntityTableBuilder ToCompoundStructureTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.CompoundStructure); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Width; } - tb.AddDataColumn("double:Width", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._StructuralLayer?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.CompoundStructureLayer:StructuralLayer", columnData); - } - return tb; - } - public static EntityTableBuilder ToNodeTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Node); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToGeometryTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Geometry); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Min_X; } - tb.AddDataColumn("float:Box.Min.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Min_Y; } - tb.AddDataColumn("float:Box.Min.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Min_Z; } - tb.AddDataColumn("float:Box.Min.Z", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Max_X; } - tb.AddDataColumn("float:Box.Max.X", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Max_Y; } - tb.AddDataColumn("float:Box.Max.Y", columnData); - } - { - var columnData = new Single[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Max_Z; } - tb.AddDataColumn("float:Box.Max.Z", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].VertexCount; } - tb.AddDataColumn("int:VertexCount", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FaceCount; } - tb.AddDataColumn("int:FaceCount", columnData); - } - return tb; - } - public static EntityTableBuilder ToShapeTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Shape); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToShapeCollectionTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ShapeCollection); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToShapeInShapeCollectionTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ShapeInShapeCollection); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Shape?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Shape:Shape", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ShapeCollection?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ShapeCollection:ShapeCollection", columnData); - } - return tb; - } - public static EntityTableBuilder ToSystemTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.System); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SystemType; } - tb.AddDataColumn("int:SystemType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToElementInSystemTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ElementInSystem); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Roles; } - tb.AddDataColumn("int:Roles", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._System?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.System:System", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToWarningTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Warning); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Guid; } - tb.AddStringColumn("string:Guid", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Severity; } - tb.AddStringColumn("string:Severity", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Description; } - tb.AddStringColumn("string:Description", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); - } - return tb; - } - public static EntityTableBuilder ToElementInWarningTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ElementInWarning); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Warning?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Warning:Warning", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToBasePointTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.BasePoint); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsSurveyPoint; } - tb.AddDataColumn("byte:IsSurveyPoint", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_X; } - tb.AddDataColumn("double:Position.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Y; } - tb.AddDataColumn("double:Position.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Z; } - tb.AddDataColumn("double:Position.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SharedPosition_X; } - tb.AddDataColumn("double:SharedPosition.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SharedPosition_Y; } - tb.AddDataColumn("double:SharedPosition.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SharedPosition_Z; } - tb.AddDataColumn("double:SharedPosition.Z", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToPhaseFilterTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.PhaseFilter); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].New; } - tb.AddDataColumn("int:New", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Existing; } - tb.AddDataColumn("int:Existing", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Demolished; } - tb.AddDataColumn("int:Demolished", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Temporary; } - tb.AddDataColumn("int:Temporary", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToGridTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Grid); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StartPoint_X; } - tb.AddDataColumn("double:StartPoint.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StartPoint_Y; } - tb.AddDataColumn("double:StartPoint.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StartPoint_Z; } - tb.AddDataColumn("double:StartPoint.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].EndPoint_X; } - tb.AddDataColumn("double:EndPoint.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].EndPoint_Y; } - tb.AddDataColumn("double:EndPoint.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].EndPoint_Z; } - tb.AddDataColumn("double:EndPoint.Z", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsCurved; } - tb.AddDataColumn("byte:IsCurved", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_X; } - tb.AddDataColumn("double:Extents.Min.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Y; } - tb.AddDataColumn("double:Extents.Min.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Z; } - tb.AddDataColumn("double:Extents.Min.Z", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_X; } - tb.AddDataColumn("double:Extents.Max.X", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Y; } - tb.AddDataColumn("double:Extents.Max.Y", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Z; } - tb.AddDataColumn("double:Extents.Max.Z", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToAreaTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Area); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Value; } - tb.AddDataColumn("double:Value", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Perimeter; } - tb.AddDataColumn("double:Perimeter", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } - tb.AddStringColumn("string:Number", columnData); - } - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsGrossInterior; } - tb.AddDataColumn("byte:IsGrossInterior", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._AreaScheme?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.AreaScheme:AreaScheme", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToAreaSchemeTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.AreaScheme); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Boolean[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsGrossBuildingArea; } - tb.AddDataColumn("byte:IsGrossBuildingArea", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToScheduleTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Schedule); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToScheduleColumnTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ScheduleColumn); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } - tb.AddStringColumn("string:Name", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColumnIndex; } - tb.AddDataColumn("int:ColumnIndex", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Schedule?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Schedule:Schedule", columnData); - } - return tb; - } - public static EntityTableBuilder ToScheduleCellTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ScheduleCell); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Value; } - tb.AddStringColumn("string:Value", columnData); - } - { - var columnData = new Int32[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].RowIndex; } - tb.AddDataColumn("int:RowIndex", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ScheduleColumn?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ScheduleColumn:ScheduleColumn", columnData); - } - return tb; - } - public static EntityTableBuilder ToViewSheetSetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ViewSheetSet); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToViewSheetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ViewSheet); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToViewSheetInViewSheetSetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ViewSheetInViewSheetSet); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheet?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ViewSheet:ViewSheet", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheetSet?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ViewSheetSet:ViewSheetSet", columnData); - } - return tb; - } - public static EntityTableBuilder ToViewInViewSheetSetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ViewInViewSheetSet); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:View", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheetSet?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ViewSheetSet:ViewSheetSet", columnData); - } - return tb; - } - public static EntityTableBuilder ToViewInViewSheetTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.ViewInViewSheet); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.View:View", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheet?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.ViewSheet:ViewSheet", columnData); - } - return tb; - } - public static EntityTableBuilder ToSiteTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Site); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Latitude; } - tb.AddDataColumn("double:Latitude", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Longitude; } - tb.AddDataColumn("double:Longitude", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Address; } - tb.AddStringColumn("string:Address", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } - tb.AddDataColumn("double:Elevation", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } - tb.AddStringColumn("string:Number", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - public static EntityTableBuilder ToBuildingTableBuilder(this EntitySetBuilder entitySet) - { - var tb = new EntityTableBuilder(TableNames.Building); - var entities = entitySet.Entities; - var entityCount = entities.Count; - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } - tb.AddDataColumn("double:Elevation", columnData); - } - { - var columnData = new Double[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].TerrainElevation; } - tb.AddDataColumn("double:TerrainElevation", columnData); - } - { - var columnData = new String[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Address; } - tb.AddStringColumn("string:Address", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Site?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Site:Site", columnData); - } - { - var columnData = new int[entityCount]; - for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } - tb.AddIndexColumn("index:Vim.Element:Element", columnData); - } - return tb; - } - } // DocumentBuilderExtensions - - public partial class ObjectModelBuilder - { - public readonly EntitySetBuilder AssetBuilder = new EntitySetBuilder(TableNames.Asset); - public readonly EntitySetBuilder DisplayUnitBuilder = new EntitySetBuilder(TableNames.DisplayUnit); - public readonly EntitySetBuilder ParameterDescriptorBuilder = new EntitySetBuilder(TableNames.ParameterDescriptor); - public readonly EntitySetBuilder ParameterBuilder = new EntitySetBuilder(TableNames.Parameter); - public readonly EntitySetBuilder ElementBuilder = new EntitySetBuilder(TableNames.Element); - public readonly EntitySetBuilder WorksetBuilder = new EntitySetBuilder(TableNames.Workset); - public readonly EntitySetBuilder AssemblyInstanceBuilder = new EntitySetBuilder(TableNames.AssemblyInstance); - public readonly EntitySetBuilder GroupBuilder = new EntitySetBuilder(TableNames.Group); - public readonly EntitySetBuilder DesignOptionBuilder = new EntitySetBuilder(TableNames.DesignOption); - public readonly EntitySetBuilder LevelBuilder = new EntitySetBuilder(TableNames.Level); - public readonly EntitySetBuilder PhaseBuilder = new EntitySetBuilder(TableNames.Phase); - public readonly EntitySetBuilder RoomBuilder = new EntitySetBuilder(TableNames.Room); - public readonly EntitySetBuilder BimDocumentBuilder = new EntitySetBuilder(TableNames.BimDocument); - public readonly EntitySetBuilder DisplayUnitInBimDocumentBuilder = new EntitySetBuilder(TableNames.DisplayUnitInBimDocument); - public readonly EntitySetBuilder PhaseOrderInBimDocumentBuilder = new EntitySetBuilder(TableNames.PhaseOrderInBimDocument); - public readonly EntitySetBuilder CategoryBuilder = new EntitySetBuilder(TableNames.Category); - public readonly EntitySetBuilder FamilyBuilder = new EntitySetBuilder(TableNames.Family); - public readonly EntitySetBuilder FamilyTypeBuilder = new EntitySetBuilder(TableNames.FamilyType); - public readonly EntitySetBuilder FamilyInstanceBuilder = new EntitySetBuilder(TableNames.FamilyInstance); - public readonly EntitySetBuilder ViewBuilder = new EntitySetBuilder(TableNames.View); - public readonly EntitySetBuilder ElementInViewBuilder = new EntitySetBuilder(TableNames.ElementInView); - public readonly EntitySetBuilder ShapeInViewBuilder = new EntitySetBuilder(TableNames.ShapeInView); - public readonly EntitySetBuilder AssetInViewBuilder = new EntitySetBuilder(TableNames.AssetInView); - public readonly EntitySetBuilder AssetInViewSheetBuilder = new EntitySetBuilder(TableNames.AssetInViewSheet); - public readonly EntitySetBuilder LevelInViewBuilder = new EntitySetBuilder(TableNames.LevelInView); - public readonly EntitySetBuilder CameraBuilder = new EntitySetBuilder(TableNames.Camera); - public readonly EntitySetBuilder MaterialBuilder = new EntitySetBuilder(TableNames.Material); - public readonly EntitySetBuilder MaterialInElementBuilder = new EntitySetBuilder(TableNames.MaterialInElement); - public readonly EntitySetBuilder CompoundStructureLayerBuilder = new EntitySetBuilder(TableNames.CompoundStructureLayer); - public readonly EntitySetBuilder CompoundStructureBuilder = new EntitySetBuilder(TableNames.CompoundStructure); - public readonly EntitySetBuilder NodeBuilder = new EntitySetBuilder(TableNames.Node); - public readonly EntitySetBuilder GeometryBuilder = new EntitySetBuilder(TableNames.Geometry); - public readonly EntitySetBuilder ShapeBuilder = new EntitySetBuilder(TableNames.Shape); - public readonly EntitySetBuilder ShapeCollectionBuilder = new EntitySetBuilder(TableNames.ShapeCollection); - public readonly EntitySetBuilder ShapeInShapeCollectionBuilder = new EntitySetBuilder(TableNames.ShapeInShapeCollection); - public readonly EntitySetBuilder SystemBuilder = new EntitySetBuilder(TableNames.System); - public readonly EntitySetBuilder ElementInSystemBuilder = new EntitySetBuilder(TableNames.ElementInSystem); - public readonly EntitySetBuilder WarningBuilder = new EntitySetBuilder(TableNames.Warning); - public readonly EntitySetBuilder ElementInWarningBuilder = new EntitySetBuilder(TableNames.ElementInWarning); - public readonly EntitySetBuilder BasePointBuilder = new EntitySetBuilder(TableNames.BasePoint); - public readonly EntitySetBuilder PhaseFilterBuilder = new EntitySetBuilder(TableNames.PhaseFilter); - public readonly EntitySetBuilder GridBuilder = new EntitySetBuilder(TableNames.Grid); - public readonly EntitySetBuilder AreaBuilder = new EntitySetBuilder(TableNames.Area); - public readonly EntitySetBuilder AreaSchemeBuilder = new EntitySetBuilder(TableNames.AreaScheme); - public readonly EntitySetBuilder ScheduleBuilder = new EntitySetBuilder(TableNames.Schedule); - public readonly EntitySetBuilder ScheduleColumnBuilder = new EntitySetBuilder(TableNames.ScheduleColumn); - public readonly EntitySetBuilder ScheduleCellBuilder = new EntitySetBuilder(TableNames.ScheduleCell); - public readonly EntitySetBuilder ViewSheetSetBuilder = new EntitySetBuilder(TableNames.ViewSheetSet); - public readonly EntitySetBuilder ViewSheetBuilder = new EntitySetBuilder(TableNames.ViewSheet); - public readonly EntitySetBuilder ViewSheetInViewSheetSetBuilder = new EntitySetBuilder(TableNames.ViewSheetInViewSheetSet); - public readonly EntitySetBuilder ViewInViewSheetSetBuilder = new EntitySetBuilder(TableNames.ViewInViewSheetSet); - public readonly EntitySetBuilder ViewInViewSheetBuilder = new EntitySetBuilder(TableNames.ViewInViewSheet); - public readonly EntitySetBuilder SiteBuilder = new EntitySetBuilder(TableNames.Site); - public readonly EntitySetBuilder BuildingBuilder = new EntitySetBuilder(TableNames.Building); - - public DocumentBuilder AddEntityTableSets(DocumentBuilder db) - { - db.Tables.Add(AssetBuilder.EntityTableName, AssetBuilder.ToAssetTableBuilder()); - db.Tables.Add(DisplayUnitBuilder.EntityTableName, DisplayUnitBuilder.ToDisplayUnitTableBuilder()); - db.Tables.Add(ParameterDescriptorBuilder.EntityTableName, ParameterDescriptorBuilder.ToParameterDescriptorTableBuilder()); - db.Tables.Add(ParameterBuilder.EntityTableName, ParameterBuilder.ToParameterTableBuilder()); - db.Tables.Add(ElementBuilder.EntityTableName, ElementBuilder.ToElementTableBuilder()); - db.Tables.Add(WorksetBuilder.EntityTableName, WorksetBuilder.ToWorksetTableBuilder()); - db.Tables.Add(AssemblyInstanceBuilder.EntityTableName, AssemblyInstanceBuilder.ToAssemblyInstanceTableBuilder()); - db.Tables.Add(GroupBuilder.EntityTableName, GroupBuilder.ToGroupTableBuilder()); - db.Tables.Add(DesignOptionBuilder.EntityTableName, DesignOptionBuilder.ToDesignOptionTableBuilder()); - db.Tables.Add(LevelBuilder.EntityTableName, LevelBuilder.ToLevelTableBuilder()); - db.Tables.Add(PhaseBuilder.EntityTableName, PhaseBuilder.ToPhaseTableBuilder()); - db.Tables.Add(RoomBuilder.EntityTableName, RoomBuilder.ToRoomTableBuilder()); - db.Tables.Add(BimDocumentBuilder.EntityTableName, BimDocumentBuilder.ToBimDocumentTableBuilder()); - db.Tables.Add(DisplayUnitInBimDocumentBuilder.EntityTableName, DisplayUnitInBimDocumentBuilder.ToDisplayUnitInBimDocumentTableBuilder()); - db.Tables.Add(PhaseOrderInBimDocumentBuilder.EntityTableName, PhaseOrderInBimDocumentBuilder.ToPhaseOrderInBimDocumentTableBuilder()); - db.Tables.Add(CategoryBuilder.EntityTableName, CategoryBuilder.ToCategoryTableBuilder()); - db.Tables.Add(FamilyBuilder.EntityTableName, FamilyBuilder.ToFamilyTableBuilder()); - db.Tables.Add(FamilyTypeBuilder.EntityTableName, FamilyTypeBuilder.ToFamilyTypeTableBuilder()); - db.Tables.Add(FamilyInstanceBuilder.EntityTableName, FamilyInstanceBuilder.ToFamilyInstanceTableBuilder()); - db.Tables.Add(ViewBuilder.EntityTableName, ViewBuilder.ToViewTableBuilder()); - db.Tables.Add(ElementInViewBuilder.EntityTableName, ElementInViewBuilder.ToElementInViewTableBuilder()); - db.Tables.Add(ShapeInViewBuilder.EntityTableName, ShapeInViewBuilder.ToShapeInViewTableBuilder()); - db.Tables.Add(AssetInViewBuilder.EntityTableName, AssetInViewBuilder.ToAssetInViewTableBuilder()); - db.Tables.Add(AssetInViewSheetBuilder.EntityTableName, AssetInViewSheetBuilder.ToAssetInViewSheetTableBuilder()); - db.Tables.Add(LevelInViewBuilder.EntityTableName, LevelInViewBuilder.ToLevelInViewTableBuilder()); - db.Tables.Add(CameraBuilder.EntityTableName, CameraBuilder.ToCameraTableBuilder()); - db.Tables.Add(MaterialBuilder.EntityTableName, MaterialBuilder.ToMaterialTableBuilder()); - db.Tables.Add(MaterialInElementBuilder.EntityTableName, MaterialInElementBuilder.ToMaterialInElementTableBuilder()); - db.Tables.Add(CompoundStructureLayerBuilder.EntityTableName, CompoundStructureLayerBuilder.ToCompoundStructureLayerTableBuilder()); - db.Tables.Add(CompoundStructureBuilder.EntityTableName, CompoundStructureBuilder.ToCompoundStructureTableBuilder()); - db.Tables.Add(NodeBuilder.EntityTableName, NodeBuilder.ToNodeTableBuilder()); - db.Tables.Add(GeometryBuilder.EntityTableName, GeometryBuilder.ToGeometryTableBuilder()); - db.Tables.Add(ShapeBuilder.EntityTableName, ShapeBuilder.ToShapeTableBuilder()); - db.Tables.Add(ShapeCollectionBuilder.EntityTableName, ShapeCollectionBuilder.ToShapeCollectionTableBuilder()); - db.Tables.Add(ShapeInShapeCollectionBuilder.EntityTableName, ShapeInShapeCollectionBuilder.ToShapeInShapeCollectionTableBuilder()); - db.Tables.Add(SystemBuilder.EntityTableName, SystemBuilder.ToSystemTableBuilder()); - db.Tables.Add(ElementInSystemBuilder.EntityTableName, ElementInSystemBuilder.ToElementInSystemTableBuilder()); - db.Tables.Add(WarningBuilder.EntityTableName, WarningBuilder.ToWarningTableBuilder()); - db.Tables.Add(ElementInWarningBuilder.EntityTableName, ElementInWarningBuilder.ToElementInWarningTableBuilder()); - db.Tables.Add(BasePointBuilder.EntityTableName, BasePointBuilder.ToBasePointTableBuilder()); - db.Tables.Add(PhaseFilterBuilder.EntityTableName, PhaseFilterBuilder.ToPhaseFilterTableBuilder()); - db.Tables.Add(GridBuilder.EntityTableName, GridBuilder.ToGridTableBuilder()); - db.Tables.Add(AreaBuilder.EntityTableName, AreaBuilder.ToAreaTableBuilder()); - db.Tables.Add(AreaSchemeBuilder.EntityTableName, AreaSchemeBuilder.ToAreaSchemeTableBuilder()); - db.Tables.Add(ScheduleBuilder.EntityTableName, ScheduleBuilder.ToScheduleTableBuilder()); - db.Tables.Add(ScheduleColumnBuilder.EntityTableName, ScheduleColumnBuilder.ToScheduleColumnTableBuilder()); - db.Tables.Add(ScheduleCellBuilder.EntityTableName, ScheduleCellBuilder.ToScheduleCellTableBuilder()); - db.Tables.Add(ViewSheetSetBuilder.EntityTableName, ViewSheetSetBuilder.ToViewSheetSetTableBuilder()); - db.Tables.Add(ViewSheetBuilder.EntityTableName, ViewSheetBuilder.ToViewSheetTableBuilder()); - db.Tables.Add(ViewSheetInViewSheetSetBuilder.EntityTableName, ViewSheetInViewSheetSetBuilder.ToViewSheetInViewSheetSetTableBuilder()); - db.Tables.Add(ViewInViewSheetSetBuilder.EntityTableName, ViewInViewSheetSetBuilder.ToViewInViewSheetSetTableBuilder()); - db.Tables.Add(ViewInViewSheetBuilder.EntityTableName, ViewInViewSheetBuilder.ToViewInViewSheetTableBuilder()); - db.Tables.Add(SiteBuilder.EntityTableName, SiteBuilder.ToSiteTableBuilder()); - db.Tables.Add(BuildingBuilder.EntityTableName, BuildingBuilder.ToBuildingTableBuilder()); - - return db; - } // AddEntityTableSets - - public void Clear() - { - AssetBuilder.Clear(); - DisplayUnitBuilder.Clear(); - ParameterDescriptorBuilder.Clear(); - ParameterBuilder.Clear(); - ElementBuilder.Clear(); - WorksetBuilder.Clear(); - AssemblyInstanceBuilder.Clear(); - GroupBuilder.Clear(); - DesignOptionBuilder.Clear(); - LevelBuilder.Clear(); - PhaseBuilder.Clear(); - RoomBuilder.Clear(); - BimDocumentBuilder.Clear(); - DisplayUnitInBimDocumentBuilder.Clear(); - PhaseOrderInBimDocumentBuilder.Clear(); - CategoryBuilder.Clear(); - FamilyBuilder.Clear(); - FamilyTypeBuilder.Clear(); - FamilyInstanceBuilder.Clear(); - ViewBuilder.Clear(); - ElementInViewBuilder.Clear(); - ShapeInViewBuilder.Clear(); - AssetInViewBuilder.Clear(); - AssetInViewSheetBuilder.Clear(); - LevelInViewBuilder.Clear(); - CameraBuilder.Clear(); - MaterialBuilder.Clear(); - MaterialInElementBuilder.Clear(); - CompoundStructureLayerBuilder.Clear(); - CompoundStructureBuilder.Clear(); - NodeBuilder.Clear(); - GeometryBuilder.Clear(); - ShapeBuilder.Clear(); - ShapeCollectionBuilder.Clear(); - ShapeInShapeCollectionBuilder.Clear(); - SystemBuilder.Clear(); - ElementInSystemBuilder.Clear(); - WarningBuilder.Clear(); - ElementInWarningBuilder.Clear(); - BasePointBuilder.Clear(); - PhaseFilterBuilder.Clear(); - GridBuilder.Clear(); - AreaBuilder.Clear(); - AreaSchemeBuilder.Clear(); - ScheduleBuilder.Clear(); - ScheduleColumnBuilder.Clear(); - ScheduleCellBuilder.Clear(); - ViewSheetSetBuilder.Clear(); - ViewSheetBuilder.Clear(); - ViewSheetInViewSheetSetBuilder.Clear(); - ViewInViewSheetSetBuilder.Clear(); - ViewInViewSheetBuilder.Clear(); - SiteBuilder.Clear(); - BuildingBuilder.Clear(); - } // Clear - } // ObjectModelBuilder -} // namespace diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs deleted file mode 100644 index 214e1b4b..00000000 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.Math3d; - -namespace Vim.Format.ObjectModel -{ - /// - /// Stores converted object models encountered during the Export process. - /// - public class ObjectModelStore - { - /// - /// A Utility for building the ORM (Object Relational Model) - /// - public ObjectModelBuilder ObjectModelBuilder = new ObjectModelBuilder(); - - public List Meshes { get; private set; } = new List(); - public List Instances { get; } = new List(); - public List Shapes { get; } = new List(); - - public DocumentBuilder ToDocumentBuilder(string generator, string versionString) - { - return ObjectModelBuilder.ToDocumentBuilder(generator, versionString) - .AddMeshes(Meshes.Select(g => g.Subdivide())) - .AddInstances(Instances) - .AddShapes(Shapes) - .AddMaterials(CreateMaterialBuilders()); - } - - private IEnumerable CreateMaterialBuilders() - => ObjectModelBuilder.MaterialBuilder.Entities.Select(ConvertMaterialEntityToRenderableMaterial); - - public static DocumentBuilder.Material ConvertMaterialEntityToRenderableMaterial(Material m) - => ConvertMaterialEntityFieldsToRenderableMaterial( - m.Color.X, - m.Color.Y, - m.Color.Z, - m.Transparency, - m.Glossiness, - m.Smoothness); - - public static DocumentBuilder.Material ConvertMaterialEntityFieldsToRenderableMaterial( - double colorX, - double colorY, - double colorZ, - double transparency, - double glossiness, - double smoothness) - => new DocumentBuilder.Material() - { - Color = new Vector4( - (float) colorX, - (float) colorY, - (float) colorZ, - (float)(1 - transparency)), // TECH DEBT: rendered material value is 1.0f - transparency - Glossiness = (float) glossiness, - Smoothness = (float) smoothness - }; - - /// - /// Mutates the Meshes and Instances to remove any meshes which are not referenced by at least one instance. - /// - public ObjectModelStore TrimOrphanMeshes() - { - // Example: - // - // old instance mesh indices: [0, 2, 4, 2] - // --- - // old mesh indices: [0, 1, 2, 3, 4] - // orphan mesh indices: [ 1, 3 ] - // next mesh indices: [0, -1, 1, -1, 2] - // --- - // next instance mesh indices: [0, 1, 2, 1] - - const int nullMeshIndex = -1; - - // Initialize the mesh indices - var meshIsReferenced = new bool[Meshes.Count]; - for (var i = 0; i < meshIsReferenced.Length; i++) - meshIsReferenced[i] = false; - - // Mark the mesh indices which are referenced by an instance. - foreach (var instance in Instances) - { - if (instance.MeshIndex <= nullMeshIndex) - continue; - - meshIsReferenced[instance.MeshIndex] = true; - } - - // Early exit if all meshes are referenced. - if (meshIsReferenced.All(isReferenced => isReferenced)) - return this; - - // Update the new mesh indices. - var nextMeshIndex = 0; - var nextMeshIndices = new int[meshIsReferenced.Length]; - for (var i = 0; i < nextMeshIndices.Length; ++i) - { - nextMeshIndices[i] = meshIsReferenced[i] - ? nextMeshIndex++ - : nullMeshIndex; - } - - // Create a new mesh list which excludes the orphaned meshes. - Meshes = Meshes.Where((m, i) => nextMeshIndices[i] > nullMeshIndex).ToList(); - - // Mutate the instances to update their mesh index. - foreach (var instance in Instances) - { - if (instance.MeshIndex <= nullMeshIndex) - continue; - - instance.MeshIndex = nextMeshIndices[instance.MeshIndex]; - Debug.Assert(instance.MeshIndex > nullMeshIndex, $"Invalid instance mesh index ({instance.MeshIndex})"); - } - - return this; - } - } -} diff --git a/src/cs/vim/Vim.Format/ObjectModel/RevitBuiltInCategory.cs b/src/cs/vim/Vim.Format/ObjectModel/RevitBuiltInCategory.cs index abcd40e1..42a4eaf1 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/RevitBuiltInCategory.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/RevitBuiltInCategory.cs @@ -1,7 +1,7 @@ // FILE ORIGINALLY GENERATED FROM GenerateRevitBuiltInCategories.cs using System.Collections.Generic; -namespace Vim.Format.ObjectModel +namespace Vim.Format { public enum RevitBuiltInCategory : long { diff --git a/src/cs/vim/Vim.Format/ObjectModel/Urn.cs b/src/cs/vim/Vim.Format/ObjectModel/Urn.cs index 70e96b78..0417a9aa 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/Urn.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/Urn.cs @@ -1,6 +1,6 @@ using System.Linq; -namespace Vim.Format.ObjectModel +namespace Vim.Format { public static class Urn { diff --git a/src/cs/vim/Vim.Format/ObjectModel/Validation.cs b/src/cs/vim/Vim.Format/ObjectModel/Validation.cs deleted file mode 100644 index 24fb6399..00000000 --- a/src/cs/vim/Vim.Format/ObjectModel/Validation.cs +++ /dev/null @@ -1,347 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.ObjectModel -{ - public class ObjectModelValidationOptions - { - /// - /// Validation will fail if duplicate storage keys are detected. Setting this to false simplifies merged VIM validation. - /// - public bool UniqueStorageKeys { get; set; } = true; - - /// - /// By default, we expect at least one BimDocument entity. Setting this to false suppresses this requirement. This is typically - /// useful when stripping the bim data from the VIM file to keep it as light as possible. - /// - public bool BimDocumentMustExist { get; set; } = true; - - /// - /// By default, it is recommended that the bim document element has an element id of -1. - /// Note: this may not always be the case, particularly for IFC to VIM conversions. - /// - public bool BimDocumentElementMustBeSynthetic { get; set; } = true; - - /// - /// By default, it is recommended that the bim document element has an element whose name is equal to the bim document's name. - /// Note: this may not always be the case, particularly for IFC to VIM conversions. - /// - public bool BimDocumentElementNameMustMatchBimDocumentName { get; set; } = true; - - /// - /// By default, it is recommended that the bim document element's type is set to "BimDocument Parameter Holder" - /// Note: this may not always be the case, particularly for IFC to VIM conversions. - /// - public bool BimDocumentElementTypeMustBeParameterHolder { get; set; } = true; - - /// - /// By default, it is recommended to avoid elements in systems having null values. This has been fixed as of object model v4.5.0 - /// - public bool ElementInSystemMustNotHaveNullValues { get; set; } = true; - } - - public class ObjectModelValidationException : Exception - { - public ObjectModelValidationException(string message) : base(message) { } - } - - public static class Validation - { - public static void ValidateBimDocument(this DocumentModel dm, ObjectModelValidationOptions validationOptions) - { - // There is at least one BimDocument in the document model. - if (dm.NumBimDocument == 0 && validationOptions.BimDocumentMustExist) - throw new ObjectModelValidationException($"No {nameof(BimDocument)} found."); - - foreach (var bd in dm.BimDocumentList.ToEnumerable()) - { - var bdElement = bd.Element; - if (bdElement == null) - throw new ObjectModelValidationException($"{nameof(BimDocument)} @{bd.Index} has null {nameof(Element)}."); - - var expectedElementId = VimConstants.SyntheticElementId; - if (validationOptions.BimDocumentElementMustBeSynthetic && bdElement.Id != expectedElementId) - throw new ObjectModelValidationException($"{nameof(BimDocument)} @{bd.Index} - Related {nameof(Element)}.{nameof(Element.Id)} @{bdElement.Index} is not {expectedElementId}"); - - var expectedName = bd.Name; - if (validationOptions.BimDocumentElementNameMustMatchBimDocumentName && bdElement.Name != expectedName) - throw new ObjectModelValidationException($"{nameof(BimDocument)} @{bd.Index} - Related {nameof(Element)}.{nameof(Element.Name)} @{bdElement.Index} does not match {nameof(BimDocument)}.{nameof(BimDocument.Name)} ({expectedName})"); - - var expectedElementType = VimConstants.BimDocumentParameterHolderElementType; - if (validationOptions.BimDocumentElementTypeMustBeParameterHolder && bdElement.Type != expectedElementType) - throw new ObjectModelValidationException($"{nameof(BimDocument)} @{bd.Index} - Related {nameof(Element)}.{nameof(Element.Type)} @{bdElement.Index} is not '{expectedElementType}'."); - } - } - - public static void ValidateCompoundStructureLayer(this CompoundStructureLayer layer) - { - // All CompoundLayers have a CompoundStructure - if (layer.CompoundStructure == null) - throw new ObjectModelValidationException($"{nameof(CompoundStructureLayer)} {layer.Index} has null {nameof(CompoundStructure)}"); - } - - public static void ValidateCompoundStructures(this DocumentModel dm) - { - var cslArray = dm.CompoundStructureLayerList.ToArray(); - - // All compound structure layers are valid - foreach (var csl in cslArray) - csl.ValidateCompoundStructureLayer(); - - // There are no gaps in the order index of compound structure layers. - foreach (var cslCluster in cslArray.GroupBy(csl => csl._CompoundStructure.Index)) - { - var ordered = cslCluster.OrderBy(csl => csl.OrderIndex).ToArray(); - for (var i = 0; i < ordered.Length; ++i) - { - var orderIndex = ordered[i].OrderIndex; - if (orderIndex != i) - throw new ObjectModelValidationException($"{nameof(CompoundStructureLayer.OrderIndex)} {orderIndex} does not match expected value of {i}"); - } - - var csIndex = cslCluster.Key; - var csStructuralLayerIndex = dm.CompoundStructureStructuralLayerIndex.ElementAtOrDefault(csIndex, EntityRelation.None); - if (csStructuralLayerIndex != EntityRelation.None) - { - // If the CompoundStructure.StructuralMaterial exists, it should be a valid relation to a CompoundStructureLayer - var maxIndex = cslArray.Length - 1; - if (csStructuralLayerIndex < 0 || csStructuralLayerIndex > maxIndex) - throw new ObjectModelValidationException($"{nameof(CompoundStructure)} {csIndex} has an invalid {nameof(CompoundStructure.StructuralLayer)} relation index of {csStructuralLayerIndex}. Expected value between [0..{maxIndex}]"); - } - } - - // All FamilyTypes with compound structures are system families. - var ftArray = dm.FamilyTypeList.ToArray(); - var cslRelationIndices = new HashSet(cslArray.Select(l => l.CompoundStructure.Index)); - var ftRelationIndices = new HashSet(ftArray.Where(ft => ft.CompoundStructure != null).Select(ft => ft.CompoundStructure.Index)); - var csArray = dm.CompoundStructureList.ToArray(); - foreach (var cs in csArray) - { - // All compound structures are referenced by at least one compound structure layer - if (!cslRelationIndices.Contains(cs.Index)) - throw new ObjectModelValidationException($"{nameof(CompoundStructure)} index: {cs.Index} does not have a corresponding {nameof(CompoundStructureLayer)}"); - - // All compound structures are referenced by at least one family type. - if (!ftRelationIndices.Contains(cs.Index)) - throw new ObjectModelValidationException($"{nameof(CompoundStructure)} index: {cs.Index} does not have a corresponding {nameof(FamilyType)}"); - } - - // A compound structure must be referenced by exactly one family type (no re-using compound structures). - if (ftRelationIndices.Count != ftRelationIndices.Distinct().Count()) - throw new ObjectModelValidationException($"A {nameof(CompoundStructure)} must be referenced by exactly one {nameof(FamilyType)}."); - } - - public static void ValidateAssets(this DocumentModel dm) - { - // Validate that the assets contained in the buffers matches the assets entity table. - var assetBuffers = dm.Document.Assets; - var assetEntities = dm.AssetList.ToArray(); - foreach (var asset in assetEntities) - { - if (!assetBuffers.Contains(asset.BufferName)) - throw new ObjectModelValidationException($"No matching asset buffer found for asset entity {asset.Index} with {nameof(asset.BufferName)} '{asset.BufferName}'"); - } - } - - public static void ValidateParameters(this DocumentModel dm) - { - Parallel.ForEach(dm.ParameterList.ToEnumerable(), p => - { - // Each parameter must be associated to an element. - if (p._Element.Index == EntityRelation.None) - throw new ObjectModelValidationException($"{nameof(Element)} not found for {nameof(Parameter)} {p.Index}"); - - // Each parameter must have a parameter descriptor. - if (p.ParameterDescriptor == null) - throw new ObjectModelValidationException($"{nameof(ParameterDescriptor)} is null for {nameof(Parameter)} {p.Index}"); - }); - - // Validate the parameter descriptors. - foreach (var pd in dm.ParameterDescriptorList.ToEnumerable()) - { - if (pd.DisplayUnit == null) - throw new ObjectModelValidationException($"{nameof(DisplayUnit)} is null for {nameof(ParameterDescriptor)} {pd.Index}"); - } - } - - public static void ValidatePhases(this DocumentModel dm) - { - // Validate the phase order information. - var poArray = dm.PhaseOrderInBimDocumentList.ToArray(); - foreach (var po in poArray) - { - var bd = po.BimDocument; - if (bd == null) - throw new ObjectModelValidationException($"{nameof(BimDocument)} is null for {nameof(PhaseOrderInBimDocument)} {po.Index}"); - - var phase = po.Phase; - if (phase == null) - throw new ObjectModelValidationException($"{nameof(Phase)} is null for {nameof(PhaseOrderInBimDocument)} {po.Index}"); - } - - // Validate the order indices in the bim documents. - foreach (var g in poArray.GroupBy(po => po._BimDocument.Index)) - { - var ordered = g.OrderBy(v => v.OrderIndex).ToArray(); - for (var i = 0; i < ordered.Length; ++i) - { - var po = ordered[i]; - var orderIndex = po.OrderIndex; - if (orderIndex != i) - throw new ObjectModelValidationException($"Unexpected OrderIndex {orderIndex}; expected {i} in {nameof(PhaseOrderInBimDocument)} {po.Index}"); - } - } - - // Validate that the phase order information covers the set of phases. - var phaseIndexSet = new HashSet(dm.PhaseList.Select(p => p.Index).ToEnumerable()); - phaseIndexSet.ExceptWith(poArray.Select(po => po.Index)); - if (phaseIndexSet.Count != 0) - throw new ObjectModelValidationException($"{nameof(Phase)} index coverage is incomplete among {nameof(PhaseOrderInBimDocument)}"); - } - - /// - /// Generic storage key check; ensures that the keys only appear once in the keySet. - /// - public static void ValidateStorageKeys(IEnumerable storageKeyEntities) - { - var keySet = new HashSet(); - foreach (var entity in storageKeyEntities) - { - var key = entity.GetStorageKey(); - if (!keySet.Add(key)) - throw new ObjectModelValidationException($"Duplicate storage key ({key}) found for {entity.GetType().Name}"); - } - } - - /// - /// Validate that the entities which inherit from IStorageKey all have unique storage key values. - /// - public static void ValidateStorageKeys(this DocumentModel dm) - { - // ReSharper disable once SuspiciousTypeConversion.Global - var storageKeyEntityLists = dm.AllEntities - .OfType>(); - foreach (var storageKeyEntities in storageKeyEntityLists) - { - ValidateStorageKeys(storageKeyEntities); - } - } - - public static void ValidateMaterials(this DocumentModel dm) - { - void ValidateDomain(string label, double value, double lowerInclusive, double upperInclusive, int index) - { - if (value < lowerInclusive || value > upperInclusive) - throw new ObjectModelValidationException($"{label} {value} is not in the range [{lowerInclusive}..{upperInclusive}] for material {index}"); - } - - void ValidateDVector3Domain(string label, DVector3 value, DVector3 lowerInclusive, DVector3 upperInclusive, int index) - { - if (value.X < lowerInclusive.X || - value.Y < lowerInclusive.Y || - value.Z < lowerInclusive.Z || - value.X > upperInclusive.X || - value.Y > upperInclusive.Y || - value.Z > upperInclusive.Z) - { - throw new ObjectModelValidationException($"{label} {value} is not in the range [{lowerInclusive}..{upperInclusive}] for material {index}"); - } - } - - foreach (var material in dm.MaterialList.ToEnumerable()) - { - var index = material.Index; - ValidateDVector3Domain(nameof(material.Color), material.Color, DVector3.Zero, DVector3.One, index); - ValidateDomain(nameof(material.Glossiness), material.Glossiness, 0d, 1d, index); - ValidateDomain(nameof(material.Smoothness), material.Smoothness, 0d, 1d, index); - ValidateDomain(nameof(material.Transparency), material.Transparency, 0d, 1d, index); - ValidateDomain(nameof(material.NormalAmount), material.NormalAmount, 0d, 1d, index); - } - } - - public static Dictionary> GetViewToElementsMap( - this IArray elementInViewList) - => elementInViewList - .Select(eiv => (viewIndex: eiv._View?.Index ?? -1, elementIndex: eiv._Element?.Index ?? -1)) - .GroupBy(t => t.viewIndex) - .ToDictionary( - g => g.Key, - g => new HashSet(g.Select(t => t.elementIndex))); - - public static void ValidateShapesInView(this DocumentModel dm) - { - var viewToElementsMap = dm.ElementInViewList.GetViewToElementsMap(); - - // Validate that the shapes in view have an element which is also in the same view. - foreach (var item in dm.ShapeInViewList.ToEnumerable()) - { - var viewIndex = item._View.Index; - var shape = item.Shape; - var shapeIndex = shape.Index; - var shapeElementIndex = shape._Element.Index; - - if (!viewToElementsMap.TryGetValue(viewIndex, out var elementsInView)) - throw new ObjectModelValidationException($"{nameof(Shape)} ({shapeIndex}) {nameof(View)} ({viewIndex}) not found in {nameof(viewToElementsMap)}"); - - if (!elementsInView.Contains(shapeElementIndex)) - throw new ObjectModelValidationException($"{nameof(Shape)} ({shapeIndex}) in {nameof(View)} ({viewIndex}) does not have a matching {nameof(ElementInView)} ({nameof(Element)} index: {shapeElementIndex})"); - } - } - - public static void ValidateEntitiesWithElement(this DocumentModel dm) - { - var entityWithElementTypes = new HashSet(ObjectModelReflection.GetEntityTypes() - .Where(t => t.GetCustomAttributes(typeof(G3dAttributeReferenceAttribute)).Count() == 0)); - - var numElements = dm.NumElement; - - Parallel.ForEach(entityWithElementTypes, entityWithElementType => - { - var elementIndices = ((IArray)dm.GetPropertyValue(entityWithElementType.Name + "ElementIndex")).ToArray(); - for (var i = 0; i < elementIndices.Length; ++i) - { - var elementIndex = elementIndices[i]; - if (elementIndex < 0) - throw new ObjectModelValidationException($"{nameof(EntityWithElement)} {entityWithElementType} @{i} has a negative element index: {elementIndex}."); - if (elementIndex >= numElements) - throw new ObjectModelValidationException($"{nameof(EntityWithElement)} {entityWithElementType} @{i} has an invalid element index: {elementIndex}; NumElements: {numElements}"); - } - }); - } - - public static void ValidateElementInSystem(this DocumentModel dm) - { - foreach (var eis in dm.ElementInSystemList.ToEnumerable()) - { - if (eis.System == null) - throw new ObjectModelValidationException($"{nameof(ElementInSystem)} @ {eis.Index} has a null {nameof(ElementInSystem.System)}"); - - if (eis.Element == null) - throw new ObjectModelValidationException($"{nameof(ElementInSystem)} @ {eis.Index} has a null {nameof(ElementInSystem.Element)}"); - } - } - - public static void Validate(this DocumentModel dm, ObjectModelValidationOptions options = null) - { - options = options ?? new ObjectModelValidationOptions(); - - dm.ValidateEntitiesWithElement(); - dm.ValidateBimDocument(options); - dm.ValidateCompoundStructures(); - dm.ValidateAssets(); - dm.ValidateParameters(); - dm.ValidatePhases(); - if (options.UniqueStorageKeys) - dm.ValidateStorageKeys(); - if (options.ElementInSystemMustNotHaveNullValues) - dm.ValidateElementInSystem(); - dm.ValidateMaterials(); - dm.ValidateShapesInView(); - } - } -} diff --git a/src/cs/vim/Vim.Format/README.md b/src/cs/vim/Vim.Format/README.md new file mode 100644 index 00000000..ece07287 --- /dev/null +++ b/src/cs/vim/Vim.Format/README.md @@ -0,0 +1,3 @@ +# VIM Format + +C# API for reading and writing VIM files diff --git a/src/cs/vim/Vim.Format/SceneBuilder/Validation.cs b/src/cs/vim/Vim.Format/SceneBuilder/Validation.cs deleted file mode 100644 index 55dc2b94..00000000 --- a/src/cs/vim/Vim.Format/SceneBuilder/Validation.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Vim.BFast; -using Vim.Format.Geometry; -using Vim.Format.ObjectModel; -using Vim.Util; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim.Format.SceneBuilder -{ - public class VimValidationOptions - { - public ObjectModelValidationOptions ObjectModelValidationOptions { get; set; } = new ObjectModelValidationOptions(); - } - - public static class Validation - { - public class VimValidationException : Exception - { - public VimValidationException(string message) : base(message) { } - } - - public static void ValidateGeometry(this VimScene vim) - { - // Validate the packed geometry. - vim.Document.Geometry.ToIMesh().Validate(); - - // Validate the individual meshes. - foreach (var g in vim.Meshes.ToEnumerable()) - g.Validate(); - } - - public static void ValidateDocumentModelToG3dInvariants(this VimScene vim) - { - var g3d = vim._SerializableDocument.Geometry; - var errors = new List(); - - errors.AddRange(Vim.G3d.Validation.Validate(g3d).Select(e => e.ToString("G"))); - - var entityTypesWithG3dReferences = new HashSet<(Type, G3dAttributeReferenceAttribute[])>( - ObjectModelReflection.GetEntityTypes() - .Select(t => ( - type: t, - attrs: t.GetCustomAttributes(typeof(G3dAttributeReferenceAttribute)) - .Select(a => a as G3dAttributeReferenceAttribute) - .ToArray())) - .Where(tuple => tuple.attrs.Length != 0)); - - var dm = vim.DocumentModel; - - foreach (var tuple in entityTypesWithG3dReferences) - { - var (type, attrs) = tuple; - var propertyName = type.Name + "List"; - if (dm.GetPropertyValue(propertyName) is IArray arr) - { - var numEntities = arr.Count; - - foreach (var attr in attrs) - { - var attributeName = attr.AttributeName; - var isOptional = attr.AttributeIsOptional; - - var g3dAttribute = g3d.GetAttribute(attributeName); - - // We don't check the relation if the attribute is optional and absent (null). - if (isOptional && g3dAttribute == null) - continue; - - var g3dElementCount = g3dAttribute?.ElementCount ?? 0; - var mult = attr.AttributeReferenceMultiplicity; - - // Validate one-to-one relationships - if (mult == G3dAttributeReferenceMultiplicity.OneToOne && numEntities != g3dElementCount) - { - errors.Add($"Multiplicity Error ({mult}); the number of entities of type \"{type.Name}\" ({numEntities}) is not equal to the number of elements in the g3d attribute \"{attributeName}\" ({g3dElementCount})"); - } - } - } - else - { - throw new VimValidationException($"DocumentModel.{propertyName} not found"); - } - } - - if (errors.Count > 0) - { - throw new VimValidationException( - $"DocumentModel to G3d invariant error(s):{Environment.NewLine}{string.Join(Environment.NewLine, errors)}"); - } - } - - public static void ValidateNodes(this VimScene vim) - { - if (vim.VimNodes.Count != vim.DocumentModel.NumNode) - throw new VimValidationException($"The number of {nameof(VimSceneNode)} ({vim.VimNodes.Count}) does not match the number of node entities ({vim.DocumentModel.NumNode})"); - } - - public static void ValidateShapes(this VimScene vim) - { - var shapes = vim.VimShapes; - var numShapes = vim.DocumentModel.NumShape; - if (shapes.Count != numShapes) - throw new VimValidationException($"The number of {nameof(VimShape)} ({shapes.Count}) does not match the number of shape entities ({numShapes})"); - - void ValidateColorDomain(string label, Vector4 value, Vector4 lowerInclusive, Vector4 upperInclusive, int index) - { - if (value.X < lowerInclusive.X || - value.Y < lowerInclusive.Y || - value.Z < lowerInclusive.Z || - value.W < lowerInclusive.W || - value.X > upperInclusive.X || - value.Y > upperInclusive.Y || - value.Z > upperInclusive.Z || - value.W > upperInclusive.W) - { - throw new Exception($"{label} {value} is not in the range [{lowerInclusive}..{upperInclusive}] for {index}"); - } - } - - Parallel.For(0, numShapes, shapeIndex => - { - var shape = shapes[shapeIndex]; - if (shape.ElementIndex < 0) - throw new VimValidationException($"{nameof(Element)} is null for {nameof(VimShape)} {shape.ShapeIndex}"); - ValidateColorDomain($"{nameof(VimShape)} color", shape.Color, Vector4.Zero, Vector4.One, shape.ShapeIndex); - }); - } - - public static void Validate(this VimScene vim, VimValidationOptions options = null) - { - options = options ?? new VimValidationOptions(); - - vim.Document.Validate(); - vim.DocumentModel.Validate(options.ObjectModelValidationOptions); - vim.ValidateGeometry(); - vim.ValidateDocumentModelToG3dInvariants(); - vim.ValidateNodes(); - vim.ValidateShapes(); - } - - public static void ValidateEquality(this DocumentBuilder db, VimScene vim) - { - // Test the geometry both ways - var vimGeoBuilders = vim.Meshes.Select(g => new DocumentBuilder.SubdividedMesh( - g.Indices.ToList(), - g.Vertices.ToList(), - g.SubmeshIndexOffsets.ToList(), - g.SubmeshMaterials.ToList() - )).ToList(); - - for (var i = 0; i < db.Meshes.Count; ++i) - { - if (!db.Meshes[i].IsEquivalentTo(vimGeoBuilders[i])) - throw new VimValidationException($"{nameof(DocumentBuilder)} mesh {i} is not equivalent to {nameof(VimScene)} mesh {i}"); - - if (!db.Meshes[i].ToIMesh().GeometryEquals(vim.Meshes[i])) - throw new VimValidationException($"{nameof(DocumentBuilder)} mesh {i} geometry is not equal to {nameof(VimScene)} mesh {i}"); - } - - // Test the assets. - var dbAssetDictionary = db.Assets; - var vimAssetDictionary = vim._SerializableDocument.Assets.ToDictionary(a => a.Name, a => a.ToBytes()); - if (!dbAssetDictionary.DictionaryEqual(vimAssetDictionary, new ArrayEqualityComparer())) - throw new VimValidationException($"{nameof(DocumentBuilder)} assets are not equal to {nameof(VimScene)} assets"); - - // Test the entity tables. - var tableNames = new HashSet(db.Tables.Values.Select(t => t.Name)); - foreach (var et in vim.Document.EntityTables.Keys.ToEnumerable()) - { - if (!tableNames.Contains(et)) - throw new VimValidationException($"{nameof(DocumentBuilder)} does not contain table name {et} from {nameof(VimScene)}"); - - // TODO: compare entity table equality. - } - } - } -} diff --git a/src/cs/vim/Vim.Format/SceneBuilder/VimScene.cs b/src/cs/vim/Vim.Format/SceneBuilder/VimScene.cs deleted file mode 100644 index 6d53fa79..00000000 --- a/src/cs/vim/Vim.Format/SceneBuilder/VimScene.cs +++ /dev/null @@ -1,283 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Vim.Format; -using Vim.Format.Geometry; -using Vim.Format.ObjectModel; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; -using Vim.Util; - -using ElementIndexToNodeAndGeometryMap = Vim.Util.DictionaryOfLists; -using IVimSceneProgress = System.IProgress<(string, double)>; - -namespace Vim -{ - // TODO: add property cache lookup - - /// - /// This is the top-level class of a loaded VIM file. - /// - public class VimScene : IScene - { - public static VimScene LoadVim(string f, LoadOptions loadOptions, IVimSceneProgress progress = null, bool inParallel = false, int vimIndex = 0) - => new VimScene(Serializer.Deserialize(f, loadOptions), progress, inParallel, vimIndex); - - public static VimScene LoadVim(string f, IVimSceneProgress progress = null, bool skipGeometry = false, bool skipAssets = false, bool skipNodes = false, bool inParallel = false) - => LoadVim(f, new LoadOptions { SkipGeometry = skipGeometry, SkipAssets = skipAssets}, progress, inParallel); - - public static VimScene LoadVim(Stream stream, LoadOptions loadOptions, IVimSceneProgress progress = null, bool inParallel = false) - => new VimScene(Serializer.Deserialize(stream, loadOptions), progress, inParallel); - - public static VimScene LoadVim(Stream stream, IVimSceneProgress progress = null, bool skipGeometry = false, bool skipAssets = false, bool skipNodes = false, bool inParallel = false) - => LoadVim(stream, new LoadOptions { SkipGeometry = skipGeometry, SkipAssets = skipAssets}, progress, inParallel); - - public int VimIndex { get; set; } - public IArray Meshes { get; private set; } - public IArray Nodes { get; private set; } - public IArray VimNodes { get; private set; } - public IArray VimShapes { get; private set; } - public IArray Materials { get; private set; } - - public SerializableDocument _SerializableDocument { get; } - public Document Document { get; private set; } - public DocumentModel DocumentModel { get; private set; } - - public string PersistingId - => Document.Header.PersistingId; - - public Material GetMaterial(int materialIndex) - => DocumentModel.MaterialList.ElementAtOrDefault(materialIndex); - - public Vector4 GetMaterialColor(int materialIndex) - => _SerializableDocument.Geometry.MaterialColors[materialIndex]; - - public static IMesh ToIMesh(G3dMesh g3d) - => Primitives.TriMesh( - g3d.Vertices.ToPositionAttribute(), - g3d.Indices.ToIndexAttribute(), - g3d.VertexUvs?.ToVertexUvAttribute(), - g3d.SubmeshIndexOffsets?.ToSubmeshIndexOffsetAttribute(), - g3d.SubmeshMaterials?.ToSubmeshMaterialAttribute(), - g3d.MeshSubmeshOffset?.ToMeshSubmeshOffsetAttribute() - ); - - private VimScene(SerializableDocument doc) - => _SerializableDocument = doc; - - public VimScene(SerializableDocument doc, IVimSceneProgress progress = null, bool inParallel = false, int vimIndex = 0) : this(doc) - { - VimIndex = vimIndex; - progress?.Report(($"Creating scene from {doc.FileName}", 0.0)); - - var actions = GetInitStepsWithProgress(inParallel, progress); - - if (inParallel) - { - Parallel.Invoke(actions); - } - else - { - foreach (var action in actions) - action(); - } - - progress?.Report(("Completed creating scene", 1.0)); - } - - private Action[] GetInitStepsWithProgress(bool inParallel, IVimSceneProgress progress = null) - { - var steps = GetInitSteps(inParallel); - var total = steps.Sum(s => s.Effort); - var cumulProgress = CumulativeProgressDecorator.Decorate(progress, total); - var actions = steps.Select(s => new Action(() => s.Run(cumulProgress))).ToArray(); - return actions; - } - - private IStep[] GetInitSteps(bool inParallel) - { - var createDocument = new Step( - () => Document = _SerializableDocument.ToDocument(), - "Creating Document" - ); - - var createModel = new Step( - () => DocumentModel = new DocumentModel(Document, inParallel), - "Creating Model" - ); - - //Requires model to be ready. - var createScene = new Step( - () => CreateScene(inParallel), - "Creating Scene", - 3f - ); - - var createMeshes = new Step( - () => CreateMeshes(inParallel), - "Unpacking Meshes", - 3f - ); - - var createMaterials = new Step( - () => CreateMaterials(inParallel), - "Creating Materials", - 1f - ); - - var createShapes = new Step( - () => CreateShapes(inParallel), - "Creating Shapes" - ); - - if (inParallel) - { - var dataSequence = new StepSequence( - createDocument, - createModel, - createScene, - createShapes - ); - - return new IStep[] - { - dataSequence, - createMeshes, - createMaterials - }; - } - else - { - return new IStep[] - { - createDocument, - createModel, - createMeshes, - createScene, - createShapes, - createMaterials, - }; - } - } - - private void CreateMeshes(bool inParallel) - { - var srcGeo = _SerializableDocument.Geometry; - var tmp = srcGeo?.Meshes.Select(ToIMesh); - Meshes = (tmp == null) - ? LinqArray.LinqArray.Empty() - : inParallel - ? tmp.EvaluateInParallel() - : tmp.Evaluate(); - } - - private void CreateShapes(bool inParallel) - { - var r = _SerializableDocument.Geometry.Shapes.Select((s, i) => new VimShape(this, i)); - VimShapes = inParallel ? r.EvaluateInParallel() : r.Evaluate(); - } - - private void CreateScene(bool inParallel) - { - VimNodes = CreateVimSceneNodes(this, _SerializableDocument.Geometry, inParallel); - Nodes = VimNodes.Select(n => n as ISceneNode); - } - - private void CreateMaterials(bool inParallel) - { - var query = _SerializableDocument.Geometry.Materials.Select(m => new VimMaterial(m) as IMaterial); - Materials = inParallel ? query.EvaluateInParallel() : query.Evaluate(); - } - - public static IArray CreateVimSceneNodes(VimScene scene, G3D g3d, bool inParallel) - { - Matrix4x4 GetMatrix(int i) => i >= 0 ? g3d.InstanceTransforms[i] : Matrix4x4.Identity; - - var r = g3d.InstanceTransforms.Select((_, i) => - new VimSceneNode(scene, i, g3d.InstanceMeshes[i], GetMatrix(i))); - - return inParallel ? r.EvaluateInParallel() : r.Evaluate(); - } - - public void Save(string filePath) - => _SerializableDocument.Serialize(filePath); - - public string FileName => _SerializableDocument.FileName; - - public void TransformSceneInPlace(Func meshTransform = null, Func nodeTransform = null) - { - if (meshTransform != null) - Meshes = Meshes.Select(meshTransform).EvaluateInParallel(); - if (nodeTransform != null) - VimNodes = VimNodes.Select(nodeTransform).EvaluateInParallel(); - } - - - - private class Step : IStep - { - private readonly Action _action; - private readonly string _name; - public float Effort { get; } - - public Step(Action action, string name, float effort = 1f) - { - _action = action; - _name = name; - Effort = effort; - } - - public void Run(IVimSceneProgress progress) - { - progress?.Report((_name, Effort)); - _action(); - } - } - - private class StepSequence : IStep - { - private readonly Step[] _steps; - public float Effort { get; } - - public StepSequence(params Step[] steps) - { - _steps = steps; - Effort = _steps.Sum(s => s.Effort); - } - - public void Run(IVimSceneProgress progress) - { - foreach (var step in _steps) - step.Run(progress); - } - } - - public interface IStep - { - void Run(IVimSceneProgress progress); - float Effort { get; } - } - - private class CumulativeProgressDecorator : IVimSceneProgress - { - private readonly double _total; - private double _current; - - private readonly IVimSceneProgress _progress; - - private CumulativeProgressDecorator(IVimSceneProgress progress, float total) - => (_progress, _total) = (progress, total); - - public static CumulativeProgressDecorator Decorate(IVimSceneProgress logger, float total) - => logger != null ? new CumulativeProgressDecorator(logger, total) : null; - - public void Report((string, double) value) - { - _current += value.Item2; - _progress.Report((value.Item1, _current / _total)); - } - } - } -} diff --git a/src/cs/vim/Vim.Format/SceneBuilder/VimSceneHelpers.cs b/src/cs/vim/Vim.Format/SceneBuilder/VimSceneHelpers.cs deleted file mode 100644 index 3c6e5ceb..00000000 --- a/src/cs/vim/Vim.Format/SceneBuilder/VimSceneHelpers.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Vim.Format; -using Vim.Format.ObjectModel; -using Vim.Util; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim -{ - public static class VimSceneHelpers - { - public static string[] DisciplineAndCategories = new[] { -"Mechanical:Air Terminals", -"Architecture:Areas", -"Generic:Assemblies", -"Electrical:Cable Tray Fittings", -"Electrical:Cable Tray Runs", -"Electrical:Cable Trays", -"Architecture:Casework", -"Architecture:Ceiling", -"Architecture:Columns", -"Electrical:Communication Devices", -"Electrical:Conduit Fittings", -"Electrical:Conduit Runs", -"Electrical:Conduits", -"Architecture:Curtain Panels", -"Architecture:Curtain Systems", -"Architecture:Curtain Wall Mullions", -"Electrical:Data Devices", -"Generic:Detail Items", -"Architecture:Doors", -"Mechanical:Duct Accessories", -"Mechanical:Duct Fittings", -"Mechanical:Duct Insulations", -"Mechanical:Duct Linings", -"Mechanical:Duct Placeholders", -"Mechanical:Duct Systems", -"Mechanical:Ducts", -"Electrical:Electrical Circuits", -"Electrical:Electrical Equipment", -"Electrical:Electrical Fixtures", -"Electrical:Fire Alarm Devices", -"Mechanical:Flex Ducts", -"Plumbing:Flex Pipes", -"Architecture:Floors", -"Generic:Generic Models", -"Architecture:Grids", -"Mechanical:HVAC Zones", -"Architecture:Levels", -"Architecture:Lines", -"Electrical:Lighting Devices", -"Electrical:Lighting Fixtures", -"Architecture:Mass", -"Architecture:Materials", -"Mechanical:Mechanical Equipment", -"Mechanical:MEP Fabrication Ductwork", -"Mechanical:MEP Fabrication Hangers", -"Mechanical:MEP Fabrication Containment", -"Mechanical:MEP Fabrication Pipework", -"Electrical:Nurse Call Devices", -"Mechanical:Parts", -"Architecture:Parking", -"Plumbing:Pipe Accessories", -"Plumbing:Pipe Fittings", -"Plumbing:Pipe Insulations", -"Plumbing:Pipe Placeholders", -"Plumbing:Pipes", -"Architecture:Planting", -"Plumbing:Piping Systems", -"Plumbing:Plumbing Fixtures", -"Generic:Project Info", -"Architecture:Railings", -"Architecture:Ramps", -"Generic:Raster Images", -"Architecture:Rooms", -"Architecture:Roofs ", -"Electrical:Security Devices", -"Architecture:Shaft Openings", -"Generic:Sheets", -"Architecture:Spaces", -"Generic:Specialty Equipment", -"Plumbing:Sprinklers", -"Architecture:Stairs", -"Structural:Structural Area Reinforcement", -"Structural:Structural Beam Systems", -"Structural:Structural Columns", -"Structural:Structural Connections", -"Structural:Structural Fabric Areas", -"Structural:Structural Fabric Reinforcement", -"Structural:Structural Foundations", -"Structural:Structural Framing", -"Structural:Structural Path Reinforcement", -"Structural:Structural Rebar", -"Structural:Structural Rebar Couplers", -"Structural:Structural Stiffeners", -"Structural:Structural Trusses", -"Electrical:Switch Systems", -"Electrical:Telephone Devices", -"Architecture:Topography", -"Architecture:Views", -"Architecture:Walls", -"Architecture:Windows", -//IFC Groups -"Generic:OST_GenericModel", -"Architecture:OST_Site", -"Generic:OST_SpecialityEquipment", -"Structural:OST_StructuralFraming", -"Architecture:OST_Walls", -"Architecture:OST_Doors", -"Architecture:OST_Floors", -"Architecture:OST_Ceilings", -"Architecture:OST_Roofs", -"Architecture:OST_Windows", -"Structural:OST_StructuralFoundation", -"Architecture:OST_Stairs", -"Architecture:OST_Columns", -"Structural:OST_StructuralColumns", -"Structural:OST_Rebar", -"Mechanical:OST_MechanicalEquipment", -"Architecture:OST_StairsLandings", -"Architecture:OST_StairsRailing", -"Architecture:OST_Ramps", -"Architecture:OST_CurtaSystem", -"Generic:OST_GenericAnnotation", -"Plumbing:OST_PlumbingFixtures", -"Architecture:OST_Grids", -"Structural:OST_StructConnections", -"Mechanical:OST_Parts", -"Architecture:OST_Furniture", -"Architecture:OST_CurtainWallPanels", -"Architecture:OST_CurtainWallMullions", -"Mechanical:OST_DuctTerminal", -"Mechanical:OST_DuctCurves", -"Electrical:OST_LightingFixtures", -"Plumbing:OST_PipeCurves", -"Plumbing:OST_PipeFitting", -"Plumbing:OST_PipeAccessory", -"Mechanical:OST_DuctFitting", -"Structural:OST_FabricAreas" - }; - - public static Dictionary CategoryToDiscipline - = DisciplineAndCategories.ToDictionary(c => c.Substring(c.IndexOf(':') + 1), c => c.Substring(0, c.IndexOf(':'))); - - public static string[] Categories - = CategoryToDiscipline.Keys.OrderBy(x => x).ToArray(); - - public static string GetDisiplineFromCategory(string category, string defaultDiscipline = "Generic") - => CategoryToDiscipline.GetOrDefault(category ?? "", defaultDiscipline); - - public static Vector4 GetDiffuseColor(this Material m) - => m?.Color.ToDiffuseColor(m.Transparency) ?? DefaultColor; - - public static Vector4 ToDiffuseColor(this DVector3 v, double transparency) - => new Vector4((float)v.X, (float)v.Y, (float)v.Z, 1.0f - (float)transparency); - - public static IArray MaterialColors(this VimScene scene) => scene.DocumentModel.MaterialList.Select(GetDiffuseColor); - - public static Vector4 DefaultColor = new Vector4(0.5f, 0.5f, 0.5f, 1); - - public static IEnumerable<(string assetBufferName, FileInfo assetFileInfo)> ExtractAssets(this VimScene vim, DirectoryInfo directory) - => vim.Document.ExtractAssets(directory); - - public static FileInfo ExtractAsset(this VimScene vim, string assetBufferName, FileInfo fileInfo) - => vim.Document.ExtractAsset(assetBufferName, fileInfo); - - public static ElementInfo GetElementInfo(this VimScene vim, int elementIndex) - => vim.DocumentModel.GetElementInfo(elementIndex); - - public static ElementInfo GetElementInfo(this VimScene vim, Element element) - => vim.DocumentModel.GetElementInfo(element); - - public static VimSchema GetVimSchema(this VimScene vim) - => VimSchema.Create(vim.Document); - } -} diff --git a/src/cs/vim/Vim.Format/SceneBuilder/VimSceneNode.cs b/src/cs/vim/Vim.Format/SceneBuilder/VimSceneNode.cs deleted file mode 100644 index 6ec1d6f8..00000000 --- a/src/cs/vim/Vim.Format/SceneBuilder/VimSceneNode.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Vim.Format.Geometry; -using Vim.Format.ObjectModel; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim -{ - public sealed class VimSceneNode : ElementInfo, ISceneNode, ITransformable3D - { - public VimSceneNode(VimScene scene, int nodeIndex, int geometryIndex, Matrix4x4 transform) - : base(scene.DocumentModel, scene.DocumentModel.GetNodeElementIndex(nodeIndex)) - { - VimIndex = scene.VimIndex; - _Scene = scene; - Transform = transform; - MeshIndex = geometryIndex; - NodeIndex = nodeIndex; - } - - public VimScene _Scene { get; } - - public Matrix4x4 Transform { get; } - - public InstanceFlags InstanceFlags - => (InstanceFlags)_Scene.Document.Geometry.InstanceFlags.ElementAtOrDefault(NodeIndex); - - public bool HideByDefault - => (InstanceFlags & InstanceFlags.Hidden) == InstanceFlags.Hidden; - - public int VimIndex { get; } = -1; - public int NodeIndex { get; } = -1; - - public IMesh GetMesh() - => _Scene.Meshes.ElementAtOrDefault(MeshIndex); - - public int MeshIndex { get; } - - public bool HasMesh => MeshIndex != -1; - - // TODO: I think this should be "IEnumerable" in the interface - public ISceneNode Parent => null; - - public string DisciplineName => VimSceneHelpers.GetDisiplineFromCategory(CategoryName); - - VimSceneNode ITransformable3D.Transform(Matrix4x4 mat) - => new VimSceneNode(_Scene, NodeIndex, MeshIndex, mat * Transform); - } -} diff --git a/src/cs/vim/Vim.Format/SceneBuilder/VimShape.cs b/src/cs/vim/Vim.Format/SceneBuilder/VimShape.cs deleted file mode 100644 index 112a6a13..00000000 --- a/src/cs/vim/Vim.Format/SceneBuilder/VimShape.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Vim.Format.ObjectModel; -using Vim.G3d; -using Vim.LinqArray; -using Vim.Math3d; - -namespace Vim -{ - public class VimShape : ElementInfo - { - public readonly VimScene Scene; - public readonly int ShapeIndex; - - public G3dShape G3dShape => Scene.Document.Geometry.Shapes[ShapeIndex]; - public IArray Vertices => G3dShape.Vertices; - public Vector4 Color => G3dShape.Color; - public float Width => G3dShape.Width; - - public VimShape(VimScene scene, int shapeIndex) - : base(scene.DocumentModel, scene.DocumentModel.GetShapeElementIndex(shapeIndex)) - { - Scene = scene; - ShapeIndex = shapeIndex; - } - } -} diff --git a/src/cs/vim/Vim.Format/TransformService.cs b/src/cs/vim/Vim.Format/TransformService.cs deleted file mode 100644 index 4acb4813..00000000 --- a/src/cs/vim/Vim.Format/TransformService.cs +++ /dev/null @@ -1,414 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Vim.Format.Geometry; -using Vim.LinqArray; -using Vim.Math3d; -using Vim.Format.ObjectModel; -using Vim.Util; - -namespace Vim.Format -{ - public class TransformService - { - /// - /// A string representing the application which is emitting the new VIM document. - /// - private readonly string _generatorString; - - /// - /// The version of the application which is emitting the new VIM document. - /// - private readonly string _versionString; - - /// - /// Constructor. - /// - /// A string representing the application which is emitting the new VIM document. - /// The version of the application which is emitting the new VIM document. - public TransformService(string generatorString, string versionString) - { - _generatorString = generatorString; - _versionString = versionString; - } - - /// - /// Returns a new VIM document builder in which the original meshes have been deduplicated. - /// - public DocumentBuilder DeduplicateGeometry(VimScene vim) - => Transform( - vim, - _ => true, - _ => true, - n => n.Transform, - m => m, - true); - - /// - /// Returns a new VIM document builder in which the nodes have been filtered. - /// - public DocumentBuilder Filter(VimScene vim, NodeFilter nodeFilter, bool deduplicateMeshes = false) - => Transform( - vim, - nodeFilter, - _ => true, - n => n.Transform, - m => m, - deduplicateMeshes); - - /// - /// Returns a new VIM document builder in which the instance transforms have been multiplied by the given matrix. - /// - public DocumentBuilder TransformInstances(VimScene vim, Matrix4x4 matrix, bool deduplicateMeshes = false) - => Transform( - vim, - _ => true, - _ => true, - n => n.Transform * matrix, - m => m, - deduplicateMeshes); - - public delegate bool NodeFilter(VimSceneNode node); - public delegate Matrix4x4 NodeTransform(VimSceneNode node); - public delegate bool MeshFilter(IMesh mesh); - public delegate IMesh MeshTransform(IMesh mesh); - - /// - /// Transforms the VIM into a new VIM document builder based on the given filters and transformations. - /// - /// The VIM to transform into a new VIM document builder. - /// Returns true if the given node should be present in the new VIM document builder. - /// Returns true if the given mesh should be present in the new VIM document builder. - /// Returns the node's new transform (or its current transform if left unchanged). - /// Returns the mesh's new mesh (or its current mesh if left unchanged). - /// Determines whether the mesh deduplication process is applied. - public DocumentBuilder Transform( - VimScene vim, - NodeFilter nodeFilter, - MeshFilter meshFilter, - NodeTransform nodeTransform, - MeshTransform meshTransform, - bool deduplicateMeshes) - { - var db = new DocumentBuilder(_generatorString, SchemaVersion.Current, _versionString); - - // Filter the nodes we want to keep - var nodesToKeep = new List(); - var nodeElementIndicesToKeep = new HashSet(); - var oldNodeIndexToNewNodeIndex = new Dictionary(); - var vimNodes = vim.VimNodes; - for (var i = 0; i < vimNodes.Count; ++i) - { - var node = vimNodes[i]; - if (nodeFilter?.Invoke(node) ?? true) - { - var oldNodeIndex = i; - var newNodeIndex = nodesToKeep.Count; - nodesToKeep.Add(node); - oldNodeIndexToNewNodeIndex.Add(oldNodeIndex, newNodeIndex); - nodeElementIndicesToKeep.Add(node.ElementIndex); - } - } - - // Filter the meshes we want to keep - var meshesToKeep = new List(); - foreach (var node in nodesToKeep) - { - var mesh = node.GetMesh(); - if (mesh == null || mesh.NumFaces == 0) - continue; - - if (meshFilter?.Invoke(mesh) ?? true) - meshesToKeep.Add(mesh); - } - - var meshLookup = new Dictionary(); - var meshIndices = new IndexedSet(); - - if (deduplicateMeshes) - { - // Group meshes according to a hash function - const float tolerance = 1f / 12f / 8f; - var groupedMeshes = meshesToKeep.GroupMeshesByHash(tolerance); - - // Create the lookup from old mesh to new mesh - meshLookup = groupedMeshes - .SelectMany(grp => grp.Value.Select(m => (m, grp.Key.Mesh))) - .ToDictionaryIgnoreDuplicates(pair => pair.m, pair => pair.Mesh); - } - else - { - // Create a dummy mapping from mesh to mesh - foreach (var m in meshesToKeep) - meshLookup.AddIfNotPresent(m, m); - } - - // Collect the mesh indices in an indexed set. - foreach (var m in meshLookup.Values) - meshIndices.Add(m); - - // Add the assets - foreach (var asset in vim.Document.Assets.Values.ToEnumerable()) - db.AddAsset(asset); - - // Add the transformed meshes. - var subdividedMeshes = meshIndices.OrderedKeys.Select(m => (meshTransform?.Invoke(m) ?? m).ToDocumentBuilderSubdividedMesh()); - db.AddMeshes(subdividedMeshes); - - // Add the materials. - // TECH DEBT: this could be improved to remove duplicate materials, but this would require a remapping among the material entities as well. - var materials = vim.Document.Geometry.Materials.Select(m => m.ToDocumentBuilderMaterial()).ToEnumerable(); - db.AddMaterials(materials); - - // Remove the associated FamilyInstances and remap the entities. - var nodeEntityRemap = new EntityRemap( - TableNames.Node, - nodesToKeep.Select(n => n.NodeIndex).ToList(), - oldNodeIndexToNewNodeIndex - ); - var entityRemaps = EntityRemap.GetEntityRemaps(vim, nodeEntityRemap, nodeElementIndicesToKeep); - StoreTransformedEntityTables(vim.Document, db, entityRemaps); - - // Add the nodes - foreach (var node in nodesToKeep) - { - var g = meshLookup.GetOrDefaultAllowNulls(node.GetMesh()); - var meshIndex = meshIndices.GetOrDefaultAllowNulls(g, -1); - var transform = nodeTransform?.Invoke(node) ?? node.Transform; - var flags = node.InstanceFlags; - db.AddInstance(transform, meshIndex, flags); - } - - return db; - } - - public class EntityRemap - { - public string EntityTableName { get; } - public List RemappedIndices { get; } - public Dictionary OldToNewIndexMap { get; } - - public EntityRemap(string entityTableName, List remappedIndices, Dictionary oldToNewIndexMap) - { - EntityTableName = entityTableName; - RemappedIndices = remappedIndices; - OldToNewIndexMap = oldToNewIndexMap; - } - - private EntityRemap(EntityTable entityTable, HashSet entityIndicesToKeep) - { - EntityTableName = entityTable.Name; - RemappedIndices = new List(); - OldToNewIndexMap = new Dictionary(); - - for (var entityIndex = 0; entityIndex < entityTable.NumRows; ++entityIndex) - { - if (!entityIndicesToKeep.Contains(entityIndex)) - continue; - - var newEntityIndex = RemappedIndices.Count; - RemappedIndices.Add(entityIndex); - OldToNewIndexMap.Add(entityIndex, newEntityIndex); - } - } - - public static Dictionary GetEntityRemaps( - VimScene vim, - EntityRemap nodeRemap, - HashSet nodeElementIndicesToKeep) - { - var dm = vim.DocumentModel; - - // Start by presuming we will keep all the element indices. - var elementIndicesToKeep = new HashSet(); - for (var elementIndex = 0; elementIndex < dm.NumElement; ++elementIndex) - { - var elementInfo = dm.GetElementInfo(elementIndex); - - var keep = true; - - if (elementInfo.IsSystem) - { - // TECH DEBT: for simplicity, we keep all elements which represent systems. - // Specifically, in the case of curtain walls in RoomTest.vim, an element - // can be -BOTH- a System and a FamilyInstance, which complicates things - // if we were to remove that element (we would also need to remove other - // ElementInSystem records referencing that removed system) - keep = true; - } - else if (elementInfo.IsFamilyInstance && !nodeElementIndicesToKeep.Contains(elementIndex)) - { - // Here, the element represents a FamilyInstance, which we want to remove from the - // transformed collection of elements. - keep = false; - } - - if (keep) - { - elementIndicesToKeep.Add(elementIndex); - } - } - - var entityRemaps = new Dictionary() - { - { TableNames.Node, nodeRemap }, - }; - - // Add the element table to the remapped set. - if (TryGet(vim, TableNames.Element, elementIndicesToKeep, out var elementRemap)) - { - entityRemaps.Add(TableNames.Element, elementRemap); - } - - var cascadeElementRemapTableNames = ObjectModelReflection.GetEntityTypes() - .Where(t => t.HasCascadeElementRemap()) - .Select(t => t.GetEntityTableName()); - - // Compute the remapping for the following entity tables: Node, FamilyInstance, Parameter, ElementInSystem, ... - foreach (var entityTableName in cascadeElementRemapTableNames) - { - if (TryGetCascadeElementRemap(vim, entityTableName, elementIndicesToKeep, out var remap)) - { - // Add the cascading entity table to the remapped set. - entityRemaps.Add(entityTableName, remap); - } - } - - return entityRemaps; - } - - private static bool TryGet( - VimScene vim, - string entityTableName, - HashSet filteredIndices, - out EntityRemap remap) - { - remap = null; - - var entityTables = vim.Document.EntityTables; - - if (!entityTables.Contains(entityTableName)) - return false; - - remap = new EntityRemap(entityTables[entityTableName], filteredIndices); - - return true; - } - - private static bool TryGetCascadeElementRemap( - VimScene vim, - string entityTableName, - HashSet elementIndicesToKeep, - out EntityRemap remap) - { - remap = null; - - var entityTables = vim.Document.EntityTables; - - if (!entityTables.Contains(entityTableName)) - return false; - - var entityTable = entityTables[entityTableName]; - var indexColumns = entityTable.IndexColumns; - if (indexColumns.Keys.Count == 0) - return false; - - var elementIndexColumnName = indexColumns.Keys - .FirstOrDefault(columnName => columnName == $"index:{TableNames.Element}:Element"); - - if (string.IsNullOrWhiteSpace(elementIndexColumnName)) - return false; - - var entityIndicesToKeep = new HashSet(); - var elementIndices = indexColumns[elementIndexColumnName].Array; - for (var i = 0; i < elementIndices.Length; ++i) - { - var elementIndex = elementIndices[i]; - - if (elementIndicesToKeep.Contains(elementIndex)) - { - entityIndicesToKeep.Add(i); - } - } - - remap = new EntityRemap(entityTable, entityIndicesToKeep); - - return true; - } - } - - private static void StoreTransformedEntityTables( - Document sourceDocument, - DocumentBuilder db, - Dictionary entityRemaps = null) - { - // Iterate over all the source tables. - foreach (var sourceEntityTable in sourceDocument.EntityTables.Values.ToEnumerable()) - { - var entityTableName = sourceEntityTable.Name; - - // Don't copy tables that are computed automatically - if (VimConstants.ComputedTableNames.Contains(entityTableName)) - continue; - - var remappedIndices = entityRemaps != null && entityRemaps.TryGetValue(entityTableName, out var entityRemap) - ? entityRemap.RemappedIndices - : null; - - StoreTransformedTable(sourceEntityTable, db, remappedIndices, entityRemaps); - } - } - - public static EntityTableBuilder StoreTransformedTable( - EntityTable sourceTable, - DocumentBuilder db, - List remapping = null, - Dictionary entityRemaps = null) - { - var sourceTableName = sourceTable.Name; - var tb = db.CreateTableBuilder(sourceTableName); - - foreach (var col in sourceTable.IndexColumns.Values.ToEnumerable()) - { - var remappedIndexRelations = col.GetTypedData().Copy(remapping); - - // Remap the referenced indices. - var relatedTableName = col.GetRelatedTableName(); - if (entityRemaps?.TryGetValue(relatedTableName, out var entityRemap) ?? false) - { - for (var i = 0; i < remappedIndexRelations.Length; ++i) - { - var oldIndex = remappedIndexRelations[i]; - var newIndex = entityRemap.OldToNewIndexMap.TryGetValue(oldIndex, out var ni) - ? ni - : EntityRelation.None; - - if (newIndex == EntityRelation.None && - col.Name == $"index:{TableNames.Element}:Element" && - sourceTableName != TableNames.Node) // NOTE: special exception for the Node table which must always be 1:1 aligned with the g3d instances (and may not always have a backing element) - { - Debug.Fail($"Remapped index is {EntityRelation.None} in {sourceTableName} > {col.Name}"); - } - - remappedIndexRelations[i] = newIndex; - } - } - - tb.AddIndexColumn(col.Name, remappedIndexRelations); - } - - foreach (var col in sourceTable.DataColumns.Values.ToEnumerable()) - { - tb.AddDataColumn(col.Name, col.RemapOrSelfDataColumn(remapping)); - } - - foreach (var col in sourceTable.StringColumns.Values.ToEnumerable()) - { - var strings = col.GetTypedData().Select(i => sourceTable.Document.StringTable.ElementAtOrDefault(i, null)); - tb.AddStringColumn(col.Name, strings.ToArray().RemapOrSelf(remapping)); - } - - return tb; - } - } -} diff --git a/src/cs/vim/Vim.Format/VIM.cs b/src/cs/vim/Vim.Format/VIM.cs new file mode 100644 index 00000000..6c68b67b --- /dev/null +++ b/src/cs/vim/Vim.Format/VIM.cs @@ -0,0 +1,391 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using Vim.BFast; +using Vim.Util; + +// TODO +// - Clean up throw new Exception() -> turn them into actual VimExceptions +// - Merge with mainline + integrate +// - Test beyond this repository (i.e. with Revit exporter) > check the buildup using VimMesh +// - (!) Material and VimMaterial must be inserted simultaneously +// - See if we can create a simple example to modify node render materials as well. +// - Visitor pattern on geometry deserialization to minimize memory footprint in 3dsMax importer. + +namespace Vim.Format +{ + /// + /// A VIM represents a building design (one or more BIM models). A VIM contains the building element geometry and its associated parameters. + /// + public class VIM + { + /// + /// The file path of the opened VIM. Can be empty if the VIM is being written. + /// + public string FilePath { get; } = ""; + + /// + /// The header of the VIM, which contains IDs used to distinguish different VIM files and information about the provenance of the VIM. + /// + public VimHeader Header { get; } = new VimHeader(); + public const string HeaderBufferName = VimBufferNames.Header; + + /// + /// The geometry of the building elements. + /// + public VimGeometryData GeometryData { get; } = new VimGeometryData(); + public const string GeometryDataBufferName = VimBufferNames.Geometry; + + /// + /// The string table for the entities defined among the entity tables. Strings are de-duplicated in this table and indexed using string columns to avoid repetition. + /// + public string[] StringTable { get; } = Array.Empty(); + public const string StringTableBufferName = VimBufferNames.Strings; + + /// + /// The entity tables which define the various entities in the building model. + /// + public List EntityTableData { get; } = new List(); + public const string EntityTableDataBufferName = VimBufferNames.Entities; + + /// + /// The binary assets contained in the building model, including renders, textures, etc. + /// + public INamedBuffer[] Assets { get; } = Array.Empty(); + public const string AssetsBufferName = VimBufferNames.Assets; + + /// + /// Serialization constructor + /// + public VIM( + VimHeader header, + string[] stringTable, + List entityTableData, + INamedBuffer[] assets) + { + Header = header; + StringTable = stringTable; + EntityTableData = entityTableData; + Assets = assets; + // ... GeometryData is serialized in VimBuilder ... + } + + /// + /// Stream-based constructor. + /// + public VIM( + Stream vimStream, + string vimFilePath, + VimOpenOptions options = null, + IProgress progress = null, + CancellationToken ct = default) + { + vimStream.ThrowIfNotSeekable("Could not open VIM file"); + + options = options ?? new VimOpenOptions(); + + FilePath = vimFilePath; + + foreach (var bufferReader in vimStream.GetBFastBufferReaders()) + { + ct.ThrowIfCancellationRequested(); + + var (name, numBytes) = bufferReader; + bufferReader.Seek(); + + switch (name) + { + case HeaderBufferName: + { + progress?.Report("Reading VIM header"); + // vim stream has been seeked to header. + var headerString = Encoding.UTF8.GetString(vimStream.ReadArray((int)numBytes)); + Header = VimHeader.Parse(headerString); + break; + } + + case AssetsBufferName: + { + if (options.IncludeAssets) + { + progress?.Report("Reading VIM assets"); + // vim stream has been seeked to asset buffer + Assets = vimStream.ReadBFast().ToArray(); + } + break; + } + + case StringTableBufferName: + { + if (options.IncludeStringTable) + { + progress?.Report("Reading VIM string table"); + // vim stream has been seeked to string table + StringTable = ReadStringTable(vimStream, numBytes); + } + break; + } + + case GeometryDataBufferName: + { + if (options.IncludeGeometry) + { + progress?.Report("Reading VIM geometry"); + // vim stream has been seeked to geometry buffer + GeometryData = new VimGeometryData(vimStream); + } + break; + } + + case EntityTableDataBufferName: + { + if (options.IncludeEntityTables) + { + progress?.Report("Reading VIM entity tables"); + // vim stream has been seeked to entities buffer + EntityTableData = VimEntityTableData.EnumerateEntityTables(bufferReader, options.SchemaOnly).ToList(); + } + break; + } + } + } + } + + /// + /// Opens the VIM file defined at the given file path. + /// + public static VIM Open( + string vimFilePath, + VimOpenOptions options = null, + IProgress progress = null, + CancellationToken ct = default) + { + return Open(new FileInfo(vimFilePath), options, progress, ct); + } + + /// + /// Opens the VIM file defined in the given FileInfo + /// + public static VIM Open( + FileInfo vimFileInfo, + VimOpenOptions options = null, + IProgress progress = null, + CancellationToken ct = default) + { + vimFileInfo.ThrowIfNotExists("VIM file not found"); + + using (var vimFileStream = vimFileInfo.OpenRead()) + { + return Open(vimFileStream, vimFileInfo.FullName, options, progress, ct); + } + } + + /// + /// Opens the VIM file defined in the given seekable Stream. + /// Note: The given filePath is assigned to the VIM's FilePath property. + /// + public static VIM Open( + Stream vimStream, + string vimFilePath, + VimOpenOptions options = null, + IProgress progress = null, + CancellationToken ct = default) + { + return new VIM(vimStream, vimFilePath, options, progress, ct); + } + + /// + /// Returns the VimGeometryData contained in the VIM at the given file path. + /// + public static VimGeometryData GetGeometryData(string vimFilePath) + { + return GetGeometryData(new FileInfo(vimFilePath)); + } + + /// + /// Returns the VimGeometryData contained in the VIM in the given FileInfo. + /// + public static VimGeometryData GetGeometryData(FileInfo vimFileInfo) + { + vimFileInfo.ThrowIfNotExists("Could not get VIM geometry"); + using (var stream = vimFileInfo.OpenRead()) + { + return GetGeometryData(stream); + } + } + + /// + /// Returns the VimGeometryData contained in the VIM in the given stream. + /// + public static VimGeometryData GetGeometryData(Stream vimStream) + { + vimStream.ThrowIfNotSeekable("Could not get VIM geometry"); + + var geometryBufferReader = vimStream.GetBFastBufferReader(GeometryDataBufferName); + if (geometryBufferReader == null) + return new VimGeometryData(); + + geometryBufferReader.Seek(); // Seek to the correct position in the stream. + + // vim stream has been seeked to geometry buffer. + return new VimGeometryData(vimStream); + } + + /// + /// Returns the string table contained in the VIM file. + /// + public static string[] GetStringTable(FileInfo vimFileInfo) + { + vimFileInfo.ThrowIfNotExists("VIM file not found. Could not get string table."); + + using (var fileStream = vimFileInfo.OpenRead()) + { + return GetStringTable(fileStream); + } + } + + /// + /// Returns the string table contained in the VIM file contained in the stream. + /// + public static string[] GetStringTable(Stream vimStream) + { + vimStream.ThrowIfNotSeekable("Could not get string table"); + + var stringTableReader = vimStream.GetBFastBufferReader(StringTableBufferName); + if (stringTableReader == null) + return Array.Empty(); + + stringTableReader.Seek(); + + var (_, numBytes) = stringTableReader; + + return ReadStringTable(vimStream, numBytes); + } + + private static string[] ReadStringTable(Stream stream, long numBytes) + { + var stringBytes = stream.ReadArray((int)numBytes); + var joinedStringTable = Encoding.UTF8.GetString(stringBytes); + return joinedStringTable.Split('\0'); + } + + private VimEntityTableSet _cachedEntityTableSet = null; + + /// + /// Returns the VimEntityTableSet contained in this VIM file. + /// + public VimEntityTableSet GetEntityTableSet(bool inParallel = true) + { + if (_cachedEntityTableSet == null) + { + _cachedEntityTableSet = new VimEntityTableSet(EntityTableData.ToArray(), StringTable, inParallel); + } + + return _cachedEntityTableSet; + } + + private VimElementGeometryInfo[] _cachedElementGeometryMap = null; + + /// + /// Returns the VimElementGeometryMap contained in this VIM file. + /// + public VimElementGeometryInfo[] GetElementGeometryInfoList() + { + if (_cachedElementGeometryMap == null) + { + _cachedElementGeometryMap = VimElementGeometryInfo.GetElementGeometryInfoList(GetEntityTableSet(), GeometryData); + } + + return _cachedElementGeometryMap; + } + + private VimElementHierarchyService _cachedElementHierarchyService; + + /// + /// Returns the VimElementHierarchyService contained in this VIM file. + /// + public VimElementHierarchyService GetElementHierarchyService(bool isElementAndDescendantPrimaryKey = false) + { + if (_cachedElementHierarchyService == null) + { + _cachedElementHierarchyService = new VimElementHierarchyService( + GetEntityTableSet(), + GetElementGeometryInfoList(), + isElementAndDescendantPrimaryKey); + } + + return _cachedElementHierarchyService; + } + + /// + /// Returns the asset buffer based on the given name. + /// + public bool TryGetAssetBuffer(string assetBufferName, out INamedBuffer assetBuffer) + { + assetBuffer = Assets.FirstOrDefault(buffer => buffer.Name == assetBufferName); + return assetBuffer != null; + } + + /// + /// Extracts the asset corresponding to the assetBufferName and returns a FileInfo representing the extracted asset on disk.
+ /// Returns null if the asset could not be extracted. + ///
+ public FileInfo ExtractAsset(string assetBufferName, FileInfo fileInfo) + { + if (!TryGetAssetBuffer(assetBufferName, out var assetBuffer)) + return null; + + return VimAssetInfo.ExtractAsset(assetBuffer, fileInfo); + } + + /// + /// Extracts the assets contained in the Document to the given directory. + /// + public IEnumerable<(string assetBufferName, FileInfo assetFileInfo)> + ExtractAssets(DirectoryInfo directoryInfo) + { + var result = new List<(string assetBufferName, FileInfo assetFileInfo)>(); + foreach (var assetBuffer in Assets) + { + var assetBufferName = assetBuffer.Name; + var assetFilePath = VimAssetInfo.ExtractAsset(assetBuffer, directoryInfo); + result.Add((assetBufferName, assetFilePath)); + } + return result; + } + + /// + /// Gets the byte array which defines the given asset. Returns false if the asset was not found or if the byte array is empty or null. + /// + public bool TryGetAssetBytes(string assetBufferName, out byte[] bytes) + { + bytes = null; + + if (!TryGetAssetBuffer(assetBufferName, out var assetBuffer)) + return false; + + if (!(assetBuffer is NamedBuffer byteBuffer)) + return false; + + bytes = byteBuffer.Array; + + return bytes != null && bytes.Length > 0; + } + + /// + /// Gets the byte array which defines the given asset. Returns false if the asset was not found or if the byte array is empty or null. + /// + public bool TryGetAssetBytes(VimAssetType assetType, string assetName, out byte[] bytes) + => TryGetAssetBytes(new VimAssetInfo(assetName, assetType).ToString(), out bytes); + + /// + /// Gets the byte array which defines the main image asset. Returns false if the asset was not found or if the byte array is empty or null. + /// + public bool TryGetMainImageBytes(out byte[] bytes) + => TryGetAssetBytes(VimAssetType.Render, VimAssetInfo.MainPng, out bytes); + } +} + diff --git a/src/cs/vim/Vim.Format/Vim.Format.csproj b/src/cs/vim/Vim.Format/Vim.Format.csproj index 582543cf..9346ea6a 100644 --- a/src/cs/vim/Vim.Format/Vim.Format.csproj +++ b/src/cs/vim/Vim.Format/Vim.Format.csproj @@ -19,8 +19,6 @@ - - diff --git a/src/cs/vim/Vim.Format/VimBuilder.cs b/src/cs/vim/Vim.Format/VimBuilder.cs new file mode 100644 index 00000000..3a0bdff7 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimBuilder.cs @@ -0,0 +1,293 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Vim.BFast; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + public partial class VimBuilder + { + /// + /// The underlying VIM file which will be serialized. + /// + private VimHeader VimHeader { get; } + + /// + /// The list of subdivided meshes which will be accumulated. + /// + public List Meshes { get; private set; } = new List(); + + /// + /// The list of instances which will be accumulated. + /// + public List Instances { get; } = new List(); + + /// + /// The list of materials which will be accumulated. + /// + public List Materials { get; } = new List(); + + // NOTE: see other partial class definition for entity set builder definitions + + /// + /// The dictionary of all binary assets, keyed by buffer name. + /// + public readonly Dictionary Assets = new Dictionary(); + + /// + /// Constructor + /// + public VimBuilder( + string generator, + SerializableVersion schema, + string versionString, + IReadOnlyDictionary optionalHeaderValues = null) + { + VimHeader = new VimHeader( + generator, + schema, + versionString, + optionalHeaderValues + ); + } + + /// + /// Returns a list of VimEntityTableBuilders based on the given VIM file's entity table data + /// + public static List GetVimEntityTableBuilders(VIM vim) + { + var result = new List(); + + foreach (var et in vim.EntityTableData) + { + var builder = new VimEntityTableBuilder(et, vim.StringTable); + result.Add(builder); + } + + return result; + } + + /// + /// Writes the VIM file to the given file path. Overwrites any existing file. + /// + public void Write(string vimFilePath, IReadOnlyList tableBuilders = null) + { + IO.Delete(vimFilePath); + IO.CreateFileDirectory(vimFilePath); + + using (var fileStream = File.OpenWrite(vimFilePath)) + { + Write(fileStream, tableBuilders); + } + } + + /// + /// Writes the VIM file to the given stream. + /// + public void Write(Stream vimStream, IReadOnlyList tableBuilders = null) + { + tableBuilders = tableBuilders ?? GetVimEntityTableBuilders(); // code-generated. + + var stringLookupInfo = new StringLookupInfo(tableBuilders); + + // Instantiate a new VIM object and apply the header we created in the constructor. + var vim = new VIM( + VimHeader, + stringLookupInfo.StringTable, + GetVimEntityTableData(tableBuilders, stringLookupInfo).ToList(), + Assets.Values.ToArray() + ); + + // For efficiency, we create a geometryWriter to avoid extra allocations in memory while writing. + var geometryWriter = new VimGeometryDataWriter(Meshes, Instances, Materials); + + // Write the VIM's buffers using a BFastBuilder. + var bfastBuilder = new BFastBuilder(); + + bfastBuilder.Add(VIM.HeaderBufferName, vim.Header.ToBuffer()); + bfastBuilder.Add(VIM.AssetsBufferName, vim.Assets ?? Array.Empty()); + bfastBuilder.Add(VIM.EntityTableDataBufferName, GetBFastBuilder(vim.EntityTableData)); + bfastBuilder.Add(VIM.StringTableBufferName, vim.StringTable.PackStrings().ToBuffer()); + bfastBuilder.Add(VIM.GeometryDataBufferName, geometryWriter); + + bfastBuilder.Write(vimStream); + } + + private static BFastBuilder GetBFastBuilder(IEnumerable entityTables) + { + var bldr = new BFastBuilder(); + foreach (var et in entityTables) + { + bldr.Add(et.Name, et.GetColumns()); + } + return bldr; + } + + /// + /// A helper class which collects all the strings from the entity tables to create the indexed string lookups. + /// + private class StringLookupInfo + { + public readonly IReadOnlyDictionary StringLookup; + public readonly string[] StringTable; + + public StringLookupInfo(IEnumerable allStrings, int indexOffset = 0) + { + // NOTE: ensure the empty string is part of the string table. + var stringTable = allStrings.Prepend("").Distinct().ToList(); + + // By construction, the contents of stringTable should not have repeating items. + var stringLookup = new Dictionary(); + for (var i = 0; i < stringTable.Count; ++i) + stringLookup[stringTable[i]] = i + indexOffset; + + StringTable = stringTable.ToArray(); + StringLookup = stringLookup; + } + + public StringLookupInfo(IEnumerable tableBuilders, int indexOffset = 0) + : this(tableBuilders.SelectMany(tb => tb.GetAllStrings()), indexOffset) + { } + } + + private IEnumerable GetVimEntityTableData( + IReadOnlyList tableBuilders, + StringLookupInfo stringLookupInfo) + => WithGeometryTable(tableBuilders) + .Select((Func)(tb => + // Transfer each table builder's data + new VimEntityTableData() + { + Name = tb.Name, + IndexColumns = tb.IndexColumns + .Select(kv => kv.Value.ToNamedBuffer(kv.Key)) + .ToList(), + StringColumns = tb.StringColumns + .Select(kv => kv.Value + .Select(s => stringLookupInfo.StringLookup[s ?? string.Empty]) + .ToArray() + .ToNamedBuffer(kv.Key)) + .ToList(), + DataColumns = Enumerable.Select, INamedBuffer>(tb.DataColumns +, (Func, INamedBuffer>)(kv => kv.Value.ToNamedBuffer(kv.Key) as INamedBuffer)) + .ToList() + }) + ); + + private IEnumerable WithGeometryTable(IEnumerable tableBuilders) + => tableBuilders.Where(tb => tb.Name != VimEntityTableNames.Geometry) + .Append(CreateGeometryTable()); + + private VimEntityTableBuilder CreateGeometryTable() + { + // At the last moment, we generate the geometry table based on the mesh bounding boxes. + + var tb = new VimEntityTableBuilder(VimEntityTableNames.Geometry); + tb.Clear(); + + // Populate the box + var boxMinX = new float[Meshes.Count]; + var boxMinY = new float[Meshes.Count]; + var boxMinZ = new float[Meshes.Count]; + + var boxMaxX = new float[Meshes.Count]; + var boxMaxY = new float[Meshes.Count]; + var boxMaxZ = new float[Meshes.Count]; + + for (var i = 0; i < Meshes.Count; ++i) + { + var b = AABox.Create(Meshes[i].Vertices); + boxMinX[i] = b.Min.X; + boxMinY[i] = b.Min.Y; + boxMinZ[i] = b.Min.Z; + + boxMaxX[i] = b.Max.X; + boxMaxY[i] = b.Max.Y; + boxMaxZ[i] = b.Max.Z; + } + + tb.AddDataColumn("float:Box.Min.X", boxMinX); + tb.AddDataColumn("float:Box.Min.Y", boxMinY); + tb.AddDataColumn("float:Box.Min.Z", boxMinZ); + + tb.AddDataColumn("float:Box.Max.X", boxMaxX); + tb.AddDataColumn("float:Box.Max.Y", boxMaxY); + tb.AddDataColumn("float:Box.Max.Z", boxMaxZ); + + tb.AddDataColumn("int:VertexCount", Meshes.Select(g => g.Vertices.Count)); + tb.AddDataColumn("int:FaceCount", Meshes.Select(g => g.Indices.Count / 3)); + + return tb; + } + + public void AddAsset(INamedBuffer asset) + { + Assets[asset.Name] = asset; + } + + /// + /// Mutates the Meshes and Instances to remove any meshes which are not referenced by at least one instance. + /// + public VimBuilder TrimOrphanMeshes() + { + // Example: + // + // old instance mesh indices: [0, 2, 4, 2] + // --- + // old mesh indices: [0, 1, 2, 3, 4] + // orphan mesh indices: [ 1, 3 ] + // next mesh indices: [0, -1, 1, -1, 2] + // --- + // next instance mesh indices: [0, 1, 2, 1] + + const int nullMeshIndex = -1; + + // Initialize the mesh indices + var meshIsReferenced = new bool[Meshes.Count]; + for (var i = 0; i < meshIsReferenced.Length; i++) + meshIsReferenced[i] = false; + + // Mark the mesh indices which are referenced by an instance. + foreach (var instance in Instances) + { + if (instance.MeshIndex <= nullMeshIndex) + continue; + + meshIsReferenced[instance.MeshIndex] = true; + } + + // Early exit if all meshes are referenced. + if (meshIsReferenced.All(isReferenced => isReferenced)) + return this; + + // Update the new mesh indices. + var nextMeshIndex = 0; + var nextMeshIndices = new int[meshIsReferenced.Length]; + for (var i = 0; i < nextMeshIndices.Length; ++i) + { + nextMeshIndices[i] = meshIsReferenced[i] + ? nextMeshIndex++ + : nullMeshIndex; + } + + // Create a new mesh list which excludes the orphaned meshes. + Meshes = Meshes.Where((m, i) => nextMeshIndices[i] > nullMeshIndex).ToList(); + + // Mutate the instances to update their mesh index. + foreach (var instance in Instances) + { + if (instance.MeshIndex <= nullMeshIndex) + continue; + + instance.MeshIndex = nextMeshIndices[instance.MeshIndex]; + Debug.Assert(instance.MeshIndex > nullMeshIndex, $"Invalid instance mesh index ({instance.MeshIndex})"); + } + + return this; + } + } +} diff --git a/src/cs/vim/Vim.Format/VimElementGeometryInfo.cs b/src/cs/vim/Vim.Format/VimElementGeometryInfo.cs new file mode 100644 index 00000000..6c2ab8d9 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimElementGeometryInfo.cs @@ -0,0 +1,200 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + /// + /// Represents the geometric information of an element. + /// + public class VimElementGeometryInfo + { + public int ElementIndex { get; } + + public int VertexCount { get; set; } + + public int FaceCount { get; set; } + + public AABox WorldSpaceBoundingBox { get; set; } = AABox.Empty; + + public List<(int InstanceIndex, int MeshIndex)> InstanceAndMeshIndices { get; } = new List<(int InstanceIndex, int MeshIndex)>(); + + public int NodeCount + => InstanceAndMeshIndices.Count; + + public bool HasMesh + => FaceCount > 0; + + /// + /// Constructor + /// + public VimElementGeometryInfo(int elementIndex) + { + ElementIndex = elementIndex; + } + + /// + /// Returns the world-space meshes associated with this element. + /// + public IEnumerable GetWorldSpaceMeshes(VimGeometryData geometryData) + { + foreach (var tuple in InstanceAndMeshIndices) + { + var (nodeIndex, meshIndex) = tuple; + + if (meshIndex < 0) + continue; + + if (!geometryData.TryGetTransformedMesh(nodeIndex, meshIndex, out var vimMeshData)) + continue; + + yield return vimMeshData; + }; + } + + /// + /// Returns a 1:1 list mapping Element -> VimElementGeometryInfo based on the given VIM file. + /// + public static VimElementGeometryInfo[] GetElementGeometryInfoList( + FileInfo vimFileInfo, + VimEntityTableSet tableSetWithNodeAndElement = null) + { + vimFileInfo.ThrowIfNotExists("Could not get VIM element geometry map."); + + var tableSet = tableSetWithNodeAndElement ?? + VimEntityTableSet.GetEntityTableSetByTableName( + vimFileInfo, + VimEntityTableNames.Node, + VimEntityTableNames.Element + ); + + var vimGeometryData = VIM.GetGeometryData(vimFileInfo); + + return GetElementGeometryInfoList(tableSet, vimGeometryData); + } + + /// + /// Returns a 1:1 list mapping Element -> VimElementGeometryInfo + /// + public static VimElementGeometryInfo[] GetElementGeometryInfoList( + VimEntityTableSet tableSet, + VimGeometryData vimGeometryData) + { + var elementCount = tableSet.ElementTable?.RowCount ?? 0; + + var result = new VimElementGeometryInfo[elementCount]; + + // Initialize the set of items with new geometry info. + for (var elementIndex = 0; elementIndex < result.Length; ++elementIndex) + result[elementIndex] = new VimElementGeometryInfo(elementIndex); + + if (!(tableSet.NodeTable is NodeTable nodeTable)) + return result; + + // Calculate the element associations to nodes and geometry. + // NOTE: one element may have more than one node and associated geometry + + var elementIndexGroups = nodeTable + .Column_ElementIndex + .AsParallel() + .Select((elementIndex, nodeIndex) => (ElementIndex: elementIndex, NodeIndex: nodeIndex)) + .GroupBy(t => t.ElementIndex) + .Where(g => g.Key >= 0); + + foreach (var group in elementIndexGroups) + { + foreach (var (elementIndex, nodeIndex) in group) + { + if (elementIndex < 0 || elementIndex >= result.Length) + continue; + + // INVARIANT: there is a 1:1 relationship between Node entities and instances in the VimGeometryData. + var instanceIndex = nodeIndex; + + if (!TryGetMeshIndex(vimGeometryData, instanceIndex, out var meshIndex)) + continue; // Skip nodes with no geometry. + + result[elementIndex].InstanceAndMeshIndices.Add((nodeIndex, meshIndex)); + } + } + + // Calculate the element geometry in parallel. + + Parallel.For(0, result.Length, elementIndex => + { + var item = result[elementIndex]; + var list = item.InstanceAndMeshIndices; + var vertexCount = 0; + var faceCount = 0; + var bb = new AABox(Vector3.MaxValue, Vector3.MinValue); // world space element bounding box + + // Aggregate the geometry info + foreach (var (nodeIndex, meshIndex) in list) + { + // INVARIANT: there is a 1:1 relationship between Node entities and instances in the g3d buffer. + var instanceIndex = nodeIndex; + + if (!TryGetTransformedGeometryInfo( + vimGeometryData, + instanceIndex, + meshIndex, + out var meshVertexCount, + out var meshFaceCount, + out var instanceBb)) + { + continue; + } + + // Aggregate the ElementGeometry data + vertexCount += meshVertexCount; + faceCount += meshFaceCount; + bb = bb.Merge(instanceBb); + } + + item.VertexCount = vertexCount; + item.FaceCount = faceCount; + item.WorldSpaceBoundingBox = bb; + }); + + return result; + } + + private static bool TryGetMeshIndex(VimGeometryData vimGeometryData, int instanceIndex, out int meshIndex) + { + meshIndex = vimGeometryData.InstanceMeshes.ElementAtOrDefault(instanceIndex, -1); + return meshIndex >= 0; + } + + private static bool TryGetTransformedGeometryInfo( + VimGeometryData vimGeometryData, + int instanceIndex, + int meshIndex, + out int vertexCount, + out int faceCount, + out AABox worldSpaceBb) + { + vertexCount = 0; + faceCount = 0; + worldSpaceBb = AABox.Empty; + + if (meshIndex < 0) + return false; + + if (!vimGeometryData.TryGetVimMeshView(meshIndex, out var meshData)) + return false; + + vertexCount = meshData.VertexCount; + faceCount = meshData.FaceCount; + + var transform = vimGeometryData.InstanceTransforms.ElementAtOrDefault(instanceIndex, Matrix4x4.Identity); + + // Calculate the world-space bounding box of the mesh. + worldSpaceBb = AABox.Create(meshData.GetVertices().Select(v => v.Transform(transform))); + + return true; + } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format/ElementHierarchyService.cs b/src/cs/vim/Vim.Format/VimElementHierarchyService.cs similarity index 83% rename from src/cs/vim/Vim.Format/ElementHierarchyService.cs rename to src/cs/vim/Vim.Format/VimElementHierarchyService.cs index 2c90ed95..38da1afc 100644 --- a/src/cs/vim/Vim.Format/ElementHierarchyService.cs +++ b/src/cs/vim/Vim.Format/VimElementHierarchyService.cs @@ -1,13 +1,11 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; using System.Linq; -using Vim.Format.ObjectModel; using Vim.Util; namespace Vim.Format { - public class ElementHierarchy + public class VimElementHierarchy { /// /// The index of the ancestor Element. @@ -47,18 +45,18 @@ public class ElementHierarchy public int RootDistance { get; set; } } - public class ElementHierarchyService + public class VimElementHierarchyService { - private ElementGeometryMap ElementGeometryMap { get; } - private EntityTableSet TableSet { get; } + private VimElementGeometryInfo[] ElementGeometryMap { get; } + private VimEntityTableSet TableSet { get; } private bool IsElementAndDescendantPrimaryKey { get; } /// /// Constructor. /// - public ElementHierarchyService( - EntityTableSet tableSet, - ElementGeometryMap elementGeometryMap, + public VimElementHierarchyService( + VimEntityTableSet tableSet, + VimElementGeometryInfo[] elementGeometryMap, bool isElementAndDescendantPrimaryKey = false) { TableSet = tableSet; @@ -67,29 +65,32 @@ public ElementHierarchyService( } /// - /// Constructor. Loads the required entity table set. + /// Returns an instance of the element hierarchy service based on the given VIM file. /// - public ElementHierarchyService( + public static VimElementHierarchyService GetElementHierarchyService( FileInfo vimFileInfo, - ElementGeometryMap elementGeometryMap, + VimEntityTableSet tableSetForElementHierarchyService = null, + VimElementGeometryInfo[] geometryMap = null, bool isElementAndDescendantPrimaryKey = false) - : this( - new EntityTableSet( - vimFileInfo, - Array.Empty(), // an empty string table indicates that the strings will not be loaded. - n => - n is TableNames.Element || - n is TableNames.Group || - n is TableNames.FamilyInstance || - n is TableNames.System || - n is TableNames.ElementInSystem, - inParallel: false - ), - elementGeometryMap, - isElementAndDescendantPrimaryKey) - { } - - public HashSet GetElementHierarchy() + { + vimFileInfo.ThrowIfNotExists("Could not get VIM element hierarchy service"); + + var tableSet = tableSetForElementHierarchyService ?? + VimEntityTableSet.GetEntityTableSetByTableName(vimFileInfo, + VimEntityTableNames.Node, // required for geometry map (if not present) + VimEntityTableNames.Element, + VimEntityTableNames.Group, + VimEntityTableNames.FamilyInstance, + VimEntityTableNames.System, + VimEntityTableNames.ElementInSystem + ); + + geometryMap = geometryMap ?? VimElementGeometryInfo.GetElementGeometryInfoList(vimFileInfo, tableSet); + + return new VimElementHierarchyService(tableSet, geometryMap, isElementAndDescendantPrimaryKey); + } + + public HashSet GetElementHierarchy() { var root = GetElementIndexHierarchy(); var flattened = FlattenElementHierarchy(root, IsElementAndDescendantPrimaryKey); @@ -209,19 +210,19 @@ void AddElementParentChildRelationship(int parentElementIndex, int childElementI return result; } - public class ElementHierarchyComparer : IEqualityComparer + public class VimElementHierarchyComparer : IEqualityComparer { private readonly bool _isElementAndDescendantPrimaryKey; // The element and descendant fields are primary keys in v5.4.0.a and previous. /// /// Constructor /// - public ElementHierarchyComparer(bool isElementAndDescendantPrimaryKey) + public VimElementHierarchyComparer(bool isElementAndDescendantPrimaryKey) { _isElementAndDescendantPrimaryKey = isElementAndDescendantPrimaryKey; } - public bool Equals(ElementHierarchy x, ElementHierarchy y) + public bool Equals(VimElementHierarchy x, VimElementHierarchy y) { if (ReferenceEquals(x, y)) return true; if (x is null) return false; @@ -244,16 +245,16 @@ public bool Equals(ElementHierarchy x, ElementHierarchy y) } } - public int GetHashCode(ElementHierarchy obj) + public int GetHashCode(VimElementHierarchy obj) { return HashCodeStd2.Combine(obj.Element, obj.Descendant, obj.Distance); } } - public static HashSet FlattenElementHierarchy( + public static HashSet FlattenElementHierarchy( Tree root, bool isElementAndDescendantPrimaryKey, - ElementGeometryMap elementGeometryMap) + VimElementGeometryInfo[] elementGeometryMap) { // Visits the tree and flattens it to a list of records representing the hierarchy. // @@ -279,7 +280,7 @@ public static HashSet FlattenElementHierarchy( // Observations: // - RootDistance is always the distance of the terminal object from the root. - var result = new HashSet(new ElementHierarchyComparer(isElementAndDescendantPrimaryKey)); + var result = new HashSet(new VimElementHierarchyComparer(isElementAndDescendantPrimaryKey)); // NOTE: this function is only invoked on each leaf; the last item in ancestorElements is the leaf. void ProcessLeafAncestors(IReadOnlyList> ancestorElements, int rootToLeafDistance) @@ -301,14 +302,14 @@ void ProcessLeafAncestors(IReadOnlyList> ancestorElements, int rootToL var nodeAndGeometryIndices = elementGeometryMap .ElementAtOrDefault(descendantElementIndex) - ?.NodeAndGeometryIndices; + ?.InstanceAndMeshIndices; if ((nodeAndGeometryIndices?.Count ?? 0) > 0) { // Node and geometry info is present. foreach (var (descendantNodeIndex, descendantGeometryIndex) in nodeAndGeometryIndices) { - result.Add(new ElementHierarchy + result.Add(new VimElementHierarchy { Element = ancestorElementIndex, Descendant = descendantElementIndex, @@ -322,7 +323,7 @@ void ProcessLeafAncestors(IReadOnlyList> ancestorElements, int rootToL else { // Node and geometry info is absent. - result.Add(new ElementHierarchy + result.Add(new VimElementHierarchy { Element = ancestorElementIndex, Descendant = descendantElementIndex, @@ -354,7 +355,7 @@ void VisitElementTreeNodes(Tree node, IReadOnlyList> ancestors, i /// /// Flattens the element index hierarchy represented by the root. The root is skipped during the traversal. /// - private HashSet FlattenElementHierarchy(Tree root, bool isElementAndDescendantPrimaryKey) + private HashSet FlattenElementHierarchy(Tree root, bool isElementAndDescendantPrimaryKey) => FlattenElementHierarchy(root, isElementAndDescendantPrimaryKey, ElementGeometryMap); } } diff --git a/src/cs/vim/Vim.Format/ObjectModel/ElementIndexMaps.cs b/src/cs/vim/Vim.Format/VimElementIndexMaps.cs similarity index 51% rename from src/cs/vim/Vim.Format/ObjectModel/ElementIndexMaps.cs rename to src/cs/vim/Vim.Format/VimElementIndexMaps.cs index 1293cae5..b0a84a98 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ElementIndexMaps.cs +++ b/src/cs/vim/Vim.Format/VimElementIndexMaps.cs @@ -1,16 +1,14 @@ -using System; +using System; using System.Collections.Generic; using System.Threading.Tasks; using Vim.Util; + using IndexMap = System.Collections.Generic.Dictionary; using ReadOnlyIndexMap = System.Collections.Generic.IReadOnlyDictionary; -namespace Vim.Format.ObjectModel +namespace Vim.Format { - /// - /// A collection of maps from element index to other related entity indices. - /// - public class ElementIndexMaps + public class VimElementIndexMaps { public ReadOnlyIndexMap FamilyInstanceIndexFromElementIndex { get; private set; } public ReadOnlyIndexMap FamilyTypeIndexFromElementIndex { get; private set; } @@ -28,39 +26,14 @@ public class ElementIndexMaps /// public IReadOnlyDictionary> ParameterIndicesFromElementIndex { get; private set; } - public ElementIndexMaps(DocumentModel documentModel, bool inParallel = true) - { - var dm = documentModel; - var actions = new Action[] - { - () => FamilyInstanceIndexFromElementIndex = GetElementIndexMap(dm.FamilyInstanceEntityTable), - () => FamilyTypeIndexFromElementIndex = GetElementIndexMap(dm.FamilyTypeEntityTable), - () => FamilyIndexFromElementIndex = GetElementIndexMap(dm.FamilyEntityTable), - () => ViewIndexFromElementIndex = GetElementIndexMap(dm.ViewEntityTable), - () => AssemblyIndexFromElementIndex = GetElementIndexMap(dm.AssemblyInstanceEntityTable), - () => DesignOptionIndexFromElementIndex = GetElementIndexMap(dm.DesignOptionEntityTable), - () => LevelIndexFromElementIndex = GetElementIndexMap(dm.LevelEntityTable), - () => PhaseIndexFromElementIndex = GetElementIndexMap(dm.PhaseEntityTable), - () => RoomIndexFromElementIndex = GetElementIndexMap(dm.RoomEntityTable), - () => ParameterIndicesFromElementIndex = GetElementIndicesMap(dm.ParameterEntityTable), - () => SystemIndexFromElementIndex = GetElementIndexMap(dm.SystemEntityTable) - }; - - if (inParallel) - { - Parallel.Invoke(actions); - } - else - { - foreach (var action in actions) - action.Invoke(); - } - } - - public ElementIndexMaps(EntityTableSet entityTables, bool inParallel = true) + /// + /// Constructor + /// + public VimElementIndexMaps(VimEntityTableSet entityTables, bool inParallel = true) { var actions = new Action[] { + // TODO () => FamilyInstanceIndexFromElementIndex = GetElementIndexMap(entityTables.FamilyInstanceTable), () => FamilyTypeIndexFromElementIndex = GetElementIndexMap(entityTables.FamilyTypeTable), () => FamilyIndexFromElementIndex = GetElementIndexMap(entityTables.FamilyTable), @@ -85,30 +58,14 @@ public ElementIndexMaps(EntityTableSet entityTables, bool inParallel = true) } } - public static readonly string ElementIndexColumnName = ColumnExtensions.GetIndexColumnName(TableNames.Element, nameof(Element)); - - public static DictionaryOfLists GetElementIndicesMap(EntityTable et) - { - var indicesMap = new DictionaryOfLists(); - - if (et?.IndexColumns?.Contains(ElementIndexColumnName) != true) - return indicesMap; - - var elementIndices = et.IndexColumns[ElementIndexColumnName]?.GetTypedData(); - if (elementIndices == null) - return indicesMap; - - for (var i = 0; i < elementIndices.Length; ++i) - indicesMap.Add(elementIndices[i], i); - - return indicesMap; - } + public static readonly string ElementIndexColumnName + = VimEntityTableColumnName.GetIndexColumnName(VimEntityTableNames.Element, "Element"); - public static DictionaryOfLists GetElementIndicesMap(EntityTable_v2 et) + public static DictionaryOfLists GetElementIndicesMap(VimEntityTable et) { var indicesMap = new DictionaryOfLists(); - if (et?.IndexColumns?.TryGetValue(ElementIndexColumnName, out var buffer) != true || buffer == null) + if (et?.IndexColumnMap?.TryGetValue(ElementIndexColumnName, out var buffer) != true || buffer == null) return indicesMap; var elementIndices = buffer.GetTypedData(); @@ -120,14 +77,14 @@ public static DictionaryOfLists GetElementIndicesMap(EntityTable_v2 et return indicesMap; } - public static IndexMap GetElementIndexMap(EntityTable et) + public static IndexMap GetElementIndexMap(VimEntityTable et) { var indexMap = new IndexMap(); - if (et?.IndexColumns?.Contains(ElementIndexColumnName) != true) + if (et?.IndexColumnMap?.TryGetValue(ElementIndexColumnName, out var buffer) != true || buffer == null) return indexMap; - var elementIndices = et.IndexColumns[ElementIndexColumnName]?.GetTypedData(); + var elementIndices = buffer.GetTypedData(); if (elementIndices == null) return indexMap; @@ -137,21 +94,14 @@ public static IndexMap GetElementIndexMap(EntityTable et) return indexMap; } - public static IndexMap GetElementIndexMap(EntityTable_v2 et) + /// + /// Returns the list of parameter indices associated with the given element index. + /// + public List GetParameterIndicesFromElementIndex(int elementIndex) { - var indexMap = new IndexMap(); - - if (et?.IndexColumns?.TryGetValue(ElementIndexColumnName, out var buffer) != true || buffer == null) - return indexMap; - - var elementIndices = buffer.GetTypedData(); - if (elementIndices == null) - return indexMap; - - for (var i = 0; i < elementIndices.Length; ++i) - indexMap.TryAdd(elementIndices[i], i); - - return indexMap; + return ParameterIndicesFromElementIndex.TryGetValue(elementIndex, out var parameterIndices) + ? parameterIndices + : new List(); } } } diff --git a/src/cs/vim/Vim.Format/VimEntity.g.cs b/src/cs/vim/Vim.Format/VimEntity.g.cs new file mode 100644 index 00000000..68fe9748 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimEntity.g.cs @@ -0,0 +1,6209 @@ +// AUTO-GENERATED FILE; see VimEntityCodeGen.cs +// ReSharper disable All +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using Vim.Math3d; +using Vim.Format.ObjectModel; +using Vim.Util; + +namespace Vim.Format +{ + public partial class VimEntityTableSet + { + public void Initialize(bool inParallel = true) + { + Tables[VimEntityTableNames.Asset] = AssetTable = new AssetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Asset), StringTable, this); + Tables[VimEntityTableNames.DisplayUnit] = DisplayUnitTable = new DisplayUnitTable(GetEntityTableDataOrEmpty(VimEntityTableNames.DisplayUnit), StringTable, this); + Tables[VimEntityTableNames.ParameterDescriptor] = ParameterDescriptorTable = new ParameterDescriptorTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ParameterDescriptor), StringTable, this); + Tables[VimEntityTableNames.Parameter] = ParameterTable = new ParameterTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Parameter), StringTable, this); + Tables[VimEntityTableNames.Element] = ElementTable = new ElementTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Element), StringTable, this); + Tables[VimEntityTableNames.Workset] = WorksetTable = new WorksetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Workset), StringTable, this); + Tables[VimEntityTableNames.AssemblyInstance] = AssemblyInstanceTable = new AssemblyInstanceTable(GetEntityTableDataOrEmpty(VimEntityTableNames.AssemblyInstance), StringTable, this); + Tables[VimEntityTableNames.Group] = GroupTable = new GroupTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Group), StringTable, this); + Tables[VimEntityTableNames.DesignOption] = DesignOptionTable = new DesignOptionTable(GetEntityTableDataOrEmpty(VimEntityTableNames.DesignOption), StringTable, this); + Tables[VimEntityTableNames.Level] = LevelTable = new LevelTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Level), StringTable, this); + Tables[VimEntityTableNames.Phase] = PhaseTable = new PhaseTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Phase), StringTable, this); + Tables[VimEntityTableNames.Room] = RoomTable = new RoomTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Room), StringTable, this); + Tables[VimEntityTableNames.BimDocument] = BimDocumentTable = new BimDocumentTable(GetEntityTableDataOrEmpty(VimEntityTableNames.BimDocument), StringTable, this); + Tables[VimEntityTableNames.DisplayUnitInBimDocument] = DisplayUnitInBimDocumentTable = new DisplayUnitInBimDocumentTable(GetEntityTableDataOrEmpty(VimEntityTableNames.DisplayUnitInBimDocument), StringTable, this); + Tables[VimEntityTableNames.PhaseOrderInBimDocument] = PhaseOrderInBimDocumentTable = new PhaseOrderInBimDocumentTable(GetEntityTableDataOrEmpty(VimEntityTableNames.PhaseOrderInBimDocument), StringTable, this); + Tables[VimEntityTableNames.Category] = CategoryTable = new CategoryTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Category), StringTable, this); + Tables[VimEntityTableNames.Family] = FamilyTable = new FamilyTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Family), StringTable, this); + Tables[VimEntityTableNames.FamilyType] = FamilyTypeTable = new FamilyTypeTable(GetEntityTableDataOrEmpty(VimEntityTableNames.FamilyType), StringTable, this); + Tables[VimEntityTableNames.FamilyInstance] = FamilyInstanceTable = new FamilyInstanceTable(GetEntityTableDataOrEmpty(VimEntityTableNames.FamilyInstance), StringTable, this); + Tables[VimEntityTableNames.View] = ViewTable = new ViewTable(GetEntityTableDataOrEmpty(VimEntityTableNames.View), StringTable, this); + Tables[VimEntityTableNames.ElementInView] = ElementInViewTable = new ElementInViewTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ElementInView), StringTable, this); + Tables[VimEntityTableNames.ShapeInView] = ShapeInViewTable = new ShapeInViewTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ShapeInView), StringTable, this); + Tables[VimEntityTableNames.AssetInView] = AssetInViewTable = new AssetInViewTable(GetEntityTableDataOrEmpty(VimEntityTableNames.AssetInView), StringTable, this); + Tables[VimEntityTableNames.AssetInViewSheet] = AssetInViewSheetTable = new AssetInViewSheetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.AssetInViewSheet), StringTable, this); + Tables[VimEntityTableNames.LevelInView] = LevelInViewTable = new LevelInViewTable(GetEntityTableDataOrEmpty(VimEntityTableNames.LevelInView), StringTable, this); + Tables[VimEntityTableNames.Camera] = CameraTable = new CameraTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Camera), StringTable, this); + Tables[VimEntityTableNames.Material] = MaterialTable = new MaterialTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Material), StringTable, this); + Tables[VimEntityTableNames.MaterialInElement] = MaterialInElementTable = new MaterialInElementTable(GetEntityTableDataOrEmpty(VimEntityTableNames.MaterialInElement), StringTable, this); + Tables[VimEntityTableNames.CompoundStructureLayer] = CompoundStructureLayerTable = new CompoundStructureLayerTable(GetEntityTableDataOrEmpty(VimEntityTableNames.CompoundStructureLayer), StringTable, this); + Tables[VimEntityTableNames.CompoundStructure] = CompoundStructureTable = new CompoundStructureTable(GetEntityTableDataOrEmpty(VimEntityTableNames.CompoundStructure), StringTable, this); + Tables[VimEntityTableNames.Node] = NodeTable = new NodeTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Node), StringTable, this); + Tables[VimEntityTableNames.Geometry] = GeometryTable = new GeometryTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Geometry), StringTable, this); + Tables[VimEntityTableNames.Shape] = ShapeTable = new ShapeTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Shape), StringTable, this); + Tables[VimEntityTableNames.ShapeCollection] = ShapeCollectionTable = new ShapeCollectionTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ShapeCollection), StringTable, this); + Tables[VimEntityTableNames.ShapeInShapeCollection] = ShapeInShapeCollectionTable = new ShapeInShapeCollectionTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ShapeInShapeCollection), StringTable, this); + Tables[VimEntityTableNames.System] = SystemTable = new SystemTable(GetEntityTableDataOrEmpty(VimEntityTableNames.System), StringTable, this); + Tables[VimEntityTableNames.ElementInSystem] = ElementInSystemTable = new ElementInSystemTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ElementInSystem), StringTable, this); + Tables[VimEntityTableNames.Warning] = WarningTable = new WarningTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Warning), StringTable, this); + Tables[VimEntityTableNames.ElementInWarning] = ElementInWarningTable = new ElementInWarningTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ElementInWarning), StringTable, this); + Tables[VimEntityTableNames.BasePoint] = BasePointTable = new BasePointTable(GetEntityTableDataOrEmpty(VimEntityTableNames.BasePoint), StringTable, this); + Tables[VimEntityTableNames.PhaseFilter] = PhaseFilterTable = new PhaseFilterTable(GetEntityTableDataOrEmpty(VimEntityTableNames.PhaseFilter), StringTable, this); + Tables[VimEntityTableNames.Grid] = GridTable = new GridTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Grid), StringTable, this); + Tables[VimEntityTableNames.Area] = AreaTable = new AreaTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Area), StringTable, this); + Tables[VimEntityTableNames.AreaScheme] = AreaSchemeTable = new AreaSchemeTable(GetEntityTableDataOrEmpty(VimEntityTableNames.AreaScheme), StringTable, this); + Tables[VimEntityTableNames.Schedule] = ScheduleTable = new ScheduleTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Schedule), StringTable, this); + Tables[VimEntityTableNames.ScheduleColumn] = ScheduleColumnTable = new ScheduleColumnTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ScheduleColumn), StringTable, this); + Tables[VimEntityTableNames.ScheduleCell] = ScheduleCellTable = new ScheduleCellTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ScheduleCell), StringTable, this); + Tables[VimEntityTableNames.ViewSheetSet] = ViewSheetSetTable = new ViewSheetSetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ViewSheetSet), StringTable, this); + Tables[VimEntityTableNames.ViewSheet] = ViewSheetTable = new ViewSheetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ViewSheet), StringTable, this); + Tables[VimEntityTableNames.ViewSheetInViewSheetSet] = ViewSheetInViewSheetSetTable = new ViewSheetInViewSheetSetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ViewSheetInViewSheetSet), StringTable, this); + Tables[VimEntityTableNames.ViewInViewSheetSet] = ViewInViewSheetSetTable = new ViewInViewSheetSetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ViewInViewSheetSet), StringTable, this); + Tables[VimEntityTableNames.ViewInViewSheet] = ViewInViewSheetTable = new ViewInViewSheetTable(GetEntityTableDataOrEmpty(VimEntityTableNames.ViewInViewSheet), StringTable, this); + Tables[VimEntityTableNames.Site] = SiteTable = new SiteTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Site), StringTable, this); + Tables[VimEntityTableNames.Building] = BuildingTable = new BuildingTable(GetEntityTableDataOrEmpty(VimEntityTableNames.Building), StringTable, this); + + // Initialize element index maps + ElementIndexMaps = new VimElementIndexMaps(this, inParallel); + + } // end of Initialize + + public AssetTable AssetTable { get; private set; } // can be null + public Vim.Format.Asset GetAsset(int index) => AssetTable?.Get(index); + public DisplayUnitTable DisplayUnitTable { get; private set; } // can be null + public Vim.Format.DisplayUnit GetDisplayUnit(int index) => DisplayUnitTable?.Get(index); + public ParameterDescriptorTable ParameterDescriptorTable { get; private set; } // can be null + public Vim.Format.ParameterDescriptor GetParameterDescriptor(int index) => ParameterDescriptorTable?.Get(index); + public ParameterTable ParameterTable { get; private set; } // can be null + public Vim.Format.Parameter GetParameter(int index) => ParameterTable?.Get(index); + public ElementTable ElementTable { get; private set; } // can be null + public Vim.Format.Element GetElement(int index) => ElementTable?.Get(index); + public WorksetTable WorksetTable { get; private set; } // can be null + public Vim.Format.Workset GetWorkset(int index) => WorksetTable?.Get(index); + public AssemblyInstanceTable AssemblyInstanceTable { get; private set; } // can be null + public Vim.Format.AssemblyInstance GetAssemblyInstance(int index) => AssemblyInstanceTable?.Get(index); + public GroupTable GroupTable { get; private set; } // can be null + public Vim.Format.Group GetGroup(int index) => GroupTable?.Get(index); + public DesignOptionTable DesignOptionTable { get; private set; } // can be null + public Vim.Format.DesignOption GetDesignOption(int index) => DesignOptionTable?.Get(index); + public LevelTable LevelTable { get; private set; } // can be null + public Vim.Format.Level GetLevel(int index) => LevelTable?.Get(index); + public PhaseTable PhaseTable { get; private set; } // can be null + public Vim.Format.Phase GetPhase(int index) => PhaseTable?.Get(index); + public RoomTable RoomTable { get; private set; } // can be null + public Vim.Format.Room GetRoom(int index) => RoomTable?.Get(index); + public BimDocumentTable BimDocumentTable { get; private set; } // can be null + public Vim.Format.BimDocument GetBimDocument(int index) => BimDocumentTable?.Get(index); + public DisplayUnitInBimDocumentTable DisplayUnitInBimDocumentTable { get; private set; } // can be null + public Vim.Format.DisplayUnitInBimDocument GetDisplayUnitInBimDocument(int index) => DisplayUnitInBimDocumentTable?.Get(index); + public PhaseOrderInBimDocumentTable PhaseOrderInBimDocumentTable { get; private set; } // can be null + public Vim.Format.PhaseOrderInBimDocument GetPhaseOrderInBimDocument(int index) => PhaseOrderInBimDocumentTable?.Get(index); + public CategoryTable CategoryTable { get; private set; } // can be null + public Vim.Format.Category GetCategory(int index) => CategoryTable?.Get(index); + public FamilyTable FamilyTable { get; private set; } // can be null + public Vim.Format.Family GetFamily(int index) => FamilyTable?.Get(index); + public FamilyTypeTable FamilyTypeTable { get; private set; } // can be null + public Vim.Format.FamilyType GetFamilyType(int index) => FamilyTypeTable?.Get(index); + public FamilyInstanceTable FamilyInstanceTable { get; private set; } // can be null + public Vim.Format.FamilyInstance GetFamilyInstance(int index) => FamilyInstanceTable?.Get(index); + public ViewTable ViewTable { get; private set; } // can be null + public Vim.Format.View GetView(int index) => ViewTable?.Get(index); + public ElementInViewTable ElementInViewTable { get; private set; } // can be null + public Vim.Format.ElementInView GetElementInView(int index) => ElementInViewTable?.Get(index); + public ShapeInViewTable ShapeInViewTable { get; private set; } // can be null + public Vim.Format.ShapeInView GetShapeInView(int index) => ShapeInViewTable?.Get(index); + public AssetInViewTable AssetInViewTable { get; private set; } // can be null + public Vim.Format.AssetInView GetAssetInView(int index) => AssetInViewTable?.Get(index); + public AssetInViewSheetTable AssetInViewSheetTable { get; private set; } // can be null + public Vim.Format.AssetInViewSheet GetAssetInViewSheet(int index) => AssetInViewSheetTable?.Get(index); + public LevelInViewTable LevelInViewTable { get; private set; } // can be null + public Vim.Format.LevelInView GetLevelInView(int index) => LevelInViewTable?.Get(index); + public CameraTable CameraTable { get; private set; } // can be null + public Vim.Format.Camera GetCamera(int index) => CameraTable?.Get(index); + public MaterialTable MaterialTable { get; private set; } // can be null + public Vim.Format.Material GetMaterial(int index) => MaterialTable?.Get(index); + public MaterialInElementTable MaterialInElementTable { get; private set; } // can be null + public Vim.Format.MaterialInElement GetMaterialInElement(int index) => MaterialInElementTable?.Get(index); + public CompoundStructureLayerTable CompoundStructureLayerTable { get; private set; } // can be null + public Vim.Format.CompoundStructureLayer GetCompoundStructureLayer(int index) => CompoundStructureLayerTable?.Get(index); + public CompoundStructureTable CompoundStructureTable { get; private set; } // can be null + public Vim.Format.CompoundStructure GetCompoundStructure(int index) => CompoundStructureTable?.Get(index); + public NodeTable NodeTable { get; private set; } // can be null + public Vim.Format.Node GetNode(int index) => NodeTable?.Get(index); + public GeometryTable GeometryTable { get; private set; } // can be null + public Vim.Format.Geometry GetGeometry(int index) => GeometryTable?.Get(index); + public ShapeTable ShapeTable { get; private set; } // can be null + public Vim.Format.Shape GetShape(int index) => ShapeTable?.Get(index); + public ShapeCollectionTable ShapeCollectionTable { get; private set; } // can be null + public Vim.Format.ShapeCollection GetShapeCollection(int index) => ShapeCollectionTable?.Get(index); + public ShapeInShapeCollectionTable ShapeInShapeCollectionTable { get; private set; } // can be null + public Vim.Format.ShapeInShapeCollection GetShapeInShapeCollection(int index) => ShapeInShapeCollectionTable?.Get(index); + public SystemTable SystemTable { get; private set; } // can be null + public Vim.Format.System GetSystem(int index) => SystemTable?.Get(index); + public ElementInSystemTable ElementInSystemTable { get; private set; } // can be null + public Vim.Format.ElementInSystem GetElementInSystem(int index) => ElementInSystemTable?.Get(index); + public WarningTable WarningTable { get; private set; } // can be null + public Vim.Format.Warning GetWarning(int index) => WarningTable?.Get(index); + public ElementInWarningTable ElementInWarningTable { get; private set; } // can be null + public Vim.Format.ElementInWarning GetElementInWarning(int index) => ElementInWarningTable?.Get(index); + public BasePointTable BasePointTable { get; private set; } // can be null + public Vim.Format.BasePoint GetBasePoint(int index) => BasePointTable?.Get(index); + public PhaseFilterTable PhaseFilterTable { get; private set; } // can be null + public Vim.Format.PhaseFilter GetPhaseFilter(int index) => PhaseFilterTable?.Get(index); + public GridTable GridTable { get; private set; } // can be null + public Vim.Format.Grid GetGrid(int index) => GridTable?.Get(index); + public AreaTable AreaTable { get; private set; } // can be null + public Vim.Format.Area GetArea(int index) => AreaTable?.Get(index); + public AreaSchemeTable AreaSchemeTable { get; private set; } // can be null + public Vim.Format.AreaScheme GetAreaScheme(int index) => AreaSchemeTable?.Get(index); + public ScheduleTable ScheduleTable { get; private set; } // can be null + public Vim.Format.Schedule GetSchedule(int index) => ScheduleTable?.Get(index); + public ScheduleColumnTable ScheduleColumnTable { get; private set; } // can be null + public Vim.Format.ScheduleColumn GetScheduleColumn(int index) => ScheduleColumnTable?.Get(index); + public ScheduleCellTable ScheduleCellTable { get; private set; } // can be null + public Vim.Format.ScheduleCell GetScheduleCell(int index) => ScheduleCellTable?.Get(index); + public ViewSheetSetTable ViewSheetSetTable { get; private set; } // can be null + public Vim.Format.ViewSheetSet GetViewSheetSet(int index) => ViewSheetSetTable?.Get(index); + public ViewSheetTable ViewSheetTable { get; private set; } // can be null + public Vim.Format.ViewSheet GetViewSheet(int index) => ViewSheetTable?.Get(index); + public ViewSheetInViewSheetSetTable ViewSheetInViewSheetSetTable { get; private set; } // can be null + public Vim.Format.ViewSheetInViewSheetSet GetViewSheetInViewSheetSet(int index) => ViewSheetInViewSheetSetTable?.Get(index); + public ViewInViewSheetSetTable ViewInViewSheetSetTable { get; private set; } // can be null + public Vim.Format.ViewInViewSheetSet GetViewInViewSheetSet(int index) => ViewInViewSheetSetTable?.Get(index); + public ViewInViewSheetTable ViewInViewSheetTable { get; private set; } // can be null + public Vim.Format.ViewInViewSheet GetViewInViewSheet(int index) => ViewInViewSheetTable?.Get(index); + public SiteTable SiteTable { get; private set; } // can be null + public Vim.Format.Site GetSite(int index) => SiteTable?.Get(index); + public BuildingTable BuildingTable { get; private set; } // can be null + public Vim.Format.Building GetBuilding(int index) => BuildingTable?.Get(index); + + public static HashSet GetJoiningTableNames() + => new HashSet() + { + VimEntityTableNames.ElementInView, + VimEntityTableNames.ShapeInView, + VimEntityTableNames.AssetInView, + VimEntityTableNames.AssetInViewSheet, + VimEntityTableNames.LevelInView, + VimEntityTableNames.MaterialInElement, + VimEntityTableNames.ShapeInShapeCollection, + VimEntityTableNames.ElementInSystem, + VimEntityTableNames.ElementInWarning, + VimEntityTableNames.ScheduleColumn, + VimEntityTableNames.ScheduleCell, + VimEntityTableNames.ViewSheetInViewSheetSet, + VimEntityTableNames.ViewInViewSheetSet, + VimEntityTableNames.ViewInViewSheet, + }; + + public static HashSet GetElementKindTableNames() + => new HashSet() + { + VimEntityTableNames.AssemblyInstance, + VimEntityTableNames.Group, + VimEntityTableNames.DesignOption, + VimEntityTableNames.Level, + VimEntityTableNames.Phase, + VimEntityTableNames.Room, + VimEntityTableNames.BimDocument, + VimEntityTableNames.Family, + VimEntityTableNames.FamilyType, + VimEntityTableNames.FamilyInstance, + VimEntityTableNames.View, + VimEntityTableNames.Material, + VimEntityTableNames.System, + VimEntityTableNames.BasePoint, + VimEntityTableNames.PhaseFilter, + VimEntityTableNames.Grid, + VimEntityTableNames.Area, + VimEntityTableNames.AreaScheme, + VimEntityTableNames.Schedule, + VimEntityTableNames.ViewSheetSet, + VimEntityTableNames.ViewSheet, + VimEntityTableNames.Site, + VimEntityTableNames.Building, + }; + + // Returns an array defining a 1:1 association of Element to its ElementKind + public ElementKind[] GetElementKinds() + { + var elementKinds = new ElementKind[ElementTable?.RowCount ?? 0]; + + if (elementKinds.Length == 0) return elementKinds; + + // Initialize all element kinds to unknown + for (var i = 0; i < elementKinds.Length; ++i) { elementKinds[i] = ElementKind.Unknown; } + + // Populate the element kinds from the relevant entity tables + for (var i = 0; i < (AssemblyInstanceTable?.RowCount ?? 0); ++i) + { + var elementIndex = AssemblyInstanceTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.AssemblyInstance; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (GroupTable?.RowCount ?? 0); ++i) + { + var elementIndex = GroupTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Group; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (DesignOptionTable?.RowCount ?? 0); ++i) + { + var elementIndex = DesignOptionTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.DesignOption; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (LevelTable?.RowCount ?? 0); ++i) + { + var elementIndex = LevelTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Level; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (PhaseTable?.RowCount ?? 0); ++i) + { + var elementIndex = PhaseTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Phase; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (RoomTable?.RowCount ?? 0); ++i) + { + var elementIndex = RoomTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Room; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (BimDocumentTable?.RowCount ?? 0); ++i) + { + var elementIndex = BimDocumentTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.BimDocument; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (FamilyTable?.RowCount ?? 0); ++i) + { + var elementIndex = FamilyTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Family; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (FamilyTypeTable?.RowCount ?? 0); ++i) + { + var elementIndex = FamilyTypeTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.FamilyType; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (FamilyInstanceTable?.RowCount ?? 0); ++i) + { + var elementIndex = FamilyInstanceTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.FamilyInstance; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (ViewTable?.RowCount ?? 0); ++i) + { + var elementIndex = ViewTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.View; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (MaterialTable?.RowCount ?? 0); ++i) + { + var elementIndex = MaterialTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Material; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (SystemTable?.RowCount ?? 0); ++i) + { + var elementIndex = SystemTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.System; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (BasePointTable?.RowCount ?? 0); ++i) + { + var elementIndex = BasePointTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.BasePoint; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (PhaseFilterTable?.RowCount ?? 0); ++i) + { + var elementIndex = PhaseFilterTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.PhaseFilter; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (GridTable?.RowCount ?? 0); ++i) + { + var elementIndex = GridTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Grid; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (AreaTable?.RowCount ?? 0); ++i) + { + var elementIndex = AreaTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Area; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (AreaSchemeTable?.RowCount ?? 0); ++i) + { + var elementIndex = AreaSchemeTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.AreaScheme; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (ScheduleTable?.RowCount ?? 0); ++i) + { + var elementIndex = ScheduleTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Schedule; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (ViewSheetSetTable?.RowCount ?? 0); ++i) + { + var elementIndex = ViewSheetSetTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.ViewSheetSet; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (ViewSheetTable?.RowCount ?? 0); ++i) + { + var elementIndex = ViewSheetTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.ViewSheet; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (SiteTable?.RowCount ?? 0); ++i) + { + var elementIndex = SiteTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Site; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + for (var i = 0; i < (BuildingTable?.RowCount ?? 0); ++i) + { + var elementIndex = BuildingTable?.Column_ElementIndex[i] ?? EntityRelation.None; + if (elementIndex < 0 || elementIndex >= elementKinds.Length) continue; + + var currentElementKind = elementKinds[elementIndex]; + var candidateElementKind = ElementKind.Building; + + // Only update the element kind if it is unknown or if it is less than the current kind. + if (currentElementKind != ElementKind.Unknown && currentElementKind <= candidateElementKind) continue; + + elementKinds[elementIndex] = candidateElementKind; + } + + return elementKinds; + } // GetElementKinds() + } // end of partial class VimEntityTableSet + + public partial class Asset + { + public Asset() + { + } + } // class Asset + + public partial class AssetTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Asset; + public VimEntityTableSet ParentTableSet { get; } // can be null + public AssetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_BufferName = GetStringColumnValues("string:BufferName") ?? Array.Empty(); + } + public String[] Column_BufferName { get; } + public String GetBufferName(int index, String @default = "") => Column_BufferName.ElementAtOrDefault(index, @default); + public Vim.Format.Asset Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Asset(); + r.Index = index; + r.BufferName = GetBufferName(index); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class AssetTable + + public partial class DisplayUnit + { + public DisplayUnit() + { + } + } // class DisplayUnit + + public partial class DisplayUnitTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.DisplayUnit; + public VimEntityTableSet ParentTableSet { get; } // can be null + public DisplayUnitTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Spec = GetStringColumnValues("string:Spec") ?? Array.Empty(); + Column_Type = GetStringColumnValues("string:Type") ?? Array.Empty(); + Column_Label = GetStringColumnValues("string:Label") ?? Array.Empty(); + } + public String[] Column_Spec { get; } + public String GetSpec(int index, String @default = "") => Column_Spec.ElementAtOrDefault(index, @default); + public String[] Column_Type { get; } + public String GetType(int index, String @default = "") => Column_Type.ElementAtOrDefault(index, @default); + public String[] Column_Label { get; } + public String GetLabel(int index, String @default = "") => Column_Label.ElementAtOrDefault(index, @default); + public Vim.Format.DisplayUnit Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.DisplayUnit(); + r.Index = index; + r.Spec = GetSpec(index); + r.Type = GetType(index); + r.Label = GetLabel(index); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class DisplayUnitTable + + public partial class ParameterDescriptor + { + public Vim.Format.DisplayUnit DisplayUnit => _DisplayUnit?.Value; + public int DisplayUnitIndex => _DisplayUnit?.Index ?? EntityRelation.None; + public ParameterDescriptor() + { + _DisplayUnit = new Relation(); + } + } // class ParameterDescriptor + + public partial class ParameterDescriptorTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ParameterDescriptor; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ParameterDescriptorTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_Group = GetStringColumnValues("string:Group") ?? Array.Empty(); + Column_ParameterType = GetStringColumnValues("string:ParameterType") ?? Array.Empty(); + Column_IsInstance = GetDataColumnValues("byte:IsInstance") ?? Array.Empty(); + Column_IsShared = GetDataColumnValues("byte:IsShared") ?? Array.Empty(); + Column_IsReadOnly = GetDataColumnValues("byte:IsReadOnly") ?? Array.Empty(); + Column_Flags = GetDataColumnValues("int:Flags") ?? Array.Empty(); + Column_Guid = GetStringColumnValues("string:Guid") ?? Array.Empty(); + Column_StorageType = GetDataColumnValues("int:StorageType") ?? Array.Empty(); + Column_DisplayUnitIndex = GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty(); + } + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public String[] Column_Group { get; } + public String GetGroup(int index, String @default = "") => Column_Group.ElementAtOrDefault(index, @default); + public String[] Column_ParameterType { get; } + public String GetParameterType(int index, String @default = "") => Column_ParameterType.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsInstance { get; } + public Boolean GetIsInstance(int index, Boolean @default = default) => Column_IsInstance.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsShared { get; } + public Boolean GetIsShared(int index, Boolean @default = default) => Column_IsShared.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsReadOnly { get; } + public Boolean GetIsReadOnly(int index, Boolean @default = default) => Column_IsReadOnly.ElementAtOrDefault(index, @default); + public Int32[] Column_Flags { get; } + public Int32 GetFlags(int index, Int32 @default = default) => Column_Flags.ElementAtOrDefault(index, @default); + public String[] Column_Guid { get; } + public String GetGuid(int index, String @default = "") => Column_Guid.ElementAtOrDefault(index, @default); + public Int32[] Column_StorageType { get; } + public Int32 GetStorageType(int index, Int32 @default = default) => Column_StorageType.ElementAtOrDefault(index, @default); + public int[] Column_DisplayUnitIndex { get; } + public int GetDisplayUnitIndex(int index) => Column_DisplayUnitIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.DisplayUnit GetDisplayUnit(int index) => _GetReferencedDisplayUnit(GetDisplayUnitIndex(index)); + private Vim.Format.DisplayUnit _GetReferencedDisplayUnit(int referencedIndex) => ParentTableSet.GetDisplayUnit(referencedIndex); + public Vim.Format.ParameterDescriptor Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ParameterDescriptor(); + r.Index = index; + r.Name = GetName(index); + r.Group = GetGroup(index); + r.ParameterType = GetParameterType(index); + r.IsInstance = GetIsInstance(index); + r.IsShared = GetIsShared(index); + r.IsReadOnly = GetIsReadOnly(index); + r.Flags = GetFlags(index); + r.Guid = GetGuid(index); + r.StorageType = GetStorageType(index); + r._DisplayUnit = new Relation(GetDisplayUnitIndex(index), _GetReferencedDisplayUnit); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ParameterDescriptorTable + + public partial class Parameter + { + public Vim.Format.ParameterDescriptor ParameterDescriptor => _ParameterDescriptor?.Value; + public int ParameterDescriptorIndex => _ParameterDescriptor?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Parameter() + { + _ParameterDescriptor = new Relation(); + _Element = new Relation(); + } + } // class Parameter + + public partial class ParameterTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Parameter; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ParameterTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Value = GetStringColumnValues("string:Value") ?? Array.Empty(); + Column_ParameterDescriptorIndex = GetIndexColumnValues("index:Vim.ParameterDescriptor:ParameterDescriptor") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_Value { get; } + public String GetValue(int index, String @default = "") => Column_Value.ElementAtOrDefault(index, @default); + public int[] Column_ParameterDescriptorIndex { get; } + public int GetParameterDescriptorIndex(int index) => Column_ParameterDescriptorIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ParameterDescriptor GetParameterDescriptor(int index) => _GetReferencedParameterDescriptor(GetParameterDescriptorIndex(index)); + private Vim.Format.ParameterDescriptor _GetReferencedParameterDescriptor(int referencedIndex) => ParentTableSet.GetParameterDescriptor(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Parameter Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Parameter(); + r.Index = index; + r.Value = GetValue(index); + r._ParameterDescriptor = new Relation(GetParameterDescriptorIndex(index), _GetReferencedParameterDescriptor); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ParameterTable + + public partial class Element + { + public Vim.Format.Level Level => _Level?.Value; + public int LevelIndex => _Level?.Index ?? EntityRelation.None; + public Vim.Format.Phase PhaseCreated => _PhaseCreated?.Value; + public int PhaseCreatedIndex => _PhaseCreated?.Index ?? EntityRelation.None; + public Vim.Format.Phase PhaseDemolished => _PhaseDemolished?.Value; + public int PhaseDemolishedIndex => _PhaseDemolished?.Index ?? EntityRelation.None; + public Vim.Format.Category Category => _Category?.Value; + public int CategoryIndex => _Category?.Index ?? EntityRelation.None; + public Vim.Format.Workset Workset => _Workset?.Value; + public int WorksetIndex => _Workset?.Index ?? EntityRelation.None; + public Vim.Format.DesignOption DesignOption => _DesignOption?.Value; + public int DesignOptionIndex => _DesignOption?.Index ?? EntityRelation.None; + public Vim.Format.View OwnerView => _OwnerView?.Value; + public int OwnerViewIndex => _OwnerView?.Index ?? EntityRelation.None; + public Vim.Format.Group Group => _Group?.Value; + public int GroupIndex => _Group?.Index ?? EntityRelation.None; + public Vim.Format.AssemblyInstance AssemblyInstance => _AssemblyInstance?.Value; + public int AssemblyInstanceIndex => _AssemblyInstance?.Index ?? EntityRelation.None; + public Vim.Format.BimDocument BimDocument => _BimDocument?.Value; + public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; + public Vim.Format.Room Room => _Room?.Value; + public int RoomIndex => _Room?.Index ?? EntityRelation.None; + public Element() + { + _Level = new Relation(); + _PhaseCreated = new Relation(); + _PhaseDemolished = new Relation(); + _Category = new Relation(); + _Workset = new Relation(); + _DesignOption = new Relation(); + _OwnerView = new Relation(); + _Group = new Relation(); + _AssemblyInstance = new Relation(); + _BimDocument = new Relation(); + _Room = new Relation(); + } + } // class Element + + public partial class ElementTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Element; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ElementTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Id = (GetDataColumnValues("long:Id") ?? GetDataColumnValues("int:Id")?.Select(v => (Int64) v).ToArray()) ?? Array.Empty(); + Column_Type = GetStringColumnValues("string:Type") ?? Array.Empty(); + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_UniqueId = GetStringColumnValues("string:UniqueId") ?? Array.Empty(); + Column_Location_X = GetDataColumnValues("float:Location.X") ?? Array.Empty(); + Column_Location_Y = GetDataColumnValues("float:Location.Y") ?? Array.Empty(); + Column_Location_Z = GetDataColumnValues("float:Location.Z") ?? Array.Empty(); + Column_FamilyName = GetStringColumnValues("string:FamilyName") ?? Array.Empty(); + Column_IsPinned = GetDataColumnValues("byte:IsPinned") ?? Array.Empty(); + Column_LevelIndex = GetIndexColumnValues("index:Vim.Level:Level") ?? Array.Empty(); + Column_PhaseCreatedIndex = GetIndexColumnValues("index:Vim.Phase:PhaseCreated") ?? Array.Empty(); + Column_PhaseDemolishedIndex = GetIndexColumnValues("index:Vim.Phase:PhaseDemolished") ?? Array.Empty(); + Column_CategoryIndex = GetIndexColumnValues("index:Vim.Category:Category") ?? Array.Empty(); + Column_WorksetIndex = GetIndexColumnValues("index:Vim.Workset:Workset") ?? Array.Empty(); + Column_DesignOptionIndex = GetIndexColumnValues("index:Vim.DesignOption:DesignOption") ?? Array.Empty(); + Column_OwnerViewIndex = GetIndexColumnValues("index:Vim.View:OwnerView") ?? Array.Empty(); + Column_GroupIndex = GetIndexColumnValues("index:Vim.Group:Group") ?? Array.Empty(); + Column_AssemblyInstanceIndex = GetIndexColumnValues("index:Vim.AssemblyInstance:AssemblyInstance") ?? Array.Empty(); + Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); + Column_RoomIndex = GetIndexColumnValues("index:Vim.Room:Room") ?? Array.Empty(); + } + public Int64[] Column_Id { get; } + public Int64 GetId(int index, Int64 @default = default) => Column_Id.ElementAtOrDefault(index, @default); + public String[] Column_Type { get; } + public String GetType(int index, String @default = "") => Column_Type.ElementAtOrDefault(index, @default); + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public String[] Column_UniqueId { get; } + public String GetUniqueId(int index, String @default = "") => Column_UniqueId.ElementAtOrDefault(index, @default); + public Single[] Column_Location_X { get; } + public Single GetLocation_X(int index, Single @default = default) => Column_Location_X.ElementAtOrDefault(index, @default); + public Single[] Column_Location_Y { get; } + public Single GetLocation_Y(int index, Single @default = default) => Column_Location_Y.ElementAtOrDefault(index, @default); + public Single[] Column_Location_Z { get; } + public Single GetLocation_Z(int index, Single @default = default) => Column_Location_Z.ElementAtOrDefault(index, @default); + public String[] Column_FamilyName { get; } + public String GetFamilyName(int index, String @default = "") => Column_FamilyName.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsPinned { get; } + public Boolean GetIsPinned(int index, Boolean @default = default) => Column_IsPinned.ElementAtOrDefault(index, @default); + public int[] Column_LevelIndex { get; } + public int GetLevelIndex(int index) => Column_LevelIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Level GetLevel(int index) => _GetReferencedLevel(GetLevelIndex(index)); + private Vim.Format.Level _GetReferencedLevel(int referencedIndex) => ParentTableSet.GetLevel(referencedIndex); + public int[] Column_PhaseCreatedIndex { get; } + public int GetPhaseCreatedIndex(int index) => Column_PhaseCreatedIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Phase GetPhaseCreated(int index) => _GetReferencedPhaseCreated(GetPhaseCreatedIndex(index)); + private Vim.Format.Phase _GetReferencedPhaseCreated(int referencedIndex) => ParentTableSet.GetPhase(referencedIndex); + public int[] Column_PhaseDemolishedIndex { get; } + public int GetPhaseDemolishedIndex(int index) => Column_PhaseDemolishedIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Phase GetPhaseDemolished(int index) => _GetReferencedPhaseDemolished(GetPhaseDemolishedIndex(index)); + private Vim.Format.Phase _GetReferencedPhaseDemolished(int referencedIndex) => ParentTableSet.GetPhase(referencedIndex); + public int[] Column_CategoryIndex { get; } + public int GetCategoryIndex(int index) => Column_CategoryIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Category GetCategory(int index) => _GetReferencedCategory(GetCategoryIndex(index)); + private Vim.Format.Category _GetReferencedCategory(int referencedIndex) => ParentTableSet.GetCategory(referencedIndex); + public int[] Column_WorksetIndex { get; } + public int GetWorksetIndex(int index) => Column_WorksetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Workset GetWorkset(int index) => _GetReferencedWorkset(GetWorksetIndex(index)); + private Vim.Format.Workset _GetReferencedWorkset(int referencedIndex) => ParentTableSet.GetWorkset(referencedIndex); + public int[] Column_DesignOptionIndex { get; } + public int GetDesignOptionIndex(int index) => Column_DesignOptionIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.DesignOption GetDesignOption(int index) => _GetReferencedDesignOption(GetDesignOptionIndex(index)); + private Vim.Format.DesignOption _GetReferencedDesignOption(int referencedIndex) => ParentTableSet.GetDesignOption(referencedIndex); + public int[] Column_OwnerViewIndex { get; } + public int GetOwnerViewIndex(int index) => Column_OwnerViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetOwnerView(int index) => _GetReferencedOwnerView(GetOwnerViewIndex(index)); + private Vim.Format.View _GetReferencedOwnerView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public int[] Column_GroupIndex { get; } + public int GetGroupIndex(int index) => Column_GroupIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Group GetGroup(int index) => _GetReferencedGroup(GetGroupIndex(index)); + private Vim.Format.Group _GetReferencedGroup(int referencedIndex) => ParentTableSet.GetGroup(referencedIndex); + public int[] Column_AssemblyInstanceIndex { get; } + public int GetAssemblyInstanceIndex(int index) => Column_AssemblyInstanceIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.AssemblyInstance GetAssemblyInstance(int index) => _GetReferencedAssemblyInstance(GetAssemblyInstanceIndex(index)); + private Vim.Format.AssemblyInstance _GetReferencedAssemblyInstance(int referencedIndex) => ParentTableSet.GetAssemblyInstance(referencedIndex); + public int[] Column_BimDocumentIndex { get; } + public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); + private Vim.Format.BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); + public int[] Column_RoomIndex { get; } + public int GetRoomIndex(int index) => Column_RoomIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Room GetRoom(int index) => _GetReferencedRoom(GetRoomIndex(index)); + private Vim.Format.Room _GetReferencedRoom(int referencedIndex) => ParentTableSet.GetRoom(referencedIndex); + public Vim.Format.Element Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Element(); + r.Index = index; + r.Id = GetId(index); + r.Type = GetType(index); + r.Name = GetName(index); + r.UniqueId = GetUniqueId(index); + r.Location_X = GetLocation_X(index); + r.Location_Y = GetLocation_Y(index); + r.Location_Z = GetLocation_Z(index); + r.FamilyName = GetFamilyName(index); + r.IsPinned = GetIsPinned(index); + r._Level = new Relation(GetLevelIndex(index), _GetReferencedLevel); + r._PhaseCreated = new Relation(GetPhaseCreatedIndex(index), _GetReferencedPhaseCreated); + r._PhaseDemolished = new Relation(GetPhaseDemolishedIndex(index), _GetReferencedPhaseDemolished); + r._Category = new Relation(GetCategoryIndex(index), _GetReferencedCategory); + r._Workset = new Relation(GetWorksetIndex(index), _GetReferencedWorkset); + r._DesignOption = new Relation(GetDesignOptionIndex(index), _GetReferencedDesignOption); + r._OwnerView = new Relation(GetOwnerViewIndex(index), _GetReferencedOwnerView); + r._Group = new Relation(GetGroupIndex(index), _GetReferencedGroup); + r._AssemblyInstance = new Relation(GetAssemblyInstanceIndex(index), _GetReferencedAssemblyInstance); + r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); + r._Room = new Relation(GetRoomIndex(index), _GetReferencedRoom); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ElementTable + + public partial class Workset + { + public Vim.Format.BimDocument BimDocument => _BimDocument?.Value; + public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; + public Workset() + { + _BimDocument = new Relation(); + } + } // class Workset + + public partial class WorksetTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Workset; + public VimEntityTableSet ParentTableSet { get; } // can be null + public WorksetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Id = GetDataColumnValues("int:Id") ?? Array.Empty(); + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_Kind = GetStringColumnValues("string:Kind") ?? Array.Empty(); + Column_IsOpen = GetDataColumnValues("byte:IsOpen") ?? Array.Empty(); + Column_IsEditable = GetDataColumnValues("byte:IsEditable") ?? Array.Empty(); + Column_Owner = GetStringColumnValues("string:Owner") ?? Array.Empty(); + Column_UniqueId = GetStringColumnValues("string:UniqueId") ?? Array.Empty(); + Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); + } + public Int32[] Column_Id { get; } + public Int32 GetId(int index, Int32 @default = default) => Column_Id.ElementAtOrDefault(index, @default); + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public String[] Column_Kind { get; } + public String GetKind(int index, String @default = "") => Column_Kind.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsOpen { get; } + public Boolean GetIsOpen(int index, Boolean @default = default) => Column_IsOpen.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsEditable { get; } + public Boolean GetIsEditable(int index, Boolean @default = default) => Column_IsEditable.ElementAtOrDefault(index, @default); + public String[] Column_Owner { get; } + public String GetOwner(int index, String @default = "") => Column_Owner.ElementAtOrDefault(index, @default); + public String[] Column_UniqueId { get; } + public String GetUniqueId(int index, String @default = "") => Column_UniqueId.ElementAtOrDefault(index, @default); + public int[] Column_BimDocumentIndex { get; } + public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); + private Vim.Format.BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); + public Vim.Format.Workset Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Workset(); + r.Index = index; + r.Id = GetId(index); + r.Name = GetName(index); + r.Kind = GetKind(index); + r.IsOpen = GetIsOpen(index); + r.IsEditable = GetIsEditable(index); + r.Owner = GetOwner(index); + r.UniqueId = GetUniqueId(index); + r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class WorksetTable + + public partial class AssemblyInstance + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public AssemblyInstance() + { + _Element = new Relation(); + } + } // class AssemblyInstance + + public partial class AssemblyInstanceTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.AssemblyInstance; + public VimEntityTableSet ParentTableSet { get; } // can be null + public AssemblyInstanceTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_AssemblyTypeName = GetStringColumnValues("string:AssemblyTypeName") ?? Array.Empty(); + Column_Position_X = GetDataColumnValues("float:Position.X") ?? Array.Empty(); + Column_Position_Y = GetDataColumnValues("float:Position.Y") ?? Array.Empty(); + Column_Position_Z = GetDataColumnValues("float:Position.Z") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_AssemblyTypeName { get; } + public String GetAssemblyTypeName(int index, String @default = "") => Column_AssemblyTypeName.ElementAtOrDefault(index, @default); + public Single[] Column_Position_X { get; } + public Single GetPosition_X(int index, Single @default = default) => Column_Position_X.ElementAtOrDefault(index, @default); + public Single[] Column_Position_Y { get; } + public Single GetPosition_Y(int index, Single @default = default) => Column_Position_Y.ElementAtOrDefault(index, @default); + public Single[] Column_Position_Z { get; } + public Single GetPosition_Z(int index, Single @default = default) => Column_Position_Z.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.AssemblyInstance Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.AssemblyInstance(); + r.Index = index; + r.AssemblyTypeName = GetAssemblyTypeName(index); + r.Position_X = GetPosition_X(index); + r.Position_Y = GetPosition_Y(index); + r.Position_Z = GetPosition_Z(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class AssemblyInstanceTable + + public partial class Group + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Group() + { + _Element = new Relation(); + } + } // class Group + + public partial class GroupTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Group; + public VimEntityTableSet ParentTableSet { get; } // can be null + public GroupTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_GroupType = GetStringColumnValues("string:GroupType") ?? Array.Empty(); + Column_Position_X = GetDataColumnValues("float:Position.X") ?? Array.Empty(); + Column_Position_Y = GetDataColumnValues("float:Position.Y") ?? Array.Empty(); + Column_Position_Z = GetDataColumnValues("float:Position.Z") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_GroupType { get; } + public String GetGroupType(int index, String @default = "") => Column_GroupType.ElementAtOrDefault(index, @default); + public Single[] Column_Position_X { get; } + public Single GetPosition_X(int index, Single @default = default) => Column_Position_X.ElementAtOrDefault(index, @default); + public Single[] Column_Position_Y { get; } + public Single GetPosition_Y(int index, Single @default = default) => Column_Position_Y.ElementAtOrDefault(index, @default); + public Single[] Column_Position_Z { get; } + public Single GetPosition_Z(int index, Single @default = default) => Column_Position_Z.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Group Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Group(); + r.Index = index; + r.GroupType = GetGroupType(index); + r.Position_X = GetPosition_X(index); + r.Position_Y = GetPosition_Y(index); + r.Position_Z = GetPosition_Z(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class GroupTable + + public partial class DesignOption + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public DesignOption() + { + _Element = new Relation(); + } + } // class DesignOption + + public partial class DesignOptionTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.DesignOption; + public VimEntityTableSet ParentTableSet { get; } // can be null + public DesignOptionTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_IsPrimary = GetDataColumnValues("byte:IsPrimary") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Boolean[] Column_IsPrimary { get; } + public Boolean GetIsPrimary(int index, Boolean @default = default) => Column_IsPrimary.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.DesignOption Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.DesignOption(); + r.Index = index; + r.IsPrimary = GetIsPrimary(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class DesignOptionTable + + public partial class Level + { + public Vim.Format.FamilyType FamilyType => _FamilyType?.Value; + public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; + public Vim.Format.Building Building => _Building?.Value; + public int BuildingIndex => _Building?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Level() + { + _FamilyType = new Relation(); + _Building = new Relation(); + _Element = new Relation(); + } + } // class Level + + public partial class LevelTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Level; + public VimEntityTableSet ParentTableSet { get; } // can be null + public LevelTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); + Column_ProjectElevation = GetDataColumnValues("double:ProjectElevation") ?? Array.Empty(); + Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); + Column_BuildingIndex = GetIndexColumnValues("index:Vim.Building:Building") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_Elevation { get; } + public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); + public Double[] Column_ProjectElevation { get; } + public Double GetProjectElevation(int index, Double @default = default) => Column_ProjectElevation.ElementAtOrDefault(index, @default); + public int[] Column_FamilyTypeIndex { get; } + public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); + private Vim.Format.FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); + public int[] Column_BuildingIndex { get; } + public int GetBuildingIndex(int index) => Column_BuildingIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Building GetBuilding(int index) => _GetReferencedBuilding(GetBuildingIndex(index)); + private Vim.Format.Building _GetReferencedBuilding(int referencedIndex) => ParentTableSet.GetBuilding(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Level Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Level(); + r.Index = index; + r.Elevation = GetElevation(index); + r.ProjectElevation = GetProjectElevation(index); + r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); + r._Building = new Relation(GetBuildingIndex(index), _GetReferencedBuilding); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class LevelTable + + public partial class Phase + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Phase() + { + _Element = new Relation(); + } + } // class Phase + + public partial class PhaseTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Phase; + public VimEntityTableSet ParentTableSet { get; } // can be null + public PhaseTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Phase Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Phase(); + r.Index = index; + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class PhaseTable + + public partial class Room + { + public Vim.Format.Level UpperLimit => _UpperLimit?.Value; + public int UpperLimitIndex => _UpperLimit?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Room() + { + _UpperLimit = new Relation(); + _Element = new Relation(); + } + } // class Room + + public partial class RoomTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Room; + public VimEntityTableSet ParentTableSet { get; } // can be null + public RoomTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_BaseOffset = GetDataColumnValues("double:BaseOffset") ?? Array.Empty(); + Column_LimitOffset = GetDataColumnValues("double:LimitOffset") ?? Array.Empty(); + Column_UnboundedHeight = GetDataColumnValues("double:UnboundedHeight") ?? Array.Empty(); + Column_Volume = GetDataColumnValues("double:Volume") ?? Array.Empty(); + Column_Perimeter = GetDataColumnValues("double:Perimeter") ?? Array.Empty(); + Column_Area = GetDataColumnValues("double:Area") ?? Array.Empty(); + Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); + Column_UpperLimitIndex = GetIndexColumnValues("index:Vim.Level:UpperLimit") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_BaseOffset { get; } + public Double GetBaseOffset(int index, Double @default = default) => Column_BaseOffset.ElementAtOrDefault(index, @default); + public Double[] Column_LimitOffset { get; } + public Double GetLimitOffset(int index, Double @default = default) => Column_LimitOffset.ElementAtOrDefault(index, @default); + public Double[] Column_UnboundedHeight { get; } + public Double GetUnboundedHeight(int index, Double @default = default) => Column_UnboundedHeight.ElementAtOrDefault(index, @default); + public Double[] Column_Volume { get; } + public Double GetVolume(int index, Double @default = default) => Column_Volume.ElementAtOrDefault(index, @default); + public Double[] Column_Perimeter { get; } + public Double GetPerimeter(int index, Double @default = default) => Column_Perimeter.ElementAtOrDefault(index, @default); + public Double[] Column_Area { get; } + public Double GetArea(int index, Double @default = default) => Column_Area.ElementAtOrDefault(index, @default); + public String[] Column_Number { get; } + public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); + public int[] Column_UpperLimitIndex { get; } + public int GetUpperLimitIndex(int index) => Column_UpperLimitIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Level GetUpperLimit(int index) => _GetReferencedUpperLimit(GetUpperLimitIndex(index)); + private Vim.Format.Level _GetReferencedUpperLimit(int referencedIndex) => ParentTableSet.GetLevel(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Room Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Room(); + r.Index = index; + r.BaseOffset = GetBaseOffset(index); + r.LimitOffset = GetLimitOffset(index); + r.UnboundedHeight = GetUnboundedHeight(index); + r.Volume = GetVolume(index); + r.Perimeter = GetPerimeter(index); + r.Area = GetArea(index); + r.Number = GetNumber(index); + r._UpperLimit = new Relation(GetUpperLimitIndex(index), _GetReferencedUpperLimit); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class RoomTable + + public partial class BimDocument + { + public Vim.Format.View ActiveView => _ActiveView?.Value; + public int ActiveViewIndex => _ActiveView?.Index ?? EntityRelation.None; + public Vim.Format.Family OwnerFamily => _OwnerFamily?.Value; + public int OwnerFamilyIndex => _OwnerFamily?.Index ?? EntityRelation.None; + public Vim.Format.BimDocument Parent => _Parent?.Value; + public int ParentIndex => _Parent?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public BimDocument() + { + _ActiveView = new Relation(); + _OwnerFamily = new Relation(); + _Parent = new Relation(); + _Element = new Relation(); + } + } // class BimDocument + + public partial class BimDocumentTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.BimDocument; + public VimEntityTableSet ParentTableSet { get; } // can be null + public BimDocumentTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Title = GetStringColumnValues("string:Title") ?? Array.Empty(); + Column_IsMetric = GetDataColumnValues("byte:IsMetric") ?? Array.Empty(); + Column_Guid = GetStringColumnValues("string:Guid") ?? Array.Empty(); + Column_NumSaves = GetDataColumnValues("int:NumSaves") ?? Array.Empty(); + Column_IsLinked = GetDataColumnValues("byte:IsLinked") ?? Array.Empty(); + Column_IsDetached = GetDataColumnValues("byte:IsDetached") ?? Array.Empty(); + Column_IsWorkshared = GetDataColumnValues("byte:IsWorkshared") ?? Array.Empty(); + Column_PathName = GetStringColumnValues("string:PathName") ?? Array.Empty(); + Column_Latitude = GetDataColumnValues("double:Latitude") ?? Array.Empty(); + Column_Longitude = GetDataColumnValues("double:Longitude") ?? Array.Empty(); + Column_TimeZone = GetDataColumnValues("double:TimeZone") ?? Array.Empty(); + Column_PlaceName = GetStringColumnValues("string:PlaceName") ?? Array.Empty(); + Column_WeatherStationName = GetStringColumnValues("string:WeatherStationName") ?? Array.Empty(); + Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); + Column_ProjectLocation = GetStringColumnValues("string:ProjectLocation") ?? Array.Empty(); + Column_IssueDate = GetStringColumnValues("string:IssueDate") ?? Array.Empty(); + Column_Status = GetStringColumnValues("string:Status") ?? Array.Empty(); + Column_ClientName = GetStringColumnValues("string:ClientName") ?? Array.Empty(); + Column_Address = GetStringColumnValues("string:Address") ?? Array.Empty(); + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); + Column_Author = GetStringColumnValues("string:Author") ?? Array.Empty(); + Column_BuildingName = GetStringColumnValues("string:BuildingName") ?? Array.Empty(); + Column_OrganizationName = GetStringColumnValues("string:OrganizationName") ?? Array.Empty(); + Column_OrganizationDescription = GetStringColumnValues("string:OrganizationDescription") ?? Array.Empty(); + Column_Product = GetStringColumnValues("string:Product") ?? Array.Empty(); + Column_Version = GetStringColumnValues("string:Version") ?? Array.Empty(); + Column_User = GetStringColumnValues("string:User") ?? Array.Empty(); + Column_FileLength = GetDataColumnValues("long:FileLength") ?? Array.Empty(); + Column_ActiveViewIndex = GetIndexColumnValues("index:Vim.View:ActiveView") ?? Array.Empty(); + Column_OwnerFamilyIndex = GetIndexColumnValues("index:Vim.Family:OwnerFamily") ?? Array.Empty(); + Column_ParentIndex = GetIndexColumnValues("index:Vim.BimDocument:Parent") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_Title { get; } + public String GetTitle(int index, String @default = "") => Column_Title.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsMetric { get; } + public Boolean GetIsMetric(int index, Boolean @default = default) => Column_IsMetric.ElementAtOrDefault(index, @default); + public String[] Column_Guid { get; } + public String GetGuid(int index, String @default = "") => Column_Guid.ElementAtOrDefault(index, @default); + public Int32[] Column_NumSaves { get; } + public Int32 GetNumSaves(int index, Int32 @default = default) => Column_NumSaves.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsLinked { get; } + public Boolean GetIsLinked(int index, Boolean @default = default) => Column_IsLinked.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsDetached { get; } + public Boolean GetIsDetached(int index, Boolean @default = default) => Column_IsDetached.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsWorkshared { get; } + public Boolean GetIsWorkshared(int index, Boolean @default = default) => Column_IsWorkshared.ElementAtOrDefault(index, @default); + public String[] Column_PathName { get; } + public String GetPathName(int index, String @default = "") => Column_PathName.ElementAtOrDefault(index, @default); + public Double[] Column_Latitude { get; } + public Double GetLatitude(int index, Double @default = default) => Column_Latitude.ElementAtOrDefault(index, @default); + public Double[] Column_Longitude { get; } + public Double GetLongitude(int index, Double @default = default) => Column_Longitude.ElementAtOrDefault(index, @default); + public Double[] Column_TimeZone { get; } + public Double GetTimeZone(int index, Double @default = default) => Column_TimeZone.ElementAtOrDefault(index, @default); + public String[] Column_PlaceName { get; } + public String GetPlaceName(int index, String @default = "") => Column_PlaceName.ElementAtOrDefault(index, @default); + public String[] Column_WeatherStationName { get; } + public String GetWeatherStationName(int index, String @default = "") => Column_WeatherStationName.ElementAtOrDefault(index, @default); + public Double[] Column_Elevation { get; } + public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); + public String[] Column_ProjectLocation { get; } + public String GetProjectLocation(int index, String @default = "") => Column_ProjectLocation.ElementAtOrDefault(index, @default); + public String[] Column_IssueDate { get; } + public String GetIssueDate(int index, String @default = "") => Column_IssueDate.ElementAtOrDefault(index, @default); + public String[] Column_Status { get; } + public String GetStatus(int index, String @default = "") => Column_Status.ElementAtOrDefault(index, @default); + public String[] Column_ClientName { get; } + public String GetClientName(int index, String @default = "") => Column_ClientName.ElementAtOrDefault(index, @default); + public String[] Column_Address { get; } + public String GetAddress(int index, String @default = "") => Column_Address.ElementAtOrDefault(index, @default); + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public String[] Column_Number { get; } + public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); + public String[] Column_Author { get; } + public String GetAuthor(int index, String @default = "") => Column_Author.ElementAtOrDefault(index, @default); + public String[] Column_BuildingName { get; } + public String GetBuildingName(int index, String @default = "") => Column_BuildingName.ElementAtOrDefault(index, @default); + public String[] Column_OrganizationName { get; } + public String GetOrganizationName(int index, String @default = "") => Column_OrganizationName.ElementAtOrDefault(index, @default); + public String[] Column_OrganizationDescription { get; } + public String GetOrganizationDescription(int index, String @default = "") => Column_OrganizationDescription.ElementAtOrDefault(index, @default); + public String[] Column_Product { get; } + public String GetProduct(int index, String @default = "") => Column_Product.ElementAtOrDefault(index, @default); + public String[] Column_Version { get; } + public String GetVersion(int index, String @default = "") => Column_Version.ElementAtOrDefault(index, @default); + public String[] Column_User { get; } + public String GetUser(int index, String @default = "") => Column_User.ElementAtOrDefault(index, @default); + public Int64[] Column_FileLength { get; } + public Int64 GetFileLength(int index, Int64 @default = default) => Column_FileLength.ElementAtOrDefault(index, @default); + public int[] Column_ActiveViewIndex { get; } + public int GetActiveViewIndex(int index) => Column_ActiveViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetActiveView(int index) => _GetReferencedActiveView(GetActiveViewIndex(index)); + private Vim.Format.View _GetReferencedActiveView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public int[] Column_OwnerFamilyIndex { get; } + public int GetOwnerFamilyIndex(int index) => Column_OwnerFamilyIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Family GetOwnerFamily(int index) => _GetReferencedOwnerFamily(GetOwnerFamilyIndex(index)); + private Vim.Format.Family _GetReferencedOwnerFamily(int referencedIndex) => ParentTableSet.GetFamily(referencedIndex); + public int[] Column_ParentIndex { get; } + public int GetParentIndex(int index) => Column_ParentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.BimDocument GetParent(int index) => _GetReferencedParent(GetParentIndex(index)); + private Vim.Format.BimDocument _GetReferencedParent(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.BimDocument Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.BimDocument(); + r.Index = index; + r.Title = GetTitle(index); + r.IsMetric = GetIsMetric(index); + r.Guid = GetGuid(index); + r.NumSaves = GetNumSaves(index); + r.IsLinked = GetIsLinked(index); + r.IsDetached = GetIsDetached(index); + r.IsWorkshared = GetIsWorkshared(index); + r.PathName = GetPathName(index); + r.Latitude = GetLatitude(index); + r.Longitude = GetLongitude(index); + r.TimeZone = GetTimeZone(index); + r.PlaceName = GetPlaceName(index); + r.WeatherStationName = GetWeatherStationName(index); + r.Elevation = GetElevation(index); + r.ProjectLocation = GetProjectLocation(index); + r.IssueDate = GetIssueDate(index); + r.Status = GetStatus(index); + r.ClientName = GetClientName(index); + r.Address = GetAddress(index); + r.Name = GetName(index); + r.Number = GetNumber(index); + r.Author = GetAuthor(index); + r.BuildingName = GetBuildingName(index); + r.OrganizationName = GetOrganizationName(index); + r.OrganizationDescription = GetOrganizationDescription(index); + r.Product = GetProduct(index); + r.Version = GetVersion(index); + r.User = GetUser(index); + r.FileLength = GetFileLength(index); + r._ActiveView = new Relation(GetActiveViewIndex(index), _GetReferencedActiveView); + r._OwnerFamily = new Relation(GetOwnerFamilyIndex(index), _GetReferencedOwnerFamily); + r._Parent = new Relation(GetParentIndex(index), _GetReferencedParent); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class BimDocumentTable + + public partial class DisplayUnitInBimDocument + { + public Vim.Format.DisplayUnit DisplayUnit => _DisplayUnit?.Value; + public int DisplayUnitIndex => _DisplayUnit?.Index ?? EntityRelation.None; + public Vim.Format.BimDocument BimDocument => _BimDocument?.Value; + public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; + public DisplayUnitInBimDocument() + { + _DisplayUnit = new Relation(); + _BimDocument = new Relation(); + } + } // class DisplayUnitInBimDocument + + public partial class DisplayUnitInBimDocumentTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.DisplayUnitInBimDocument; + public VimEntityTableSet ParentTableSet { get; } // can be null + public DisplayUnitInBimDocumentTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_DisplayUnitIndex = GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty(); + Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); + } + public int[] Column_DisplayUnitIndex { get; } + public int GetDisplayUnitIndex(int index) => Column_DisplayUnitIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.DisplayUnit GetDisplayUnit(int index) => _GetReferencedDisplayUnit(GetDisplayUnitIndex(index)); + private Vim.Format.DisplayUnit _GetReferencedDisplayUnit(int referencedIndex) => ParentTableSet.GetDisplayUnit(referencedIndex); + public int[] Column_BimDocumentIndex { get; } + public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); + private Vim.Format.BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); + public Vim.Format.DisplayUnitInBimDocument Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.DisplayUnitInBimDocument(); + r.Index = index; + r._DisplayUnit = new Relation(GetDisplayUnitIndex(index), _GetReferencedDisplayUnit); + r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class DisplayUnitInBimDocumentTable + + public partial class PhaseOrderInBimDocument + { + public Vim.Format.Phase Phase => _Phase?.Value; + public int PhaseIndex => _Phase?.Index ?? EntityRelation.None; + public Vim.Format.BimDocument BimDocument => _BimDocument?.Value; + public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; + public PhaseOrderInBimDocument() + { + _Phase = new Relation(); + _BimDocument = new Relation(); + } + } // class PhaseOrderInBimDocument + + public partial class PhaseOrderInBimDocumentTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.PhaseOrderInBimDocument; + public VimEntityTableSet ParentTableSet { get; } // can be null + public PhaseOrderInBimDocumentTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_OrderIndex = GetDataColumnValues("int:OrderIndex") ?? Array.Empty(); + Column_PhaseIndex = GetIndexColumnValues("index:Vim.Phase:Phase") ?? Array.Empty(); + Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); + } + public Int32[] Column_OrderIndex { get; } + public Int32 GetOrderIndex(int index, Int32 @default = default) => Column_OrderIndex.ElementAtOrDefault(index, @default); + public int[] Column_PhaseIndex { get; } + public int GetPhaseIndex(int index) => Column_PhaseIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Phase GetPhase(int index) => _GetReferencedPhase(GetPhaseIndex(index)); + private Vim.Format.Phase _GetReferencedPhase(int referencedIndex) => ParentTableSet.GetPhase(referencedIndex); + public int[] Column_BimDocumentIndex { get; } + public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); + private Vim.Format.BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); + public Vim.Format.PhaseOrderInBimDocument Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.PhaseOrderInBimDocument(); + r.Index = index; + r.OrderIndex = GetOrderIndex(index); + r._Phase = new Relation(GetPhaseIndex(index), _GetReferencedPhase); + r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class PhaseOrderInBimDocumentTable + + public partial class Category + { + public Vim.Format.Category Parent => _Parent?.Value; + public int ParentIndex => _Parent?.Index ?? EntityRelation.None; + public Vim.Format.Material Material => _Material?.Value; + public int MaterialIndex => _Material?.Index ?? EntityRelation.None; + public Category() + { + _Parent = new Relation(); + _Material = new Relation(); + } + } // class Category + + public partial class CategoryTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Category; + public VimEntityTableSet ParentTableSet { get; } // can be null + public CategoryTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_Id = (GetDataColumnValues("long:Id") ?? GetDataColumnValues("int:Id")?.Select(v => (Int64) v).ToArray()) ?? Array.Empty(); + Column_CategoryType = GetStringColumnValues("string:CategoryType") ?? Array.Empty(); + Column_LineColor_X = GetDataColumnValues("double:LineColor.X") ?? Array.Empty(); + Column_LineColor_Y = GetDataColumnValues("double:LineColor.Y") ?? Array.Empty(); + Column_LineColor_Z = GetDataColumnValues("double:LineColor.Z") ?? Array.Empty(); + Column_BuiltInCategory = GetStringColumnValues("string:BuiltInCategory") ?? Array.Empty(); + Column_ParentIndex = GetIndexColumnValues("index:Vim.Category:Parent") ?? Array.Empty(); + Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); + } + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public Int64[] Column_Id { get; } + public Int64 GetId(int index, Int64 @default = default) => Column_Id.ElementAtOrDefault(index, @default); + public String[] Column_CategoryType { get; } + public String GetCategoryType(int index, String @default = "") => Column_CategoryType.ElementAtOrDefault(index, @default); + public Double[] Column_LineColor_X { get; } + public Double GetLineColor_X(int index, Double @default = default) => Column_LineColor_X.ElementAtOrDefault(index, @default); + public Double[] Column_LineColor_Y { get; } + public Double GetLineColor_Y(int index, Double @default = default) => Column_LineColor_Y.ElementAtOrDefault(index, @default); + public Double[] Column_LineColor_Z { get; } + public Double GetLineColor_Z(int index, Double @default = default) => Column_LineColor_Z.ElementAtOrDefault(index, @default); + public String[] Column_BuiltInCategory { get; } + public String GetBuiltInCategory(int index, String @default = "") => Column_BuiltInCategory.ElementAtOrDefault(index, @default); + public int[] Column_ParentIndex { get; } + public int GetParentIndex(int index) => Column_ParentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Category GetParent(int index) => _GetReferencedParent(GetParentIndex(index)); + private Vim.Format.Category _GetReferencedParent(int referencedIndex) => ParentTableSet.GetCategory(referencedIndex); + public int[] Column_MaterialIndex { get; } + public int GetMaterialIndex(int index) => Column_MaterialIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Material GetMaterial(int index) => _GetReferencedMaterial(GetMaterialIndex(index)); + private Vim.Format.Material _GetReferencedMaterial(int referencedIndex) => ParentTableSet.GetMaterial(referencedIndex); + public Vim.Format.Category Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Category(); + r.Index = index; + r.Name = GetName(index); + r.Id = GetId(index); + r.CategoryType = GetCategoryType(index); + r.LineColor_X = GetLineColor_X(index); + r.LineColor_Y = GetLineColor_Y(index); + r.LineColor_Z = GetLineColor_Z(index); + r.BuiltInCategory = GetBuiltInCategory(index); + r._Parent = new Relation(GetParentIndex(index), _GetReferencedParent); + r._Material = new Relation(GetMaterialIndex(index), _GetReferencedMaterial); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class CategoryTable + + public partial class Family + { + public Vim.Format.Category FamilyCategory => _FamilyCategory?.Value; + public int FamilyCategoryIndex => _FamilyCategory?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Family() + { + _FamilyCategory = new Relation(); + _Element = new Relation(); + } + } // class Family + + public partial class FamilyTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Family; + public VimEntityTableSet ParentTableSet { get; } // can be null + public FamilyTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_StructuralMaterialType = GetStringColumnValues("string:StructuralMaterialType") ?? Array.Empty(); + Column_StructuralSectionShape = GetStringColumnValues("string:StructuralSectionShape") ?? Array.Empty(); + Column_IsSystemFamily = GetDataColumnValues("byte:IsSystemFamily") ?? Array.Empty(); + Column_IsInPlace = GetDataColumnValues("byte:IsInPlace") ?? Array.Empty(); + Column_FamilyCategoryIndex = GetIndexColumnValues("index:Vim.Category:FamilyCategory") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_StructuralMaterialType { get; } + public String GetStructuralMaterialType(int index, String @default = "") => Column_StructuralMaterialType.ElementAtOrDefault(index, @default); + public String[] Column_StructuralSectionShape { get; } + public String GetStructuralSectionShape(int index, String @default = "") => Column_StructuralSectionShape.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsSystemFamily { get; } + public Boolean GetIsSystemFamily(int index, Boolean @default = default) => Column_IsSystemFamily.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsInPlace { get; } + public Boolean GetIsInPlace(int index, Boolean @default = default) => Column_IsInPlace.ElementAtOrDefault(index, @default); + public int[] Column_FamilyCategoryIndex { get; } + public int GetFamilyCategoryIndex(int index) => Column_FamilyCategoryIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Category GetFamilyCategory(int index) => _GetReferencedFamilyCategory(GetFamilyCategoryIndex(index)); + private Vim.Format.Category _GetReferencedFamilyCategory(int referencedIndex) => ParentTableSet.GetCategory(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Family Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Family(); + r.Index = index; + r.StructuralMaterialType = GetStructuralMaterialType(index); + r.StructuralSectionShape = GetStructuralSectionShape(index); + r.IsSystemFamily = GetIsSystemFamily(index); + r.IsInPlace = GetIsInPlace(index); + r._FamilyCategory = new Relation(GetFamilyCategoryIndex(index), _GetReferencedFamilyCategory); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class FamilyTable + + public partial class FamilyType + { + public Vim.Format.Family Family => _Family?.Value; + public int FamilyIndex => _Family?.Index ?? EntityRelation.None; + public Vim.Format.CompoundStructure CompoundStructure => _CompoundStructure?.Value; + public int CompoundStructureIndex => _CompoundStructure?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public FamilyType() + { + _Family = new Relation(); + _CompoundStructure = new Relation(); + _Element = new Relation(); + } + } // class FamilyType + + public partial class FamilyTypeTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.FamilyType; + public VimEntityTableSet ParentTableSet { get; } // can be null + public FamilyTypeTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_IsSystemFamilyType = GetDataColumnValues("byte:IsSystemFamilyType") ?? Array.Empty(); + Column_FamilyIndex = GetIndexColumnValues("index:Vim.Family:Family") ?? Array.Empty(); + Column_CompoundStructureIndex = GetIndexColumnValues("index:Vim.CompoundStructure:CompoundStructure") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Boolean[] Column_IsSystemFamilyType { get; } + public Boolean GetIsSystemFamilyType(int index, Boolean @default = default) => Column_IsSystemFamilyType.ElementAtOrDefault(index, @default); + public int[] Column_FamilyIndex { get; } + public int GetFamilyIndex(int index) => Column_FamilyIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Family GetFamily(int index) => _GetReferencedFamily(GetFamilyIndex(index)); + private Vim.Format.Family _GetReferencedFamily(int referencedIndex) => ParentTableSet.GetFamily(referencedIndex); + public int[] Column_CompoundStructureIndex { get; } + public int GetCompoundStructureIndex(int index) => Column_CompoundStructureIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.CompoundStructure GetCompoundStructure(int index) => _GetReferencedCompoundStructure(GetCompoundStructureIndex(index)); + private Vim.Format.CompoundStructure _GetReferencedCompoundStructure(int referencedIndex) => ParentTableSet.GetCompoundStructure(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.FamilyType Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.FamilyType(); + r.Index = index; + r.IsSystemFamilyType = GetIsSystemFamilyType(index); + r._Family = new Relation(GetFamilyIndex(index), _GetReferencedFamily); + r._CompoundStructure = new Relation(GetCompoundStructureIndex(index), _GetReferencedCompoundStructure); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class FamilyTypeTable + + public partial class FamilyInstance + { + public Vim.Format.FamilyType FamilyType => _FamilyType?.Value; + public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; + public Vim.Format.Element Host => _Host?.Value; + public int HostIndex => _Host?.Index ?? EntityRelation.None; + public Vim.Format.Room FromRoom => _FromRoom?.Value; + public int FromRoomIndex => _FromRoom?.Index ?? EntityRelation.None; + public Vim.Format.Room ToRoom => _ToRoom?.Value; + public int ToRoomIndex => _ToRoom?.Index ?? EntityRelation.None; + public Vim.Format.Element SuperComponent => _SuperComponent?.Value; + public int SuperComponentIndex => _SuperComponent?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public FamilyInstance() + { + _FamilyType = new Relation(); + _Host = new Relation(); + _FromRoom = new Relation(); + _ToRoom = new Relation(); + _SuperComponent = new Relation(); + _Element = new Relation(); + } + } // class FamilyInstance + + public partial class FamilyInstanceTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.FamilyInstance; + public VimEntityTableSet ParentTableSet { get; } // can be null + public FamilyInstanceTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_FacingFlipped = GetDataColumnValues("byte:FacingFlipped") ?? Array.Empty(); + Column_FacingOrientation_X = GetDataColumnValues("float:FacingOrientation.X") ?? Array.Empty(); + Column_FacingOrientation_Y = GetDataColumnValues("float:FacingOrientation.Y") ?? Array.Empty(); + Column_FacingOrientation_Z = GetDataColumnValues("float:FacingOrientation.Z") ?? Array.Empty(); + Column_HandFlipped = GetDataColumnValues("byte:HandFlipped") ?? Array.Empty(); + Column_Mirrored = GetDataColumnValues("byte:Mirrored") ?? Array.Empty(); + Column_HasModifiedGeometry = GetDataColumnValues("byte:HasModifiedGeometry") ?? Array.Empty(); + Column_Scale = GetDataColumnValues("float:Scale") ?? Array.Empty(); + Column_BasisX_X = GetDataColumnValues("float:BasisX.X") ?? Array.Empty(); + Column_BasisX_Y = GetDataColumnValues("float:BasisX.Y") ?? Array.Empty(); + Column_BasisX_Z = GetDataColumnValues("float:BasisX.Z") ?? Array.Empty(); + Column_BasisY_X = GetDataColumnValues("float:BasisY.X") ?? Array.Empty(); + Column_BasisY_Y = GetDataColumnValues("float:BasisY.Y") ?? Array.Empty(); + Column_BasisY_Z = GetDataColumnValues("float:BasisY.Z") ?? Array.Empty(); + Column_BasisZ_X = GetDataColumnValues("float:BasisZ.X") ?? Array.Empty(); + Column_BasisZ_Y = GetDataColumnValues("float:BasisZ.Y") ?? Array.Empty(); + Column_BasisZ_Z = GetDataColumnValues("float:BasisZ.Z") ?? Array.Empty(); + Column_Translation_X = GetDataColumnValues("float:Translation.X") ?? Array.Empty(); + Column_Translation_Y = GetDataColumnValues("float:Translation.Y") ?? Array.Empty(); + Column_Translation_Z = GetDataColumnValues("float:Translation.Z") ?? Array.Empty(); + Column_HandOrientation_X = GetDataColumnValues("float:HandOrientation.X") ?? Array.Empty(); + Column_HandOrientation_Y = GetDataColumnValues("float:HandOrientation.Y") ?? Array.Empty(); + Column_HandOrientation_Z = GetDataColumnValues("float:HandOrientation.Z") ?? Array.Empty(); + Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); + Column_HostIndex = GetIndexColumnValues("index:Vim.Element:Host") ?? Array.Empty(); + Column_FromRoomIndex = GetIndexColumnValues("index:Vim.Room:FromRoom") ?? Array.Empty(); + Column_ToRoomIndex = GetIndexColumnValues("index:Vim.Room:ToRoom") ?? Array.Empty(); + Column_SuperComponentIndex = GetIndexColumnValues("index:Vim.Element:SuperComponent") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Boolean[] Column_FacingFlipped { get; } + public Boolean GetFacingFlipped(int index, Boolean @default = default) => Column_FacingFlipped.ElementAtOrDefault(index, @default); + public Single[] Column_FacingOrientation_X { get; } + public Single GetFacingOrientation_X(int index, Single @default = default) => Column_FacingOrientation_X.ElementAtOrDefault(index, @default); + public Single[] Column_FacingOrientation_Y { get; } + public Single GetFacingOrientation_Y(int index, Single @default = default) => Column_FacingOrientation_Y.ElementAtOrDefault(index, @default); + public Single[] Column_FacingOrientation_Z { get; } + public Single GetFacingOrientation_Z(int index, Single @default = default) => Column_FacingOrientation_Z.ElementAtOrDefault(index, @default); + public Boolean[] Column_HandFlipped { get; } + public Boolean GetHandFlipped(int index, Boolean @default = default) => Column_HandFlipped.ElementAtOrDefault(index, @default); + public Boolean[] Column_Mirrored { get; } + public Boolean GetMirrored(int index, Boolean @default = default) => Column_Mirrored.ElementAtOrDefault(index, @default); + public Boolean[] Column_HasModifiedGeometry { get; } + public Boolean GetHasModifiedGeometry(int index, Boolean @default = default) => Column_HasModifiedGeometry.ElementAtOrDefault(index, @default); + public Single[] Column_Scale { get; } + public Single GetScale(int index, Single @default = default) => Column_Scale.ElementAtOrDefault(index, @default); + public Single[] Column_BasisX_X { get; } + public Single GetBasisX_X(int index, Single @default = default) => Column_BasisX_X.ElementAtOrDefault(index, @default); + public Single[] Column_BasisX_Y { get; } + public Single GetBasisX_Y(int index, Single @default = default) => Column_BasisX_Y.ElementAtOrDefault(index, @default); + public Single[] Column_BasisX_Z { get; } + public Single GetBasisX_Z(int index, Single @default = default) => Column_BasisX_Z.ElementAtOrDefault(index, @default); + public Single[] Column_BasisY_X { get; } + public Single GetBasisY_X(int index, Single @default = default) => Column_BasisY_X.ElementAtOrDefault(index, @default); + public Single[] Column_BasisY_Y { get; } + public Single GetBasisY_Y(int index, Single @default = default) => Column_BasisY_Y.ElementAtOrDefault(index, @default); + public Single[] Column_BasisY_Z { get; } + public Single GetBasisY_Z(int index, Single @default = default) => Column_BasisY_Z.ElementAtOrDefault(index, @default); + public Single[] Column_BasisZ_X { get; } + public Single GetBasisZ_X(int index, Single @default = default) => Column_BasisZ_X.ElementAtOrDefault(index, @default); + public Single[] Column_BasisZ_Y { get; } + public Single GetBasisZ_Y(int index, Single @default = default) => Column_BasisZ_Y.ElementAtOrDefault(index, @default); + public Single[] Column_BasisZ_Z { get; } + public Single GetBasisZ_Z(int index, Single @default = default) => Column_BasisZ_Z.ElementAtOrDefault(index, @default); + public Single[] Column_Translation_X { get; } + public Single GetTranslation_X(int index, Single @default = default) => Column_Translation_X.ElementAtOrDefault(index, @default); + public Single[] Column_Translation_Y { get; } + public Single GetTranslation_Y(int index, Single @default = default) => Column_Translation_Y.ElementAtOrDefault(index, @default); + public Single[] Column_Translation_Z { get; } + public Single GetTranslation_Z(int index, Single @default = default) => Column_Translation_Z.ElementAtOrDefault(index, @default); + public Single[] Column_HandOrientation_X { get; } + public Single GetHandOrientation_X(int index, Single @default = default) => Column_HandOrientation_X.ElementAtOrDefault(index, @default); + public Single[] Column_HandOrientation_Y { get; } + public Single GetHandOrientation_Y(int index, Single @default = default) => Column_HandOrientation_Y.ElementAtOrDefault(index, @default); + public Single[] Column_HandOrientation_Z { get; } + public Single GetHandOrientation_Z(int index, Single @default = default) => Column_HandOrientation_Z.ElementAtOrDefault(index, @default); + public int[] Column_FamilyTypeIndex { get; } + public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); + private Vim.Format.FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); + public int[] Column_HostIndex { get; } + public int GetHostIndex(int index) => Column_HostIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetHost(int index) => _GetReferencedHost(GetHostIndex(index)); + private Vim.Format.Element _GetReferencedHost(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public int[] Column_FromRoomIndex { get; } + public int GetFromRoomIndex(int index) => Column_FromRoomIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Room GetFromRoom(int index) => _GetReferencedFromRoom(GetFromRoomIndex(index)); + private Vim.Format.Room _GetReferencedFromRoom(int referencedIndex) => ParentTableSet.GetRoom(referencedIndex); + public int[] Column_ToRoomIndex { get; } + public int GetToRoomIndex(int index) => Column_ToRoomIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Room GetToRoom(int index) => _GetReferencedToRoom(GetToRoomIndex(index)); + private Vim.Format.Room _GetReferencedToRoom(int referencedIndex) => ParentTableSet.GetRoom(referencedIndex); + public int[] Column_SuperComponentIndex { get; } + public int GetSuperComponentIndex(int index) => Column_SuperComponentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetSuperComponent(int index) => _GetReferencedSuperComponent(GetSuperComponentIndex(index)); + private Vim.Format.Element _GetReferencedSuperComponent(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.FamilyInstance Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.FamilyInstance(); + r.Index = index; + r.FacingFlipped = GetFacingFlipped(index); + r.FacingOrientation_X = GetFacingOrientation_X(index); + r.FacingOrientation_Y = GetFacingOrientation_Y(index); + r.FacingOrientation_Z = GetFacingOrientation_Z(index); + r.HandFlipped = GetHandFlipped(index); + r.Mirrored = GetMirrored(index); + r.HasModifiedGeometry = GetHasModifiedGeometry(index); + r.Scale = GetScale(index); + r.BasisX_X = GetBasisX_X(index); + r.BasisX_Y = GetBasisX_Y(index); + r.BasisX_Z = GetBasisX_Z(index); + r.BasisY_X = GetBasisY_X(index); + r.BasisY_Y = GetBasisY_Y(index); + r.BasisY_Z = GetBasisY_Z(index); + r.BasisZ_X = GetBasisZ_X(index); + r.BasisZ_Y = GetBasisZ_Y(index); + r.BasisZ_Z = GetBasisZ_Z(index); + r.Translation_X = GetTranslation_X(index); + r.Translation_Y = GetTranslation_Y(index); + r.Translation_Z = GetTranslation_Z(index); + r.HandOrientation_X = GetHandOrientation_X(index); + r.HandOrientation_Y = GetHandOrientation_Y(index); + r.HandOrientation_Z = GetHandOrientation_Z(index); + r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); + r._Host = new Relation(GetHostIndex(index), _GetReferencedHost); + r._FromRoom = new Relation(GetFromRoomIndex(index), _GetReferencedFromRoom); + r._ToRoom = new Relation(GetToRoomIndex(index), _GetReferencedToRoom); + r._SuperComponent = new Relation(GetSuperComponentIndex(index), _GetReferencedSuperComponent); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class FamilyInstanceTable + + public partial class View + { + public Vim.Format.Camera Camera => _Camera?.Value; + public int CameraIndex => _Camera?.Index ?? EntityRelation.None; + public Vim.Format.FamilyType FamilyType => _FamilyType?.Value; + public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public View() + { + _Camera = new Relation(); + _FamilyType = new Relation(); + _Element = new Relation(); + } + } // class View + + public partial class ViewTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.View; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ViewTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Title = GetStringColumnValues("string:Title") ?? Array.Empty(); + Column_ViewType = GetStringColumnValues("string:ViewType") ?? Array.Empty(); + Column_Up_X = GetDataColumnValues("double:Up.X") ?? Array.Empty(); + Column_Up_Y = GetDataColumnValues("double:Up.Y") ?? Array.Empty(); + Column_Up_Z = GetDataColumnValues("double:Up.Z") ?? Array.Empty(); + Column_Right_X = GetDataColumnValues("double:Right.X") ?? Array.Empty(); + Column_Right_Y = GetDataColumnValues("double:Right.Y") ?? Array.Empty(); + Column_Right_Z = GetDataColumnValues("double:Right.Z") ?? Array.Empty(); + Column_Origin_X = GetDataColumnValues("double:Origin.X") ?? Array.Empty(); + Column_Origin_Y = GetDataColumnValues("double:Origin.Y") ?? Array.Empty(); + Column_Origin_Z = GetDataColumnValues("double:Origin.Z") ?? Array.Empty(); + Column_ViewDirection_X = GetDataColumnValues("double:ViewDirection.X") ?? Array.Empty(); + Column_ViewDirection_Y = GetDataColumnValues("double:ViewDirection.Y") ?? Array.Empty(); + Column_ViewDirection_Z = GetDataColumnValues("double:ViewDirection.Z") ?? Array.Empty(); + Column_ViewPosition_X = GetDataColumnValues("double:ViewPosition.X") ?? Array.Empty(); + Column_ViewPosition_Y = GetDataColumnValues("double:ViewPosition.Y") ?? Array.Empty(); + Column_ViewPosition_Z = GetDataColumnValues("double:ViewPosition.Z") ?? Array.Empty(); + Column_Scale = GetDataColumnValues("double:Scale") ?? Array.Empty(); + Column_Outline_Min_X = GetDataColumnValues("double:Outline.Min.X") ?? Array.Empty(); + Column_Outline_Min_Y = GetDataColumnValues("double:Outline.Min.Y") ?? Array.Empty(); + Column_Outline_Max_X = GetDataColumnValues("double:Outline.Max.X") ?? Array.Empty(); + Column_Outline_Max_Y = GetDataColumnValues("double:Outline.Max.Y") ?? Array.Empty(); + Column_DetailLevel = GetDataColumnValues("int:DetailLevel") ?? Array.Empty(); + Column_CameraIndex = GetIndexColumnValues("index:Vim.Camera:Camera") ?? Array.Empty(); + Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_Title { get; } + public String GetTitle(int index, String @default = "") => Column_Title.ElementAtOrDefault(index, @default); + public String[] Column_ViewType { get; } + public String GetViewType(int index, String @default = "") => Column_ViewType.ElementAtOrDefault(index, @default); + public Double[] Column_Up_X { get; } + public Double GetUp_X(int index, Double @default = default) => Column_Up_X.ElementAtOrDefault(index, @default); + public Double[] Column_Up_Y { get; } + public Double GetUp_Y(int index, Double @default = default) => Column_Up_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Up_Z { get; } + public Double GetUp_Z(int index, Double @default = default) => Column_Up_Z.ElementAtOrDefault(index, @default); + public Double[] Column_Right_X { get; } + public Double GetRight_X(int index, Double @default = default) => Column_Right_X.ElementAtOrDefault(index, @default); + public Double[] Column_Right_Y { get; } + public Double GetRight_Y(int index, Double @default = default) => Column_Right_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Right_Z { get; } + public Double GetRight_Z(int index, Double @default = default) => Column_Right_Z.ElementAtOrDefault(index, @default); + public Double[] Column_Origin_X { get; } + public Double GetOrigin_X(int index, Double @default = default) => Column_Origin_X.ElementAtOrDefault(index, @default); + public Double[] Column_Origin_Y { get; } + public Double GetOrigin_Y(int index, Double @default = default) => Column_Origin_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Origin_Z { get; } + public Double GetOrigin_Z(int index, Double @default = default) => Column_Origin_Z.ElementAtOrDefault(index, @default); + public Double[] Column_ViewDirection_X { get; } + public Double GetViewDirection_X(int index, Double @default = default) => Column_ViewDirection_X.ElementAtOrDefault(index, @default); + public Double[] Column_ViewDirection_Y { get; } + public Double GetViewDirection_Y(int index, Double @default = default) => Column_ViewDirection_Y.ElementAtOrDefault(index, @default); + public Double[] Column_ViewDirection_Z { get; } + public Double GetViewDirection_Z(int index, Double @default = default) => Column_ViewDirection_Z.ElementAtOrDefault(index, @default); + public Double[] Column_ViewPosition_X { get; } + public Double GetViewPosition_X(int index, Double @default = default) => Column_ViewPosition_X.ElementAtOrDefault(index, @default); + public Double[] Column_ViewPosition_Y { get; } + public Double GetViewPosition_Y(int index, Double @default = default) => Column_ViewPosition_Y.ElementAtOrDefault(index, @default); + public Double[] Column_ViewPosition_Z { get; } + public Double GetViewPosition_Z(int index, Double @default = default) => Column_ViewPosition_Z.ElementAtOrDefault(index, @default); + public Double[] Column_Scale { get; } + public Double GetScale(int index, Double @default = default) => Column_Scale.ElementAtOrDefault(index, @default); + public Double[] Column_Outline_Min_X { get; } + public Double GetOutline_Min_X(int index, Double @default = default) => Column_Outline_Min_X.ElementAtOrDefault(index, @default); + public Double[] Column_Outline_Min_Y { get; } + public Double GetOutline_Min_Y(int index, Double @default = default) => Column_Outline_Min_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Outline_Max_X { get; } + public Double GetOutline_Max_X(int index, Double @default = default) => Column_Outline_Max_X.ElementAtOrDefault(index, @default); + public Double[] Column_Outline_Max_Y { get; } + public Double GetOutline_Max_Y(int index, Double @default = default) => Column_Outline_Max_Y.ElementAtOrDefault(index, @default); + public Int32[] Column_DetailLevel { get; } + public Int32 GetDetailLevel(int index, Int32 @default = default) => Column_DetailLevel.ElementAtOrDefault(index, @default); + public int[] Column_CameraIndex { get; } + public int GetCameraIndex(int index) => Column_CameraIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Camera GetCamera(int index) => _GetReferencedCamera(GetCameraIndex(index)); + private Vim.Format.Camera _GetReferencedCamera(int referencedIndex) => ParentTableSet.GetCamera(referencedIndex); + public int[] Column_FamilyTypeIndex { get; } + public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); + private Vim.Format.FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.View Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.View(); + r.Index = index; + r.Title = GetTitle(index); + r.ViewType = GetViewType(index); + r.Up_X = GetUp_X(index); + r.Up_Y = GetUp_Y(index); + r.Up_Z = GetUp_Z(index); + r.Right_X = GetRight_X(index); + r.Right_Y = GetRight_Y(index); + r.Right_Z = GetRight_Z(index); + r.Origin_X = GetOrigin_X(index); + r.Origin_Y = GetOrigin_Y(index); + r.Origin_Z = GetOrigin_Z(index); + r.ViewDirection_X = GetViewDirection_X(index); + r.ViewDirection_Y = GetViewDirection_Y(index); + r.ViewDirection_Z = GetViewDirection_Z(index); + r.ViewPosition_X = GetViewPosition_X(index); + r.ViewPosition_Y = GetViewPosition_Y(index); + r.ViewPosition_Z = GetViewPosition_Z(index); + r.Scale = GetScale(index); + r.Outline_Min_X = GetOutline_Min_X(index); + r.Outline_Min_Y = GetOutline_Min_Y(index); + r.Outline_Max_X = GetOutline_Max_X(index); + r.Outline_Max_Y = GetOutline_Max_Y(index); + r.DetailLevel = GetDetailLevel(index); + r._Camera = new Relation(GetCameraIndex(index), _GetReferencedCamera); + r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ViewTable + + public partial class ElementInView + { + public Vim.Format.View View => _View?.Value; + public int ViewIndex => _View?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public ElementInView() + { + _View = new Relation(); + _Element = new Relation(); + } + } // class ElementInView + + public partial class ElementInViewTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ElementInView; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ElementInViewTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ViewIndex { get; } + public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetView(int index) => _GetReferencedView(GetViewIndex(index)); + private Vim.Format.View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.ElementInView Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ElementInView(); + r.Index = index; + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ElementInViewTable + + public partial class ShapeInView + { + public Vim.Format.Shape Shape => _Shape?.Value; + public int ShapeIndex => _Shape?.Index ?? EntityRelation.None; + public Vim.Format.View View => _View?.Value; + public int ViewIndex => _View?.Index ?? EntityRelation.None; + public ShapeInView() + { + _Shape = new Relation(); + _View = new Relation(); + } + } // class ShapeInView + + public partial class ShapeInViewTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ShapeInView; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ShapeInViewTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ShapeIndex = GetIndexColumnValues("index:Vim.Shape:Shape") ?? Array.Empty(); + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + } + public int[] Column_ShapeIndex { get; } + public int GetShapeIndex(int index) => Column_ShapeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Shape GetShape(int index) => _GetReferencedShape(GetShapeIndex(index)); + private Vim.Format.Shape _GetReferencedShape(int referencedIndex) => ParentTableSet.GetShape(referencedIndex); + public int[] Column_ViewIndex { get; } + public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetView(int index) => _GetReferencedView(GetViewIndex(index)); + private Vim.Format.View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public Vim.Format.ShapeInView Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ShapeInView(); + r.Index = index; + r._Shape = new Relation(GetShapeIndex(index), _GetReferencedShape); + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ShapeInViewTable + + public partial class AssetInView + { + public Vim.Format.Asset Asset => _Asset?.Value; + public int AssetIndex => _Asset?.Index ?? EntityRelation.None; + public Vim.Format.View View => _View?.Value; + public int ViewIndex => _View?.Index ?? EntityRelation.None; + public AssetInView() + { + _Asset = new Relation(); + _View = new Relation(); + } + } // class AssetInView + + public partial class AssetInViewTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.AssetInView; + public VimEntityTableSet ParentTableSet { get; } // can be null + public AssetInViewTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_AssetIndex = GetIndexColumnValues("index:Vim.Asset:Asset") ?? Array.Empty(); + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + } + public int[] Column_AssetIndex { get; } + public int GetAssetIndex(int index) => Column_AssetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Asset GetAsset(int index) => _GetReferencedAsset(GetAssetIndex(index)); + private Vim.Format.Asset _GetReferencedAsset(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); + public int[] Column_ViewIndex { get; } + public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetView(int index) => _GetReferencedView(GetViewIndex(index)); + private Vim.Format.View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public Vim.Format.AssetInView Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.AssetInView(); + r.Index = index; + r._Asset = new Relation(GetAssetIndex(index), _GetReferencedAsset); + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class AssetInViewTable + + public partial class AssetInViewSheet + { + public Vim.Format.Asset Asset => _Asset?.Value; + public int AssetIndex => _Asset?.Index ?? EntityRelation.None; + public Vim.Format.ViewSheet ViewSheet => _ViewSheet?.Value; + public int ViewSheetIndex => _ViewSheet?.Index ?? EntityRelation.None; + public AssetInViewSheet() + { + _Asset = new Relation(); + _ViewSheet = new Relation(); + } + } // class AssetInViewSheet + + public partial class AssetInViewSheetTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.AssetInViewSheet; + public VimEntityTableSet ParentTableSet { get; } // can be null + public AssetInViewSheetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_AssetIndex = GetIndexColumnValues("index:Vim.Asset:Asset") ?? Array.Empty(); + Column_ViewSheetIndex = GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty(); + } + public int[] Column_AssetIndex { get; } + public int GetAssetIndex(int index) => Column_AssetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Asset GetAsset(int index) => _GetReferencedAsset(GetAssetIndex(index)); + private Vim.Format.Asset _GetReferencedAsset(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); + public int[] Column_ViewSheetIndex { get; } + public int GetViewSheetIndex(int index) => Column_ViewSheetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ViewSheet GetViewSheet(int index) => _GetReferencedViewSheet(GetViewSheetIndex(index)); + private Vim.Format.ViewSheet _GetReferencedViewSheet(int referencedIndex) => ParentTableSet.GetViewSheet(referencedIndex); + public Vim.Format.AssetInViewSheet Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.AssetInViewSheet(); + r.Index = index; + r._Asset = new Relation(GetAssetIndex(index), _GetReferencedAsset); + r._ViewSheet = new Relation(GetViewSheetIndex(index), _GetReferencedViewSheet); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class AssetInViewSheetTable + + public partial class LevelInView + { + public Vim.Format.Level Level => _Level?.Value; + public int LevelIndex => _Level?.Index ?? EntityRelation.None; + public Vim.Format.View View => _View?.Value; + public int ViewIndex => _View?.Index ?? EntityRelation.None; + public LevelInView() + { + _Level = new Relation(); + _View = new Relation(); + } + } // class LevelInView + + public partial class LevelInViewTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.LevelInView; + public VimEntityTableSet ParentTableSet { get; } // can be null + public LevelInViewTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Extents_Min_X = GetDataColumnValues("double:Extents.Min.X") ?? Array.Empty(); + Column_Extents_Min_Y = GetDataColumnValues("double:Extents.Min.Y") ?? Array.Empty(); + Column_Extents_Min_Z = GetDataColumnValues("double:Extents.Min.Z") ?? Array.Empty(); + Column_Extents_Max_X = GetDataColumnValues("double:Extents.Max.X") ?? Array.Empty(); + Column_Extents_Max_Y = GetDataColumnValues("double:Extents.Max.Y") ?? Array.Empty(); + Column_Extents_Max_Z = GetDataColumnValues("double:Extents.Max.Z") ?? Array.Empty(); + Column_LevelIndex = GetIndexColumnValues("index:Vim.Level:Level") ?? Array.Empty(); + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + } + public Double[] Column_Extents_Min_X { get; } + public Double GetExtents_Min_X(int index, Double @default = default) => Column_Extents_Min_X.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Min_Y { get; } + public Double GetExtents_Min_Y(int index, Double @default = default) => Column_Extents_Min_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Min_Z { get; } + public Double GetExtents_Min_Z(int index, Double @default = default) => Column_Extents_Min_Z.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Max_X { get; } + public Double GetExtents_Max_X(int index, Double @default = default) => Column_Extents_Max_X.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Max_Y { get; } + public Double GetExtents_Max_Y(int index, Double @default = default) => Column_Extents_Max_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Max_Z { get; } + public Double GetExtents_Max_Z(int index, Double @default = default) => Column_Extents_Max_Z.ElementAtOrDefault(index, @default); + public int[] Column_LevelIndex { get; } + public int GetLevelIndex(int index) => Column_LevelIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Level GetLevel(int index) => _GetReferencedLevel(GetLevelIndex(index)); + private Vim.Format.Level _GetReferencedLevel(int referencedIndex) => ParentTableSet.GetLevel(referencedIndex); + public int[] Column_ViewIndex { get; } + public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetView(int index) => _GetReferencedView(GetViewIndex(index)); + private Vim.Format.View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public Vim.Format.LevelInView Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.LevelInView(); + r.Index = index; + r.Extents_Min_X = GetExtents_Min_X(index); + r.Extents_Min_Y = GetExtents_Min_Y(index); + r.Extents_Min_Z = GetExtents_Min_Z(index); + r.Extents_Max_X = GetExtents_Max_X(index); + r.Extents_Max_Y = GetExtents_Max_Y(index); + r.Extents_Max_Z = GetExtents_Max_Z(index); + r._Level = new Relation(GetLevelIndex(index), _GetReferencedLevel); + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class LevelInViewTable + + public partial class Camera + { + public Camera() + { + } + } // class Camera + + public partial class CameraTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Camera; + public VimEntityTableSet ParentTableSet { get; } // can be null + public CameraTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Id = GetDataColumnValues("int:Id") ?? Array.Empty(); + Column_IsPerspective = GetDataColumnValues("int:IsPerspective") ?? Array.Empty(); + Column_VerticalExtent = GetDataColumnValues("double:VerticalExtent") ?? Array.Empty(); + Column_HorizontalExtent = GetDataColumnValues("double:HorizontalExtent") ?? Array.Empty(); + Column_FarDistance = GetDataColumnValues("double:FarDistance") ?? Array.Empty(); + Column_NearDistance = GetDataColumnValues("double:NearDistance") ?? Array.Empty(); + Column_TargetDistance = GetDataColumnValues("double:TargetDistance") ?? Array.Empty(); + Column_RightOffset = GetDataColumnValues("double:RightOffset") ?? Array.Empty(); + Column_UpOffset = GetDataColumnValues("double:UpOffset") ?? Array.Empty(); + } + public Int32[] Column_Id { get; } + public Int32 GetId(int index, Int32 @default = default) => Column_Id.ElementAtOrDefault(index, @default); + public Int32[] Column_IsPerspective { get; } + public Int32 GetIsPerspective(int index, Int32 @default = default) => Column_IsPerspective.ElementAtOrDefault(index, @default); + public Double[] Column_VerticalExtent { get; } + public Double GetVerticalExtent(int index, Double @default = default) => Column_VerticalExtent.ElementAtOrDefault(index, @default); + public Double[] Column_HorizontalExtent { get; } + public Double GetHorizontalExtent(int index, Double @default = default) => Column_HorizontalExtent.ElementAtOrDefault(index, @default); + public Double[] Column_FarDistance { get; } + public Double GetFarDistance(int index, Double @default = default) => Column_FarDistance.ElementAtOrDefault(index, @default); + public Double[] Column_NearDistance { get; } + public Double GetNearDistance(int index, Double @default = default) => Column_NearDistance.ElementAtOrDefault(index, @default); + public Double[] Column_TargetDistance { get; } + public Double GetTargetDistance(int index, Double @default = default) => Column_TargetDistance.ElementAtOrDefault(index, @default); + public Double[] Column_RightOffset { get; } + public Double GetRightOffset(int index, Double @default = default) => Column_RightOffset.ElementAtOrDefault(index, @default); + public Double[] Column_UpOffset { get; } + public Double GetUpOffset(int index, Double @default = default) => Column_UpOffset.ElementAtOrDefault(index, @default); + public Vim.Format.Camera Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Camera(); + r.Index = index; + r.Id = GetId(index); + r.IsPerspective = GetIsPerspective(index); + r.VerticalExtent = GetVerticalExtent(index); + r.HorizontalExtent = GetHorizontalExtent(index); + r.FarDistance = GetFarDistance(index); + r.NearDistance = GetNearDistance(index); + r.TargetDistance = GetTargetDistance(index); + r.RightOffset = GetRightOffset(index); + r.UpOffset = GetUpOffset(index); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class CameraTable + + public partial class Material + { + public Vim.Format.Asset ColorTextureFile => _ColorTextureFile?.Value; + public int ColorTextureFileIndex => _ColorTextureFile?.Index ?? EntityRelation.None; + public Vim.Format.Asset NormalTextureFile => _NormalTextureFile?.Value; + public int NormalTextureFileIndex => _NormalTextureFile?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Material() + { + _ColorTextureFile = new Relation(); + _NormalTextureFile = new Relation(); + _Element = new Relation(); + } + } // class Material + + public partial class MaterialTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Material; + public VimEntityTableSet ParentTableSet { get; } // can be null + public MaterialTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_MaterialCategory = GetStringColumnValues("string:MaterialCategory") ?? Array.Empty(); + Column_Color_X = GetDataColumnValues("double:Color.X") ?? Array.Empty(); + Column_Color_Y = GetDataColumnValues("double:Color.Y") ?? Array.Empty(); + Column_Color_Z = GetDataColumnValues("double:Color.Z") ?? Array.Empty(); + Column_ColorUvScaling_X = GetDataColumnValues("double:ColorUvScaling.X") ?? Array.Empty(); + Column_ColorUvScaling_Y = GetDataColumnValues("double:ColorUvScaling.Y") ?? Array.Empty(); + Column_ColorUvOffset_X = GetDataColumnValues("double:ColorUvOffset.X") ?? Array.Empty(); + Column_ColorUvOffset_Y = GetDataColumnValues("double:ColorUvOffset.Y") ?? Array.Empty(); + Column_NormalUvScaling_X = GetDataColumnValues("double:NormalUvScaling.X") ?? Array.Empty(); + Column_NormalUvScaling_Y = GetDataColumnValues("double:NormalUvScaling.Y") ?? Array.Empty(); + Column_NormalUvOffset_X = GetDataColumnValues("double:NormalUvOffset.X") ?? Array.Empty(); + Column_NormalUvOffset_Y = GetDataColumnValues("double:NormalUvOffset.Y") ?? Array.Empty(); + Column_NormalAmount = GetDataColumnValues("double:NormalAmount") ?? Array.Empty(); + Column_Glossiness = GetDataColumnValues("double:Glossiness") ?? Array.Empty(); + Column_Smoothness = GetDataColumnValues("double:Smoothness") ?? Array.Empty(); + Column_Transparency = GetDataColumnValues("double:Transparency") ?? Array.Empty(); + Column_ColorTextureFileIndex = GetIndexColumnValues("index:Vim.Asset:ColorTextureFile") ?? Array.Empty(); + Column_NormalTextureFileIndex = GetIndexColumnValues("index:Vim.Asset:NormalTextureFile") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public String[] Column_MaterialCategory { get; } + public String GetMaterialCategory(int index, String @default = "") => Column_MaterialCategory.ElementAtOrDefault(index, @default); + public Double[] Column_Color_X { get; } + public Double GetColor_X(int index, Double @default = default) => Column_Color_X.ElementAtOrDefault(index, @default); + public Double[] Column_Color_Y { get; } + public Double GetColor_Y(int index, Double @default = default) => Column_Color_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Color_Z { get; } + public Double GetColor_Z(int index, Double @default = default) => Column_Color_Z.ElementAtOrDefault(index, @default); + public Double[] Column_ColorUvScaling_X { get; } + public Double GetColorUvScaling_X(int index, Double @default = default) => Column_ColorUvScaling_X.ElementAtOrDefault(index, @default); + public Double[] Column_ColorUvScaling_Y { get; } + public Double GetColorUvScaling_Y(int index, Double @default = default) => Column_ColorUvScaling_Y.ElementAtOrDefault(index, @default); + public Double[] Column_ColorUvOffset_X { get; } + public Double GetColorUvOffset_X(int index, Double @default = default) => Column_ColorUvOffset_X.ElementAtOrDefault(index, @default); + public Double[] Column_ColorUvOffset_Y { get; } + public Double GetColorUvOffset_Y(int index, Double @default = default) => Column_ColorUvOffset_Y.ElementAtOrDefault(index, @default); + public Double[] Column_NormalUvScaling_X { get; } + public Double GetNormalUvScaling_X(int index, Double @default = default) => Column_NormalUvScaling_X.ElementAtOrDefault(index, @default); + public Double[] Column_NormalUvScaling_Y { get; } + public Double GetNormalUvScaling_Y(int index, Double @default = default) => Column_NormalUvScaling_Y.ElementAtOrDefault(index, @default); + public Double[] Column_NormalUvOffset_X { get; } + public Double GetNormalUvOffset_X(int index, Double @default = default) => Column_NormalUvOffset_X.ElementAtOrDefault(index, @default); + public Double[] Column_NormalUvOffset_Y { get; } + public Double GetNormalUvOffset_Y(int index, Double @default = default) => Column_NormalUvOffset_Y.ElementAtOrDefault(index, @default); + public Double[] Column_NormalAmount { get; } + public Double GetNormalAmount(int index, Double @default = default) => Column_NormalAmount.ElementAtOrDefault(index, @default); + public Double[] Column_Glossiness { get; } + public Double GetGlossiness(int index, Double @default = default) => Column_Glossiness.ElementAtOrDefault(index, @default); + public Double[] Column_Smoothness { get; } + public Double GetSmoothness(int index, Double @default = default) => Column_Smoothness.ElementAtOrDefault(index, @default); + public Double[] Column_Transparency { get; } + public Double GetTransparency(int index, Double @default = default) => Column_Transparency.ElementAtOrDefault(index, @default); + public int[] Column_ColorTextureFileIndex { get; } + public int GetColorTextureFileIndex(int index) => Column_ColorTextureFileIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Asset GetColorTextureFile(int index) => _GetReferencedColorTextureFile(GetColorTextureFileIndex(index)); + private Vim.Format.Asset _GetReferencedColorTextureFile(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); + public int[] Column_NormalTextureFileIndex { get; } + public int GetNormalTextureFileIndex(int index) => Column_NormalTextureFileIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Asset GetNormalTextureFile(int index) => _GetReferencedNormalTextureFile(GetNormalTextureFileIndex(index)); + private Vim.Format.Asset _GetReferencedNormalTextureFile(int referencedIndex) => ParentTableSet.GetAsset(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Material Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Material(); + r.Index = index; + r.Name = GetName(index); + r.MaterialCategory = GetMaterialCategory(index); + r.Color_X = GetColor_X(index); + r.Color_Y = GetColor_Y(index); + r.Color_Z = GetColor_Z(index); + r.ColorUvScaling_X = GetColorUvScaling_X(index); + r.ColorUvScaling_Y = GetColorUvScaling_Y(index); + r.ColorUvOffset_X = GetColorUvOffset_X(index); + r.ColorUvOffset_Y = GetColorUvOffset_Y(index); + r.NormalUvScaling_X = GetNormalUvScaling_X(index); + r.NormalUvScaling_Y = GetNormalUvScaling_Y(index); + r.NormalUvOffset_X = GetNormalUvOffset_X(index); + r.NormalUvOffset_Y = GetNormalUvOffset_Y(index); + r.NormalAmount = GetNormalAmount(index); + r.Glossiness = GetGlossiness(index); + r.Smoothness = GetSmoothness(index); + r.Transparency = GetTransparency(index); + r._ColorTextureFile = new Relation(GetColorTextureFileIndex(index), _GetReferencedColorTextureFile); + r._NormalTextureFile = new Relation(GetNormalTextureFileIndex(index), _GetReferencedNormalTextureFile); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class MaterialTable + + public partial class MaterialInElement + { + public Vim.Format.Material Material => _Material?.Value; + public int MaterialIndex => _Material?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public MaterialInElement() + { + _Material = new Relation(); + _Element = new Relation(); + } + } // class MaterialInElement + + public partial class MaterialInElementTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.MaterialInElement; + public VimEntityTableSet ParentTableSet { get; } // can be null + public MaterialInElementTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Area = GetDataColumnValues("double:Area") ?? Array.Empty(); + Column_Volume = GetDataColumnValues("double:Volume") ?? Array.Empty(); + Column_IsPaint = GetDataColumnValues("byte:IsPaint") ?? Array.Empty(); + Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_Area { get; } + public Double GetArea(int index, Double @default = default) => Column_Area.ElementAtOrDefault(index, @default); + public Double[] Column_Volume { get; } + public Double GetVolume(int index, Double @default = default) => Column_Volume.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsPaint { get; } + public Boolean GetIsPaint(int index, Boolean @default = default) => Column_IsPaint.ElementAtOrDefault(index, @default); + public int[] Column_MaterialIndex { get; } + public int GetMaterialIndex(int index) => Column_MaterialIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Material GetMaterial(int index) => _GetReferencedMaterial(GetMaterialIndex(index)); + private Vim.Format.Material _GetReferencedMaterial(int referencedIndex) => ParentTableSet.GetMaterial(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.MaterialInElement Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.MaterialInElement(); + r.Index = index; + r.Area = GetArea(index); + r.Volume = GetVolume(index); + r.IsPaint = GetIsPaint(index); + r._Material = new Relation(GetMaterialIndex(index), _GetReferencedMaterial); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class MaterialInElementTable + + public partial class CompoundStructureLayer + { + public Vim.Format.Material Material => _Material?.Value; + public int MaterialIndex => _Material?.Index ?? EntityRelation.None; + public Vim.Format.CompoundStructure CompoundStructure => _CompoundStructure?.Value; + public int CompoundStructureIndex => _CompoundStructure?.Index ?? EntityRelation.None; + public CompoundStructureLayer() + { + _Material = new Relation(); + _CompoundStructure = new Relation(); + } + } // class CompoundStructureLayer + + public partial class CompoundStructureLayerTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.CompoundStructureLayer; + public VimEntityTableSet ParentTableSet { get; } // can be null + public CompoundStructureLayerTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_OrderIndex = GetDataColumnValues("int:OrderIndex") ?? Array.Empty(); + Column_Width = GetDataColumnValues("double:Width") ?? Array.Empty(); + Column_MaterialFunctionAssignment = GetStringColumnValues("string:MaterialFunctionAssignment") ?? Array.Empty(); + Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); + Column_CompoundStructureIndex = GetIndexColumnValues("index:Vim.CompoundStructure:CompoundStructure") ?? Array.Empty(); + } + public Int32[] Column_OrderIndex { get; } + public Int32 GetOrderIndex(int index, Int32 @default = default) => Column_OrderIndex.ElementAtOrDefault(index, @default); + public Double[] Column_Width { get; } + public Double GetWidth(int index, Double @default = default) => Column_Width.ElementAtOrDefault(index, @default); + public String[] Column_MaterialFunctionAssignment { get; } + public String GetMaterialFunctionAssignment(int index, String @default = "") => Column_MaterialFunctionAssignment.ElementAtOrDefault(index, @default); + public int[] Column_MaterialIndex { get; } + public int GetMaterialIndex(int index) => Column_MaterialIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Material GetMaterial(int index) => _GetReferencedMaterial(GetMaterialIndex(index)); + private Vim.Format.Material _GetReferencedMaterial(int referencedIndex) => ParentTableSet.GetMaterial(referencedIndex); + public int[] Column_CompoundStructureIndex { get; } + public int GetCompoundStructureIndex(int index) => Column_CompoundStructureIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.CompoundStructure GetCompoundStructure(int index) => _GetReferencedCompoundStructure(GetCompoundStructureIndex(index)); + private Vim.Format.CompoundStructure _GetReferencedCompoundStructure(int referencedIndex) => ParentTableSet.GetCompoundStructure(referencedIndex); + public Vim.Format.CompoundStructureLayer Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.CompoundStructureLayer(); + r.Index = index; + r.OrderIndex = GetOrderIndex(index); + r.Width = GetWidth(index); + r.MaterialFunctionAssignment = GetMaterialFunctionAssignment(index); + r._Material = new Relation(GetMaterialIndex(index), _GetReferencedMaterial); + r._CompoundStructure = new Relation(GetCompoundStructureIndex(index), _GetReferencedCompoundStructure); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class CompoundStructureLayerTable + + public partial class CompoundStructure + { + public Vim.Format.CompoundStructureLayer StructuralLayer => _StructuralLayer?.Value; + public int StructuralLayerIndex => _StructuralLayer?.Index ?? EntityRelation.None; + public CompoundStructure() + { + _StructuralLayer = new Relation(); + } + } // class CompoundStructure + + public partial class CompoundStructureTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.CompoundStructure; + public VimEntityTableSet ParentTableSet { get; } // can be null + public CompoundStructureTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Width = GetDataColumnValues("double:Width") ?? Array.Empty(); + Column_StructuralLayerIndex = GetIndexColumnValues("index:Vim.CompoundStructureLayer:StructuralLayer") ?? Array.Empty(); + } + public Double[] Column_Width { get; } + public Double GetWidth(int index, Double @default = default) => Column_Width.ElementAtOrDefault(index, @default); + public int[] Column_StructuralLayerIndex { get; } + public int GetStructuralLayerIndex(int index) => Column_StructuralLayerIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.CompoundStructureLayer GetStructuralLayer(int index) => _GetReferencedStructuralLayer(GetStructuralLayerIndex(index)); + private Vim.Format.CompoundStructureLayer _GetReferencedStructuralLayer(int referencedIndex) => ParentTableSet.GetCompoundStructureLayer(referencedIndex); + public Vim.Format.CompoundStructure Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.CompoundStructure(); + r.Index = index; + r.Width = GetWidth(index); + r._StructuralLayer = new Relation(GetStructuralLayerIndex(index), _GetReferencedStructuralLayer); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class CompoundStructureTable + + public partial class Node + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Node() + { + _Element = new Relation(); + } + } // class Node + + public partial class NodeTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Node; + public VimEntityTableSet ParentTableSet { get; } // can be null + public NodeTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Node Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Node(); + r.Index = index; + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class NodeTable + + public partial class Geometry + { + public Geometry() + { + } + } // class Geometry + + public partial class GeometryTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Geometry; + public VimEntityTableSet ParentTableSet { get; } // can be null + public GeometryTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Box_Min_X = GetDataColumnValues("float:Box.Min.X") ?? Array.Empty(); + Column_Box_Min_Y = GetDataColumnValues("float:Box.Min.Y") ?? Array.Empty(); + Column_Box_Min_Z = GetDataColumnValues("float:Box.Min.Z") ?? Array.Empty(); + Column_Box_Max_X = GetDataColumnValues("float:Box.Max.X") ?? Array.Empty(); + Column_Box_Max_Y = GetDataColumnValues("float:Box.Max.Y") ?? Array.Empty(); + Column_Box_Max_Z = GetDataColumnValues("float:Box.Max.Z") ?? Array.Empty(); + Column_VertexCount = GetDataColumnValues("int:VertexCount") ?? Array.Empty(); + Column_FaceCount = GetDataColumnValues("int:FaceCount") ?? Array.Empty(); + } + public Single[] Column_Box_Min_X { get; } + public Single GetBox_Min_X(int index, Single @default = default) => Column_Box_Min_X.ElementAtOrDefault(index, @default); + public Single[] Column_Box_Min_Y { get; } + public Single GetBox_Min_Y(int index, Single @default = default) => Column_Box_Min_Y.ElementAtOrDefault(index, @default); + public Single[] Column_Box_Min_Z { get; } + public Single GetBox_Min_Z(int index, Single @default = default) => Column_Box_Min_Z.ElementAtOrDefault(index, @default); + public Single[] Column_Box_Max_X { get; } + public Single GetBox_Max_X(int index, Single @default = default) => Column_Box_Max_X.ElementAtOrDefault(index, @default); + public Single[] Column_Box_Max_Y { get; } + public Single GetBox_Max_Y(int index, Single @default = default) => Column_Box_Max_Y.ElementAtOrDefault(index, @default); + public Single[] Column_Box_Max_Z { get; } + public Single GetBox_Max_Z(int index, Single @default = default) => Column_Box_Max_Z.ElementAtOrDefault(index, @default); + public Int32[] Column_VertexCount { get; } + public Int32 GetVertexCount(int index, Int32 @default = default) => Column_VertexCount.ElementAtOrDefault(index, @default); + public Int32[] Column_FaceCount { get; } + public Int32 GetFaceCount(int index, Int32 @default = default) => Column_FaceCount.ElementAtOrDefault(index, @default); + public Vim.Format.Geometry Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Geometry(); + r.Index = index; + r.Box_Min_X = GetBox_Min_X(index); + r.Box_Min_Y = GetBox_Min_Y(index); + r.Box_Min_Z = GetBox_Min_Z(index); + r.Box_Max_X = GetBox_Max_X(index); + r.Box_Max_Y = GetBox_Max_Y(index); + r.Box_Max_Z = GetBox_Max_Z(index); + r.VertexCount = GetVertexCount(index); + r.FaceCount = GetFaceCount(index); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class GeometryTable + + public partial class Shape + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Shape() + { + _Element = new Relation(); + } + } // class Shape + + public partial class ShapeTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Shape; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ShapeTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Shape Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Shape(); + r.Index = index; + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ShapeTable + + public partial class ShapeCollection + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public ShapeCollection() + { + _Element = new Relation(); + } + } // class ShapeCollection + + public partial class ShapeCollectionTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ShapeCollection; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ShapeCollectionTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.ShapeCollection Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ShapeCollection(); + r.Index = index; + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ShapeCollectionTable + + public partial class ShapeInShapeCollection + { + public Vim.Format.Shape Shape => _Shape?.Value; + public int ShapeIndex => _Shape?.Index ?? EntityRelation.None; + public Vim.Format.ShapeCollection ShapeCollection => _ShapeCollection?.Value; + public int ShapeCollectionIndex => _ShapeCollection?.Index ?? EntityRelation.None; + public ShapeInShapeCollection() + { + _Shape = new Relation(); + _ShapeCollection = new Relation(); + } + } // class ShapeInShapeCollection + + public partial class ShapeInShapeCollectionTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ShapeInShapeCollection; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ShapeInShapeCollectionTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ShapeIndex = GetIndexColumnValues("index:Vim.Shape:Shape") ?? Array.Empty(); + Column_ShapeCollectionIndex = GetIndexColumnValues("index:Vim.ShapeCollection:ShapeCollection") ?? Array.Empty(); + } + public int[] Column_ShapeIndex { get; } + public int GetShapeIndex(int index) => Column_ShapeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Shape GetShape(int index) => _GetReferencedShape(GetShapeIndex(index)); + private Vim.Format.Shape _GetReferencedShape(int referencedIndex) => ParentTableSet.GetShape(referencedIndex); + public int[] Column_ShapeCollectionIndex { get; } + public int GetShapeCollectionIndex(int index) => Column_ShapeCollectionIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ShapeCollection GetShapeCollection(int index) => _GetReferencedShapeCollection(GetShapeCollectionIndex(index)); + private Vim.Format.ShapeCollection _GetReferencedShapeCollection(int referencedIndex) => ParentTableSet.GetShapeCollection(referencedIndex); + public Vim.Format.ShapeInShapeCollection Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ShapeInShapeCollection(); + r.Index = index; + r._Shape = new Relation(GetShapeIndex(index), _GetReferencedShape); + r._ShapeCollection = new Relation(GetShapeCollectionIndex(index), _GetReferencedShapeCollection); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ShapeInShapeCollectionTable + + public partial class System + { + public Vim.Format.FamilyType FamilyType => _FamilyType?.Value; + public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public System() + { + _FamilyType = new Relation(); + _Element = new Relation(); + } + } // class System + + public partial class SystemTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.System; + public VimEntityTableSet ParentTableSet { get; } // can be null + public SystemTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_SystemType = GetDataColumnValues("int:SystemType") ?? Array.Empty(); + Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Int32[] Column_SystemType { get; } + public Int32 GetSystemType(int index, Int32 @default = default) => Column_SystemType.ElementAtOrDefault(index, @default); + public int[] Column_FamilyTypeIndex { get; } + public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); + private Vim.Format.FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.System Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.System(); + r.Index = index; + r.SystemType = GetSystemType(index); + r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class SystemTable + + public partial class ElementInSystem + { + public Vim.Format.System System => _System?.Value; + public int SystemIndex => _System?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public ElementInSystem() + { + _System = new Relation(); + _Element = new Relation(); + } + } // class ElementInSystem + + public partial class ElementInSystemTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ElementInSystem; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ElementInSystemTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Roles = GetDataColumnValues("int:Roles") ?? Array.Empty(); + Column_SystemIndex = GetIndexColumnValues("index:Vim.System:System") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Int32[] Column_Roles { get; } + public Int32 GetRoles(int index, Int32 @default = default) => Column_Roles.ElementAtOrDefault(index, @default); + public int[] Column_SystemIndex { get; } + public int GetSystemIndex(int index) => Column_SystemIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.System GetSystem(int index) => _GetReferencedSystem(GetSystemIndex(index)); + private Vim.Format.System _GetReferencedSystem(int referencedIndex) => ParentTableSet.GetSystem(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.ElementInSystem Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ElementInSystem(); + r.Index = index; + r.Roles = GetRoles(index); + r._System = new Relation(GetSystemIndex(index), _GetReferencedSystem); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ElementInSystemTable + + public partial class Warning + { + public Vim.Format.BimDocument BimDocument => _BimDocument?.Value; + public int BimDocumentIndex => _BimDocument?.Index ?? EntityRelation.None; + public Warning() + { + _BimDocument = new Relation(); + } + } // class Warning + + public partial class WarningTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.Warning; + public VimEntityTableSet ParentTableSet { get; } // can be null + public WarningTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Guid = GetStringColumnValues("string:Guid") ?? Array.Empty(); + Column_Severity = GetStringColumnValues("string:Severity") ?? Array.Empty(); + Column_Description = GetStringColumnValues("string:Description") ?? Array.Empty(); + Column_BimDocumentIndex = GetIndexColumnValues("index:Vim.BimDocument:BimDocument") ?? Array.Empty(); + } + public String[] Column_Guid { get; } + public String GetGuid(int index, String @default = "") => Column_Guid.ElementAtOrDefault(index, @default); + public String[] Column_Severity { get; } + public String GetSeverity(int index, String @default = "") => Column_Severity.ElementAtOrDefault(index, @default); + public String[] Column_Description { get; } + public String GetDescription(int index, String @default = "") => Column_Description.ElementAtOrDefault(index, @default); + public int[] Column_BimDocumentIndex { get; } + public int GetBimDocumentIndex(int index) => Column_BimDocumentIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.BimDocument GetBimDocument(int index) => _GetReferencedBimDocument(GetBimDocumentIndex(index)); + private Vim.Format.BimDocument _GetReferencedBimDocument(int referencedIndex) => ParentTableSet.GetBimDocument(referencedIndex); + public Vim.Format.Warning Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Warning(); + r.Index = index; + r.Guid = GetGuid(index); + r.Severity = GetSeverity(index); + r.Description = GetDescription(index); + r._BimDocument = new Relation(GetBimDocumentIndex(index), _GetReferencedBimDocument); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class WarningTable + + public partial class ElementInWarning + { + public Vim.Format.Warning Warning => _Warning?.Value; + public int WarningIndex => _Warning?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public ElementInWarning() + { + _Warning = new Relation(); + _Element = new Relation(); + } + } // class ElementInWarning + + public partial class ElementInWarningTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ElementInWarning; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ElementInWarningTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_WarningIndex = GetIndexColumnValues("index:Vim.Warning:Warning") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_WarningIndex { get; } + public int GetWarningIndex(int index) => Column_WarningIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Warning GetWarning(int index) => _GetReferencedWarning(GetWarningIndex(index)); + private Vim.Format.Warning _GetReferencedWarning(int referencedIndex) => ParentTableSet.GetWarning(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.ElementInWarning Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ElementInWarning(); + r.Index = index; + r._Warning = new Relation(GetWarningIndex(index), _GetReferencedWarning); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ElementInWarningTable + + public partial class BasePoint + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public BasePoint() + { + _Element = new Relation(); + } + } // class BasePoint + + public partial class BasePointTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.BasePoint; + public VimEntityTableSet ParentTableSet { get; } // can be null + public BasePointTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_IsSurveyPoint = GetDataColumnValues("byte:IsSurveyPoint") ?? Array.Empty(); + Column_Position_X = GetDataColumnValues("double:Position.X") ?? Array.Empty(); + Column_Position_Y = GetDataColumnValues("double:Position.Y") ?? Array.Empty(); + Column_Position_Z = GetDataColumnValues("double:Position.Z") ?? Array.Empty(); + Column_SharedPosition_X = GetDataColumnValues("double:SharedPosition.X") ?? Array.Empty(); + Column_SharedPosition_Y = GetDataColumnValues("double:SharedPosition.Y") ?? Array.Empty(); + Column_SharedPosition_Z = GetDataColumnValues("double:SharedPosition.Z") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Boolean[] Column_IsSurveyPoint { get; } + public Boolean GetIsSurveyPoint(int index, Boolean @default = default) => Column_IsSurveyPoint.ElementAtOrDefault(index, @default); + public Double[] Column_Position_X { get; } + public Double GetPosition_X(int index, Double @default = default) => Column_Position_X.ElementAtOrDefault(index, @default); + public Double[] Column_Position_Y { get; } + public Double GetPosition_Y(int index, Double @default = default) => Column_Position_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Position_Z { get; } + public Double GetPosition_Z(int index, Double @default = default) => Column_Position_Z.ElementAtOrDefault(index, @default); + public Double[] Column_SharedPosition_X { get; } + public Double GetSharedPosition_X(int index, Double @default = default) => Column_SharedPosition_X.ElementAtOrDefault(index, @default); + public Double[] Column_SharedPosition_Y { get; } + public Double GetSharedPosition_Y(int index, Double @default = default) => Column_SharedPosition_Y.ElementAtOrDefault(index, @default); + public Double[] Column_SharedPosition_Z { get; } + public Double GetSharedPosition_Z(int index, Double @default = default) => Column_SharedPosition_Z.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.BasePoint Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.BasePoint(); + r.Index = index; + r.IsSurveyPoint = GetIsSurveyPoint(index); + r.Position_X = GetPosition_X(index); + r.Position_Y = GetPosition_Y(index); + r.Position_Z = GetPosition_Z(index); + r.SharedPosition_X = GetSharedPosition_X(index); + r.SharedPosition_Y = GetSharedPosition_Y(index); + r.SharedPosition_Z = GetSharedPosition_Z(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class BasePointTable + + public partial class PhaseFilter + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public PhaseFilter() + { + _Element = new Relation(); + } + } // class PhaseFilter + + public partial class PhaseFilterTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.PhaseFilter; + public VimEntityTableSet ParentTableSet { get; } // can be null + public PhaseFilterTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_New = GetDataColumnValues("int:New") ?? Array.Empty(); + Column_Existing = GetDataColumnValues("int:Existing") ?? Array.Empty(); + Column_Demolished = GetDataColumnValues("int:Demolished") ?? Array.Empty(); + Column_Temporary = GetDataColumnValues("int:Temporary") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Int32[] Column_New { get; } + public Int32 GetNew(int index, Int32 @default = default) => Column_New.ElementAtOrDefault(index, @default); + public Int32[] Column_Existing { get; } + public Int32 GetExisting(int index, Int32 @default = default) => Column_Existing.ElementAtOrDefault(index, @default); + public Int32[] Column_Demolished { get; } + public Int32 GetDemolished(int index, Int32 @default = default) => Column_Demolished.ElementAtOrDefault(index, @default); + public Int32[] Column_Temporary { get; } + public Int32 GetTemporary(int index, Int32 @default = default) => Column_Temporary.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.PhaseFilter Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.PhaseFilter(); + r.Index = index; + r.New = GetNew(index); + r.Existing = GetExisting(index); + r.Demolished = GetDemolished(index); + r.Temporary = GetTemporary(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class PhaseFilterTable + + public partial class Grid + { + public Vim.Format.FamilyType FamilyType => _FamilyType?.Value; + public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Grid() + { + _FamilyType = new Relation(); + _Element = new Relation(); + } + } // class Grid + + public partial class GridTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Grid; + public VimEntityTableSet ParentTableSet { get; } // can be null + public GridTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_StartPoint_X = GetDataColumnValues("double:StartPoint.X") ?? Array.Empty(); + Column_StartPoint_Y = GetDataColumnValues("double:StartPoint.Y") ?? Array.Empty(); + Column_StartPoint_Z = GetDataColumnValues("double:StartPoint.Z") ?? Array.Empty(); + Column_EndPoint_X = GetDataColumnValues("double:EndPoint.X") ?? Array.Empty(); + Column_EndPoint_Y = GetDataColumnValues("double:EndPoint.Y") ?? Array.Empty(); + Column_EndPoint_Z = GetDataColumnValues("double:EndPoint.Z") ?? Array.Empty(); + Column_IsCurved = GetDataColumnValues("byte:IsCurved") ?? Array.Empty(); + Column_Extents_Min_X = GetDataColumnValues("double:Extents.Min.X") ?? Array.Empty(); + Column_Extents_Min_Y = GetDataColumnValues("double:Extents.Min.Y") ?? Array.Empty(); + Column_Extents_Min_Z = GetDataColumnValues("double:Extents.Min.Z") ?? Array.Empty(); + Column_Extents_Max_X = GetDataColumnValues("double:Extents.Max.X") ?? Array.Empty(); + Column_Extents_Max_Y = GetDataColumnValues("double:Extents.Max.Y") ?? Array.Empty(); + Column_Extents_Max_Z = GetDataColumnValues("double:Extents.Max.Z") ?? Array.Empty(); + Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_StartPoint_X { get; } + public Double GetStartPoint_X(int index, Double @default = default) => Column_StartPoint_X.ElementAtOrDefault(index, @default); + public Double[] Column_StartPoint_Y { get; } + public Double GetStartPoint_Y(int index, Double @default = default) => Column_StartPoint_Y.ElementAtOrDefault(index, @default); + public Double[] Column_StartPoint_Z { get; } + public Double GetStartPoint_Z(int index, Double @default = default) => Column_StartPoint_Z.ElementAtOrDefault(index, @default); + public Double[] Column_EndPoint_X { get; } + public Double GetEndPoint_X(int index, Double @default = default) => Column_EndPoint_X.ElementAtOrDefault(index, @default); + public Double[] Column_EndPoint_Y { get; } + public Double GetEndPoint_Y(int index, Double @default = default) => Column_EndPoint_Y.ElementAtOrDefault(index, @default); + public Double[] Column_EndPoint_Z { get; } + public Double GetEndPoint_Z(int index, Double @default = default) => Column_EndPoint_Z.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsCurved { get; } + public Boolean GetIsCurved(int index, Boolean @default = default) => Column_IsCurved.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Min_X { get; } + public Double GetExtents_Min_X(int index, Double @default = default) => Column_Extents_Min_X.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Min_Y { get; } + public Double GetExtents_Min_Y(int index, Double @default = default) => Column_Extents_Min_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Min_Z { get; } + public Double GetExtents_Min_Z(int index, Double @default = default) => Column_Extents_Min_Z.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Max_X { get; } + public Double GetExtents_Max_X(int index, Double @default = default) => Column_Extents_Max_X.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Max_Y { get; } + public Double GetExtents_Max_Y(int index, Double @default = default) => Column_Extents_Max_Y.ElementAtOrDefault(index, @default); + public Double[] Column_Extents_Max_Z { get; } + public Double GetExtents_Max_Z(int index, Double @default = default) => Column_Extents_Max_Z.ElementAtOrDefault(index, @default); + public int[] Column_FamilyTypeIndex { get; } + public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); + private Vim.Format.FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Grid Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Grid(); + r.Index = index; + r.StartPoint_X = GetStartPoint_X(index); + r.StartPoint_Y = GetStartPoint_Y(index); + r.StartPoint_Z = GetStartPoint_Z(index); + r.EndPoint_X = GetEndPoint_X(index); + r.EndPoint_Y = GetEndPoint_Y(index); + r.EndPoint_Z = GetEndPoint_Z(index); + r.IsCurved = GetIsCurved(index); + r.Extents_Min_X = GetExtents_Min_X(index); + r.Extents_Min_Y = GetExtents_Min_Y(index); + r.Extents_Min_Z = GetExtents_Min_Z(index); + r.Extents_Max_X = GetExtents_Max_X(index); + r.Extents_Max_Y = GetExtents_Max_Y(index); + r.Extents_Max_Z = GetExtents_Max_Z(index); + r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class GridTable + + public partial class Area + { + public Vim.Format.AreaScheme AreaScheme => _AreaScheme?.Value; + public int AreaSchemeIndex => _AreaScheme?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Area() + { + _AreaScheme = new Relation(); + _Element = new Relation(); + } + } // class Area + + public partial class AreaTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Area; + public VimEntityTableSet ParentTableSet { get; } // can be null + public AreaTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Value = GetDataColumnValues("double:Value") ?? Array.Empty(); + Column_Perimeter = GetDataColumnValues("double:Perimeter") ?? Array.Empty(); + Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); + Column_IsGrossInterior = GetDataColumnValues("byte:IsGrossInterior") ?? Array.Empty(); + Column_AreaSchemeIndex = GetIndexColumnValues("index:Vim.AreaScheme:AreaScheme") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_Value { get; } + public Double GetValue(int index, Double @default = default) => Column_Value.ElementAtOrDefault(index, @default); + public Double[] Column_Perimeter { get; } + public Double GetPerimeter(int index, Double @default = default) => Column_Perimeter.ElementAtOrDefault(index, @default); + public String[] Column_Number { get; } + public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); + public Boolean[] Column_IsGrossInterior { get; } + public Boolean GetIsGrossInterior(int index, Boolean @default = default) => Column_IsGrossInterior.ElementAtOrDefault(index, @default); + public int[] Column_AreaSchemeIndex { get; } + public int GetAreaSchemeIndex(int index) => Column_AreaSchemeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.AreaScheme GetAreaScheme(int index) => _GetReferencedAreaScheme(GetAreaSchemeIndex(index)); + private Vim.Format.AreaScheme _GetReferencedAreaScheme(int referencedIndex) => ParentTableSet.GetAreaScheme(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Area Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Area(); + r.Index = index; + r.Value = GetValue(index); + r.Perimeter = GetPerimeter(index); + r.Number = GetNumber(index); + r.IsGrossInterior = GetIsGrossInterior(index); + r._AreaScheme = new Relation(GetAreaSchemeIndex(index), _GetReferencedAreaScheme); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class AreaTable + + public partial class AreaScheme + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public AreaScheme() + { + _Element = new Relation(); + } + } // class AreaScheme + + public partial class AreaSchemeTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.AreaScheme; + public VimEntityTableSet ParentTableSet { get; } // can be null + public AreaSchemeTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_IsGrossBuildingArea = GetDataColumnValues("byte:IsGrossBuildingArea") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Boolean[] Column_IsGrossBuildingArea { get; } + public Boolean GetIsGrossBuildingArea(int index, Boolean @default = default) => Column_IsGrossBuildingArea.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.AreaScheme Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.AreaScheme(); + r.Index = index; + r.IsGrossBuildingArea = GetIsGrossBuildingArea(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class AreaSchemeTable + + public partial class Schedule + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Schedule() + { + _Element = new Relation(); + } + } // class Schedule + + public partial class ScheduleTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Schedule; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ScheduleTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Schedule Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Schedule(); + r.Index = index; + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ScheduleTable + + public partial class ScheduleColumn + { + public Vim.Format.Schedule Schedule => _Schedule?.Value; + public int ScheduleIndex => _Schedule?.Index ?? EntityRelation.None; + public ScheduleColumn() + { + _Schedule = new Relation(); + } + } // class ScheduleColumn + + public partial class ScheduleColumnTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ScheduleColumn; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ScheduleColumnTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Name = GetStringColumnValues("string:Name") ?? Array.Empty(); + Column_ColumnIndex = GetDataColumnValues("int:ColumnIndex") ?? Array.Empty(); + Column_ScheduleIndex = GetIndexColumnValues("index:Vim.Schedule:Schedule") ?? Array.Empty(); + } + public String[] Column_Name { get; } + public String GetName(int index, String @default = "") => Column_Name.ElementAtOrDefault(index, @default); + public Int32[] Column_ColumnIndex { get; } + public Int32 GetColumnIndex(int index, Int32 @default = default) => Column_ColumnIndex.ElementAtOrDefault(index, @default); + public int[] Column_ScheduleIndex { get; } + public int GetScheduleIndex(int index) => Column_ScheduleIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Schedule GetSchedule(int index) => _GetReferencedSchedule(GetScheduleIndex(index)); + private Vim.Format.Schedule _GetReferencedSchedule(int referencedIndex) => ParentTableSet.GetSchedule(referencedIndex); + public Vim.Format.ScheduleColumn Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ScheduleColumn(); + r.Index = index; + r.Name = GetName(index); + r.ColumnIndex = GetColumnIndex(index); + r._Schedule = new Relation(GetScheduleIndex(index), _GetReferencedSchedule); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ScheduleColumnTable + + public partial class ScheduleCell + { + public Vim.Format.ScheduleColumn ScheduleColumn => _ScheduleColumn?.Value; + public int ScheduleColumnIndex => _ScheduleColumn?.Index ?? EntityRelation.None; + public ScheduleCell() + { + _ScheduleColumn = new Relation(); + } + } // class ScheduleCell + + public partial class ScheduleCellTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ScheduleCell; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ScheduleCellTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Value = GetStringColumnValues("string:Value") ?? Array.Empty(); + Column_RowIndex = GetDataColumnValues("int:RowIndex") ?? Array.Empty(); + Column_ScheduleColumnIndex = GetIndexColumnValues("index:Vim.ScheduleColumn:ScheduleColumn") ?? Array.Empty(); + } + public String[] Column_Value { get; } + public String GetValue(int index, String @default = "") => Column_Value.ElementAtOrDefault(index, @default); + public Int32[] Column_RowIndex { get; } + public Int32 GetRowIndex(int index, Int32 @default = default) => Column_RowIndex.ElementAtOrDefault(index, @default); + public int[] Column_ScheduleColumnIndex { get; } + public int GetScheduleColumnIndex(int index) => Column_ScheduleColumnIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ScheduleColumn GetScheduleColumn(int index) => _GetReferencedScheduleColumn(GetScheduleColumnIndex(index)); + private Vim.Format.ScheduleColumn _GetReferencedScheduleColumn(int referencedIndex) => ParentTableSet.GetScheduleColumn(referencedIndex); + public Vim.Format.ScheduleCell Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ScheduleCell(); + r.Index = index; + r.Value = GetValue(index); + r.RowIndex = GetRowIndex(index); + r._ScheduleColumn = new Relation(GetScheduleColumnIndex(index), _GetReferencedScheduleColumn); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ScheduleCellTable + + public partial class ViewSheetSet + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public ViewSheetSet() + { + _Element = new Relation(); + } + } // class ViewSheetSet + + public partial class ViewSheetSetTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.ViewSheetSet; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ViewSheetSetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.ViewSheetSet Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ViewSheetSet(); + r.Index = index; + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ViewSheetSetTable + + public partial class ViewSheet + { + public Vim.Format.FamilyType FamilyType => _FamilyType?.Value; + public int FamilyTypeIndex => _FamilyType?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public ViewSheet() + { + _FamilyType = new Relation(); + _Element = new Relation(); + } + } // class ViewSheet + + public partial class ViewSheetTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.ViewSheet; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ViewSheetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_FamilyTypeIndex = GetIndexColumnValues("index:Vim.FamilyType:FamilyType") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public int[] Column_FamilyTypeIndex { get; } + public int GetFamilyTypeIndex(int index) => Column_FamilyTypeIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.FamilyType GetFamilyType(int index) => _GetReferencedFamilyType(GetFamilyTypeIndex(index)); + private Vim.Format.FamilyType _GetReferencedFamilyType(int referencedIndex) => ParentTableSet.GetFamilyType(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.ViewSheet Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ViewSheet(); + r.Index = index; + r._FamilyType = new Relation(GetFamilyTypeIndex(index), _GetReferencedFamilyType); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ViewSheetTable + + public partial class ViewSheetInViewSheetSet + { + public Vim.Format.ViewSheet ViewSheet => _ViewSheet?.Value; + public int ViewSheetIndex => _ViewSheet?.Index ?? EntityRelation.None; + public Vim.Format.ViewSheetSet ViewSheetSet => _ViewSheetSet?.Value; + public int ViewSheetSetIndex => _ViewSheetSet?.Index ?? EntityRelation.None; + public ViewSheetInViewSheetSet() + { + _ViewSheet = new Relation(); + _ViewSheetSet = new Relation(); + } + } // class ViewSheetInViewSheetSet + + public partial class ViewSheetInViewSheetSetTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ViewSheetInViewSheetSet; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ViewSheetInViewSheetSetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ViewSheetIndex = GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty(); + Column_ViewSheetSetIndex = GetIndexColumnValues("index:Vim.ViewSheetSet:ViewSheetSet") ?? Array.Empty(); + } + public int[] Column_ViewSheetIndex { get; } + public int GetViewSheetIndex(int index) => Column_ViewSheetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ViewSheet GetViewSheet(int index) => _GetReferencedViewSheet(GetViewSheetIndex(index)); + private Vim.Format.ViewSheet _GetReferencedViewSheet(int referencedIndex) => ParentTableSet.GetViewSheet(referencedIndex); + public int[] Column_ViewSheetSetIndex { get; } + public int GetViewSheetSetIndex(int index) => Column_ViewSheetSetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ViewSheetSet GetViewSheetSet(int index) => _GetReferencedViewSheetSet(GetViewSheetSetIndex(index)); + private Vim.Format.ViewSheetSet _GetReferencedViewSheetSet(int referencedIndex) => ParentTableSet.GetViewSheetSet(referencedIndex); + public Vim.Format.ViewSheetInViewSheetSet Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ViewSheetInViewSheetSet(); + r.Index = index; + r._ViewSheet = new Relation(GetViewSheetIndex(index), _GetReferencedViewSheet); + r._ViewSheetSet = new Relation(GetViewSheetSetIndex(index), _GetReferencedViewSheetSet); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ViewSheetInViewSheetSetTable + + public partial class ViewInViewSheetSet + { + public Vim.Format.View View => _View?.Value; + public int ViewIndex => _View?.Index ?? EntityRelation.None; + public Vim.Format.ViewSheetSet ViewSheetSet => _ViewSheetSet?.Value; + public int ViewSheetSetIndex => _ViewSheetSet?.Index ?? EntityRelation.None; + public ViewInViewSheetSet() + { + _View = new Relation(); + _ViewSheetSet = new Relation(); + } + } // class ViewInViewSheetSet + + public partial class ViewInViewSheetSetTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ViewInViewSheetSet; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ViewInViewSheetSetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + Column_ViewSheetSetIndex = GetIndexColumnValues("index:Vim.ViewSheetSet:ViewSheetSet") ?? Array.Empty(); + } + public int[] Column_ViewIndex { get; } + public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetView(int index) => _GetReferencedView(GetViewIndex(index)); + private Vim.Format.View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public int[] Column_ViewSheetSetIndex { get; } + public int GetViewSheetSetIndex(int index) => Column_ViewSheetSetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ViewSheetSet GetViewSheetSet(int index) => _GetReferencedViewSheetSet(GetViewSheetSetIndex(index)); + private Vim.Format.ViewSheetSet _GetReferencedViewSheetSet(int referencedIndex) => ParentTableSet.GetViewSheetSet(referencedIndex); + public Vim.Format.ViewInViewSheetSet Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ViewInViewSheetSet(); + r.Index = index; + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + r._ViewSheetSet = new Relation(GetViewSheetSetIndex(index), _GetReferencedViewSheetSet); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ViewInViewSheetSetTable + + public partial class ViewInViewSheet + { + public Vim.Format.View View => _View?.Value; + public int ViewIndex => _View?.Index ?? EntityRelation.None; + public Vim.Format.ViewSheet ViewSheet => _ViewSheet?.Value; + public int ViewSheetIndex => _ViewSheet?.Index ?? EntityRelation.None; + public ViewInViewSheet() + { + _View = new Relation(); + _ViewSheet = new Relation(); + } + } // class ViewInViewSheet + + public partial class ViewInViewSheetTable : VimEntityTable, IEnumerable + { + public const string TableName = VimEntityTableNames.ViewInViewSheet; + public VimEntityTableSet ParentTableSet { get; } // can be null + public ViewInViewSheetTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + Column_ViewSheetIndex = GetIndexColumnValues("index:Vim.ViewSheet:ViewSheet") ?? Array.Empty(); + } + public int[] Column_ViewIndex { get; } + public int GetViewIndex(int index) => Column_ViewIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.View GetView(int index) => _GetReferencedView(GetViewIndex(index)); + private Vim.Format.View _GetReferencedView(int referencedIndex) => ParentTableSet.GetView(referencedIndex); + public int[] Column_ViewSheetIndex { get; } + public int GetViewSheetIndex(int index) => Column_ViewSheetIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.ViewSheet GetViewSheet(int index) => _GetReferencedViewSheet(GetViewSheetIndex(index)); + private Vim.Format.ViewSheet _GetReferencedViewSheet(int referencedIndex) => ParentTableSet.GetViewSheet(referencedIndex); + public Vim.Format.ViewInViewSheet Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.ViewInViewSheet(); + r.Index = index; + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + r._ViewSheet = new Relation(GetViewSheetIndex(index), _GetReferencedViewSheet); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class ViewInViewSheetTable + + public partial class Site + { + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Site() + { + _Element = new Relation(); + } + } // class Site + + public partial class SiteTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Site; + public VimEntityTableSet ParentTableSet { get; } // can be null + public SiteTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Latitude = GetDataColumnValues("double:Latitude") ?? Array.Empty(); + Column_Longitude = GetDataColumnValues("double:Longitude") ?? Array.Empty(); + Column_Address = GetStringColumnValues("string:Address") ?? Array.Empty(); + Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); + Column_Number = GetStringColumnValues("string:Number") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_Latitude { get; } + public Double GetLatitude(int index, Double @default = default) => Column_Latitude.ElementAtOrDefault(index, @default); + public Double[] Column_Longitude { get; } + public Double GetLongitude(int index, Double @default = default) => Column_Longitude.ElementAtOrDefault(index, @default); + public String[] Column_Address { get; } + public String GetAddress(int index, String @default = "") => Column_Address.ElementAtOrDefault(index, @default); + public Double[] Column_Elevation { get; } + public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); + public String[] Column_Number { get; } + public String GetNumber(int index, String @default = "") => Column_Number.ElementAtOrDefault(index, @default); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Site Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Site(); + r.Index = index; + r.Latitude = GetLatitude(index); + r.Longitude = GetLongitude(index); + r.Address = GetAddress(index); + r.Elevation = GetElevation(index); + r.Number = GetNumber(index); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class SiteTable + + public partial class Building + { + public Vim.Format.Site Site => _Site?.Value; + public int SiteIndex => _Site?.Index ?? EntityRelation.None; + public Vim.Format.Element Element => _Element?.Value; + public int ElementIndex => _Element?.Index ?? EntityRelation.None; + public Building() + { + _Site = new Relation(); + _Element = new Relation(); + } + } // class Building + + public partial class BuildingTable : VimEntityTable, IEnumerable, IElementKindTable + { + public const string TableName = VimEntityTableNames.Building; + public VimEntityTableSet ParentTableSet { get; } // can be null + public BuildingTable(VimEntityTableData tableData, string[] stringTable, VimEntityTableSet parentTableSet = null) : base(tableData, stringTable) + { + ParentTableSet = parentTableSet; + Column_Elevation = GetDataColumnValues("double:Elevation") ?? Array.Empty(); + Column_TerrainElevation = GetDataColumnValues("double:TerrainElevation") ?? Array.Empty(); + Column_Address = GetStringColumnValues("string:Address") ?? Array.Empty(); + Column_SiteIndex = GetIndexColumnValues("index:Vim.Site:Site") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + public Double[] Column_Elevation { get; } + public Double GetElevation(int index, Double @default = default) => Column_Elevation.ElementAtOrDefault(index, @default); + public Double[] Column_TerrainElevation { get; } + public Double GetTerrainElevation(int index, Double @default = default) => Column_TerrainElevation.ElementAtOrDefault(index, @default); + public String[] Column_Address { get; } + public String GetAddress(int index, String @default = "") => Column_Address.ElementAtOrDefault(index, @default); + public int[] Column_SiteIndex { get; } + public int GetSiteIndex(int index) => Column_SiteIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Site GetSite(int index) => _GetReferencedSite(GetSiteIndex(index)); + private Vim.Format.Site _GetReferencedSite(int referencedIndex) => ParentTableSet.GetSite(referencedIndex); + public int[] Column_ElementIndex { get; } + public int GetElementIndex(int index) => Column_ElementIndex.ElementAtOrDefault(index, EntityRelation.None); + public Vim.Format.Element GetElement(int index) => _GetReferencedElement(GetElementIndex(index)); + private Vim.Format.Element _GetReferencedElement(int referencedIndex) => ParentTableSet.GetElement(referencedIndex); + public Vim.Format.Building Get(int index) + { + if (index < 0) return null; + var r = new Vim.Format.Building(); + r.Index = index; + r.Elevation = GetElevation(index); + r.TerrainElevation = GetTerrainElevation(index); + r.Address = GetAddress(index); + r._Site = new Relation(GetSiteIndex(index), _GetReferencedSite); + r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); + return r; + } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class BuildingTable + + public static class VimEntitySetBuilderExtensions + { + public static VimEntityTableBuilder ToAssetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Asset); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BufferName; } + tb.AddStringColumn("string:BufferName", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToDisplayUnitTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.DisplayUnit); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Spec; } + tb.AddStringColumn("string:Spec", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Type; } + tb.AddStringColumn("string:Type", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Label; } + tb.AddStringColumn("string:Label", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToParameterDescriptorTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ParameterDescriptor); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Group; } + tb.AddStringColumn("string:Group", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ParameterType; } + tb.AddStringColumn("string:ParameterType", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsInstance; } + tb.AddDataColumn("byte:IsInstance", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsShared; } + tb.AddDataColumn("byte:IsShared", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsReadOnly; } + tb.AddDataColumn("byte:IsReadOnly", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Flags; } + tb.AddDataColumn("int:Flags", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Guid; } + tb.AddStringColumn("string:Guid", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StorageType; } + tb.AddDataColumn("int:StorageType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._DisplayUnit?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.DisplayUnit:DisplayUnit", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToParameterTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Parameter); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Value; } + tb.AddStringColumn("string:Value", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ParameterDescriptor?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ParameterDescriptor:ParameterDescriptor", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToElementTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Element); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int64[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } + tb.AddDataColumn("long:Id", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Type; } + tb.AddStringColumn("string:Type", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UniqueId; } + tb.AddStringColumn("string:UniqueId", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Location_X; } + tb.AddDataColumn("float:Location.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Location_Y; } + tb.AddDataColumn("float:Location.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Location_Z; } + tb.AddDataColumn("float:Location.Z", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FamilyName; } + tb.AddStringColumn("string:FamilyName", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPinned; } + tb.AddDataColumn("byte:IsPinned", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Level?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Level:Level", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._PhaseCreated?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Phase:PhaseCreated", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._PhaseDemolished?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Phase:PhaseDemolished", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Category?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Category:Category", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Workset?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Workset:Workset", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._DesignOption?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.DesignOption:DesignOption", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._OwnerView?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:OwnerView", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Group?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Group:Group", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._AssemblyInstance?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.AssemblyInstance:AssemblyInstance", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Room?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Room:Room", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToWorksetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Workset); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } + tb.AddDataColumn("int:Id", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Kind; } + tb.AddStringColumn("string:Kind", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsOpen; } + tb.AddDataColumn("byte:IsOpen", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsEditable; } + tb.AddDataColumn("byte:IsEditable", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Owner; } + tb.AddStringColumn("string:Owner", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UniqueId; } + tb.AddStringColumn("string:UniqueId", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToAssemblyInstanceTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.AssemblyInstance); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].AssemblyTypeName; } + tb.AddStringColumn("string:AssemblyTypeName", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_X; } + tb.AddDataColumn("float:Position.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Y; } + tb.AddDataColumn("float:Position.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Z; } + tb.AddDataColumn("float:Position.Z", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToGroupTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Group); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].GroupType; } + tb.AddStringColumn("string:GroupType", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_X; } + tb.AddDataColumn("float:Position.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Y; } + tb.AddDataColumn("float:Position.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Z; } + tb.AddDataColumn("float:Position.Z", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToDesignOptionTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.DesignOption); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPrimary; } + tb.AddDataColumn("byte:IsPrimary", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToLevelTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Level); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } + tb.AddDataColumn("double:Elevation", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ProjectElevation; } + tb.AddDataColumn("double:ProjectElevation", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Building?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Building:Building", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToPhaseTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Phase); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToRoomTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Room); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BaseOffset; } + tb.AddDataColumn("double:BaseOffset", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LimitOffset; } + tb.AddDataColumn("double:LimitOffset", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UnboundedHeight; } + tb.AddDataColumn("double:UnboundedHeight", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Volume; } + tb.AddDataColumn("double:Volume", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Perimeter; } + tb.AddDataColumn("double:Perimeter", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Area; } + tb.AddDataColumn("double:Area", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } + tb.AddStringColumn("string:Number", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._UpperLimit?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Level:UpperLimit", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToBimDocumentTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.BimDocument); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Title; } + tb.AddStringColumn("string:Title", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsMetric; } + tb.AddDataColumn("byte:IsMetric", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Guid; } + tb.AddStringColumn("string:Guid", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NumSaves; } + tb.AddDataColumn("int:NumSaves", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsLinked; } + tb.AddDataColumn("byte:IsLinked", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsDetached; } + tb.AddDataColumn("byte:IsDetached", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsWorkshared; } + tb.AddDataColumn("byte:IsWorkshared", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].PathName; } + tb.AddStringColumn("string:PathName", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Latitude; } + tb.AddDataColumn("double:Latitude", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Longitude; } + tb.AddDataColumn("double:Longitude", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].TimeZone; } + tb.AddDataColumn("double:TimeZone", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].PlaceName; } + tb.AddStringColumn("string:PlaceName", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].WeatherStationName; } + tb.AddStringColumn("string:WeatherStationName", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } + tb.AddDataColumn("double:Elevation", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ProjectLocation; } + tb.AddStringColumn("string:ProjectLocation", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IssueDate; } + tb.AddStringColumn("string:IssueDate", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Status; } + tb.AddStringColumn("string:Status", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ClientName; } + tb.AddStringColumn("string:ClientName", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Address; } + tb.AddStringColumn("string:Address", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } + tb.AddStringColumn("string:Number", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Author; } + tb.AddStringColumn("string:Author", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BuildingName; } + tb.AddStringColumn("string:BuildingName", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrganizationName; } + tb.AddStringColumn("string:OrganizationName", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrganizationDescription; } + tb.AddStringColumn("string:OrganizationDescription", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Product; } + tb.AddStringColumn("string:Product", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Version; } + tb.AddStringColumn("string:Version", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].User; } + tb.AddStringColumn("string:User", columnData); + } + { + var columnData = new Int64[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FileLength; } + tb.AddDataColumn("long:FileLength", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ActiveView?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:ActiveView", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._OwnerFamily?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Family:OwnerFamily", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Parent?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.BimDocument:Parent", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToDisplayUnitInBimDocumentTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.DisplayUnitInBimDocument); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._DisplayUnit?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.DisplayUnit:DisplayUnit", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToPhaseOrderInBimDocumentTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.PhaseOrderInBimDocument); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrderIndex; } + tb.AddDataColumn("int:OrderIndex", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Phase?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Phase:Phase", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToCategoryTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Category); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new Int64[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } + tb.AddDataColumn("long:Id", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].CategoryType; } + tb.AddStringColumn("string:CategoryType", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LineColor_X; } + tb.AddDataColumn("double:LineColor.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LineColor_Y; } + tb.AddDataColumn("double:LineColor.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].LineColor_Z; } + tb.AddDataColumn("double:LineColor.Z", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BuiltInCategory; } + tb.AddStringColumn("string:BuiltInCategory", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Parent?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Category:Parent", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Material?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Material:Material", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToFamilyTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Family); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StructuralMaterialType; } + tb.AddStringColumn("string:StructuralMaterialType", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StructuralSectionShape; } + tb.AddStringColumn("string:StructuralSectionShape", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsSystemFamily; } + tb.AddDataColumn("byte:IsSystemFamily", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsInPlace; } + tb.AddDataColumn("byte:IsInPlace", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyCategory?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Category:FamilyCategory", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToFamilyTypeTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.FamilyType); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsSystemFamilyType; } + tb.AddDataColumn("byte:IsSystemFamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Family?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Family:Family", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._CompoundStructure?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.CompoundStructure:CompoundStructure", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToFamilyInstanceTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.FamilyInstance); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingFlipped; } + tb.AddDataColumn("byte:FacingFlipped", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingOrientation_X; } + tb.AddDataColumn("float:FacingOrientation.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingOrientation_Y; } + tb.AddDataColumn("float:FacingOrientation.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FacingOrientation_Z; } + tb.AddDataColumn("float:FacingOrientation.Z", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandFlipped; } + tb.AddDataColumn("byte:HandFlipped", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Mirrored; } + tb.AddDataColumn("byte:Mirrored", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HasModifiedGeometry; } + tb.AddDataColumn("byte:HasModifiedGeometry", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Scale; } + tb.AddDataColumn("float:Scale", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisX_X; } + tb.AddDataColumn("float:BasisX.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisX_Y; } + tb.AddDataColumn("float:BasisX.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisX_Z; } + tb.AddDataColumn("float:BasisX.Z", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisY_X; } + tb.AddDataColumn("float:BasisY.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisY_Y; } + tb.AddDataColumn("float:BasisY.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisY_Z; } + tb.AddDataColumn("float:BasisY.Z", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisZ_X; } + tb.AddDataColumn("float:BasisZ.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisZ_Y; } + tb.AddDataColumn("float:BasisZ.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].BasisZ_Z; } + tb.AddDataColumn("float:BasisZ.Z", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Translation_X; } + tb.AddDataColumn("float:Translation.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Translation_Y; } + tb.AddDataColumn("float:Translation.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Translation_Z; } + tb.AddDataColumn("float:Translation.Z", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandOrientation_X; } + tb.AddDataColumn("float:HandOrientation.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandOrientation_Y; } + tb.AddDataColumn("float:HandOrientation.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HandOrientation_Z; } + tb.AddDataColumn("float:HandOrientation.Z", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Host?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Host", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FromRoom?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Room:FromRoom", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ToRoom?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Room:ToRoom", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._SuperComponent?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:SuperComponent", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToViewTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.View); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Title; } + tb.AddStringColumn("string:Title", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewType; } + tb.AddStringColumn("string:ViewType", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Up_X; } + tb.AddDataColumn("double:Up.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Up_Y; } + tb.AddDataColumn("double:Up.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Up_Z; } + tb.AddDataColumn("double:Up.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Right_X; } + tb.AddDataColumn("double:Right.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Right_Y; } + tb.AddDataColumn("double:Right.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Right_Z; } + tb.AddDataColumn("double:Right.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Origin_X; } + tb.AddDataColumn("double:Origin.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Origin_Y; } + tb.AddDataColumn("double:Origin.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Origin_Z; } + tb.AddDataColumn("double:Origin.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewDirection_X; } + tb.AddDataColumn("double:ViewDirection.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewDirection_Y; } + tb.AddDataColumn("double:ViewDirection.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewDirection_Z; } + tb.AddDataColumn("double:ViewDirection.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewPosition_X; } + tb.AddDataColumn("double:ViewPosition.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewPosition_Y; } + tb.AddDataColumn("double:ViewPosition.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ViewPosition_Z; } + tb.AddDataColumn("double:ViewPosition.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Scale; } + tb.AddDataColumn("double:Scale", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Min_X; } + tb.AddDataColumn("double:Outline.Min.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Min_Y; } + tb.AddDataColumn("double:Outline.Min.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Max_X; } + tb.AddDataColumn("double:Outline.Max.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Outline_Max_Y; } + tb.AddDataColumn("double:Outline.Max.Y", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].DetailLevel; } + tb.AddDataColumn("int:DetailLevel", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Camera?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Camera:Camera", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToElementInViewTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ElementInView); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:View", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToShapeInViewTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ShapeInView); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Shape?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Shape:Shape", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:View", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToAssetInViewTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.AssetInView); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Asset?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Asset:Asset", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:View", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToAssetInViewSheetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.AssetInViewSheet); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Asset?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Asset:Asset", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheet?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ViewSheet:ViewSheet", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToLevelInViewTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.LevelInView); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_X; } + tb.AddDataColumn("double:Extents.Min.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Y; } + tb.AddDataColumn("double:Extents.Min.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Z; } + tb.AddDataColumn("double:Extents.Min.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_X; } + tb.AddDataColumn("double:Extents.Max.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Y; } + tb.AddDataColumn("double:Extents.Max.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Z; } + tb.AddDataColumn("double:Extents.Max.Z", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Level?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Level:Level", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:View", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToCameraTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Camera); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Id; } + tb.AddDataColumn("int:Id", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPerspective; } + tb.AddDataColumn("int:IsPerspective", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].VerticalExtent; } + tb.AddDataColumn("double:VerticalExtent", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].HorizontalExtent; } + tb.AddDataColumn("double:HorizontalExtent", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FarDistance; } + tb.AddDataColumn("double:FarDistance", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NearDistance; } + tb.AddDataColumn("double:NearDistance", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].TargetDistance; } + tb.AddDataColumn("double:TargetDistance", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].RightOffset; } + tb.AddDataColumn("double:RightOffset", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].UpOffset; } + tb.AddDataColumn("double:UpOffset", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToMaterialTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Material); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].MaterialCategory; } + tb.AddStringColumn("string:MaterialCategory", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Color_X; } + tb.AddDataColumn("double:Color.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Color_Y; } + tb.AddDataColumn("double:Color.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Color_Z; } + tb.AddDataColumn("double:Color.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvScaling_X; } + tb.AddDataColumn("double:ColorUvScaling.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvScaling_Y; } + tb.AddDataColumn("double:ColorUvScaling.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvOffset_X; } + tb.AddDataColumn("double:ColorUvOffset.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColorUvOffset_Y; } + tb.AddDataColumn("double:ColorUvOffset.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvScaling_X; } + tb.AddDataColumn("double:NormalUvScaling.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvScaling_Y; } + tb.AddDataColumn("double:NormalUvScaling.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvOffset_X; } + tb.AddDataColumn("double:NormalUvOffset.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalUvOffset_Y; } + tb.AddDataColumn("double:NormalUvOffset.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].NormalAmount; } + tb.AddDataColumn("double:NormalAmount", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Glossiness; } + tb.AddDataColumn("double:Glossiness", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Smoothness; } + tb.AddDataColumn("double:Smoothness", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Transparency; } + tb.AddDataColumn("double:Transparency", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ColorTextureFile?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Asset:ColorTextureFile", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._NormalTextureFile?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Asset:NormalTextureFile", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToMaterialInElementTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.MaterialInElement); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Area; } + tb.AddDataColumn("double:Area", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Volume; } + tb.AddDataColumn("double:Volume", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsPaint; } + tb.AddDataColumn("byte:IsPaint", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Material?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Material:Material", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToCompoundStructureLayerTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.CompoundStructureLayer); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].OrderIndex; } + tb.AddDataColumn("int:OrderIndex", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Width; } + tb.AddDataColumn("double:Width", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].MaterialFunctionAssignment; } + tb.AddStringColumn("string:MaterialFunctionAssignment", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Material?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Material:Material", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._CompoundStructure?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.CompoundStructure:CompoundStructure", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToCompoundStructureTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.CompoundStructure); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Width; } + tb.AddDataColumn("double:Width", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._StructuralLayer?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.CompoundStructureLayer:StructuralLayer", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToNodeTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Node); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToGeometryTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Geometry); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Min_X; } + tb.AddDataColumn("float:Box.Min.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Min_Y; } + tb.AddDataColumn("float:Box.Min.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Min_Z; } + tb.AddDataColumn("float:Box.Min.Z", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Max_X; } + tb.AddDataColumn("float:Box.Max.X", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Max_Y; } + tb.AddDataColumn("float:Box.Max.Y", columnData); + } + { + var columnData = new Single[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Box_Max_Z; } + tb.AddDataColumn("float:Box.Max.Z", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].VertexCount; } + tb.AddDataColumn("int:VertexCount", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].FaceCount; } + tb.AddDataColumn("int:FaceCount", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToShapeTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Shape); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToShapeCollectionTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ShapeCollection); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToShapeInShapeCollectionTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ShapeInShapeCollection); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Shape?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Shape:Shape", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ShapeCollection?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ShapeCollection:ShapeCollection", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToSystemTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.System); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SystemType; } + tb.AddDataColumn("int:SystemType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToElementInSystemTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ElementInSystem); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Roles; } + tb.AddDataColumn("int:Roles", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._System?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.System:System", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToWarningTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Warning); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Guid; } + tb.AddStringColumn("string:Guid", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Severity; } + tb.AddStringColumn("string:Severity", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Description; } + tb.AddStringColumn("string:Description", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._BimDocument?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.BimDocument:BimDocument", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToElementInWarningTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ElementInWarning); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Warning?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Warning:Warning", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToBasePointTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.BasePoint); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsSurveyPoint; } + tb.AddDataColumn("byte:IsSurveyPoint", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_X; } + tb.AddDataColumn("double:Position.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Y; } + tb.AddDataColumn("double:Position.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Position_Z; } + tb.AddDataColumn("double:Position.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SharedPosition_X; } + tb.AddDataColumn("double:SharedPosition.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SharedPosition_Y; } + tb.AddDataColumn("double:SharedPosition.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].SharedPosition_Z; } + tb.AddDataColumn("double:SharedPosition.Z", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToPhaseFilterTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.PhaseFilter); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].New; } + tb.AddDataColumn("int:New", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Existing; } + tb.AddDataColumn("int:Existing", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Demolished; } + tb.AddDataColumn("int:Demolished", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Temporary; } + tb.AddDataColumn("int:Temporary", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToGridTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Grid); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StartPoint_X; } + tb.AddDataColumn("double:StartPoint.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StartPoint_Y; } + tb.AddDataColumn("double:StartPoint.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].StartPoint_Z; } + tb.AddDataColumn("double:StartPoint.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].EndPoint_X; } + tb.AddDataColumn("double:EndPoint.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].EndPoint_Y; } + tb.AddDataColumn("double:EndPoint.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].EndPoint_Z; } + tb.AddDataColumn("double:EndPoint.Z", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsCurved; } + tb.AddDataColumn("byte:IsCurved", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_X; } + tb.AddDataColumn("double:Extents.Min.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Y; } + tb.AddDataColumn("double:Extents.Min.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Min_Z; } + tb.AddDataColumn("double:Extents.Min.Z", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_X; } + tb.AddDataColumn("double:Extents.Max.X", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Y; } + tb.AddDataColumn("double:Extents.Max.Y", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Extents_Max_Z; } + tb.AddDataColumn("double:Extents.Max.Z", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToAreaTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Area); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Value; } + tb.AddDataColumn("double:Value", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Perimeter; } + tb.AddDataColumn("double:Perimeter", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } + tb.AddStringColumn("string:Number", columnData); + } + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsGrossInterior; } + tb.AddDataColumn("byte:IsGrossInterior", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._AreaScheme?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.AreaScheme:AreaScheme", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToAreaSchemeTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.AreaScheme); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Boolean[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].IsGrossBuildingArea; } + tb.AddDataColumn("byte:IsGrossBuildingArea", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToScheduleTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Schedule); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToScheduleColumnTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ScheduleColumn); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Name; } + tb.AddStringColumn("string:Name", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].ColumnIndex; } + tb.AddDataColumn("int:ColumnIndex", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Schedule?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Schedule:Schedule", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToScheduleCellTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ScheduleCell); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Value; } + tb.AddStringColumn("string:Value", columnData); + } + { + var columnData = new Int32[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].RowIndex; } + tb.AddDataColumn("int:RowIndex", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ScheduleColumn?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ScheduleColumn:ScheduleColumn", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToViewSheetSetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ViewSheetSet); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToViewSheetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ViewSheet); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._FamilyType?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.FamilyType:FamilyType", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToViewSheetInViewSheetSetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ViewSheetInViewSheetSet); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheet?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ViewSheet:ViewSheet", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheetSet?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ViewSheetSet:ViewSheetSet", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToViewInViewSheetSetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ViewInViewSheetSet); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:View", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheetSet?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ViewSheetSet:ViewSheetSet", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToViewInViewSheetTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.ViewInViewSheet); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._View?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.View:View", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._ViewSheet?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.ViewSheet:ViewSheet", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToSiteTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Site); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Latitude; } + tb.AddDataColumn("double:Latitude", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Longitude; } + tb.AddDataColumn("double:Longitude", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Address; } + tb.AddStringColumn("string:Address", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } + tb.AddDataColumn("double:Elevation", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Number; } + tb.AddStringColumn("string:Number", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + public static VimEntityTableBuilder ToBuildingTableBuilder(this VimEntitySetBuilder entitySetBuilder) + { + var tb = new VimEntityTableBuilder(VimEntityTableNames.Building); + var entities = entitySetBuilder.Entities; + var entityCount = entities.Count; + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Elevation; } + tb.AddDataColumn("double:Elevation", columnData); + } + { + var columnData = new Double[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].TerrainElevation; } + tb.AddDataColumn("double:TerrainElevation", columnData); + } + { + var columnData = new String[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i].Address; } + tb.AddStringColumn("string:Address", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Site?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Site:Site", columnData); + } + { + var columnData = new int[entityCount]; + for (var i = 0; i < columnData.Length; ++i) { columnData[i] = entities[i]._Element?.Index ?? EntityRelation.None; } + tb.AddIndexColumn("index:Vim.Element:Element", columnData); + } + return tb; + } + } // VimEntitySetBuilderExtensions + + public partial class VimBuilder + { + public readonly VimEntitySetBuilder AssetBuilder = new VimEntitySetBuilder(VimEntityTableNames.Asset); + public readonly VimEntitySetBuilder DisplayUnitBuilder = new VimEntitySetBuilder(VimEntityTableNames.DisplayUnit); + public readonly VimEntitySetBuilder ParameterDescriptorBuilder = new VimEntitySetBuilder(VimEntityTableNames.ParameterDescriptor); + public readonly VimEntitySetBuilder ParameterBuilder = new VimEntitySetBuilder(VimEntityTableNames.Parameter); + public readonly VimEntitySetBuilder ElementBuilder = new VimEntitySetBuilder(VimEntityTableNames.Element); + public readonly VimEntitySetBuilder WorksetBuilder = new VimEntitySetBuilder(VimEntityTableNames.Workset); + public readonly VimEntitySetBuilder AssemblyInstanceBuilder = new VimEntitySetBuilder(VimEntityTableNames.AssemblyInstance); + public readonly VimEntitySetBuilder GroupBuilder = new VimEntitySetBuilder(VimEntityTableNames.Group); + public readonly VimEntitySetBuilder DesignOptionBuilder = new VimEntitySetBuilder(VimEntityTableNames.DesignOption); + public readonly VimEntitySetBuilder LevelBuilder = new VimEntitySetBuilder(VimEntityTableNames.Level); + public readonly VimEntitySetBuilder PhaseBuilder = new VimEntitySetBuilder(VimEntityTableNames.Phase); + public readonly VimEntitySetBuilder RoomBuilder = new VimEntitySetBuilder(VimEntityTableNames.Room); + public readonly VimEntitySetBuilder BimDocumentBuilder = new VimEntitySetBuilder(VimEntityTableNames.BimDocument); + public readonly VimEntitySetBuilder DisplayUnitInBimDocumentBuilder = new VimEntitySetBuilder(VimEntityTableNames.DisplayUnitInBimDocument); + public readonly VimEntitySetBuilder PhaseOrderInBimDocumentBuilder = new VimEntitySetBuilder(VimEntityTableNames.PhaseOrderInBimDocument); + public readonly VimEntitySetBuilder CategoryBuilder = new VimEntitySetBuilder(VimEntityTableNames.Category); + public readonly VimEntitySetBuilder FamilyBuilder = new VimEntitySetBuilder(VimEntityTableNames.Family); + public readonly VimEntitySetBuilder FamilyTypeBuilder = new VimEntitySetBuilder(VimEntityTableNames.FamilyType); + public readonly VimEntitySetBuilder FamilyInstanceBuilder = new VimEntitySetBuilder(VimEntityTableNames.FamilyInstance); + public readonly VimEntitySetBuilder ViewBuilder = new VimEntitySetBuilder(VimEntityTableNames.View); + public readonly VimEntitySetBuilder ElementInViewBuilder = new VimEntitySetBuilder(VimEntityTableNames.ElementInView); + public readonly VimEntitySetBuilder ShapeInViewBuilder = new VimEntitySetBuilder(VimEntityTableNames.ShapeInView); + public readonly VimEntitySetBuilder AssetInViewBuilder = new VimEntitySetBuilder(VimEntityTableNames.AssetInView); + public readonly VimEntitySetBuilder AssetInViewSheetBuilder = new VimEntitySetBuilder(VimEntityTableNames.AssetInViewSheet); + public readonly VimEntitySetBuilder LevelInViewBuilder = new VimEntitySetBuilder(VimEntityTableNames.LevelInView); + public readonly VimEntitySetBuilder CameraBuilder = new VimEntitySetBuilder(VimEntityTableNames.Camera); + public readonly VimEntitySetBuilder MaterialBuilder = new VimEntitySetBuilder(VimEntityTableNames.Material); + public readonly VimEntitySetBuilder MaterialInElementBuilder = new VimEntitySetBuilder(VimEntityTableNames.MaterialInElement); + public readonly VimEntitySetBuilder CompoundStructureLayerBuilder = new VimEntitySetBuilder(VimEntityTableNames.CompoundStructureLayer); + public readonly VimEntitySetBuilder CompoundStructureBuilder = new VimEntitySetBuilder(VimEntityTableNames.CompoundStructure); + public readonly VimEntitySetBuilder NodeBuilder = new VimEntitySetBuilder(VimEntityTableNames.Node); + public readonly VimEntitySetBuilder GeometryBuilder = new VimEntitySetBuilder(VimEntityTableNames.Geometry); + public readonly VimEntitySetBuilder ShapeBuilder = new VimEntitySetBuilder(VimEntityTableNames.Shape); + public readonly VimEntitySetBuilder ShapeCollectionBuilder = new VimEntitySetBuilder(VimEntityTableNames.ShapeCollection); + public readonly VimEntitySetBuilder ShapeInShapeCollectionBuilder = new VimEntitySetBuilder(VimEntityTableNames.ShapeInShapeCollection); + public readonly VimEntitySetBuilder SystemBuilder = new VimEntitySetBuilder(VimEntityTableNames.System); + public readonly VimEntitySetBuilder ElementInSystemBuilder = new VimEntitySetBuilder(VimEntityTableNames.ElementInSystem); + public readonly VimEntitySetBuilder WarningBuilder = new VimEntitySetBuilder(VimEntityTableNames.Warning); + public readonly VimEntitySetBuilder ElementInWarningBuilder = new VimEntitySetBuilder(VimEntityTableNames.ElementInWarning); + public readonly VimEntitySetBuilder BasePointBuilder = new VimEntitySetBuilder(VimEntityTableNames.BasePoint); + public readonly VimEntitySetBuilder PhaseFilterBuilder = new VimEntitySetBuilder(VimEntityTableNames.PhaseFilter); + public readonly VimEntitySetBuilder GridBuilder = new VimEntitySetBuilder(VimEntityTableNames.Grid); + public readonly VimEntitySetBuilder AreaBuilder = new VimEntitySetBuilder(VimEntityTableNames.Area); + public readonly VimEntitySetBuilder AreaSchemeBuilder = new VimEntitySetBuilder(VimEntityTableNames.AreaScheme); + public readonly VimEntitySetBuilder ScheduleBuilder = new VimEntitySetBuilder(VimEntityTableNames.Schedule); + public readonly VimEntitySetBuilder ScheduleColumnBuilder = new VimEntitySetBuilder(VimEntityTableNames.ScheduleColumn); + public readonly VimEntitySetBuilder ScheduleCellBuilder = new VimEntitySetBuilder(VimEntityTableNames.ScheduleCell); + public readonly VimEntitySetBuilder ViewSheetSetBuilder = new VimEntitySetBuilder(VimEntityTableNames.ViewSheetSet); + public readonly VimEntitySetBuilder ViewSheetBuilder = new VimEntitySetBuilder(VimEntityTableNames.ViewSheet); + public readonly VimEntitySetBuilder ViewSheetInViewSheetSetBuilder = new VimEntitySetBuilder(VimEntityTableNames.ViewSheetInViewSheetSet); + public readonly VimEntitySetBuilder ViewInViewSheetSetBuilder = new VimEntitySetBuilder(VimEntityTableNames.ViewInViewSheetSet); + public readonly VimEntitySetBuilder ViewInViewSheetBuilder = new VimEntitySetBuilder(VimEntityTableNames.ViewInViewSheet); + public readonly VimEntitySetBuilder SiteBuilder = new VimEntitySetBuilder(VimEntityTableNames.Site); + public readonly VimEntitySetBuilder BuildingBuilder = new VimEntitySetBuilder(VimEntityTableNames.Building); + + public List GetVimEntityTableBuilders() + { + var tableBuilders = new List(); + tableBuilders.Add(AssetBuilder.ToAssetTableBuilder()); + tableBuilders.Add(DisplayUnitBuilder.ToDisplayUnitTableBuilder()); + tableBuilders.Add(ParameterDescriptorBuilder.ToParameterDescriptorTableBuilder()); + tableBuilders.Add(ParameterBuilder.ToParameterTableBuilder()); + tableBuilders.Add(ElementBuilder.ToElementTableBuilder()); + tableBuilders.Add(WorksetBuilder.ToWorksetTableBuilder()); + tableBuilders.Add(AssemblyInstanceBuilder.ToAssemblyInstanceTableBuilder()); + tableBuilders.Add(GroupBuilder.ToGroupTableBuilder()); + tableBuilders.Add(DesignOptionBuilder.ToDesignOptionTableBuilder()); + tableBuilders.Add(LevelBuilder.ToLevelTableBuilder()); + tableBuilders.Add(PhaseBuilder.ToPhaseTableBuilder()); + tableBuilders.Add(RoomBuilder.ToRoomTableBuilder()); + tableBuilders.Add(BimDocumentBuilder.ToBimDocumentTableBuilder()); + tableBuilders.Add(DisplayUnitInBimDocumentBuilder.ToDisplayUnitInBimDocumentTableBuilder()); + tableBuilders.Add(PhaseOrderInBimDocumentBuilder.ToPhaseOrderInBimDocumentTableBuilder()); + tableBuilders.Add(CategoryBuilder.ToCategoryTableBuilder()); + tableBuilders.Add(FamilyBuilder.ToFamilyTableBuilder()); + tableBuilders.Add(FamilyTypeBuilder.ToFamilyTypeTableBuilder()); + tableBuilders.Add(FamilyInstanceBuilder.ToFamilyInstanceTableBuilder()); + tableBuilders.Add(ViewBuilder.ToViewTableBuilder()); + tableBuilders.Add(ElementInViewBuilder.ToElementInViewTableBuilder()); + tableBuilders.Add(ShapeInViewBuilder.ToShapeInViewTableBuilder()); + tableBuilders.Add(AssetInViewBuilder.ToAssetInViewTableBuilder()); + tableBuilders.Add(AssetInViewSheetBuilder.ToAssetInViewSheetTableBuilder()); + tableBuilders.Add(LevelInViewBuilder.ToLevelInViewTableBuilder()); + tableBuilders.Add(CameraBuilder.ToCameraTableBuilder()); + tableBuilders.Add(MaterialBuilder.ToMaterialTableBuilder()); + tableBuilders.Add(MaterialInElementBuilder.ToMaterialInElementTableBuilder()); + tableBuilders.Add(CompoundStructureLayerBuilder.ToCompoundStructureLayerTableBuilder()); + tableBuilders.Add(CompoundStructureBuilder.ToCompoundStructureTableBuilder()); + tableBuilders.Add(NodeBuilder.ToNodeTableBuilder()); + tableBuilders.Add(GeometryBuilder.ToGeometryTableBuilder()); + tableBuilders.Add(ShapeBuilder.ToShapeTableBuilder()); + tableBuilders.Add(ShapeCollectionBuilder.ToShapeCollectionTableBuilder()); + tableBuilders.Add(ShapeInShapeCollectionBuilder.ToShapeInShapeCollectionTableBuilder()); + tableBuilders.Add(SystemBuilder.ToSystemTableBuilder()); + tableBuilders.Add(ElementInSystemBuilder.ToElementInSystemTableBuilder()); + tableBuilders.Add(WarningBuilder.ToWarningTableBuilder()); + tableBuilders.Add(ElementInWarningBuilder.ToElementInWarningTableBuilder()); + tableBuilders.Add(BasePointBuilder.ToBasePointTableBuilder()); + tableBuilders.Add(PhaseFilterBuilder.ToPhaseFilterTableBuilder()); + tableBuilders.Add(GridBuilder.ToGridTableBuilder()); + tableBuilders.Add(AreaBuilder.ToAreaTableBuilder()); + tableBuilders.Add(AreaSchemeBuilder.ToAreaSchemeTableBuilder()); + tableBuilders.Add(ScheduleBuilder.ToScheduleTableBuilder()); + tableBuilders.Add(ScheduleColumnBuilder.ToScheduleColumnTableBuilder()); + tableBuilders.Add(ScheduleCellBuilder.ToScheduleCellTableBuilder()); + tableBuilders.Add(ViewSheetSetBuilder.ToViewSheetSetTableBuilder()); + tableBuilders.Add(ViewSheetBuilder.ToViewSheetTableBuilder()); + tableBuilders.Add(ViewSheetInViewSheetSetBuilder.ToViewSheetInViewSheetSetTableBuilder()); + tableBuilders.Add(ViewInViewSheetSetBuilder.ToViewInViewSheetSetTableBuilder()); + tableBuilders.Add(ViewInViewSheetBuilder.ToViewInViewSheetTableBuilder()); + tableBuilders.Add(SiteBuilder.ToSiteTableBuilder()); + tableBuilders.Add(BuildingBuilder.ToBuildingTableBuilder()); + + return tableBuilders; + } // GetVimEntityTableBuilders + + public void Clear() + { + AssetBuilder.Clear(); + DisplayUnitBuilder.Clear(); + ParameterDescriptorBuilder.Clear(); + ParameterBuilder.Clear(); + ElementBuilder.Clear(); + WorksetBuilder.Clear(); + AssemblyInstanceBuilder.Clear(); + GroupBuilder.Clear(); + DesignOptionBuilder.Clear(); + LevelBuilder.Clear(); + PhaseBuilder.Clear(); + RoomBuilder.Clear(); + BimDocumentBuilder.Clear(); + DisplayUnitInBimDocumentBuilder.Clear(); + PhaseOrderInBimDocumentBuilder.Clear(); + CategoryBuilder.Clear(); + FamilyBuilder.Clear(); + FamilyTypeBuilder.Clear(); + FamilyInstanceBuilder.Clear(); + ViewBuilder.Clear(); + ElementInViewBuilder.Clear(); + ShapeInViewBuilder.Clear(); + AssetInViewBuilder.Clear(); + AssetInViewSheetBuilder.Clear(); + LevelInViewBuilder.Clear(); + CameraBuilder.Clear(); + MaterialBuilder.Clear(); + MaterialInElementBuilder.Clear(); + CompoundStructureLayerBuilder.Clear(); + CompoundStructureBuilder.Clear(); + NodeBuilder.Clear(); + GeometryBuilder.Clear(); + ShapeBuilder.Clear(); + ShapeCollectionBuilder.Clear(); + ShapeInShapeCollectionBuilder.Clear(); + SystemBuilder.Clear(); + ElementInSystemBuilder.Clear(); + WarningBuilder.Clear(); + ElementInWarningBuilder.Clear(); + BasePointBuilder.Clear(); + PhaseFilterBuilder.Clear(); + GridBuilder.Clear(); + AreaBuilder.Clear(); + AreaSchemeBuilder.Clear(); + ScheduleBuilder.Clear(); + ScheduleColumnBuilder.Clear(); + ScheduleCellBuilder.Clear(); + ViewSheetSetBuilder.Clear(); + ViewSheetBuilder.Clear(); + ViewSheetInViewSheetSetBuilder.Clear(); + ViewInViewSheetSetBuilder.Clear(); + ViewInViewSheetBuilder.Clear(); + SiteBuilder.Clear(); + BuildingBuilder.Clear(); + } // Clear + } // VimBuilder +} // namespace diff --git a/src/cs/vim/Vim.Format/ObjectModel/EntitySetBuilder.cs b/src/cs/vim/Vim.Format/VimEntitySetBuilder.cs similarity index 96% rename from src/cs/vim/Vim.Format/ObjectModel/EntitySetBuilder.cs rename to src/cs/vim/Vim.Format/VimEntitySetBuilder.cs index 8f062169..197307ad 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/EntitySetBuilder.cs +++ b/src/cs/vim/Vim.Format/VimEntitySetBuilder.cs @@ -1,11 +1,12 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using Vim.Util; +using Vim.Format.ObjectModel; -namespace Vim.Format.ObjectModel +namespace Vim.Format { - public class EntitySetBuilder where TEntity : Entity + public class VimEntitySetBuilder where TEntity : Entity { public readonly string EntityTableName; public readonly List Entities = new List(); @@ -14,7 +15,7 @@ public class EntitySetBuilder where TEntity : Entity /// /// Constructor /// - public EntitySetBuilder(string entityTableName) + public VimEntitySetBuilder(string entityTableName) { EntityTableName = entityTableName; } diff --git a/src/cs/vim/Vim.Format/VimEntityTableBuilderRemapped.cs b/src/cs/vim/Vim.Format/VimEntityTableBuilderRemapped.cs new file mode 100644 index 00000000..116967c6 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimEntityTableBuilderRemapped.cs @@ -0,0 +1,501 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Vim.BFast; +using Vim.Util; + +namespace Vim.Format +{ + public class VimEntityTableBuilderRemapped + { + public VimEntityTableBuilder EntityTableBuilder { get; private set; } + public int[] OldToNewIndexMap { get; private set; } + public bool IsRemapped => OldToNewIndexMap != null; + + /// + /// Constructor + /// + private VimEntityTableBuilderRemapped( + VimEntityTableBuilder entityTableBuilder, + int[] oldToNewIndexMap) + { + EntityTableBuilder = entityTableBuilder; + OldToNewIndexMap = oldToNewIndexMap; + } + + private void UpdateFrom(VimEntityTableBuilderRemapped other) + { + EntityTableBuilder = other.EntityTableBuilder; + OldToNewIndexMap = other.OldToNewIndexMap; + } + + /// + /// Returns a default remapped entity table builder in which no remapping has occurred. + /// + private static VimEntityTableBuilderRemapped CreateDefault(VimEntityTableBuilder et) + => new VimEntityTableBuilderRemapped(et, null); + + /// + /// Returns a VimTableBuilderRemapped whose contained VimEntityTableBuilder is deduplicated based on the given keyFn. + /// + private static VimEntityTableBuilderRemapped CreateDeduplicated( + IReadOnlyVimEntityTableBuilder et, + Func keyFn) + { + // We maintain a mapping of the keys to their new indices in this dictionary. + // + // ex: input keyFn sequence: [ "a", "b", "c", "b", "a", "c", "d" ] + // keyToIndexMap: { + // "a" -> 0, + // "b" -> 1, + // "c" -> 2, + // "d" -> 3, + // } + var keyToNewIndexMap = new Dictionary(); + + // We retain the non-duplicate indices in this array. + // + // ex: input keyFn sequence: [ "a", "b", "c", "b", "a", "c", "d" ] + // retainedIndices: [ 0 , 1 , 2 , 6 ] + var retainedIndices = new List(); + + // We map the old index to the new index in this array. + // + // ex: input keyFn sequence: ["a", "b", "c", "b", "a", "c", "d" ] + // old index: [ 0 , 1 , 2 , 3 , 4 , 5 , 6 ] + // oldToNewIndexMap: [ 0 , 1 , 2 , 1 , 0 , 2 , 3 ] + var oldToNewIndexMap = new int[et.RowCount]; + + // Iterate over the rows and build the maps + for (var i = 0; i < et.RowCount; ++i) + { + var key = keyFn(i, et); + + if (keyToNewIndexMap.TryGetValue(key, out var newIndex)) + { + // The key was already found, so store the remapping. + oldToNewIndexMap[i] = newIndex; + } + else + { + // This is the first time we encounter this key. + var nextIndex = keyToNewIndexMap.Count; + keyToNewIndexMap.Add(key, nextIndex); + retainedIndices.Add(i); + oldToNewIndexMap[i] = nextIndex; + } + } + + // ex: input keyFn sequence: [ "a", "b", "c", "b", "a", "c", "d" ] + // desired output sequence: [ "a", "b", "c", "d" ] + var remapped = new VimEntityTableBuilder(et.Name); + + // Remap Index columns directly/naively now. In a second pass, the indices are adjusted based OldToNewIndexMap. + foreach (var kv in et.IndexColumns) + { + var colName = kv.Key; + var col = kv.Value; + var newCol = retainedIndices.Select(retainedIndex => col[retainedIndex]); + remapped.AddIndexColumn(colName, newCol); + } + + // Remap the data columns. + foreach (var kv in et.DataColumns) + { + var colName = kv.Key; + var col = kv.Value; + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(colName, out var typePrefix)) + continue; + + var newCol = VimEntityTableColumnActions.RemapOrSelfDataColumn(col, typePrefix, retainedIndices); + remapped.AddDataColumn(colName, newCol); + } + + // Remap the string columns. + foreach (var kv in et.StringColumns) + { + var colName = kv.Key; + var col = kv.Value; + var newCol = retainedIndices.Select(retainedIndex => col[retainedIndex]); + remapped.AddStringColumn(colName, newCol); + } + + return new VimEntityTableBuilderRemapped(remapped, oldToNewIndexMap); + } + + public delegate bool EntityFilter(int entityIndex, VimEntityTableBuilder et); + + /// + /// Returns a VimTableBuilderRemapped with filtered entities. + /// + private static VimEntityTableBuilderRemapped CreateFiltered( + VimEntityTableBuilder et, + EntityFilter entityFilter) + { + var retainedIndices = new List(); + var oldToNewIndexMap = new int[et.RowCount]; + + // Iterate over the rows and build the maps + for (var i = 0; i < et.RowCount; ++i) + { + if (entityFilter(i, et)) + { + var newIndex = retainedIndices.Count; + retainedIndices.Add(i); + oldToNewIndexMap[i] = newIndex; + } + else + { + oldToNewIndexMap[i] = -1; + } + } + + var remapped = Remap(et, retainedIndices); + + return new VimEntityTableBuilderRemapped(remapped, oldToNewIndexMap); + } + + private static VimEntityTableBuilder Remap(IReadOnlyVimEntityTableBuilder et, IReadOnlyList retainedIndices) + { + var remapped = new VimEntityTableBuilder(et.Name); + + // Remap Index columns directly/naively now. In a second pass, the indices are adjusted based OldToNewIndexMap. + foreach (var kv in et.IndexColumns) + { + var colName = kv.Key; + var col = kv.Value; + var newCol = retainedIndices.Select(retainedIndex => col[retainedIndex]); + remapped.AddIndexColumn(colName, newCol); + } + + // Remap the data columns. + foreach (var kv in et.DataColumns) + { + var colName = kv.Key; + var col = kv.Value; + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(colName, out var typePrefix)) + continue; + + var newCol = VimEntityTableColumnActions.RemapOrSelfDataColumn(col, typePrefix, retainedIndices); + remapped.AddDataColumn(colName, newCol); + } + + // Remap the string columns. + foreach (var kv in et.StringColumns) + { + var colName = kv.Key; + var col = kv.Value; + var newCol = retainedIndices.Select(retainedIndex => col[retainedIndex]); + remapped.AddStringColumn(colName, newCol); + } + + return remapped; + } + + private static void UpdateRelations( + List remappedEntityTableBuilders, + CancellationToken ct = default) + { + MutateIndexRelations(remappedEntityTableBuilders, ct); + + RemoveOrphanedJoiningTableEntities(remappedEntityTableBuilders, ct); + } + + private static void MutateIndexRelations( + List remappedEntityTableBuilders, + CancellationToken ct = default) + { + var remappedTableIndices = remappedEntityTableBuilders + .Where(r => r.IsRemapped) + .ToDictionary( + r => r.EntityTableBuilder.Name, + r => r.OldToNewIndexMap); + + if (remappedTableIndices.Count == 0) + return; // nothing to do. + + // Mutate the index relationships using the remapped entity table builders' indices. + foreach (var et in remappedEntityTableBuilders.Select(r => r.EntityTableBuilder)) + { + ct.ThrowIfCancellationRequested(); + + foreach (var kv in et.IndexColumns) + { + var indexColumnName = kv.Key; + var indexColumn = kv.Value; + + // Get the related index remapping. + var tableName = VimEntityTableColumnName.GetRelatedTableNameFromColumnName(indexColumnName); + if (!remappedTableIndices.TryGetValue(tableName, out var oldToNewIndexMap)) + continue; + + // Mutate the indices + for (var i = 0; i < indexColumn.Length; ++i) + { + var oldIndex = indexColumn[i]; + if (oldIndex != VimEntityTableConstants.NoEntityRelation) + { + indexColumn[i] = oldToNewIndexMap[oldIndex]; + } + } + } + } + } + + private static bool RemoveOrphanedJoiningTableEntities( + List remappedEntityTableBuilders, + CancellationToken ct = default) + { + var orphansRemoved = false; + var joiningTableNames = VimEntityTableSet.GetJoiningTableNames(); + + foreach (var rtb in remappedEntityTableBuilders) + { + var tb = rtb.EntityTableBuilder; + + if (!joiningTableNames.Contains(tb.Name)) + continue; + + var orphanIndices = new HashSet(); + + // Find the orphaned entities + foreach (var (tablName, indexColumn) in tb.IndexColumns) + { + for (var i = 0; i < tb.RowCount; ++i) + { + if (indexColumn[i] == EntityRelation.None) + { + orphanIndices.Add(i); + } + } + } + + if (orphanIndices.Count == 0) + continue; + + // Remove the orphans. + // NOTE: these orphans can be safely/naively removed because nobody else should be referencing them. + var swept = CreateFiltered(tb, (i, e) => !orphanIndices.Contains(i)); + + rtb.UpdateFrom(swept); + + orphansRemoved = true; + } + + return orphansRemoved; + } + + private static List DeduplicateEntityTableBuilders( + IReadOnlyList entityTableBuilders, + CancellationToken ct = default) + { + var result = new List(); + + var specialTableNames = new HashSet(); + + //////////////////////////////////// + // FUTURE MAINTENANCE NOTES: + // - if we ever remap materials, we must also propagate this remapping to the submeshMaterials in the geometry buffer. + // - if we ever remap assets, we must also propagate this remapping to the merged assets in the asset buffer. + //////////////////////////////////// + + // Merge the same categories + var categoryTable = entityTableBuilders.FirstOrDefault(t => t.Name == VimEntityTableNames.Category); + VimEntityTableBuilderRemapped categoryTableRemapped = null; + if (categoryTable != null) + { + var table = categoryTable; + var nameCol = table.StringColumns.GetOrDefault("string:Name"); + var builtInCol = table.StringColumns.GetOrDefault("string:BuiltInCategory"); + categoryTableRemapped = CreateDeduplicated(table, (i, _) => ( + nameCol?.ElementAtOrDefault(i, "") ?? "", + builtInCol?.ElementAtOrDefault(i, "") ?? "" + )); + result.Add(categoryTableRemapped); + specialTableNames.Add(VimEntityTableNames.Category); + } + + ct.ThrowIfCancellationRequested(); + + // Merge the same display units + var displayUnitTable = entityTableBuilders.FirstOrDefault(t => t.Name == VimEntityTableNames.DisplayUnit); + VimEntityTableBuilderRemapped displayUnitTableRemapped = null; + if (displayUnitTable != null) + { + var table = displayUnitTable; + var specCol = table.StringColumns.GetOrDefault("string:Spec"); + var typeCol = table.StringColumns.GetOrDefault("string:Type"); + var labelCol = table.StringColumns.GetOrDefault("string:Label"); + displayUnitTableRemapped = CreateDeduplicated(table, (i, _) => ( + specCol?.ElementAtOrDefault(i, "") ?? "", + typeCol?.ElementAtOrDefault(i, "") ?? "", + labelCol?.ElementAtOrDefault(i, "") ?? "" + )); // same tuple values as DisplayUnit.GetStorageKey() + result.Add(displayUnitTableRemapped); + specialTableNames.Add(VimEntityTableNames.DisplayUnit); + } + + ct.ThrowIfCancellationRequested(); + + // Merge the same parameter descriptors + var pdTable = entityTableBuilders.FirstOrDefault(t => t.Name == VimEntityTableNames.ParameterDescriptor); + VimEntityTableBuilderRemapped pdTableRemapped = null; + { + var table = pdTable; + var nameArray = table.StringColumns.GetOrDefault("string:Name"); + var groupArray = table.StringColumns.GetOrDefault("string:Group"); + var isInstanceArray = VimEntityTableColumnTypeInfo.GetDataColumnAsTypedArray(table.DataColumns.GetOrDefault("byte:IsInstance")); + var isSharedArray = VimEntityTableColumnTypeInfo.GetDataColumnAsTypedArray(table.DataColumns.GetOrDefault("byte:IsShared")); + var isReadOnlyArray = VimEntityTableColumnTypeInfo.GetDataColumnAsTypedArray(table.DataColumns.GetOrDefault("byte:IsReadOnly")); + var parameterTypeArray = table.StringColumns.GetOrDefault("string:ParameterType"); + var flagsArray = VimEntityTableColumnTypeInfo.GetDataColumnAsTypedArray(table.DataColumns.GetOrDefault("int:Flags")); + var guidArray = table.StringColumns.GetOrDefault("string:Guid"); + var storageTypeArray = VimEntityTableColumnTypeInfo.GetDataColumnAsTypedArray(table.DataColumns.GetOrDefault("int:StorageType")); + var displayUnitIndexArray = table.IndexColumns.GetOrDefault("index:Vim.DisplayUnit:DisplayUnit"); + + pdTableRemapped = CreateDeduplicated(table, (i, _) => { + var name = nameArray?.ElementAtOrDefault(i, "") ?? ""; + var group = groupArray?.ElementAtOrDefault(i, "") ?? ""; + var isInstance = isInstanceArray?.ElementAtOrDefault(i, false) ?? false; + var isShared = isSharedArray?.ElementAtOrDefault(i, false) ?? false; + var isReadOnly = isReadOnlyArray?.ElementAtOrDefault(i, false) ?? false; + var parameterType = parameterTypeArray?.ElementAtOrDefault(i, "") ?? ""; + var flags = flagsArray?.ElementAtOrDefault(i, 0) ?? 0; + var guid = guidArray?.ElementAtOrDefault(i, "") ?? ""; + var storageType = storageTypeArray?.ElementAtOrDefault(i, 0) ?? 0; + var displayUnitIndex = displayUnitIndexArray?.ElementAtOrDefault(i, -1) ?? -1; + + var remappedDisplayUnitIndex = displayUnitIndex == -1 + ? -1 + : displayUnitTableRemapped?.OldToNewIndexMap.ElementAtOrDefault(displayUnitIndex, displayUnitIndex) ?? displayUnitIndex; + + return ( + name, + group, + isInstance, + isShared, + isReadOnly, + parameterType, + flags, + guid, + storageType, + remappedDisplayUnitIndex + ); + }); // same value tuples as ParameterDescriptor.GetStorageKey() + result.Add(pdTableRemapped); + specialTableNames.Add(VimEntityTableNames.ParameterDescriptor); + } + + ct.ThrowIfCancellationRequested(); + + // Process the remaining entity tables. + foreach (var table in entityTableBuilders) + { + ct.ThrowIfCancellationRequested(); + + var tableName = table.Name; + + if (specialTableNames.Contains(tableName)) + continue; + + result.Add(CreateDefault(table)); + } + + // Mutate all the entity index relations to adapt to the filtered entities. + UpdateRelations(result, ct); + + return result; + } + + /// + /// Returns a new collection of entity table builders by deduplicating specific entities which would be + /// meaninglessly duplicated in the resulting VIM file. + /// + public static VimEntityTableBuilder[] DeduplicateEntities( + IReadOnlyList entityTableBuilders, CancellationToken ct = default) + => DeduplicateEntityTableBuilders(entityTableBuilders, ct) + .Select(r => r.EntityTableBuilder) + .ToArray(); + + /// + /// Returns a filtered collection of entity tables. + /// + public static List FilterEntities( + IReadOnlyList entityTableBuilders, + Dictionary entityTableFilters, + CancellationToken ct = default) + { + var result = new List(); + + foreach (var et in entityTableBuilders) + { + ct.ThrowIfCancellationRequested(); + + if (entityTableFilters.TryGetValue(et.Name, out var filter)) + { + result.Add(CreateFiltered(et, filter)); + } + else + { + result.Add(CreateDefault(et)); + } + } + + // Update all the entity index relations. + UpdateRelations(result, ct); + + return result; + } + + public static VimEntityTableBuilder[] FilterElements( + IReadOnlyList entityTableBuilders, + HashSet filteredElementIndices, + IReadOnlyList nodesToKeep = null, + CancellationToken ct = default) + { + // Go through each entity table corresponding to an element kind and remove those entities. + var entityTableFilters = new Dictionary() + { + { VimEntityTableNames.Element, (i, _) => filteredElementIndices.Contains(i) }, + }; + + foreach (var entityTableBuilder in entityTableBuilders) + { + var tableName = entityTableBuilder.Name; + + ct.ThrowIfCancellationRequested(); + + if (tableName == VimEntityTableNames.Node && nodesToKeep != null) + continue; // We explicitly remap the node table below. + + entityTableFilters[tableName] = (i, et) => + { + if (!et.IndexColumns.TryGetValue("index:Vim.Element:Element", out var elementIndexCol)) + return true; + + var elementIndex = elementIndexCol.ElementAtOrDefault(i, -1); + return elementIndex == -1 + ? false + : filteredElementIndices.Contains(elementIndex); + }; + } + + var result = FilterEntities(entityTableBuilders, entityTableFilters, ct).Select(r => r.EntityTableBuilder).ToList(); + + // mutate the result's node table if the nodesToKeep is defined. + if (nodesToKeep != null) + { + var nodeTableIndex = result.FindIndex(t => t.Name == VimEntityTableNames.Node); + if (nodeTableIndex >= 0) + { + var nodeTable = result[nodeTableIndex]; + var remappedNodeTable = Remap(nodeTable, nodesToKeep); + result[nodeTableIndex] = remappedNodeTable; + } + } + + return result.ToArray(); + } + } +} diff --git a/src/cs/vim/Vim.Format/ObjectModel/EntityTableSet.cs b/src/cs/vim/Vim.Format/VimEntityTableSet.cs similarity index 63% rename from src/cs/vim/Vim.Format/ObjectModel/EntityTableSet.cs rename to src/cs/vim/Vim.Format/VimEntityTableSet.cs index 1ff370bb..a6addaee 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/EntityTableSet.cs +++ b/src/cs/vim/Vim.Format/VimEntityTableSet.cs @@ -1,82 +1,158 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; - -using static Vim.Format.Serializer; +using Vim.BFast; +using Vim.Util; using ReadOnlyIndexMap = System.Collections.Generic.IReadOnlyDictionary; -namespace Vim.Format.ObjectModel +namespace Vim.Format { /// - /// Additional partial definitions of EntityTableSet. + /// A set of entity tables. /// - public partial class EntityTableSet + public partial class VimEntityTableSet { /// - /// Represents a collection of entity tables. + /// The string table. Can be null (when only loading the schema) /// - /// - /// The VIM file from which to load the entity tables. - /// - /// - /// The string table, which can be loaded separately. - /// If null (and schemaOnly is false), the string table will be loaded from the VIM file. - /// Provide an empty array to avoid loading the string table. - /// - /// - /// A filter which specifies which entity tables to load by name. - /// - /// - /// A filter which specifies which entity table column to load by name. - /// - /// - /// Determines whether the loading process may occur in parallel (speeds up the loading time). - /// - /// - /// If true, only the table schema will be returned. - /// - public EntityTableSet( - FileInfo vimFileInfo, - string[] stringTable = null, - Func entityTableNameFilterFunc = null, - EntityTableColumnFilter entityTableColumnFilter = null, - bool inParallel = true, - bool schemaOnly = false) - : this( - vimFileInfo.EnumerateEntityTables(schemaOnly, entityTableNameFilterFunc, entityTableColumnFilter).ToArray(), - stringTable ?? (schemaOnly ? null : vimFileInfo.GetStringTable()), - inParallel) - { } + public string[] StringTable { get; } + + /// + /// A mapping of entity table data objects keyed by entity table name. + /// + public Dictionary TableData { get; } = new Dictionary(); /// - /// Represents a collection of entity tables contained in the serializable document. + /// A mapping of entity tables keyed by entity table name. /// - public EntityTableSet(SerializableDocument serializableDocument, bool inParallel = true) - : this(serializableDocument.EntityTables.ToArray(), serializableDocument.StringTable, inParallel) - {} + public Dictionary Tables { get; } = new Dictionary(); - public static ElementKind[] GetElementKinds(FileInfo vimFileInfo) + /// + /// Maps elements to table records which are referencing those elements. + /// + public VimElementIndexMaps ElementIndexMaps { get; private set; } + + /// + /// Constructor + /// + public VimEntityTableSet(VimEntityTableData[] entityTableData, string[] stringTable, bool inParallel = true) { - var elementTableName = TableNames.Element; + StringTable = stringTable; + + foreach (var table in entityTableData) + TableData[table.Name] = table; + + Initialize(); // Code-generated. + } + + /// + /// Returns an entity table data object based on the given entity table name. If the object does not exist, returns a new empty table. + /// + public VimEntityTableData GetEntityTableDataOrEmpty(string tableName) + => TableData.TryGetValue(tableName, out var result) ? result : new VimEntityTableData { Name = tableName }; + + /// + /// Returns the entity table based on the given table name. + /// + public bool TryGetEntityTable(string tableName, out VimEntityTable entityTable) + { + entityTable = null; + return string.IsNullOrEmpty(tableName) + ? false + : Tables.TryGetValue(tableName, out entityTable); + } + + /// + /// Returns the related entity table based on the given index column's name. + /// + public bool TryGetRelatedEntityTable(INamedBuffer indexColumn, out VimEntityTable entityTable) + { + entityTable = null; + var relatedTableName = VimEntityTableColumnName.GetRelatedTableName(indexColumn); + return string.IsNullOrEmpty(relatedTableName) + ? false + : TryGetEntityTable(relatedTableName, out entityTable); + } + + /// + /// Returns an array aligned with the Element table which defines the kind of each element (ex: FamilyInstance, FamilyType, Family, Level, Room, Material, Phase, etc) + /// + public static Vim.Format.ElementKind[] GetElementKinds(FileInfo vimFileInfo) + { + vimFileInfo.ThrowIfNotExists("Could not get the element kinds."); + + var elementTableName = VimEntityTableNames.Element; var elementKindTableNames = GetElementKindTableNames(); elementKindTableNames.Add(elementTableName); - - var ets = new EntityTableSet( + + var entityTableData = VimEntityTableData.EnumerateEntityTables( vimFileInfo, - Array.Empty(), + false, entityTableName => elementKindTableNames.Contains(entityTableName), (entityTableName, colName) => // If we're dealing with the element table, load a single column from the element table (i.e. the ID column) (entityTableName == elementTableName && (colName is "long:Id" || colName is "int:Id")) || // Otherwise, load the element index column. colName == "index:Vim.Element:Element" - ); + ).ToArray(); + + var ets = new VimEntityTableSet(entityTableData, Array.Empty()); return ets.GetElementKinds(); } + + /// + /// Returns the VimEntityTableSet contained in the given VIM file. + /// + public static VimEntityTableSet GetEntityTableSet( + string vimFilePath, + VimEntityTableSetOptions options = null) + { + return GetEntityTableSet(new FileInfo(vimFilePath), options); + } + + /// + /// Returns the VimEntityTableSet contained in the given VIM file. + /// + public static VimEntityTableSet GetEntityTableSet( + FileInfo vimFileInfo, + VimEntityTableSetOptions options = null) + { + vimFileInfo.ThrowIfNotExists("Could not get the entity table set."); + + var stringTable = options.StringTable + ?? (options.SchemaOnly ? null : VIM.GetStringTable(vimFileInfo)); + + var entityTableData = VimEntityTableData.EnumerateEntityTables( + vimFileInfo, + options.SchemaOnly, + options.EntityTableNameFilter, + options.EntityTableColumnFilter) + .ToArray(); + + return new VimEntityTableSet(entityTableData, stringTable, options.InParallel); + } + + /// + /// Returns an entity table set from the given VIM file containing only the specified tables by name. + /// If no entity table names are specified, all entity tables are loaded. + /// Useful for loading specific entity tables without loading the whole file into memory. + /// + public static VimEntityTableSet GetEntityTableSetByTableName( + FileInfo vimFileInfo, + params string[] tableNames) + { + var tableSet = new HashSet(tableNames); + + return GetEntityTableSet(vimFileInfo, new VimEntityTableSetOptions() + { + StringTable = Array.Empty(), + EntityTableNameFilter = n => tableSet.Count == 0 ? true : tableSet.Contains(n) + }); + } } public partial class CategoryTable @@ -170,14 +246,14 @@ public int GetFamilyIndex(int elementIndex) var familyTypeIndex = GetRelatedIndex(elementIndex, ParentTableSet.ElementIndexMaps.FamilyTypeIndexFromElementIndex); return ParentTableSet.FamilyTypeTable.GetFamilyIndex(familyTypeIndex); } - + return GetRelatedIndex(elementIndex, ParentTableSet.ElementIndexMaps.FamilyIndexFromElementIndex); } - + public int GetFamilyElementIndex(int elementIndex) => ParentTableSet.FamilyTable.GetElementIndex(GetFamilyIndex(elementIndex)); - public string GetFamilyName(int elementIndex) + public string GetFamilyNameEx(int elementIndex) => ParentTableSet.ElementTable.GetName(GetFamilyElementIndex(elementIndex)); // Object-generating properties @@ -208,67 +284,51 @@ public Element GetSystemElement(int elementIndex) // Parameters - [Flags] - public enum ParameterScope - { - None = 0, - FamilyInstance = 1, - FamilyType = 1 << 1, - Family = 1 << 2, - All = FamilyInstance | FamilyType | Family, - } - public List GetParameterIndices(int elementIndex) => ParentTableSet.ElementIndexMaps.ParameterIndicesFromElementIndex .TryGetValue(elementIndex, out var pIndices) ? pIndices : new List(); - public IEnumerable GetParameters(int elementIndex) - => GetParameterIndices(elementIndex).Select(i => ParentTableSet.ParameterTable.Get(i)); - - public Dictionary> GetScopedParameters( - int elementIndex, - ParameterScope scope = ParameterScope.All) + public List GetFamilyInstanceParameterIndices(int elementIndex) { - var result = new Dictionary>(); + if (elementIndex < 0) + return new List(); + + var familyInstanceElementIndex = GetFamilyInstanceElementIndex(elementIndex); + if (familyInstanceElementIndex == EntityRelation.None) + return new List(); + return GetParameterIndices(familyInstanceElementIndex); + } + + public List GetFamilyTypeParameterIndices(int elementIndex) + { if (elementIndex < 0) - return result; + return new List(); - if ((scope & ParameterScope.FamilyInstance) == ParameterScope.FamilyInstance) - { - var familyInstanceElementIndex = GetFamilyInstanceElementIndex(elementIndex); - if (familyInstanceElementIndex != EntityRelation.None) - { - result[ParameterScope.FamilyInstance] = GetParameters(familyInstanceElementIndex); - } - } + var familyTypeElementIndex = GetFamilyTypeElementIndex(elementIndex); + if (familyTypeElementIndex == EntityRelation.None) + return new List(); - if ((scope & ParameterScope.FamilyType) == ParameterScope.FamilyType) - { - var familyTypeElementIndex = GetFamilyTypeElementIndex(elementIndex); - if (familyTypeElementIndex != EntityRelation.None) - { - result[ParameterScope.FamilyType] = GetParameters(familyTypeElementIndex); - } - } + return GetParameterIndices(familyTypeElementIndex); + } - if ((scope & ParameterScope.Family) == ParameterScope.Family) - { - var familyElementIndex = GetFamilyElementIndex(elementIndex); - if (familyElementIndex != EntityRelation.None) - { - result[ParameterScope.Family] = GetParameters(familyElementIndex); - } - } + public List GetFamilyParameterIndices(int elementIndex) + { + if (elementIndex < 0) + return new List(); - return result; + var familyElementIndex = GetFamilyElementIndex(elementIndex); + if (familyElementIndex == EntityRelation.None) + return new List(); + + return GetParameterIndices(familyElementIndex); } /// /// Returns an array of booleans aligned 1:1 with the element table. - /// Items are true if the element is visible in at least one 3d view. + /// Items are true if the element is visible in at least one Revit 3d view. /// - public bool[] GetIsVisibleIn3dView() + public bool[] GetIsVisibleInRevit3dView() { // Result is 1:1 aligned with the elements. var elementVisibility = new bool[RowCount]; diff --git a/src/cs/vim/Vim.Format/VimEntityTableSetOptions.cs b/src/cs/vim/Vim.Format/VimEntityTableSetOptions.cs new file mode 100644 index 00000000..51b10ae7 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimEntityTableSetOptions.cs @@ -0,0 +1,32 @@ +namespace Vim.Format +{ + public class VimEntityTableSetOptions + { + /// + /// The string table, which can be loaded separately. + /// If null (and schemaOnly is false), the string table will be loaded from the VIM file. + /// Provide an empty array to avoid loading the string table. + /// + public string[] StringTable { get; set; } = null; + + /// + /// A filter which specifies which entity tables to load by name. + /// + public VimEntityTableData.EntityTableFilter EntityTableNameFilter { get; set; } = null; + + /// + /// A filter which specifies which entity table columns to load based on the name of the tablea nd the name of the column. + /// + public VimEntityTableData.EntityTableColumnFilter EntityTableColumnFilter { get; set; } = null; + + /// + /// Determines whether the loading process may occur in parallel (speeds up the loading time). + /// + public bool InParallel { get; set; } = true; + + /// + /// If true, only the entity table schema will be returned; none of the entries in the entity tables will be populated. + /// + public bool SchemaOnly { get; set; } = false; + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format/VimMergeService.cs b/src/cs/vim/Vim.Format/VimMergeService.cs new file mode 100644 index 00000000..27d3dc77 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimMergeService.cs @@ -0,0 +1,634 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Vim.BFast; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + public class VimMergeConfigFiles + { + /// + /// The input VIM file paths and their transforms. + /// + public (string VimFilePath, Matrix4x4 Transform)[] InputVimFilePathsAndTransforms { get; } + + /// + /// The input VIM file paths + /// + public string[] InputVimFilePaths + => InputVimFilePathsAndTransforms.Select(t => t.VimFilePath).ToArray(); + + /// + /// The input VIM file path transforms + /// + public Matrix4x4[] InputTransforms + => InputVimFilePathsAndTransforms.Select(t => t.Transform).ToArray(); + + /// + /// The merged VIM file path. + /// + public string MergedVimFilePath { get; } + + /// + /// Constructor + /// + public VimMergeConfigFiles( + (string VimFilePath, Matrix4x4 Transform)[] inputVimFilePathsAndTransforms, + string mergedVimFilePath) + { + InputVimFilePathsAndTransforms = inputVimFilePathsAndTransforms; + MergedVimFilePath = mergedVimFilePath; + } + + /// + /// Throws an exception if the input configuration is invalid. + /// + public void Validate() + { + if (string.IsNullOrWhiteSpace(MergedVimFilePath)) + throw new HResultException((int) VimErrorCode.VimMergeConfigFilePathIsEmpty, "Merged VIM file path is empty."); + + var emptyFilePaths = InputVimFilePathsAndTransforms.Where(t => string.IsNullOrWhiteSpace(t.VimFilePath)).ToArray(); + if (emptyFilePaths.Length > 0) + { + var msg = string.Join(Environment.NewLine, emptyFilePaths.Select((t, i) => $"Input VIM file path at index {i} is empty.")); + throw new HResultException((int) VimErrorCode.VimMergeInputFileNotFound, msg); + } + + var notFoundFilePaths = InputVimFilePathsAndTransforms.Where(t => !File.Exists(t.VimFilePath)).ToArray(); + if (notFoundFilePaths.Length > 0) + { + var msg = string.Join(Environment.NewLine, notFoundFilePaths.Select(t => $"Input VIM file not found: {t.VimFilePath}")); + throw new HResultException((int) VimErrorCode.VimMergeInputFileNotFound, msg); + } + } + } + + public class VimMergeConfigOptions + { + /// + /// The generator string to embed into the VIM file header + /// + public string GeneratorString { get; set; } = "Unknown"; + + /// + /// The version string to embed into the VIM file header. + /// + public string VersionString { get; set; } = "0.0.0"; + + /// + /// Preserves the BIM data + /// + public bool KeepBimData { get; set; } = true; + + /// + /// Merges the given VIM files as a grid. + /// + public bool MergeAsGrid { get; set; } = false; + + /// + /// Applied when merging as a grid. + /// + public float GridPadding { get; set; } = 0f; + + /// + /// Deduplicates Elements and EntityWithElements based on their Element's unique ids. + /// If the unique ID is empty, the entities are not merged. + /// + public bool DeduplicateEntities { get; set; } = true; + } + + public class VimMergeConfig + { + /// + /// The input VIMs and their transforms. + /// + public (VIM Vim, Matrix4x4 Transform)[] InputVimsAndTransforms { get; } + + /// + /// The input VIMs + /// + public VIM[] InputVims + => InputVimsAndTransforms.Select(t => t.Vim).ToArray(); + + /// + /// The input VIM transforms + /// + public Matrix4x4[] InputTransforms + => InputVimsAndTransforms.Select(t => t.Transform).ToArray(); + + /// + /// Constructor. + /// + public VimMergeConfig((VIM Vim, Matrix4x4 Transform)[] inputVimScenesAndTransforms) + => InputVimsAndTransforms = inputVimScenesAndTransforms; + + /// + /// Constructor. Applies an identity matrix to the input VIMs + /// + public VimMergeConfig(VIM[] vims) + : this(vims.Select(v => (v, Matrix4x4.Identity)).ToArray()) + { } + } + + public class VimMergedTableBuilder + { + public readonly string Name; + public int RowCount; + + public VimMergedTableBuilder(string name) + => Name = name; + + public Dictionary DataColumns = new Dictionary(); + public DictionaryOfLists IndexColumns = new DictionaryOfLists(); + public DictionaryOfLists StringColumns = new DictionaryOfLists(); + + public void AddTable( + VimEntityTable entityTable, + VimEntityTableSet parentSet, + Dictionary entityIndexOffsets) + { + Debug.Assert(entityIndexOffsets[entityTable] == RowCount); + + // Add index columns from the entity table + foreach (var k in entityTable.IndexColumnMap.Keys) + { + var col = entityTable.IndexColumnMap[k]; + var indexColumnFullName = col.Name; + + // back-fill the index column if it doesn't exist. + if (!IndexColumns.ContainsKey(indexColumnFullName)) + IndexColumns.Add(indexColumnFullName, Enumerable.Repeat(EntityRelation.None, RowCount).ToList()); + + Debug.Assert(col.Array.Length == entityTable.RowCount); + + var offset = 0; + if (parentSet.TryGetRelatedEntityTable(col, out var relatedTable) && + entityIndexOffsets.TryGetValue(relatedTable, out var _offset)) + { + offset = _offset; + } + + var vals = IndexColumns[indexColumnFullName]; + foreach (var v in col.Array) + vals.Add(v < 0 ? v : v + offset); + } + + // Add data columns from the entity table + foreach (var colName in entityTable.DataColumnMap.Keys) + { + var col = entityTable.DataColumnMap[colName]; + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(colName, out var typePrefix)) + continue; + + if (!DataColumns.ContainsKey(colName)) + { + // back-fill the data column with default values. + var defaultBuffer = VimEntityTableColumnActions.CreateDefaultDataColumnBuffer(RowCount, typePrefix); + DataColumns[colName] = defaultBuffer; + } + + var cur = DataColumns[colName]; + DataColumns[colName] = VimEntityTableColumnActions.ConcatDataColumnBuffers(cur, col, typePrefix); + } + + var stringTable = parentSet.StringTable; + + // Add string columns from the entity table + foreach (var k in entityTable.StringColumnMap.Keys) + { + if (!StringColumns.ContainsKey(k)) + StringColumns.Add(k, Enumerable.Repeat("", RowCount).ToList()); + + var col = entityTable.StringColumnMap[k]; + Debug.Assert(col.Array.Length == entityTable.RowCount); + var vals = StringColumns[k]; + foreach (var v in col.Array) + vals.Add(stringTable[v]); + } + + // For each column in the builder but not in the entity table add default values + foreach (var kv in DataColumns) + { + var colName = kv.Key; + if (!VimEntityTableColumnName.TryParseColumnTypePrefix(colName, out var typePrefix)) + continue; + + if (!entityTable.DataColumnMap.ContainsKey(colName)) + { + var cur = DataColumns[colName]; + var defaultBuffer = VimEntityTableColumnActions.CreateDefaultDataColumnBuffer(entityTable.RowCount, typePrefix); + DataColumns[colName] = VimEntityTableColumnActions.ConcatDataColumnBuffers(cur, defaultBuffer, typePrefix); + } + } + + foreach (var kv in IndexColumns) + { + if (!entityTable.IndexColumnMap.ContainsKey(kv.Key)) + IndexColumns[kv.Key].AddRange(Enumerable.Repeat(-1, entityTable.RowCount)); + } + + foreach (var kv in StringColumns) + { + if (!entityTable.StringColumnMap.ContainsKey(kv.Key)) + StringColumns[kv.Key].AddRange(Enumerable.Repeat("", entityTable.RowCount)); + } + + RowCount += entityTable.RowCount; + + foreach (var kv in DataColumns) + Debug.Assert(kv.Value.Data.Length == RowCount); + foreach (var kv in IndexColumns) + Debug.Assert(kv.Value.Count == RowCount); + foreach (var kv in StringColumns) + Debug.Assert(kv.Value.Count == RowCount); + } + + public void UpdateTableBuilder(VimEntityTableBuilder tb, CancellationToken cancellationToken = default) + { + foreach (var kv in DataColumns) + { + cancellationToken.ThrowIfCancellationRequested(); + tb.AddDataColumn(kv.Key, kv.Value); + } + + foreach (var kv in StringColumns) + { + cancellationToken.ThrowIfCancellationRequested(); + tb.AddStringColumn(kv.Key, kv.Value.ToArray()); + } + + foreach (var kv in IndexColumns) + { + cancellationToken.ThrowIfCancellationRequested(); + tb.AddIndexColumn(kv.Key, kv.Value.ToArray()); + } + } + } + + public class VimMergeResult + { + public VimBuilder VimBuilder { get; } + public VimEntityTableBuilder[] VimEntityTableBuilders { get; } + + public VimMergeResult(VimBuilder vimBuilder, VimEntityTableBuilder[] vimEntityTableBuilders) + { + VimBuilder = vimBuilder; + VimEntityTableBuilders = vimEntityTableBuilders; + } + + public void Write(string vimFilePath) + { + VimBuilder.Write(vimFilePath, VimEntityTableBuilders); + } + } + + public static class VimMergeService + { + /// + /// Merges the VIM files in the specified VimMergeConfigFiles object. + /// + public static void Merge( + VimMergeConfigFiles fileConfig, + VimMergeConfigOptions optionsConfig, + IProgress progress = null, + CancellationToken cancellationToken = default) + { + fileConfig.Validate(); + + progress?.Report("Loading VIM files"); + cancellationToken.ThrowIfCancellationRequested(); + var inputVimsAndTransforms = + fileConfig.InputVimFilePathsAndTransforms + .AsParallel() + .Select(t => (VIM.Open(t.VimFilePath), t.Transform)) + .ToArray(); + + progress?.Report("Merging VIM files"); + cancellationToken.ThrowIfCancellationRequested(); + var mergeResult = Merge( + new VimMergeConfig(inputVimsAndTransforms), + optionsConfig, + progress, + cancellationToken); + + progress?.Report("Writing merged VIM file"); + cancellationToken.ThrowIfCancellationRequested(); + var mergedVimFilePath = fileConfig.MergedVimFilePath; + mergeResult.Write(mergedVimFilePath); + + progress?.Report("Completed VIM file merge"); + } + + /// + /// Merge the given VIM scenes into a VimBuilder + /// + public static VimMergeResult Merge( + VimMergeConfig vimMergeConfig, + VimMergeConfigOptions optionsConfig = null, + IProgress progress = null, + CancellationToken ct = default) + { + optionsConfig = optionsConfig ?? new VimMergeConfigOptions(); + + // Validate that all VIMs are in the same object model major version + var vims = vimMergeConfig.InputVims.ToArray(); + ValidateSameObjectModelSchemaMajorVersion(vims); + + var vimBuilder = new VimBuilder(optionsConfig.GeneratorString, SchemaVersion.Current, optionsConfig.VersionString); + + // Merge the entity data + progress?.Report("Merging entities"); + ct.ThrowIfCancellationRequested(); + var entityTableBuilders = MergeEntities(vims, optionsConfig.KeepBimData, ct); + + // Optionally deduplicate the entity data. + if (optionsConfig.DeduplicateEntities) + { + progress?.Report("Deduplicating entities"); + ct.ThrowIfCancellationRequested(); + entityTableBuilders = VimEntityTableBuilderRemapped.DeduplicateEntities(entityTableBuilders, ct); + } + + // Merge the materials + // + // IMPORTANT: there must be a 1:1 aligned relationship between the material entities and the renderable materials. + // To ensure this constraint, We use the existing material entities in the document builder, whose entities have been + // previously populated and optionally deduplicated above. + progress?.Report("Merging materials"); + ct.ThrowIfCancellationRequested(); + + var materialTable = entityTableBuilders.FirstOrDefault(et => et.Name == VimEntityTableNames.Material); + if (materialTable != null) + { + var mdcs = materialTable.DataColumns; + + var colorXColumn = mdcs.TryGetValue("double:Color.X", out var cX) + ? cX.AsArray() + : Array.Empty(); + + var colorYColumn = mdcs.TryGetValue("double:Color.Y", out var cY) + ? cY.AsArray() + : Array.Empty(); + + var colorZColumn = mdcs.TryGetValue("double:Color.Z", out var cZ) + ? cZ.AsArray() + : Array.Empty(); + + var transparencyColumn = mdcs.TryGetValue("double:Transparency", out var t) + ? t.AsArray() + : Array.Empty(); + + var glossinessColumn = mdcs.TryGetValue("double:Glossiness", out var g) + ? g.AsArray() + : Array.Empty(); + + var smoothnessColumn = mdcs.TryGetValue("double:Smoothness", out var s) + ? s.AsArray() + : Array.Empty(); + + for (var i = 0; i < materialTable.RowCount; ++i) + { + vimBuilder.Materials.Add(Material.ToVimMaterial( + colorX: (float)colorXColumn.ElementAtOrDefault(i), + colorY: (float)colorYColumn.ElementAtOrDefault(i), + colorZ: (float)colorZColumn.ElementAtOrDefault(i), + transparency: (float)transparencyColumn.ElementAtOrDefault(i), + glossiness: (float)glossinessColumn.ElementAtOrDefault(i), + smoothness: (float)smoothnessColumn.ElementAtOrDefault(i) + )); + } + } + + // Merge the geometry + progress?.Report("Merging geometry"); + ct.ThrowIfCancellationRequested(); + + var materialCounts = vims.Select(v => v.GeometryData.MaterialCount).ToArray(); + var materialOffsets = PartialSums(materialCounts); + + vimBuilder.Meshes.AddRange(vims + .SelectMany((vim, vimIndex) => vim.GeometryData.GetMeshViews().Select(mesh => (mesh, vimIndex))) + .Select( + pair => new VimSubdividedMesh( + indices: pair.mesh.GetIndices(), + vertices: pair.mesh.GetVertices(), + submeshesIndexOffset: pair.mesh.GetSubmeshIndexOffsets(), + submeshMaterials: pair.mesh.GetSubmeshMaterials().Select( + mat => mat == -1 ? -1 : mat + materialOffsets[pair.vimIndex])?.ToList() + ) + ) + .ToList()); + + ct.ThrowIfCancellationRequested(); + + // Apply the optional grid transforms. + var vimTransforms = vimMergeConfig.InputTransforms.ToArray(); + if (optionsConfig.MergeAsGrid) + { + progress?.Report("Calculating merge grid"); + var gridTransforms = GetGridTransforms(vims, optionsConfig.GridPadding); + vimTransforms = gridTransforms.Zip(vimTransforms, (g, t) => g * t).ToArray(); + } + + var meshCounts = vims.Select(v => v.GeometryData.MeshCount).ToArray(); + var meshOffsets = PartialSums(meshCounts); + + // Merge the instances + progress?.Report("Merging instances"); + ct.ThrowIfCancellationRequested(); + + var isIdentityAll = vimTransforms.All(t => t.IsIdentity); + for (var vimIndex = 0; vimIndex < vims.Length; ++vimIndex) + { + var vim = vims[vimIndex]; + var geometryData = vim.GeometryData; + for (var instanceIndex = 0; instanceIndex < geometryData.InstanceCount; ++instanceIndex) + { + + var meshIndexRaw = geometryData.InstanceMeshes.ElementAtOrDefault(instanceIndex, -1); + var meshIndex = meshIndexRaw == -1 + ? -1 + : meshIndexRaw + meshOffsets[vimIndex]; + + var instanceTransformRaw = geometryData.InstanceTransforms.ElementAtOrDefault(instanceIndex, Matrix4x4.Identity); + var instanceTransform = isIdentityAll + ? instanceTransformRaw + : instanceTransformRaw * vimTransforms[vimIndex]; + + var vimInstance = new VimInstance() + { + ParentIndex = -1, + InstanceFlags = (InstanceFlags) geometryData.InstanceFlags.ElementAtOrDefault(instanceIndex), + MeshIndex = meshIndex, + Transform = instanceTransform + }; + + vimBuilder.Instances.Add(vimInstance); + } + } + + // Merge the assets + progress?.Report("Merging assets"); + ct.ThrowIfCancellationRequested(); + foreach (var asset in vims.SelectMany(vim => vim.Assets)) + vimBuilder.AddAsset(asset); + + return new VimMergeResult(vimBuilder, entityTableBuilders); + } + + private static int[] PartialSums(int[] self, int init = default) + { + var count = self.Length; + var r = new int[count + 1]; + var prev = r[0] = init; + if (count == 0) return r; + for (var i = 0; i < count; ++i) + { + prev = r[i + 1] = prev + self[i]; + } + return r; + } + + /// + /// Throws if the given VIM files do not all have the same object model schema major version. + /// + public static void ValidateSameObjectModelSchemaMajorVersion(VIM[] vims) + { + var objectModelMajorVersions = vims + .Select(v => v.Header.Schema.Major) + .Distinct() + .OrderBy(i => i) + .ToArray(); + + // If we are only dealing with one major object model schema version, we are fine. + if (objectModelMajorVersions.Length == 1) + return; + + // Throw otherwise with a helpful error message. + var sb = new StringBuilder(); + sb.AppendLine($"Object model schema major version mismatch ({string.Join(", ", objectModelMajorVersions.Select(v => $"v{v}.*"))})"); + sb.AppendLine(); + foreach (var vim in vims.OrderBy(v => v.Header.Schema.Major)) + sb.AppendLine($"- v{vim.Header.Schema}: '{vim.FilePath}'"); + sb.AppendLine(); + sb.AppendLine("Please ensure the VIM files have all been exported with matching schema major versions."); + + throw new HResultException((int) VimErrorCode.VimMergeObjectModelMajorVersionMismatch, sb.ToString()); + } + + /// + /// Returns a collection of transforms based on the largest dimension of the largest VIM bounding box. + /// + public static Matrix4x4[] GetGridTransforms(VIM[] vims, float padding) + { + var boxes = vims.Select(v => v.GeometryData.GetWorldSpaceBoundingBox()).ToArray(); + var centerBottomTransforms = boxes.Select(b => Matrix4x4.CreateTranslation(-b.CenterBottom)); + + var columnSize = boxes.Select(b => b.Extent.X).Max() + padding; + var rowSize = boxes.Select(b => b.Extent.Y).Max() + padding; + + var numRows = (int)Math.Sqrt(vims.Length).Ceiling(); + + var transforms = GetGridOfTransforms( + vims.Length, + numRows, + columnSize, + rowSize) + .Zip(centerBottomTransforms, (g, b) => b * g) + .ToArray(); + + return transforms; + } + + private static Matrix4x4[] GetGridOfTransforms(int count, int numRows, float xSide, float ySide) + { + var result = new Matrix4x4[count]; + for (var i = 0; i < result.Length; ++i) + { + result[i] = Matrix4x4.CreateTranslation(i % numRows * xSide, i / numRows * ySide, 0); + } + return result; + } + + private static VimEntityTableBuilder[] MergeEntities( + VIM[] vims, + bool keepBimData = true, + CancellationToken cancellationToken = default) + { + // Compute the offsets for the new entities + var offsets = ComputeMergedEntityTableOffsets(vims); + + // Collect the entity tables, grouped by name + var mergedTableBuilders = new Dictionary(); + foreach (var vim in vims) + { + cancellationToken.ThrowIfCancellationRequested(); + var entityTableSet = vim.GetEntityTableSet(); + + foreach (var entityTable in entityTableSet.Tables.Values) + { + cancellationToken.ThrowIfCancellationRequested(); + + var name = entityTable.Name; + if (VimEntityTableNames.ComputedTableNames.Contains(entityTable.Name)) + continue; + + if (!keepBimData && !VimEntityTableNames.NonBimNames.Contains(entityTable.Name)) + continue; + + var mergedTableBuilder = mergedTableBuilders.GetOrCompute(name, (s) => new VimMergedTableBuilder(s)); + mergedTableBuilder.AddTable(entityTable, entityTableSet, offsets); + } + } + + // Generate the new merged entity table builder + var entityTableBuilders = mergedTableBuilders.Values.Select(mtb => new VimEntityTableBuilder(mtb.Name)).ToArray(); + + Parallel.For(0, entityTableBuilders.Length, i => + { + cancellationToken.ThrowIfCancellationRequested(); + + var tb = entityTableBuilders[i]; + var mtb = mergedTableBuilders[tb.Name]; + mtb.UpdateTableBuilder(tb, cancellationToken); + }); + + return entityTableBuilders; + } + + /// + /// For every entity table in each document, computes the offset of that entity table + /// in a merged document. This is used for remapping entity table relations when merging VIM files. + /// + private static Dictionary ComputeMergedEntityTableOffsets(IEnumerable vims) + { + var aggregateOffsetMap = new Dictionary(); + var entityTableOffsetMap = new Dictionary(); + foreach (var vim in vims) + { + foreach (var entityTable in vim.GetEntityTableSet().Tables.Values) + { + var entityTableName = entityTable.Name; + + // Add the entity table name to the aggregate offset map + aggregateOffsetMap.TryAdd(entityTableName, 0); + + // Assign the current offset to the given entity table. + entityTableOffsetMap.Add(entityTable, aggregateOffsetMap[entityTableName]); + + // Update the aggregated offsets + aggregateOffsetMap[entityTableName] += entityTable.RowCount; + } + } + return entityTableOffsetMap; + } + } +} diff --git a/src/cs/vim/Vim.Format/VimOpenOptions.cs b/src/cs/vim/Vim.Format/VimOpenOptions.cs new file mode 100644 index 00000000..b4abcde6 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimOpenOptions.cs @@ -0,0 +1,11 @@ +namespace Vim.Format +{ + public class VimOpenOptions + { + public bool IncludeGeometry { get; set; } = true; + public bool IncludeStringTable { get; set; } = true; + public bool IncludeEntityTables { get; set; } = true; + public bool SchemaOnly { get; set; } = false; + public bool IncludeAssets { get; set; } = true; + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format/RoomService.cs b/src/cs/vim/Vim.Format/VimRoomService.cs similarity index 52% rename from src/cs/vim/Vim.Format/RoomService.cs rename to src/cs/vim/Vim.Format/VimRoomService.cs index 1ea67d13..0fcdc754 100644 --- a/src/cs/vim/Vim.Format/RoomService.cs +++ b/src/cs/vim/Vim.Format/VimRoomService.cs @@ -1,86 +1,79 @@ using System; using System.Collections.Generic; using System.Linq; -using Vim.Format.Geometry; -using Vim.Format.ObjectModel; -using Vim.LinqArray; using Vim.Math3d; namespace Vim.Format { - public class ElementInRoom + public class VimElementInRoom { public int ElementIndex { get; } public int RoomIndex { get; } - public ElementInRoom(int elementIndex, int roomIndex) + public VimElementInRoom(int elementIndex, int roomIndex) { ElementIndex = elementIndex; RoomIndex = roomIndex; } } - public static class RoomService + public static class VimRoomService { - public delegate bool GeometricElementInfoFilter(ElementInfo elementInfo); + public delegate bool GeometricElementInfoFilter(VimElementGeometryInfo elementInfo); - public static ElementInRoom[] ComputeElementsInRoom(VimScene vim, GeometricElementInfoFilter geometricElementInfoFilter) + public static VimElementInRoom[] ComputeElementsInRoom(VIM vim, GeometricElementInfoFilter geometricElementInfoFilter) { - var dm = vim.DocumentModel; + var tableSet = vim.GetEntityTableSet(); - var roomElementIndices = new HashSet(dm.RoomElementIndex.ToEnumerable()); + // var roomElementIndices = new HashSet(dm.RoomElementIndex.ToEnumerable()); + var roomElementIndices = new HashSet(tableSet.RoomTable.Column_ElementIndex); if (roomElementIndices.Count == 0) - return Array.Empty(); // no rooms found. + return Array.Empty(); // no rooms found. - // Collect the bounding boxes of geometric elements - var geometricNodesGroupedByElementIndex = vim.VimNodes - .Where(n => n.HasMesh) - .GroupBy(n => n.ElementIndex) - .ToArray(); + var elementGeometryInfo = vim.GetElementGeometryInfoList(); - var roomGeometryCollection = geometricNodesGroupedByElementIndex + var roomGeometryCollection = elementGeometryInfo .AsParallel() .Where(g => { - var elementIndex = g.Key; + var elementIndex = g.ElementIndex; return roomElementIndices.Contains(elementIndex); }) .Select(g => { // ASSUMPTION: Rooms are typically represented by a single geometric node, so take the first item in the group. - var worldSpaceMesh = g.First().TransformedMesh(); - var roomElementIndex = g.Key; + var worldSpaceMesh = g.GetWorldSpaceMeshes(vim.GeometryData).FirstOrDefault(); + var roomElementIndex = g.ElementIndex; - var roomIndexFound = dm.ElementIndexMaps.RoomIndexFromElementIndex.TryGetValue(roomElementIndex, out var roomIndex); + var roomIndexFound = tableSet.ElementIndexMaps.RoomIndexFromElementIndex.TryGetValue(roomElementIndex, out var roomIndex); roomIndex = roomIndexFound ? roomIndex : -1; - return new RoomGeometry(roomIndex, worldSpaceMesh.Vertices.ToArray(), worldSpaceMesh.Indices.ToArray()); + return new RoomGeometry(roomIndex, worldSpaceMesh); }) .ToArray(); if (roomGeometryCollection.Length == 0) - return Array.Empty(); // no rooms with geometry found. + return Array.Empty(); // no rooms with geometry found. - var filteredElementGeometricNodes = geometricNodesGroupedByElementIndex + var filteredElementGeometricNodes = elementGeometryInfo .AsParallel() .Where(g => { // Filter the elements - var elementInfo = g.First(); - if (!geometricElementInfoFilter(elementInfo)) + if (!geometricElementInfoFilter(g)) return false; // Ignore room elements. - if (roomElementIndices.Contains(elementInfo.ElementIndex)) + if (roomElementIndices.Contains(g.ElementIndex)) return false; return true; }).Select(g => { - var elementIndex = g.Key; + var elementIndex = g.ElementIndex; // Determine whether the element geometry's bounding box center is contained in one of the rooms. - var boundingBox = g.Select(n => n.TransformedBoundingBox()).Aggregate((acc, cur) => acc.Merge(cur)); + var boundingBox = g.WorldSpaceBoundingBox; var boxCenter = boundingBox.Center; foreach (var roomGeometry in roomGeometryCollection) @@ -92,7 +85,7 @@ public static ElementInRoom[] ComputeElementsInRoom(VimScene vim, GeometricEleme // Refined point-in-mesh check if (roomGeometry.ContainsPoint(boxCenter)) - return new ElementInRoom(elementIndex, roomGeometry.RoomIndex); // early return on the first room which contains the bottom center of the box. + return new VimElementInRoom(elementIndex, roomGeometry.RoomIndex); // early return on the first room which contains the bottom center of the box. } return null; @@ -104,31 +97,30 @@ public static ElementInRoom[] ComputeElementsInRoom(VimScene vim, GeometricEleme private class RoomGeometry { - private readonly Vector3[] _vertices; - private readonly int[] _indices; + private readonly VimMeshData _vimMeshData; public int RoomIndex { get; } public AABox AABox { get; } - public RoomGeometry(int roomIndex, Vector3[] vertices, int[] indices) + public RoomGeometry(int roomIndex, VimMeshData vimMeshData) { RoomIndex = roomIndex; - _vertices = vertices; - _indices = indices; - AABox = AABox.Create(vertices); + _vimMeshData = vimMeshData; + AABox = AABox.Create(_vimMeshData.GetVertices()); } public bool ContainsPoint(Vector3 point) { var intersections = 0; - + var indices = _vimMeshData.GetIndices(); + var vertices = _vimMeshData.GetVertices(); var ray = new Ray(point, Vector3.UnitZ); - for (var i = 0; i < _indices.Length; i += 3) + for (var i = 0; i < indices.Length; i += 3) { - var v0 = _vertices[_indices[i]]; - var v1 = _vertices[_indices[i + 1]]; - var v2 = _vertices[_indices[i + 2]]; + var v0 = vertices[indices[i]]; + var v1 = vertices[indices[i + 1]]; + var v2 = vertices[indices[i + 2]]; var triangle = new Triangle(v0, v1, v2); diff --git a/src/cs/vim/Vim.Format.Core/VimSchema.cs b/src/cs/vim/Vim.Format/VimSchema.cs similarity index 66% rename from src/cs/vim/Vim.Format.Core/VimSchema.cs rename to src/cs/vim/Vim.Format/VimSchema.cs index a8a946e0..23f72e83 100644 --- a/src/cs/vim/Vim.Format.Core/VimSchema.cs +++ b/src/cs/vim/Vim.Format/VimSchema.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Vim.Util; -using Vim.LinqArray; namespace Vim.Format { @@ -12,12 +11,12 @@ public class VimSchema public readonly SerializableVersion VimFormatVersion; public readonly SerializableVersion SchemaVersion; - public readonly Dictionary EntityTableSchemas = new Dictionary(); + public readonly Dictionary EntityTableSchemas = new Dictionary(); public VimSchema(SerializableVersion vimFormatVersion, SerializableVersion schemaVersion) => (VimFormatVersion, SchemaVersion) = (vimFormatVersion, schemaVersion); - public VimSchema(SerializableHeader header) + public VimSchema(VimHeader header) : this(header.FileFormatVersion, header.Schema) { } @@ -34,33 +33,64 @@ public IEnumerable GetAllQualifiedColumnNames() .Select(t => string.Join(TableNameSeparator, t.TableName, t.ColumnName)) .OrderBy(x => x); - public EntityTableSchema AddEntityTableSchema(string entityTableName) + public VimEntityTableSchema AddEntityTableSchema(string entityTableName) { if (EntityTableSchemas.ContainsKey(entityTableName)) throw new Exception($"Entity Table {entityTableName} already exists in the VIM schema"); - var ets = new EntityTableSchema(entityTableName); + var ets = new VimEntityTableSchema(entityTableName); EntityTableSchemas.Add(entityTableName, ets); return ets; } public static VimSchema Create(string filePath) - => Create(Serializer.Deserialize(filePath).ToDocument()); - - public static VimSchema Create(Document doc) + => Create(VIM.Open( + filePath, + options: new VimOpenOptions() { + IncludeAssets = false, + IncludeGeometry = false, + SchemaOnly = true + })); + + public static VimSchema Create(VIM vim) { - var vimSchema = new VimSchema(doc.Header); - foreach (var entityTable in doc.EntityTables.Values.ToEnumerable()) + var vimSchema = new VimSchema(vim.Header); + foreach (var entityTable in vim.EntityTableData) { var ets = vimSchema.AddEntityTableSchema(entityTable.Name); // Collect all the column names in the entity table and sort them alphabetically. - foreach (var columnName in entityTable.Columns.Select(nb => nb.Name).OrderBy(n => n)) + foreach (var columnName in entityTable.GetColumns().Select(nb => nb.Name).OrderBy(n => n)) ets.AddColumn(columnName); } return vimSchema; } + public static VimSchema GetCurrentVimSchema() + { + var vimSchema = new VimSchema(Format.VimFormatVersion.Current, Format.SchemaVersion.Current); + + foreach (var entityType in ObjectModelReflection.GetEntityTypes()) + { + var entityTableSchema = vimSchema.AddEntityTableSchema(entityType.GetEntityTableName()); + + foreach (var fieldInfo in entityType.GetRelationFields()) + { + var (indexColumnName, _) = fieldInfo.GetIndexColumnInfo(); + entityTableSchema.AddColumn(indexColumnName); + } + + foreach (var fieldInfo in entityType.GetEntityFields()) + { + var loadingInfos = fieldInfo.GetEntityColumnLoadingInfo(); + + foreach (var li in loadingInfos) + entityTableSchema.AddColumn(li.EntityColumnAttribute.SerializedValueColumnName); + } + } + return vimSchema; + } + public VimSchemaDiff Diff(VimSchema other) { var aCols = GetAllQualifiedColumnNames().ToArray(); @@ -110,12 +140,12 @@ public VimSchemaDiff(string[] qualifiedColumnNamesA, string[] qualifiedColumnNam } } - public class EntityTableSchema + public class VimEntityTableSchema { public readonly string TableName; public readonly HashSet ColumnNames = new HashSet(); - public EntityTableSchema(string tableName) + public VimEntityTableSchema(string tableName) => TableName = tableName; public void AddColumn(string columnName) diff --git a/src/cs/vim/Vim.Format/VimTransformService.cs b/src/cs/vim/Vim.Format/VimTransformService.cs new file mode 100644 index 00000000..1bca78a9 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimTransformService.cs @@ -0,0 +1,225 @@ +using System.Collections.Generic; +using System.Linq; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + public class VimTransformResult + { + public VimBuilder VimBuilder { get; } + public VimEntityTableBuilder[] EntityTableBuilders { get; } + public VimTransformResult(VimBuilder vimBuilder, VimEntityTableBuilder[] entityTableBuilders) + { + VimBuilder = vimBuilder; + EntityTableBuilders = entityTableBuilders; + } + + public void Write(string vimFilePath) + { + VimBuilder.Write(vimFilePath, EntityTableBuilders); + } + } + + public class VimTransformService + { + /// + /// A string representing the application which is emitting the new VIM document. + /// + private readonly string _generatorString; + + /// + /// The version of the application which is emitting the new VIM document. + /// + private readonly string _versionString; + + /// + /// Constructor. + /// + /// A string representing the application which is emitting the new VIM document. + /// The version of the application which is emitting the new VIM document. + public VimTransformService(string generatorString, string versionString) + { + _generatorString = generatorString; + _versionString = versionString; + } + + /// + /// Returns a new VIM builder in which the original meshes have been deduplicated. + /// + public VimTransformResult DeduplicateGeometry(VIM vim) + => Transform( + vim, + _ => true, + (_, cur) => cur, + true); + + /// + /// Returns a new VIM builder in which the elements and their geometry have been filtered. + /// + public VimTransformResult Filter(VIM vim, ElementFilter elementFilter, bool deduplicateMeshes = false) + => Transform( + vim, + elementFilter, + (_, cur) => cur, + deduplicateMeshes); + + /// + /// Returns a new VIM builder in which the element transforms have been multiplied by the given matrix. + /// + public VimTransformResult Transform(VIM vim, Matrix4x4 matrix, bool deduplicateMeshes = false) + => Transform( + vim, + _ => true, + (_, cur) => cur * matrix, + deduplicateMeshes); + + public delegate bool ElementFilter(VimElementGeometryInfo egi); + public delegate Matrix4x4 InstanceTransform(int instanceIndex, Matrix4x4 currentTransform); + + /// + /// Transforms the VIM into a new VIM builder based on the given filters and transformations. + /// + /// The VIM to transform into a new VIM builder. + /// Returns true if the given element should be present in the new VIM builder. + /// Returns the instance's new transform (or its current transform if left unchanged). + /// Determines whether the mesh deduplication process is applied. + public VimTransformResult Transform( + VIM vim, + ElementFilter elementFilter = null, + InstanceTransform instanceTransform = null, + bool deduplicateMeshes = false) + { + var vb = new VimBuilder(_generatorString, SchemaVersion.Current, _versionString); + + var geometryData = vim.GeometryData; + var elementGeometryInfo = vim.GetElementGeometryInfoList(); + + // Filter the elements and instances we want to keep + var oldInstanceIndexToNewInstanceIndex = new Dictionary(); + var instanceIndicesToKeep = new List(); + var elementIndicesToKeep = new HashSet(); + var meshIndicesToKeep = new HashSet(); + + foreach (var egi in elementGeometryInfo) // Reminder: ElementGeometryInfo is 1:1 aligned with the Element table. + { + var keep = elementFilter?.Invoke(egi) ?? true; + if (!keep) + continue; + + elementIndicesToKeep.Add(egi.ElementIndex); + + foreach (var (oldInstanceIndex, oldMeshIndex) in egi.InstanceAndMeshIndices) + { + if (oldInstanceIndex != -1 && !oldInstanceIndexToNewInstanceIndex.ContainsKey(oldInstanceIndex)) + { + var newInstanceIndex = instanceIndicesToKeep.Count; + instanceIndicesToKeep.Add(oldInstanceIndex); + oldInstanceIndexToNewInstanceIndex.Add(oldInstanceIndex, newInstanceIndex); + } + + if (oldMeshIndex != -1 && + geometryData.TryGetVimMeshView(oldMeshIndex, out var meshView) && + meshView.FaceCount != 0) + { + meshIndicesToKeep.Add(oldMeshIndex); + } + } + } + + var filteredEntityTableBuilders = VimEntityTableBuilderRemapped.FilterElements( + VimBuilder.GetVimEntityTableBuilders(vim), + elementIndicesToKeep, + instanceIndicesToKeep); + + var meshViewsToKeep = new List(); + var oldMeshIndexToNewMeshIndex = new Dictionary(); + + int KeepMeshView(VimMeshView meshView) + { + var newMeshIndex = meshViewsToKeep.Count; + meshViewsToKeep.Add(meshView); + oldMeshIndexToNewMeshIndex[meshView.MeshIndex] = newMeshIndex; + return newMeshIndex; + } + + if (deduplicateMeshes) + { + // Group the mesh views + var groupedMeshes = geometryData.GroupMeshViews(meshIndicesToKeep); + + // Create the lookup from old mesh view index to common mesh view + foreach (var g in groupedMeshes) + { + var newMeshIndex = KeepMeshView(g.Key.MeshView); + + foreach (var meshView in g) + { + oldMeshIndexToNewMeshIndex[meshView.MeshIndex] = newMeshIndex; + } + } + } + else + { + foreach (var oldMeshIndex in meshIndicesToKeep) + { + var meshView = geometryData.GetMeshView(oldMeshIndex); + if (meshView.HasValue) + { + KeepMeshView(meshView.Value); + } + } + } + + // Add the meshes. + foreach (var meshView in meshViewsToKeep) + { + vb.Meshes.Add(new VimSubdividedMesh(meshView)); + } + + // Add the instances. + foreach (var oldInstanceIndex in instanceIndicesToKeep) + { + var oldMeshIndex = geometryData.InstanceMeshes[oldInstanceIndex]; + + var newMeshIndex = oldMeshIndex == -1 + ? oldMeshIndex + : oldMeshIndexToNewMeshIndex[oldMeshIndex]; + + var oldTransform = geometryData.InstanceTransforms[oldInstanceIndex]; + var newTransform = instanceTransform?.Invoke(oldInstanceIndex, oldTransform) ?? oldTransform; + + var oldParentIndex = geometryData.InstanceParents.ElementAtOrDefault(oldInstanceIndex, -1); + var newParentIndex = oldParentIndex == -1 + ? oldParentIndex + : oldInstanceIndexToNewInstanceIndex.TryGetValue(oldParentIndex, out var p) ? p : -1; + + vb.Instances.Add(new VimInstance() + { + MeshIndex = newMeshIndex, + Transform = newTransform, + InstanceFlags = (InstanceFlags) geometryData.InstanceFlags[oldInstanceIndex], + ParentIndex = newParentIndex, + }); + } + + // Add the materials (preserves the material indices) + // TECH DEBT: this could be improved to remove orphaned or duplicate materials, but this would require a remapping of both the entity table and the g3d buffers. + for (var i = 0; i < vim.GeometryData.MaterialCount; ++i) + { + vb.Materials.Add(new VimMaterial() + { + Color = vim.GeometryData.MaterialColors.ElementAtOrDefault(i, default), + Glossiness = vim.GeometryData.MaterialGlossiness.ElementAtOrDefault(i, default), + Smoothness = vim.GeometryData.MaterialSmoothness.ElementAtOrDefault(i, default), + }); + } + + // Add the assets + foreach (var asset in vim.Assets) + vb.AddAsset(asset); + + return new VimTransformResult(vb, filteredEntityTableBuilders); + } + } +} diff --git a/src/cs/vim/Vim.Format/VimValidation.cs b/src/cs/vim/Vim.Format/VimValidation.cs new file mode 100644 index 00000000..4cb0b1c6 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimValidation.cs @@ -0,0 +1,493 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Vim.Math3d; +using Vim.Util; + +namespace Vim.Format +{ + public static class VimValidation + { + public static void Validate(this VIM vim, VimValidationOptions options = null) + { + options = options ?? new VimValidationOptions(); + + ValidateTableRows(vim); + ValidateIndexColumns(vim); + ValidateGeometryBuffers(vim); + ValidateAssetBuffers(vim); + ValidateEntitiesWithElement(vim); + ValidateBimDocument(vim, options); + ValidateCompoundStructures(vim); + ValidateAssets(vim); + ValidateParameters(vim); + ValidatePhases(vim); + if (options.UniqueStorageKeys) ValidateStorageKeys(vim); + if (options.ElementInSystemMustNotHaveNullValues) ValidateElementInSystem(vim); + ValidateMaterials(vim); + ValidateEntityAndGeometryInvariants(vim); + ValidateNodes(vim); + } + + public static void ValidateTableRows(VIM vim) + { + foreach (var et in vim.EntityTableData) + { + var rowCount = et.GetRowCount(); + foreach (var c in et.IndexColumns) + { + if (c.Data.Length != rowCount) + throw new VimValidationException($"Expected array length {c.Data.Length} of column {c.Name} to be the same as number of rows {rowCount}"); + } + + foreach (var c in et.StringColumns) + { + if (c.Data.Length != rowCount) + throw new VimValidationException($"Expected array length {c.Data.Length} of column {c.Name} to be the same as number of rows {rowCount}"); + } + + foreach (var c in et.DataColumns) + { + if (c.Data.Length != rowCount) + throw new VimValidationException($"Expected array length {c.Data.Length} of column {c.Name} to be the same as number of rows {rowCount}"); + } + } + } + + public static void ValidateIndexColumns(VIM vim) + { + var tableSet = vim.GetEntityTableSet(); + + foreach (var kv in tableSet.Tables) + { + var et = kv.Value; + foreach (var ixKv in et.IndexColumnMap) + { + var indexColumn = ixKv.Value; + + var relatedTableName = VimEntityTableColumnName.GetRelatedTableName(indexColumn); + + if (!tableSet.TryGetEntityTable(relatedTableName, out var table)) + throw new VimValidationException($"Could not find related table for index column {indexColumn.Name}"); + } + } + } + + public static void ValidateGeometryBuffers(VIM vim) + { + var geometryData = vim.GeometryData; + + if (geometryData.Header == null) throw new VimValidationException("VIM geometry data header is null"); + if (geometryData.Indices == null) throw new VimValidationException("VIM geometry indices is null"); + if (geometryData.Vertices == null) throw new VimValidationException("VIM geometry vertices is null"); + if (geometryData.MeshSubmeshOffsets == null) throw new VimValidationException("VIM geometry mesh submesh offests is null"); + if (geometryData.SubmeshIndexOffsets == null) throw new VimValidationException("VIM geometry submesh index offsets is null"); + if (geometryData.InstanceMeshes == null) throw new VimValidationException("VIM geometry instance meshes is null"); + if (geometryData.InstanceTransforms == null) throw new VimValidationException("VIM geometry instance transforms is null"); + } + + public static void ValidateAssetBuffers(VIM vim) + { + foreach (var asset in vim.Assets) + VimAssetInfo.Parse(asset.Name); // This will throw if it fails to parse. + } + + public static void ValidateEntitiesWithElement(VIM vim) + { + // All entities with element must have a valid element index. + + var entityWithElementTypes = new HashSet( + ObjectModelReflection.GetEntityTypes() + .Where(t => t.GetCustomAttributes(typeof(G3dAttributeReferenceAttribute), true).Count() == 0) + ); + + var entityWithElementTypesAndTableNames = entityWithElementTypes + .Select(t => (t, (t.GetCustomAttribute(typeof(TableNameAttribute)) as TableNameAttribute)?.Name)) + .Where(tuple => !string.IsNullOrEmpty(tuple.Item2)); + + var tableSet = vim.GetEntityTableSet(); + var elementCount = tableSet.ElementTable.RowCount; + + Parallel.ForEach(entityWithElementTypesAndTableNames, entityWithElementTypeAndTableName => + { + var (entityType, tableName) = entityWithElementTypeAndTableName; + if (!tableSet.TryGetEntityTable(tableName, out var entityTable)) + return; + + var elementIndices = entityTable.GetType().GetProperty("Column_ElementIndex")?.GetValue(entityTable) as int[]; + for (var i = 0; i < elementIndices.Length; ++i) + { + var elementIndex = elementIndices[i]; + if (elementIndex < 0) + throw new VimValidationException($"{nameof(EntityWithElement)} {tableName} @{i} has a negative element index: {elementIndex}."); + if (elementIndex >= elementCount) + throw new VimValidationException($"{nameof(EntityWithElement)} {tableName} @{i} has an invalid element index: {elementIndex}; element count: {elementCount}"); + } + }); + } + + public static void ValidateBimDocument(VIM vim, VimValidationOptions validationOptions) + { + var tableSet = vim.GetEntityTableSet(); + + // There is at least one BimDocument in the document model. + if (tableSet.BimDocumentTable.RowCount == 0 && validationOptions.BimDocumentMustExist) + throw new VimValidationException($"No {nameof(BimDocument)} found."); + + foreach (var bd in tableSet.BimDocumentTable) + { + var bdElement = bd.Element; + if (bdElement == null) + throw new VimValidationException($"{nameof(BimDocument)} @{bd.Index} has null {nameof(Element)}."); + + var expectedElementId = VimEntityTableConstants.SyntheticElementId; + if (validationOptions.BimDocumentElementMustBeSynthetic && bdElement.Id != expectedElementId) + throw new VimValidationException($"{nameof(BimDocument)} @{bd.Index} - Related {nameof(Element)}.{nameof(Element.Id)} @{bdElement.Index} is not {expectedElementId}"); + + var expectedName = bd.Name; + if (validationOptions.BimDocumentElementNameMustMatchBimDocumentName && bdElement.Name != expectedName) + throw new VimValidationException($"{nameof(BimDocument)} @{bd.Index} - Related {nameof(Element)}.{nameof(Element.Name)} @{bdElement.Index} does not match {nameof(BimDocument)}.{nameof(BimDocument.Name)} ({expectedName})"); + + var expectedElementType = VimEntityTableConstants.BimDocumentParameterHolderElementType; + if (validationOptions.BimDocumentElementTypeMustBeParameterHolder && bdElement.Type != expectedElementType) + throw new VimValidationException($"{nameof(BimDocument)} @{bd.Index} - Related {nameof(Element)}.{nameof(Element.Type)} @{bdElement.Index} is not '{expectedElementType}'."); + } + } + + public static void ValidateCompoundStructureLayer(CompoundStructureLayer layer) + { + // All CompoundLayers have a CompoundStructure + if (layer.CompoundStructure == null) + throw new VimValidationException($"{nameof(CompoundStructureLayer)} {layer.Index} has null {nameof(CompoundStructure)}"); + } + + public static void ValidateCompoundStructures(VIM vim) + { + var tableSet = vim.GetEntityTableSet(); + + var cslArray = tableSet.CompoundStructureLayerTable.ToArray(); + + // All compound structure layers are valid + foreach (var csl in cslArray) + ValidateCompoundStructureLayer(csl); + + // There are no gaps in the order index of compound structure layers. + foreach (var cslCluster in cslArray.GroupBy(csl => csl._CompoundStructure.Index)) + { + var ordered = cslCluster.OrderBy(csl => csl.OrderIndex).ToArray(); + for (var i = 0; i < ordered.Length; ++i) + { + var orderIndex = ordered[i].OrderIndex; + if (orderIndex != i) + throw new VimValidationException($"{nameof(CompoundStructureLayer.OrderIndex)} {orderIndex} does not match expected value of {i}"); + } + + var csIndex = cslCluster.Key; + var csStructuralLayerIndex = tableSet.CompoundStructureTable.Column_StructuralLayerIndex.ElementAtOrDefault(csIndex, EntityRelation.None); + if (csStructuralLayerIndex != EntityRelation.None) + { + // If the CompoundStructure.StructuralMaterial exists, it should be a valid relation to a CompoundStructureLayer + var maxIndex = cslArray.Length - 1; + if (csStructuralLayerIndex < 0 || csStructuralLayerIndex > maxIndex) + throw new VimValidationException($"{nameof(CompoundStructure)} {csIndex} has an invalid {nameof(CompoundStructure.StructuralLayer)} relation index of {csStructuralLayerIndex}. Expected value between [0..{maxIndex}]"); + } + } + + // All FamilyTypes with compound structures are system families. + var ftArray = tableSet.FamilyTypeTable.ToArray(); + var cslRelationIndices = new HashSet(cslArray.Select(l => l.CompoundStructure.Index)); + var ftRelationIndices = new HashSet(ftArray.Where(ft => ft.CompoundStructure != null).Select(ft => ft.CompoundStructure.Index)); + var csArray = tableSet.CompoundStructureTable.ToArray(); + foreach (var cs in csArray) + { + // All compound structures are referenced by at least one compound structure layer + if (!cslRelationIndices.Contains(cs.Index)) + throw new VimValidationException($"{nameof(CompoundStructure)} index: {cs.Index} does not have a corresponding {nameof(CompoundStructureLayer)}"); + + // All compound structures are referenced by at least one family type. + if (!ftRelationIndices.Contains(cs.Index)) + throw new VimValidationException($"{nameof(CompoundStructure)} index: {cs.Index} does not have a corresponding {nameof(FamilyType)}"); + } + + // A compound structure must be referenced by exactly one family type (no re-using compound structures). + if (ftRelationIndices.Count != ftRelationIndices.Distinct().Count()) + throw new VimValidationException($"A {nameof(CompoundStructure)} must be referenced by exactly one {nameof(FamilyType)}."); + } + + public static void ValidateAssets(VIM vim) + { + // Validate that the assets contained in the buffers matches the assets entity table. + var assetBuffers = vim.Assets; + var assetEntities = vim.GetEntityTableSet().AssetTable.ToArray(); + foreach (var asset in assetEntities) + { + if (assetBuffers.FirstOrDefault(ab => ab.Name == asset.BufferName) == null) + throw new VimValidationException($"No matching asset buffer found for asset entity {asset.Index} with {nameof(asset.BufferName)} '{asset.BufferName}'"); + } + } + + public static void ValidateParameters(VIM vim) + { + var tableSet = vim.GetEntityTableSet(); + Parallel.ForEach(tableSet.ParameterTable, p => + { + // Each parameter must be associated to an element. + if (p._Element.Index == EntityRelation.None) + throw new VimValidationException($"{nameof(Element)} not found for {nameof(Parameter)} {p.Index}"); + + // Each parameter must have a parameter descriptor. + if (p.ParameterDescriptor == null) + throw new VimValidationException($"{nameof(ParameterDescriptor)} is null for {nameof(Parameter)} {p.Index}"); + }); + + // Validate the parameter descriptors. + foreach (var pd in tableSet.ParameterDescriptorTable) + { + if (pd.DisplayUnit == null) + throw new VimValidationException($"{nameof(DisplayUnit)} is null for {nameof(ParameterDescriptor)} {pd.Index}"); + } + } + + public static void ValidatePhases(VIM vim) + { + // Validate the phase order information. + var tableSet = vim.GetEntityTableSet(); + var poArray = tableSet.PhaseOrderInBimDocumentTable.ToArray(); + foreach (var po in poArray) + { + var bd = po.BimDocument; + if (bd == null) + throw new VimValidationException($"{nameof(BimDocument)} is null for {nameof(PhaseOrderInBimDocument)} {po.Index}"); + + var phase = po.Phase; + if (phase == null) + throw new VimValidationException($"{nameof(Phase)} is null for {nameof(PhaseOrderInBimDocument)} {po.Index}"); + } + + // Validate the order indices in the bim documents. + foreach (var g in poArray.GroupBy(po => po._BimDocument.Index)) + { + var ordered = g.OrderBy(v => v.OrderIndex).ToArray(); + for (var i = 0; i < ordered.Length; ++i) + { + var po = ordered[i]; + var orderIndex = po.OrderIndex; + if (orderIndex != i) + throw new VimValidationException($"Unexpected OrderIndex {orderIndex}; expected {i} in {nameof(PhaseOrderInBimDocument)} {po.Index}"); + } + } + + // Validate that the phase order information covers the set of phases. + var phaseIndexSet = new HashSet(tableSet.PhaseTable.Select(p => p.Index)); + phaseIndexSet.ExceptWith(poArray.Select(po => po.Index)); + if (phaseIndexSet.Count != 0) + throw new VimValidationException($"{nameof(Phase)} index coverage is incomplete among {nameof(PhaseOrderInBimDocument)}"); + } + + /// + /// Validate that the entity tables whose entities inherit from IStorageKey all have unique storage key values. + /// + public static void ValidateStorageKeys(VIM vim) + { + var tableSet = vim.GetEntityTableSet(); + var storageKeyTables = tableSet.Tables.Values.OfType>(); + foreach (var storageKeyTable in storageKeyTables) + { + ValidateStorageKeyTable(storageKeyTable); + } + } + + /// + /// Generic storage key check; ensures that the keys only appear once in the keySet. + /// + public static void ValidateStorageKeyTable(IEnumerable storageKeyEntities) + { + var keySet = new HashSet(); + foreach (var entity in storageKeyEntities) + { + var key = entity.GetStorageKey(); + if (!keySet.Add(key)) + throw new VimValidationException($"Duplicate storage key ({key}) found for {entity.GetType().Name}"); + } + } + + public static void ValidateElementInSystem(VIM vim) + { + foreach (var eis in vim.GetEntityTableSet().ElementInSystemTable) + { + if (eis.System == null) + throw new VimValidationException($"{nameof(ElementInSystem)} @ {eis.Index} has a null {nameof(ElementInSystem.System)}"); + + if (eis.Element == null) + throw new VimValidationException($"{nameof(ElementInSystem)} @ {eis.Index} has a null {nameof(ElementInSystem.Element)}"); + } + } + + public static void ValidateMaterials(VIM vim) + { + foreach (var material in vim.GetEntityTableSet().MaterialTable) + { + var index = material.Index; + ValidateDVector3Domain(nameof(material.Color), material.Color, DVector3.Zero, DVector3.One, index); + ValidateDomain(nameof(material.Glossiness), material.Glossiness, 0d, 1d, index); + ValidateDomain(nameof(material.Smoothness), material.Smoothness, 0d, 1d, index); + ValidateDomain(nameof(material.Transparency), material.Transparency, 0d, 1d, index); + ValidateDomain(nameof(material.NormalAmount), material.NormalAmount, 0d, 1d, index); + } + } + + public static void ValidateDomain(string label, double value, double lowerInclusive, double upperInclusive, int index) + { + if (value < lowerInclusive || value > upperInclusive) + throw new VimValidationException($"{label} {value} is not in the range [{lowerInclusive}..{upperInclusive}] for material {index}"); + } + + public static void ValidateDVector3Domain(string label, DVector3 value, DVector3 lowerInclusive, DVector3 upperInclusive, int index) + { + if (value.X < lowerInclusive.X || + value.Y < lowerInclusive.Y || + value.Z < lowerInclusive.Z || + value.X > upperInclusive.X || + value.Y > upperInclusive.Y || + value.Z > upperInclusive.Z) + { + throw new VimValidationException($"{label} {value} is not in the range [{lowerInclusive}..{upperInclusive}] for material {index}"); + } + } + + public static void ValidateGeometry(VIM vim) + { + var geometryData = vim.GeometryData; + + var indexCount = geometryData.IndexCount; + var vertexCount = geometryData.VertexCount; + var meshCount = geometryData.MeshCount; + var meshSubmeshOffset = geometryData.MeshSubmeshOffsets; + var meshSubmeshCount = geometryData.MeshSubmeshCount; + var submeshCount = geometryData.SubmeshCount; + var submeshMaterialCount = geometryData.SubmeshMaterials.Length; + var submeshIndexOffsets = geometryData.SubmeshIndexOffsets; + var submeshIndexOffsetCount = submeshIndexOffsets.Length; + var submeshIndexCount = geometryData.SubmeshIndexCount; + var instanceCount = geometryData.InstanceCount; + var instanceParentCount = geometryData.InstanceParents.Length; + var instanceMeshesCount = geometryData.InstanceMeshes.Length; + var instanceTransformsCount = geometryData.InstanceTransforms.Length; + var instanceFlagsCount = geometryData.InstanceFlags.Length; + var materialCount = geometryData.MaterialCount; + var materialColorCount = geometryData.MaterialColors.Length; + var materialGlossinessCount = geometryData.MaterialGlossiness.Length; + var materialSmoothnessCount = geometryData.MaterialSmoothness.Length; + + // Indices + ValidateIndices(geometryData); // Validates the packed geometry. + foreach (var m in geometryData.GetMeshViews()) { ValidateIndices(m.GetIndices(), m.VertexCount); } // Validates the individual meshes. + if (!(indexCount % 3 == 0)) throw new VimValidationException($"Geometry data index count {indexCount} must be divisible by 3"); + if (!geometryData.Indices.All(i => i >= 0 && i < geometryData.VertexCount)) throw new VimValidationException($"Geometry data indices must all be between 0 and the vertex count {vertexCount}"); + + // Submeshes + if (!(submeshCount >= meshCount)) throw new VimValidationException($"Geometry data submesh count {submeshCount} must be greater than or equal to the mesh count {meshCount}"); + if (!(submeshCount == submeshMaterialCount)) throw new VimValidationException($"Geometry data submesh count {submeshCount} must be equal to the submesh material count {submeshMaterialCount}"); + if (!(submeshCount == submeshIndexOffsetCount)) throw new VimValidationException($"Geometry data submesh count {submeshCount} must be equal to the length of the submesh index offsets {submeshIndexOffsetCount}"); + if (!submeshIndexOffsets.All(i => i % 3 == 0)) throw new VimValidationException("Geometry data submesh index offsets must all be divisible by 3"); + if (!submeshIndexOffsets.All(i => i >= 0 && i < indexCount)) throw new VimValidationException($"Geometry data submesh index offsets must all index into the index buffer"); + if (!submeshIndexCount.All(i => i > 0)) throw new VimValidationException("Geometry data submesh index counts must all be positive"); + + // Meshes + if (!meshSubmeshOffset.All(i => i >= 0 && i < submeshCount)) throw new VimValidationException("Geometry data mesh submesh offsets must all index into the submesh index offsets buffer"); + if (!meshSubmeshCount.All(i => i > 0)) throw new VimValidationException("Geometry data mesh submesh counts must all be positive"); + + // Instances + if (!(instanceCount == instanceParentCount)) throw new VimValidationException($"Geometry data instance count {instanceCount} must be equal to the instance parent count {instanceParentCount}"); + if (!(instanceCount == instanceMeshesCount)) throw new VimValidationException($"Geometry data instance count {instanceCount} must be equal to the instance mesh count {instanceMeshesCount}"); + if (!(instanceCount == instanceTransformsCount)) throw new VimValidationException($"Geometry data instance count {instanceCount} must be equal to the instance transform count {instanceTransformsCount}"); + if (!(instanceCount == instanceFlagsCount)) throw new VimValidationException($"Geometry data instance count {instanceCount} must be equal to the instance flag count {instanceFlagsCount}"); + if (!geometryData.InstanceParents.All(i => i < instanceCount)) throw new VimValidationException($"Geometry data instance parent indices must be less than the instance count {instanceCount}"); + if (!geometryData.InstanceMeshes.All(i => i < meshCount)) throw new VimValidationException($"Geometry data instance mesh indices must be less than the mesh count {meshCount}"); + + // Materials + if (!(materialCount == materialColorCount)) throw new VimValidationException($"Geometry data material count {materialCount} must be equal to the material color count {materialColorCount}"); + if (!(materialCount == materialGlossinessCount)) throw new VimValidationException($"Geometry data material count {materialCount} must be equal to the material glossiness count {materialGlossinessCount}"); + if (!(materialCount == materialSmoothnessCount)) throw new VimValidationException($"Geometry data material count {materialCount} must be equal to the material smoothness count {materialSmoothnessCount}"); + } + + public static void ValidateIndices(VimGeometryData geometryData) + { + ValidateIndices(geometryData.Indices, geometryData.VertexCount); + } + + public static void ValidateIndices(int[] indices, int vertexCount) + { + foreach (var index in indices) + { + if (index < 0 || index >= vertexCount) + throw new VimValidationException($"Invalid mesh index: {index}. Expected a value greater or equal to 0 and less than {vertexCount}"); + } + } + + public static void ValidateEntityAndGeometryInvariants(VIM vim) + { + var geometry = vim.GeometryData; + var errors = new List(); + + var entityTypesWithGeometryReferences = new HashSet<(Type, string, G3dAttributeReferenceAttribute[])>( + ObjectModelReflection.GetEntityTypes() + .Select(t => ( + type: t, + tableName: t.GetCustomAttribute()?.Name, + attrs: t.GetCustomAttributes(typeof(G3dAttributeReferenceAttribute)) + .Select(a => a as G3dAttributeReferenceAttribute) + .ToArray())) + .Where(tuple => tuple.attrs.Length != 0) + ); + + var tableSet = vim.GetEntityTableSet(); + + foreach (var tuple in entityTypesWithGeometryReferences) + { + var (type, tableName, attrs) = tuple; + + if (!tableSet.Tables.TryGetValue(tableName, out var table)) + throw new VimValidationException($"Entity table not found: {tableName}"); + + var numEntities = table.RowCount; + + foreach (var attr in attrs) + { + var bufferName = attr.AttributeName; + var isOptional = attr.AttributeIsOptional; + + var geometryItemCount = vim.GeometryData.GetItemCountByBufferName(bufferName); + + // We don't check the relation if the attribute is optional and absent (null). + if (isOptional && geometryItemCount == 0) + continue; + + var mult = attr.AttributeReferenceMultiplicity; + + // Validate one-to-one relationships + if (mult == G3dAttributeReferenceMultiplicity.OneToOne && numEntities != geometryItemCount) + { + errors.Add($"Multiplicity Error ({mult}); the number of entities of type \"{type.Name}\" ({numEntities}) is not equal to the number of elements in the geometry buffer \"{bufferName}\" ({geometryItemCount})"); + } + } + } + + if (errors.Count > 0) + { + throw new VimValidationException( + $"Entity geometry invariant error(s):{Environment.NewLine}{string.Join(Environment.NewLine, errors)}"); + } + } + + public static void ValidateNodes(VIM vim) + { + var nodeEntityCount = vim.GetEntityTableSet().NodeTable.RowCount; + var instanceCount = vim.GeometryData.InstanceCount; + if (nodeEntityCount != instanceCount) + throw new VimValidationException($"The number of Node entities {nodeEntityCount} must match the number of geometry instances ({instanceCount})"); + } + } +} diff --git a/src/cs/vim/Vim.Format/VimValidationException.cs b/src/cs/vim/Vim.Format/VimValidationException.cs new file mode 100644 index 00000000..21049290 --- /dev/null +++ b/src/cs/vim/Vim.Format/VimValidationException.cs @@ -0,0 +1,9 @@ +using System; + +namespace Vim.Format +{ + public class VimValidationException : Exception + { + public VimValidationException(string message) : base(message) { } + } +} \ No newline at end of file diff --git a/src/cs/vim/Vim.Format/VimValidationOptions.cs b/src/cs/vim/Vim.Format/VimValidationOptions.cs new file mode 100644 index 00000000..21a4724a --- /dev/null +++ b/src/cs/vim/Vim.Format/VimValidationOptions.cs @@ -0,0 +1,39 @@ +namespace Vim.Format +{ + public class VimValidationOptions + { + /// + /// Validation will fail if duplicate storage keys are detected. Setting this to false simplifies merged VIM validation. + /// + public bool UniqueStorageKeys { get; set; } = true; + + /// + /// By default, we expect at least one BimDocument entity. Setting this to false suppresses this requirement. This is typically + /// useful when stripping the bim data from the VIM file to keep it as light as possible. + /// + public bool BimDocumentMustExist { get; set; } = true; + + /// + /// By default, it is recommended that the bim document element has an element id of -1. + /// Note: this may not always be the case, particularly for IFC to VIM conversions. + /// + public bool BimDocumentElementMustBeSynthetic { get; set; } = true; + + /// + /// By default, it is recommended that the bim document element has an element whose name is equal to the bim document's name. + /// Note: this may not always be the case, particularly for IFC to VIM conversions. + /// + public bool BimDocumentElementNameMustMatchBimDocumentName { get; set; } = true; + + /// + /// By default, it is recommended that the bim document element's type is set to "BimDocument Parameter Holder" + /// Note: this may not always be the case, particularly for IFC to VIM conversions. + /// + public bool BimDocumentElementTypeMustBeParameterHolder { get; set; } = true; + + /// + /// By default, it is recommended to avoid elements in systems having null values. This has been fixed as of object model v4.5.0 + /// + public bool ElementInSystemMustNotHaveNullValues { get; set; } = true; + } +} \ No newline at end of file