diff --git a/docs/object-model-schema.json b/docs/object-model-schema.json index 73979ae..68bbe25 100644 --- a/docs/object-model-schema.json +++ b/docs/object-model-schema.json @@ -1,6 +1,6 @@ { "VimFormatVersion": "1.0.0", - "SchemaVersion": "5.8.0", + "SchemaVersion": "5.9.0", "Tables": { "Vim.Area": [ "byte:IsGrossInterior", @@ -151,6 +151,7 @@ "index:Vim.Room:Room", "index:Vim.View:OwnerView", "index:Vim.Workset:Workset", + "int:LocationSource", "long:Id", "string:Creator", "string:FamilyName", @@ -402,7 +403,8 @@ "string:Name" ], "Vim.Shape": [ - "index:Vim.Element:Element" + "index:Vim.Element:Element", + "int:Kind" ], "Vim.ShapeCollection": [ "index:Vim.Element:Element" diff --git a/docs/schema-diff.json b/docs/schema-diff.json index e194928..0ade04c 100644 --- a/docs/schema-diff.json +++ b/docs/schema-diff.json @@ -232,5 +232,11 @@ "Vim.SunAndShadowSettings__string:StartDateAndTime", "Vim.SunAndShadowSettings__string:SunAndShadowType" ] + }, + "5.8.0 to 5.9.0": { + "Added": [ + "Vim.Element__int:LocationSource", + "Vim.Shape__int:Kind" + ] } } \ No newline at end of file diff --git a/src/cpp/vim/object-model.h b/src/cpp/vim/object-model.h index 2037d7f..7a37add 100644 --- a/src/cpp/vim/object-model.h +++ b/src/cpp/vim/object-model.h @@ -1005,6 +1005,7 @@ namespace Vim float mLocation_X; float mLocation_Y; float mLocation_Z; + int mLocationSource; std::string mFamilyName; bool mIsPinned; std::string mCreator; @@ -1061,6 +1062,7 @@ namespace Vim element->mLocation_X = GetLocation_X(elementIndex); element->mLocation_Y = GetLocation_Y(elementIndex); element->mLocation_Z = GetLocation_Z(elementIndex); + element->mLocationSource = GetLocationSource(elementIndex); element->mFamilyName = GetFamilyName(elementIndex); element->mIsPinned = GetIsPinned(elementIndex); element->mCreator = GetCreator(elementIndex); @@ -1089,6 +1091,7 @@ namespace Vim bool existsLocation_X = mEntityTable.column_exists("float:Location.X"); bool existsLocation_Y = mEntityTable.column_exists("float:Location.Y"); bool existsLocation_Z = mEntityTable.column_exists("float:Location.Z"); + bool existsLocationSource = mEntityTable.column_exists("int:LocationSource"); bool existsFamilyName = mEntityTable.column_exists("string:FamilyName"); bool existsIsPinned = mEntityTable.column_exists("byte:IsPinned"); bool existsCreator = mEntityTable.column_exists("string:Creator"); @@ -1142,6 +1145,11 @@ namespace Vim memcpy(location_ZData, mEntityTable.mDataColumns["float:Location.Z"].begin(), count * sizeof(float)); } + int* locationSourceData = new int[count]; + if (mEntityTable.column_exists("int:LocationSource")) { + memcpy(locationSourceData, mEntityTable.mDataColumns["int:LocationSource"].begin(), count * sizeof(int)); + } + const std::vector& familyNameData = mEntityTable.column_exists("string:FamilyName") ? mEntityTable.mStringColumns["string:FamilyName"] : std::vector(); bfast::byte* isPinnedData = new bfast::byte[count]; @@ -1185,6 +1193,8 @@ namespace Vim entity.mLocation_Y = location_YData[i]; if (existsLocation_Z) entity.mLocation_Z = location_ZData[i]; + if (existsLocationSource) + entity.mLocationSource = locationSourceData[i]; if (existsFamilyName) entity.mFamilyName = std::string(reinterpret_cast(mStrings[familyNameData[i]])); if (existsIsPinned) @@ -1213,6 +1223,7 @@ namespace Vim delete[] location_XData; delete[] location_YData; delete[] location_ZData; + delete[] locationSourceData; delete[] isPinnedData; return element; @@ -1426,6 +1437,34 @@ namespace Vim return result; } + int GetLocationSource(int elementIndex) + { + if (elementIndex < 0 || elementIndex >= GetCount()) + return {}; + + if (mEntityTable.column_exists("int:LocationSource")) { + return *reinterpret_cast(const_cast(mEntityTable.mDataColumns["int:LocationSource"].begin() + elementIndex * sizeof(int))); + } + + return {}; + } + + std::vector* GetAllLocationSource() + { + const auto count = GetCount(); + + int* locationSourceData = new int[count]; + if (mEntityTable.column_exists("int:LocationSource")) { + memcpy(locationSourceData, mEntityTable.mDataColumns["int:LocationSource"].begin(), count * sizeof(int)); + } + + std::vector* result = new std::vector(locationSourceData, locationSourceData + count); + + delete[] locationSourceData; + + return result; + } + std::string GetFamilyName(int elementIndex) { if (elementIndex < 0 || elementIndex >= GetCount()) @@ -10398,6 +10437,7 @@ namespace Vim { public: int mIndex; + int mKind; int mElementIndex; Element* mElement; @@ -10422,12 +10462,14 @@ namespace Vim { Shape* shape = new Shape(); shape->mIndex = shapeIndex; + shape->mKind = GetKind(shapeIndex); shape->mElementIndex = GetElementIndex(shapeIndex); return shape; } std::vector* GetAll() { + bool existsKind = mEntityTable.column_exists("int:Kind"); bool existsElement = mEntityTable.column_exists("index:Vim.Element:Element"); const auto count = GetCount(); @@ -10435,19 +10477,56 @@ namespace Vim std::vector* shape = new std::vector(); shape->reserve(count); + int* kindData = new int[count]; + if (mEntityTable.column_exists("int:Kind")) { + memcpy(kindData, mEntityTable.mDataColumns["int:Kind"].begin(), count * sizeof(int)); + } + const std::vector& elementData = mEntityTable.column_exists("index:Vim.Element:Element") ? mEntityTable.mIndexColumns["index:Vim.Element:Element"] : std::vector(); for (int i = 0; i < count; ++i) { Shape entity; entity.mIndex = i; + if (existsKind) + entity.mKind = kindData[i]; entity.mElementIndex = existsElement ? elementData[i] : -1; shape->push_back(entity); } + delete[] kindData; + return shape; } + int GetKind(int shapeIndex) + { + if (shapeIndex < 0 || shapeIndex >= GetCount()) + return {}; + + if (mEntityTable.column_exists("int:Kind")) { + return *reinterpret_cast(const_cast(mEntityTable.mDataColumns["int:Kind"].begin() + shapeIndex * sizeof(int))); + } + + return {}; + } + + std::vector* GetAllKind() + { + const auto count = GetCount(); + + int* kindData = new int[count]; + if (mEntityTable.column_exists("int:Kind")) { + memcpy(kindData, mEntityTable.mDataColumns["int:Kind"].begin(), count * sizeof(int)); + } + + std::vector* result = new std::vector(kindData, kindData + count); + + delete[] kindData; + + return result; + } + int GetElementIndex(int shapeIndex) { if (!mEntityTable.column_exists("index:Vim.Element:Element")) { diff --git a/src/cs/vim/Vim.Format.Tests/DrawingCurveEntityTests.cs b/src/cs/vim/Vim.Format.Tests/DrawingCurveEntityTests.cs new file mode 100644 index 0000000..a264122 --- /dev/null +++ b/src/cs/vim/Vim.Format.Tests/DrawingCurveEntityTests.cs @@ -0,0 +1,78 @@ +using System.IO; +using System.Linq; +using NUnit.Framework; +using Vim.Format.ObjectModel; +using Vim.Format.SceneBuilder; +using Vim.LinqArray; +using Vim.Math3d; +using Vim.Util.Tests; + +namespace Vim.Format.Tests +{ + /// + /// Object model 5.9.0: Shape.Kind (what a polyline draws) and Element.LocationSource (where Element.Location comes from) + /// round-trip through a VIM file, and the shape polylines stay in the G3D shape buffers in Shape row order. + /// + [TestFixture] + public static class DrawingCurveEntityTests + { + [Test] + public static void TestShapeKindAndLocationSourceRoundTrip() + { + var ctx = new CallerTestContext(); + var dir = ctx.PrepareDirectory(); + + var store = new ObjectModelStore(); + var omb = store.ObjectModelBuilder; + + var bimDocument = new BimDocument { Name = "Drawing curves", Title = "Drawing curves" }; + var bimDocumentElement = omb.ElementBuilder.Add(bimDocument.CreateParameterHolderElement()).Entity; + bimDocument._Element.Index = bimDocumentElement.Index; + omb.BimDocumentBuilder.Add(bimDocument); + + var door = omb.ElementBuilder.Add(new Element + { + Id = 30, Name = "Door", UniqueId = "door", + Location = new Vector3(3, -26, 0), + LocationSource = (int) ElementLocationSource.LocationPoint, + }).Entity; + var empty = omb.ElementBuilder.Add(new Element + { + Id = 31, Name = "Empty family", UniqueId = "empty", + Location = new Vector3(19, -26, 0), + LocationSource = (int) ElementLocationSource.InstanceOrigin, + }).Entity; + var type = omb.ElementBuilder.Add(new Element { Id = 32, Name = "A type", UniqueId = "type", LocationSource = (int) ElementLocationSource.None }).Entity; + + // A door swing (symbolic arc, 3 points) and a void edge (2 points) on the door. + store.Shapes.Add(new DocumentBuilder.Shape { Vertices = new[] { new Vector3(2, -27, 0), new Vector3(2.7f, -26.7f, 0), new Vector3(3, -26, 0) }.ToList(), Color = new Vector4(0, 0, 0, 1), Width = 1 }); + omb.ShapeBuilder.AddUntracked(new Shape { _Element = { Index = door.Index }, Kind = (int) ShapeKind.SymbolicCurve }); + store.Shapes.Add(new DocumentBuilder.Shape { Vertices = new[] { new Vector3(2, -26, 0), new Vector3(2, -26, 2) }.ToList(), Color = new Vector4(0, 0, 0, 1), Width = 1 }); + omb.ShapeBuilder.AddUntracked(new Shape { _Element = { Index = door.Index }, Kind = (int) ShapeKind.VoidEdge }); + + var path = Path.Combine(dir, "drawing-curves.vim"); + store.ToDocumentBuilder(nameof(DrawingCurveEntityTests), "0.0.0").Write(path); + + var vim = VimScene.LoadVim(path); + vim.Validate(); + var dm = vim.DocumentModel; + + Assert.AreEqual(SchemaVersion.Current.ToString(), vim.Document.Header.Schema.ToString()); + Assert.AreEqual(ElementLocationSource.LocationPoint, dm.GetElement(door.Index).GetLocationSource()); + Assert.AreEqual(ElementLocationSource.InstanceOrigin, dm.GetElement(empty.Index).GetLocationSource()); + Assert.AreEqual(new Vector3(19, -26, 0), dm.GetElement(empty.Index).Location); + Assert.AreEqual(ElementLocationSource.None, dm.GetElement(type.Index).GetLocationSource()); + + Assert.AreEqual(2, dm.NumShape); + Assert.AreEqual(ShapeKind.SymbolicCurve, dm.GetShape(0).GetKind()); + Assert.AreEqual(ShapeKind.VoidEdge, dm.GetShape(1).GetKind()); + Assert.AreEqual("door", dm.GetShape(1).Element.UniqueId); + + var g = vim.Document.Geometry; + Assert.AreEqual(2, g.ShapeVertexOffsets.Count); + Assert.AreEqual(5, g.ShapeVertices.Count); + Assert.AreEqual(3, g.ShapeVertexOffsets[1]); + Assert.AreEqual(new Vector3(2, -26, 2), g.ShapeVertices[4]); + } + } +} diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs index ceaa36a..667c59c 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs @@ -14,6 +14,12 @@ public static class SchemaVersion // ReSharper disable MemberHidesStaticFromOuterClass public static class History { + // Schema additions (something drawable for the elements that have no triangles: model lines, symbolic lines, + // void outlines and location curves as Shapes of a given kind, and where each element's Location comes from) + // Vim.Element__int:LocationSource + // Vim.Shape__int:Kind + public const string v5_9_0 = "5.9.0"; + // Schema additions (light sources and the sun, previously written as "light/lights.json" and "light/sun.json" assets) // Vim.LightSource__byte:HasLightSourceTransform // Vim.LightSource__byte:IsOn @@ -240,7 +246,8 @@ public static class History // ReSharper enable MemberHidesStaticFromOuterClass // [MAINTAIN] Add more object model SerializableVersions below and update the current one. - public static SerializableVersion Current => v5_8_0; + public static SerializableVersion Current => v5_9_0; + public static SerializableVersion v5_9_0 => SerializableVersion.Parse(History.v5_9_0); public static SerializableVersion v5_8_0 => SerializableVersion.Parse(History.v5_8_0); public static SerializableVersion v5_7_0 => SerializableVersion.Parse(History.v5_7_0); public static SerializableVersion v5_6_0 => SerializableVersion.Parse(History.v5_6_0); @@ -821,6 +828,25 @@ public static (bool HasValue, bool IsDubious) GetValueInfo(string value) } } + /// + /// Where an Element's Location comes from (Element.LocationSource). + /// + public enum ElementLocationSource + { + /// Not recorded (files written before object model 5.9.0, or an exporter which does not fill it). + Unknown = 0, + /// The element has no placement (for example a type, a view, or an element without location or extent). Location is (0, 0, 0). + None = 1, + /// Revit: the element's LocationPoint.Point. + LocationPoint = 2, + /// Revit: the middle of the element's LocationCurve (Curve.Evaluate(0.5, normalized)). + LocationCurve = 3, + /// Revit: the origin of the family instance's total transform (FamilyInstance.GetTotalTransform().Origin), for an instance without a location. + InstanceOrigin = 4, + /// Revit: the centre of the element's model bounding box (Element.get_BoundingBox(null)), for an element with no other placement. + BoundingBoxCenter = 5, + } + /// /// Represents an object which can be associated to a collection of Parameters. /// @@ -839,6 +865,11 @@ public partial class Element : Entity /// public string UniqueId; + /// + /// A point which places the element, in feet. LocationSource says where it comes from.
+ /// Since object model 5.9.0 (when LocationSource is set) the point is in the same world space as the geometry + /// (a linked document's transform is applied), so an element without triangles can still be found and zoomed to. + ///
public float Location_X; public float Location_Y; public float Location_Z; @@ -848,6 +879,15 @@ public Vector3 Location set => (Location_X, Location_Y, Location_Z) = value; } + /// + /// The integer representation of the ElementLocationSource enum: where Location comes from. + /// 0 (Unknown) in files written before 5.9.0, where Location is (0, 0, 0) both for "at the origin" and for "no location". + /// + public int LocationSource; + + public ElementLocationSource GetLocationSource() + => (ElementLocationSource) LocationSource; + public string FamilyName; public bool IsPinned; @@ -1617,9 +1657,33 @@ public AABox Box public int FaceCount; } + /// + /// What a Shape draws (Shape.Kind). Kinds other than Unknown are lines of the model itself, in world space and in feet, + /// meant to be drawn in 3D as lines (never filled, never as a solid) and picked as their Element. + /// + public enum ShapeKind + { + /// Not recorded: files written before object model 5.9.0. + Unknown = 0, + /// A line of a 2D view's drawing (the linework of the exported view sheet sets) or a face outline; bound to its View by ShapeInView. + ViewLinework = 1, + /// A model curve: a model line element, or a curve inside a family instance's 3D geometry (Revit draws it in 3D). + ModelCurve = 2, + /// A symbolic line of a family (for example a door swing): Revit draws it only in plan views. Placed at the instance, in world space. + SymbolicCurve = 3, + /// An edge loop of a void: a family's void form (cutting geometry), or an opening element (wall, floor, roof or shaft opening). Never a solid. + VoidEdge = 4, + /// The location curve of an element (for example a beam's location line, or the curve of an element without triangles). + LocationCurve = 5, + /// A grid line (its full model curve). + Grid = 6, + } + /// /// 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. + /// The points live in the G3D shape vertex buffer ("g3d:shapevertex:position:0:float32:3", feet), each Shape being the + /// range [vertexoffset[i], vertexoffset[i + 1]) of that buffer: an open polyline, or a closed one when its last point equals its first. /// [TableName(TableNames.Shape)] [G3dAttributeReference("g3d:shape:vertexoffset:0:int32:1", G3dAttributeReferenceMultiplicity.OneToOne, true)] @@ -1627,6 +1691,13 @@ public AABox Box [G3dAttributeReference("g3d:shape:width:0:float32:1", G3dAttributeReferenceMultiplicity.OneToOne, true)] public partial class Shape : EntityWithElement { + /// + /// The integer representation of the ShapeKind enum: what the shape draws. 0 (Unknown) in files written before 5.9.0. + /// + public int Kind; + + public ShapeKind GetKind() + => (ShapeKind) Kind; } /// diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs index 707792d..5b0a191 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs @@ -189,6 +189,7 @@ public override bool FieldsAreEqual(object obj) (Location_X == other.Location_X) && (Location_Y == other.Location_Y) && (Location_Z == other.Location_Z) && + (LocationSource == other.LocationSource) && (FamilyName == other.FamilyName) && (IsPinned == other.IsPinned) && (Creator == other.Creator) && @@ -1279,6 +1280,7 @@ public override bool FieldsAreEqual(object obj) { var fieldsAreEqual = (Index == other.Index) && + (Kind == other.Kind) && (_Element?.Index == other._Element?.Index); if (!fieldsAreEqual) { @@ -2274,6 +2276,8 @@ public Parameter GetParameter(int n) 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 ElementLocationSource { get; } + public Int32 GetElementLocationSource(int index, Int32 defaultValue = default) => ElementLocationSource?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; public IArray ElementFamilyName { get; } public String GetElementFamilyName(int index, String defaultValue = "") => ElementFamilyName?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; public IArray ElementIsPinned { get; } @@ -2321,6 +2325,7 @@ public Element GetElement(int n) r.Location_X = ElementLocation_X.ElementAtOrDefault(n); r.Location_Y = ElementLocation_Y.ElementAtOrDefault(n); r.Location_Z = ElementLocation_Z.ElementAtOrDefault(n); + r.LocationSource = ElementLocationSource.ElementAtOrDefault(n); r.FamilyName = ElementFamilyName.ElementAtOrDefault(n); r.IsPinned = ElementIsPinned.ElementAtOrDefault(n); r.Creator = ElementCreator.ElementAtOrDefault(n); @@ -3416,6 +3421,8 @@ public Geometry GetGeometry(int n) public EntityTable ShapeEntityTable { get; } + public IArray ShapeKind { get; } + public Int32 GetShapeKind(int index, Int32 defaultValue = default) => ShapeKind?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; public IArray ShapeElementIndex { get; } public int GetShapeElementIndex(int index) => ShapeElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; public int NumShape => ShapeEntityTable?.NumRows ?? 0; @@ -3426,6 +3433,7 @@ public Shape GetShape(int n) var r = new Shape(); r.Document = Document; r.Index = n; + r.Kind = ShapeKind.ElementAtOrDefault(n); r._Element = new Relation(GetShapeElementIndex(n), GetElement); return r; } @@ -4422,6 +4430,7 @@ public DocumentModel(Document d, bool inParallel = true) 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(); + ElementLocationSource = ElementEntityTable?.GetDataColumnValues("int:LocationSource") ?? Array.Empty().ToIArray(); ElementFamilyName = ElementEntityTable?.GetStringColumnValues("string:FamilyName") ?? Array.Empty().ToIArray(); ElementIsPinned = ElementEntityTable?.GetDataColumnValues("byte:IsPinned") ?? Array.Empty().ToIArray(); ElementCreator = ElementEntityTable?.GetStringColumnValues("string:Creator") ?? Array.Empty().ToIArray(); @@ -4587,6 +4596,7 @@ public DocumentModel(Document d, bool inParallel = true) 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(); + ShapeKind = ShapeEntityTable?.GetDataColumnValues("int:Kind") ?? 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(); @@ -5627,6 +5637,7 @@ public ElementTable(SerializableEntityTable rawTable, string[] stringTable, Enti 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_LocationSource = GetDataColumnValues("int:LocationSource") ?? Array.Empty(); Column_FamilyName = GetStringColumnValues("string:FamilyName") ?? Array.Empty(); Column_IsPinned = GetDataColumnValues("byte:IsPinned") ?? Array.Empty(); Column_Creator = GetStringColumnValues("string:Creator") ?? Array.Empty(); @@ -5659,6 +5670,8 @@ public ElementTable(SerializableEntityTable rawTable, string[] stringTable, Enti 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 Int32[] Column_LocationSource { get; } + public Int32 GetLocationSource(int index, Int32 @default = default) => Column_LocationSource.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; } @@ -5726,6 +5739,7 @@ public Element Get(int index) r.Location_X = GetLocation_X(index); r.Location_Y = GetLocation_Y(index); r.Location_Z = GetLocation_Z(index); + r.LocationSource = GetLocationSource(index); r.FamilyName = GetFamilyName(index); r.IsPinned = GetIsPinned(index); r.Creator = GetCreator(index); @@ -7504,9 +7518,12 @@ public partial class ShapeTable : EntityTable_v2, IEnumerable public ShapeTable(SerializableEntityTable rawTable, string[] stringTable, EntityTableSet parentTableSet = null) : base(rawTable, stringTable) { ParentTableSet = parentTableSet; + Column_Kind = GetDataColumnValues("int:Kind") ?? Array.Empty(); Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); } + public Int32[] Column_Kind { get; } + public Int32 GetKind(int index, Int32 @default = default) => Column_Kind.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)); @@ -7517,6 +7534,7 @@ public Shape Get(int index) if (index < 0) return null; var r = new Shape(); r.Index = index; + r.Kind = GetKind(index); r._Element = new Relation(GetElementIndex(index), _GetReferencedElement); return r; } @@ -8990,6 +9008,11 @@ public static EntityTableBuilder ToElementTableBuilder(this EntitySetBuilder getLocation_Z(elementIndex: number): Promise getAllLocation_Z(): Promise + getLocationSource(elementIndex: number): Promise + getAllLocationSource(): Promise getFamilyName(elementIndex: number): Promise getAllFamilyName(): Promise getIsPinned(elementIndex: number): Promise @@ -722,6 +725,7 @@ export class Element implements IElement { location_X?: number location_Y?: number location_Z?: number + locationSource?: number familyName?: string isPinned?: boolean creator?: string @@ -763,6 +767,7 @@ export class Element implements IElement { table.getLocation_X(index).then(v => result.location_X = v), table.getLocation_Y(index).then(v => result.location_Y = v), table.getLocation_Z(index).then(v => result.location_Z = v), + table.getLocationSource(index).then(v => result.locationSource = v), table.getFamilyName(index).then(v => result.familyName = v), table.getIsPinned(index).then(v => result.isPinned = v), table.getCreator(index).then(v => result.creator = v), @@ -821,6 +826,7 @@ export class ElementTable implements IElementTable { let location_X: number[] | undefined let location_Y: number[] | undefined let location_Z: number[] | undefined + let locationSource: number[] | undefined let familyName: string[] | undefined let isPinned: boolean[] | undefined let creator: string[] | undefined @@ -846,6 +852,7 @@ export class ElementTable implements IElementTable { (async () => { location_X = (await localTable.getNumberArray("float:Location.X")) })(), (async () => { location_Y = (await localTable.getNumberArray("float:Location.Y")) })(), (async () => { location_Z = (await localTable.getNumberArray("float:Location.Z")) })(), + (async () => { locationSource = (await localTable.getNumberArray("int:LocationSource")) })(), (async () => { familyName = (await localTable.getStringArray("string:FamilyName")) })(), (async () => { isPinned = (await localTable.getBooleanArray("byte:IsPinned")) })(), (async () => { creator = (await localTable.getStringArray("string:Creator")) })(), @@ -877,6 +884,7 @@ export class ElementTable implements IElementTable { location_X: location_X ? location_X[i] : undefined, location_Y: location_Y ? location_Y[i] : undefined, location_Z: location_Z ? location_Z[i] : undefined, + locationSource: locationSource ? locationSource[i] : undefined, familyName: familyName ? familyName[i] : undefined, isPinned: isPinned ? isPinned[i] : undefined, creator: creator ? creator[i] : undefined, @@ -955,6 +963,14 @@ export class ElementTable implements IElementTable { return (await this.entityTable.getNumberArray("float:Location.Z")) } + async getLocationSource(elementIndex: number): Promise { + return (await this.entityTable.getNumber(elementIndex, "int:LocationSource")) + } + + async getAllLocationSource(): Promise { + return (await this.entityTable.getNumberArray("int:LocationSource")) + } + async getFamilyName(elementIndex: number): Promise { return (await this.entityTable.getString(elementIndex, "string:FamilyName")) } @@ -7302,6 +7318,7 @@ export class GeometryTable implements IGeometryTable { export interface IShape { index: number + kind?: number elementIndex?: number element?: IElement @@ -7312,6 +7329,9 @@ export interface IShapeTable { get(shapeIndex: number): Promise getAll(): Promise + getKind(shapeIndex: number): Promise + getAllKind(): Promise + getElementIndex(shapeIndex: number): Promise getAllElementIndex(): Promise getElement(shapeIndex: number): Promise @@ -7319,6 +7339,7 @@ export interface IShapeTable { export class Shape implements IShape { index: number + kind?: number elementIndex?: number element?: IElement @@ -7328,6 +7349,7 @@ export class Shape implements IShape { result.index = index await Promise.all([ + table.getKind(index).then(v => result.kind = v), table.getElementIndex(index).then(v => result.elementIndex = v), ]) @@ -7364,9 +7386,11 @@ export class ShapeTable implements IShapeTable { async getAll(): Promise { const localTable = await this.entityTable.getLocal() + let kind: number[] | undefined let elementIndex: number[] | undefined await Promise.all([ + (async () => { kind = (await localTable.getNumberArray("int:Kind")) })(), (async () => { elementIndex = (await localTable.getNumberArray("index:Vim.Element:Element")) })(), ]) @@ -7376,6 +7400,7 @@ export class ShapeTable implements IShapeTable { for (let i = 0; i < rowCount; i++) { shape.push({ index: i, + kind: kind ? kind[i] : undefined, elementIndex: elementIndex ? elementIndex[i] : undefined }) } @@ -7383,6 +7408,14 @@ export class ShapeTable implements IShapeTable { return shape } + async getKind(shapeIndex: number): Promise { + return (await this.entityTable.getNumber(shapeIndex, "int:Kind")) + } + + async getAllKind(): Promise { + return (await this.entityTable.getNumberArray("int:Kind")) + } + async getElementIndex(shapeIndex: number): Promise { return await this.entityTable.getNumber(shapeIndex, "index:Vim.Element:Element") }