diff --git a/src/cpp/vim/object-model.h b/src/cpp/vim/object-model.h index 2b2bedeb..838b3449 100644 --- a/src/cpp/vim/object-model.h +++ b/src/cpp/vim/object-model.h @@ -120,6 +120,16 @@ namespace Vim class SiteTable; class Building; class BuildingTable; + class FaceMesh; + class FaceMeshTable; + class FaceMeshIndexBuffer; + class FaceMeshIndexBufferTable; + class FaceMeshVertexBuffer; + class FaceMeshVertexBufferTable; + class LineShape; + class LineShapeTable; + class LineShapeVertexBuffer; + class LineShapeVertexBufferTable; class DocumentModel { @@ -178,6 +188,11 @@ namespace Vim ViewInViewSheetTable* mViewInViewSheet; SiteTable* mSite; BuildingTable* mBuilding; + FaceMeshTable* mFaceMesh; + FaceMeshIndexBufferTable* mFaceMeshIndexBuffer; + FaceMeshVertexBufferTable* mFaceMeshVertexBuffer; + LineShapeTable* mLineShape; + LineShapeVertexBufferTable* mLineShapeVertexBuffer; DocumentModel(Scene& scene); ~DocumentModel(); @@ -13886,6 +13901,631 @@ namespace Vim return new BuildingTable(scene.mEntityTables["Vim.Building"], scene.mStrings); } + class FaceMesh + { + public: + int mIndex; + + int mFaceMeshIndexBufferStartIndex; + FaceMeshIndexBuffer* mFaceMeshIndexBufferStart; + int mFaceMeshIndexBufferEndIndex; + FaceMeshIndexBuffer* mFaceMeshIndexBufferEnd; + int mViewIndex; + View* mView; + int mMaterialIndex; + Material* mMaterial; + int mElementIndex; + Element* mElement; + + FaceMesh() {} + }; + + class FaceMeshTable + { + EntityTable& mEntityTable; + std::vector& mStrings; + public: + FaceMeshTable(EntityTable& entityTable, std::vector& strings): + mEntityTable(entityTable), mStrings(strings) {} + + size_t GetCount() + { + return mEntityTable.get_count(); + } + + FaceMesh* Get(int faceMeshIndex) + { + FaceMesh* faceMesh = new FaceMesh(); + faceMesh->mIndex = faceMeshIndex; + faceMesh->mFaceMeshIndexBufferStartIndex = GetFaceMeshIndexBufferStartIndex(faceMeshIndex); + faceMesh->mFaceMeshIndexBufferEndIndex = GetFaceMeshIndexBufferEndIndex(faceMeshIndex); + faceMesh->mViewIndex = GetViewIndex(faceMeshIndex); + faceMesh->mMaterialIndex = GetMaterialIndex(faceMeshIndex); + faceMesh->mElementIndex = GetElementIndex(faceMeshIndex); + return faceMesh; + } + + std::vector* GetAll() + { + bool existsFaceMeshIndexBufferStart = mEntityTable.column_exists("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart"); + bool existsFaceMeshIndexBufferEnd = mEntityTable.column_exists("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd"); + bool existsView = mEntityTable.column_exists("index:Vim.View:View"); + bool existsMaterial = mEntityTable.column_exists("index:Vim.Material:Material"); + bool existsElement = mEntityTable.column_exists("index:Vim.Element:Element"); + + const auto count = GetCount(); + + std::vector* faceMesh = new std::vector(); + faceMesh->reserve(count); + + const std::vector& faceMeshIndexBufferStartData = mEntityTable.column_exists("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart") ? mEntityTable.mIndexColumns["index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart"] : std::vector(); + const std::vector& faceMeshIndexBufferEndData = mEntityTable.column_exists("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd") ? mEntityTable.mIndexColumns["index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd"] : std::vector(); + const std::vector& viewData = mEntityTable.column_exists("index:Vim.View:View") ? mEntityTable.mIndexColumns["index:Vim.View:View"] : std::vector(); + const std::vector& materialData = mEntityTable.column_exists("index:Vim.Material:Material") ? mEntityTable.mIndexColumns["index:Vim.Material:Material"] : std::vector(); + 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) + { + FaceMesh entity; + entity.mIndex = i; + entity.mFaceMeshIndexBufferStartIndex = existsFaceMeshIndexBufferStart ? faceMeshIndexBufferStartData[i] : -1; + entity.mFaceMeshIndexBufferEndIndex = existsFaceMeshIndexBufferEnd ? faceMeshIndexBufferEndData[i] : -1; + entity.mViewIndex = existsView ? viewData[i] : -1; + entity.mMaterialIndex = existsMaterial ? materialData[i] : -1; + entity.mElementIndex = existsElement ? elementData[i] : -1; + faceMesh->push_back(entity); + } + + return faceMesh; + } + + int GetFaceMeshIndexBufferStartIndex(int faceMeshIndex) + { + if (!mEntityTable.column_exists("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart")) { + return -1; + } + + if (faceMeshIndex < 0 || faceMeshIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart"][faceMeshIndex]; + } + + int GetFaceMeshIndexBufferEndIndex(int faceMeshIndex) + { + if (!mEntityTable.column_exists("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd")) { + return -1; + } + + if (faceMeshIndex < 0 || faceMeshIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd"][faceMeshIndex]; + } + + int GetViewIndex(int faceMeshIndex) + { + if (!mEntityTable.column_exists("index:Vim.View:View")) { + return -1; + } + + if (faceMeshIndex < 0 || faceMeshIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.View:View"][faceMeshIndex]; + } + + int GetMaterialIndex(int faceMeshIndex) + { + if (!mEntityTable.column_exists("index:Vim.Material:Material")) { + return -1; + } + + if (faceMeshIndex < 0 || faceMeshIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.Material:Material"][faceMeshIndex]; + } + + int GetElementIndex(int faceMeshIndex) + { + if (!mEntityTable.column_exists("index:Vim.Element:Element")) { + return -1; + } + + if (faceMeshIndex < 0 || faceMeshIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.Element:Element"][faceMeshIndex]; + } + + }; + + static FaceMeshTable* GetFaceMeshTable(Scene& scene) + { + if (scene.mEntityTables.find("Vim.FaceMesh") == scene.mEntityTables.end()) + return {}; + + return new FaceMeshTable(scene.mEntityTables["Vim.FaceMesh"], scene.mStrings); + } + + class FaceMeshIndexBuffer + { + public: + int mIndex; + + int mVertexIndexIndex; + FaceMeshVertexBuffer* mVertexIndex; + + FaceMeshIndexBuffer() {} + }; + + class FaceMeshIndexBufferTable + { + EntityTable& mEntityTable; + std::vector& mStrings; + public: + FaceMeshIndexBufferTable(EntityTable& entityTable, std::vector& strings): + mEntityTable(entityTable), mStrings(strings) {} + + size_t GetCount() + { + return mEntityTable.get_count(); + } + + FaceMeshIndexBuffer* Get(int faceMeshIndexBufferIndex) + { + FaceMeshIndexBuffer* faceMeshIndexBuffer = new FaceMeshIndexBuffer(); + faceMeshIndexBuffer->mIndex = faceMeshIndexBufferIndex; + faceMeshIndexBuffer->mVertexIndexIndex = GetVertexIndexIndex(faceMeshIndexBufferIndex); + return faceMeshIndexBuffer; + } + + std::vector* GetAll() + { + bool existsVertexIndex = mEntityTable.column_exists("index:Vim.FaceMeshVertexBuffer:VertexIndex"); + + const auto count = GetCount(); + + std::vector* faceMeshIndexBuffer = new std::vector(); + faceMeshIndexBuffer->reserve(count); + + const std::vector& vertexIndexData = mEntityTable.column_exists("index:Vim.FaceMeshVertexBuffer:VertexIndex") ? mEntityTable.mIndexColumns["index:Vim.FaceMeshVertexBuffer:VertexIndex"] : std::vector(); + + for (int i = 0; i < count; ++i) + { + FaceMeshIndexBuffer entity; + entity.mIndex = i; + entity.mVertexIndexIndex = existsVertexIndex ? vertexIndexData[i] : -1; + faceMeshIndexBuffer->push_back(entity); + } + + return faceMeshIndexBuffer; + } + + int GetVertexIndexIndex(int faceMeshIndexBufferIndex) + { + if (!mEntityTable.column_exists("index:Vim.FaceMeshVertexBuffer:VertexIndex")) { + return -1; + } + + if (faceMeshIndexBufferIndex < 0 || faceMeshIndexBufferIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.FaceMeshVertexBuffer:VertexIndex"][faceMeshIndexBufferIndex]; + } + + }; + + static FaceMeshIndexBufferTable* GetFaceMeshIndexBufferTable(Scene& scene) + { + if (scene.mEntityTables.find("Vim.FaceMeshIndexBuffer") == scene.mEntityTables.end()) + return {}; + + return new FaceMeshIndexBufferTable(scene.mEntityTables["Vim.FaceMeshIndexBuffer"], scene.mStrings); + } + + class FaceMeshVertexBuffer + { + public: + int mIndex; + Vector3 mVertex; + + FaceMeshVertexBuffer() {} + }; + + class FaceMeshVertexBufferTable + { + EntityTable& mEntityTable; + std::vector& mStrings; + public: + FaceMeshVertexBufferTable(EntityTable& entityTable, std::vector& strings): + mEntityTable(entityTable), mStrings(strings) {} + + size_t GetCount() + { + return mEntityTable.get_count(); + } + + FaceMeshVertexBuffer* Get(int faceMeshVertexBufferIndex) + { + FaceMeshVertexBuffer* faceMeshVertexBuffer = new FaceMeshVertexBuffer(); + faceMeshVertexBuffer->mIndex = faceMeshVertexBufferIndex; + faceMeshVertexBuffer->mVertex = GetVertex(faceMeshVertexBufferIndex); + return faceMeshVertexBuffer; + } + + std::vector* GetAll() + { + bool existsVertex = mEntityTable.column_exists("vector3:Vertex"); + + const auto count = GetCount(); + + std::vector* faceMeshVertexBuffer = new std::vector(); + faceMeshVertexBuffer->reserve(count); + + Vector3* vertexData = new Vector3[count]; + if (mEntityTable.column_exists("vector3:Vertex")) { + memcpy(vertexData, mEntityTable.mDataColumns["vector3:Vertex"].begin(), count * sizeof(Vector3)); + } + + for (int i = 0; i < count; ++i) + { + FaceMeshVertexBuffer entity; + entity.mIndex = i; + if (existsVertex) + entity.mVertex = vertexData[i]; + faceMeshVertexBuffer->push_back(entity); + } + + delete[] vertexData; + + return faceMeshVertexBuffer; + } + + Vector3 GetVertex(int faceMeshVertexBufferIndex) + { + if (faceMeshVertexBufferIndex < 0 || faceMeshVertexBufferIndex >= GetCount()) + return {}; + + if (mEntityTable.column_exists("vector3:Vertex")) { + return *reinterpret_cast(const_cast(mEntityTable.mDataColumns["vector3:Vertex"].begin() + faceMeshVertexBufferIndex * sizeof(Vector3))); + } + + return {}; + } + + std::vector* GetAllVertex() + { + const auto count = GetCount(); + + Vector3* vertexData = new Vector3[count]; + if (mEntityTable.column_exists("vector3:Vertex")) { + memcpy(vertexData, mEntityTable.mDataColumns["vector3:Vertex"].begin(), count * sizeof(Vector3)); + } + + std::vector* result = new std::vector(vertexData, vertexData + count); + + delete[] vertexData; + + return result; + } + + }; + + static FaceMeshVertexBufferTable* GetFaceMeshVertexBufferTable(Scene& scene) + { + if (scene.mEntityTables.find("Vim.FaceMeshVertexBuffer") == scene.mEntityTables.end()) + return {}; + + return new FaceMeshVertexBufferTable(scene.mEntityTables["Vim.FaceMeshVertexBuffer"], scene.mStrings); + } + + class LineShape + { + public: + int mIndex; + Vector4 mColor; + double mWidth; + + int mLineShapeVertexBufferStartIndex; + LineShapeVertexBuffer* mLineShapeVertexBufferStart; + int mLineShapeVertexBufferEndIndex; + LineShapeVertexBuffer* mLineShapeVertexBufferEnd; + int mViewIndex; + View* mView; + int mElementIndex; + Element* mElement; + + LineShape() {} + }; + + class LineShapeTable + { + EntityTable& mEntityTable; + std::vector& mStrings; + public: + LineShapeTable(EntityTable& entityTable, std::vector& strings): + mEntityTable(entityTable), mStrings(strings) {} + + size_t GetCount() + { + return mEntityTable.get_count(); + } + + LineShape* Get(int lineShapeIndex) + { + LineShape* lineShape = new LineShape(); + lineShape->mIndex = lineShapeIndex; + lineShape->mColor = GetColor(lineShapeIndex); + lineShape->mWidth = GetWidth(lineShapeIndex); + lineShape->mLineShapeVertexBufferStartIndex = GetLineShapeVertexBufferStartIndex(lineShapeIndex); + lineShape->mLineShapeVertexBufferEndIndex = GetLineShapeVertexBufferEndIndex(lineShapeIndex); + lineShape->mViewIndex = GetViewIndex(lineShapeIndex); + lineShape->mElementIndex = GetElementIndex(lineShapeIndex); + return lineShape; + } + + std::vector* GetAll() + { + bool existsColor = mEntityTable.column_exists("vector4:Color"); + bool existsWidth = mEntityTable.column_exists("double:Width"); + bool existsLineShapeVertexBufferStart = mEntityTable.column_exists("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart"); + bool existsLineShapeVertexBufferEnd = mEntityTable.column_exists("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd"); + bool existsView = mEntityTable.column_exists("index:Vim.View:View"); + bool existsElement = mEntityTable.column_exists("index:Vim.Element:Element"); + + const auto count = GetCount(); + + std::vector* lineShape = new std::vector(); + lineShape->reserve(count); + + Vector4* colorData = new Vector4[count]; + if (mEntityTable.column_exists("vector4:Color")) { + memcpy(colorData, mEntityTable.mDataColumns["vector4:Color"].begin(), count * sizeof(Vector4)); + } + + double* widthData = new double[count]; + if (mEntityTable.column_exists("double:Width")) { + memcpy(widthData, mEntityTable.mDataColumns["double:Width"].begin(), count * sizeof(double)); + } + + const std::vector& lineShapeVertexBufferStartData = mEntityTable.column_exists("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart") ? mEntityTable.mIndexColumns["index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart"] : std::vector(); + const std::vector& lineShapeVertexBufferEndData = mEntityTable.column_exists("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd") ? mEntityTable.mIndexColumns["index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd"] : std::vector(); + const std::vector& viewData = mEntityTable.column_exists("index:Vim.View:View") ? mEntityTable.mIndexColumns["index:Vim.View:View"] : std::vector(); + 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) + { + LineShape entity; + entity.mIndex = i; + if (existsColor) + entity.mColor = colorData[i]; + if (existsWidth) + entity.mWidth = widthData[i]; + entity.mLineShapeVertexBufferStartIndex = existsLineShapeVertexBufferStart ? lineShapeVertexBufferStartData[i] : -1; + entity.mLineShapeVertexBufferEndIndex = existsLineShapeVertexBufferEnd ? lineShapeVertexBufferEndData[i] : -1; + entity.mViewIndex = existsView ? viewData[i] : -1; + entity.mElementIndex = existsElement ? elementData[i] : -1; + lineShape->push_back(entity); + } + + delete[] colorData; + delete[] widthData; + + return lineShape; + } + + Vector4 GetColor(int lineShapeIndex) + { + if (lineShapeIndex < 0 || lineShapeIndex >= GetCount()) + return {}; + + if (mEntityTable.column_exists("vector4:Color")) { + return *reinterpret_cast(const_cast(mEntityTable.mDataColumns["vector4:Color"].begin() + lineShapeIndex * sizeof(Vector4))); + } + + return {}; + } + + std::vector* GetAllColor() + { + const auto count = GetCount(); + + Vector4* colorData = new Vector4[count]; + if (mEntityTable.column_exists("vector4:Color")) { + memcpy(colorData, mEntityTable.mDataColumns["vector4:Color"].begin(), count * sizeof(Vector4)); + } + + std::vector* result = new std::vector(colorData, colorData + count); + + delete[] colorData; + + return result; + } + + double GetWidth(int lineShapeIndex) + { + if (lineShapeIndex < 0 || lineShapeIndex >= GetCount()) + return {}; + + if (mEntityTable.column_exists("double:Width")) { + return *reinterpret_cast(const_cast(mEntityTable.mDataColumns["double:Width"].begin() + lineShapeIndex * sizeof(double))); + } + + return {}; + } + + std::vector* GetAllWidth() + { + const auto count = GetCount(); + + double* widthData = new double[count]; + if (mEntityTable.column_exists("double:Width")) { + memcpy(widthData, mEntityTable.mDataColumns["double:Width"].begin(), count * sizeof(double)); + } + + std::vector* result = new std::vector(widthData, widthData + count); + + delete[] widthData; + + return result; + } + + int GetLineShapeVertexBufferStartIndex(int lineShapeIndex) + { + if (!mEntityTable.column_exists("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart")) { + return -1; + } + + if (lineShapeIndex < 0 || lineShapeIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart"][lineShapeIndex]; + } + + int GetLineShapeVertexBufferEndIndex(int lineShapeIndex) + { + if (!mEntityTable.column_exists("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd")) { + return -1; + } + + if (lineShapeIndex < 0 || lineShapeIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd"][lineShapeIndex]; + } + + int GetViewIndex(int lineShapeIndex) + { + if (!mEntityTable.column_exists("index:Vim.View:View")) { + return -1; + } + + if (lineShapeIndex < 0 || lineShapeIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.View:View"][lineShapeIndex]; + } + + int GetElementIndex(int lineShapeIndex) + { + if (!mEntityTable.column_exists("index:Vim.Element:Element")) { + return -1; + } + + if (lineShapeIndex < 0 || lineShapeIndex >= GetCount()) + return -1; + + return mEntityTable.mIndexColumns["index:Vim.Element:Element"][lineShapeIndex]; + } + + }; + + static LineShapeTable* GetLineShapeTable(Scene& scene) + { + if (scene.mEntityTables.find("Vim.LineShape") == scene.mEntityTables.end()) + return {}; + + return new LineShapeTable(scene.mEntityTables["Vim.LineShape"], scene.mStrings); + } + + class LineShapeVertexBuffer + { + public: + int mIndex; + Vector3 mVertex; + + LineShapeVertexBuffer() {} + }; + + class LineShapeVertexBufferTable + { + EntityTable& mEntityTable; + std::vector& mStrings; + public: + LineShapeVertexBufferTable(EntityTable& entityTable, std::vector& strings): + mEntityTable(entityTable), mStrings(strings) {} + + size_t GetCount() + { + return mEntityTable.get_count(); + } + + LineShapeVertexBuffer* Get(int lineShapeVertexBufferIndex) + { + LineShapeVertexBuffer* lineShapeVertexBuffer = new LineShapeVertexBuffer(); + lineShapeVertexBuffer->mIndex = lineShapeVertexBufferIndex; + lineShapeVertexBuffer->mVertex = GetVertex(lineShapeVertexBufferIndex); + return lineShapeVertexBuffer; + } + + std::vector* GetAll() + { + bool existsVertex = mEntityTable.column_exists("vector3:Vertex"); + + const auto count = GetCount(); + + std::vector* lineShapeVertexBuffer = new std::vector(); + lineShapeVertexBuffer->reserve(count); + + Vector3* vertexData = new Vector3[count]; + if (mEntityTable.column_exists("vector3:Vertex")) { + memcpy(vertexData, mEntityTable.mDataColumns["vector3:Vertex"].begin(), count * sizeof(Vector3)); + } + + for (int i = 0; i < count; ++i) + { + LineShapeVertexBuffer entity; + entity.mIndex = i; + if (existsVertex) + entity.mVertex = vertexData[i]; + lineShapeVertexBuffer->push_back(entity); + } + + delete[] vertexData; + + return lineShapeVertexBuffer; + } + + Vector3 GetVertex(int lineShapeVertexBufferIndex) + { + if (lineShapeVertexBufferIndex < 0 || lineShapeVertexBufferIndex >= GetCount()) + return {}; + + if (mEntityTable.column_exists("vector3:Vertex")) { + return *reinterpret_cast(const_cast(mEntityTable.mDataColumns["vector3:Vertex"].begin() + lineShapeVertexBufferIndex * sizeof(Vector3))); + } + + return {}; + } + + std::vector* GetAllVertex() + { + const auto count = GetCount(); + + Vector3* vertexData = new Vector3[count]; + if (mEntityTable.column_exists("vector3:Vertex")) { + memcpy(vertexData, mEntityTable.mDataColumns["vector3:Vertex"].begin(), count * sizeof(Vector3)); + } + + std::vector* result = new std::vector(vertexData, vertexData + count); + + delete[] vertexData; + + return result; + } + + }; + + static LineShapeVertexBufferTable* GetLineShapeVertexBufferTable(Scene& scene) + { + if (scene.mEntityTables.find("Vim.LineShapeVertexBuffer") == scene.mEntityTables.end()) + return {}; + + return new LineShapeVertexBufferTable(scene.mEntityTables["Vim.LineShapeVertexBuffer"], scene.mStrings); + } + DocumentModel::DocumentModel(Scene& scene) { mAsset = GetAssetTable(scene); @@ -13942,6 +14582,11 @@ namespace Vim mViewInViewSheet = GetViewInViewSheetTable(scene); mSite = GetSiteTable(scene); mBuilding = GetBuildingTable(scene); + mFaceMesh = GetFaceMeshTable(scene); + mFaceMeshIndexBuffer = GetFaceMeshIndexBufferTable(scene); + mFaceMeshVertexBuffer = GetFaceMeshVertexBufferTable(scene); + mLineShape = GetLineShapeTable(scene); + mLineShapeVertexBuffer = GetLineShapeVertexBufferTable(scene); } DocumentModel::~DocumentModel() @@ -14000,6 +14645,11 @@ namespace Vim delete mViewInViewSheet; delete mSite; delete mBuilding; + delete mFaceMesh; + delete mFaceMeshIndexBuffer; + delete mFaceMeshVertexBuffer; + delete mLineShape; + delete mLineShapeVertexBuffer; } } diff --git a/src/cpp/vim/vim.h b/src/cpp/vim/vim.h index 01f6ed56..323e7f83 100644 --- a/src/cpp/vim/vim.h +++ b/src/cpp/vim/vim.h @@ -42,6 +42,47 @@ namespace Vim static const std::string data_column_ulong_prefix = "ulong:"; static const std::string data_column_float_prefix = "float:"; static const std::string data_column_double_prefix = "double:"; + static const std::string data_column_vector3_prefix = "vector3:"; + static const std::string data_column_vector4_prefix = "vector4:"; + static const std::string data_column_matrix4x4_prefix = "matrix4x4:"; + + class Vector3 + { + public: + float X = 0.0f; + float Y = 0.0f; + float Z = 0.0f; + }; + + class Vector4 + { + public: + float X = 0.0f; + float Y = 0.0f; + float Z = 0.0f; + float W = 0.0f; + }; + + class Matrix4x4 + { + public: + float M11; // row 1, column 1 + float M12; // row 1, column 2 + float M13; // ... + float M14; + float M21; + float M22; + float M23; + float M24; + float M31; + float M32; + float M33; + float M34; + float M41; + float M42; + float M43; + float M44; + }; class EntityTable { diff --git a/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs b/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs index 99de9355..0e18612f 100644 --- a/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs +++ b/src/cs/vim/Vim.Format.CodeGen/ObjectModelCppGenerator.cs @@ -33,6 +33,9 @@ private static string ToCppType(string type) => "String" or "string" => "std::string", "Int32" or "int" => "int", "Int64" or "Long" or "long" => "long long", + "Vector3" or "vector3" => "Vector3", + "Vector4" or "vector4" => "Vector4", + "Matrix4x4" or "matrix4x4" => "Matrix4x4", _ => throw new ArgumentOutOfRangeException(nameof(type), type, $"Type {type} not supported") }; diff --git a/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs b/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs index c176413c..a4169938 100644 --- a/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs +++ b/src/cs/vim/Vim.Format.CodeGen/ObjectModelGenerator.cs @@ -224,7 +224,8 @@ IEnumerable GetEquatableFields(FieldInfo[] fis) private static CodeBuilder WriteDocument(CodeBuilder cb) { - var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); + var entityTypes = ObjectModelReflection.GetEntityTypes() + .ToArray(); foreach (var et in entityTypes) WriteEntityClass(et, cb); @@ -433,7 +434,9 @@ private static void WriteEntityTable(CodeBuilder cb, Type t) private static void WriteDocumentBuilder(CodeBuilder cb) { - var entityTypes = ObjectModelReflection.GetEntityTypes().ToArray(); + var entityTypes = ObjectModelReflection.GetEntityTypes() + .Where(t => !t.IsEntityTableBuffer()) + .ToArray(); cb.AppendLine("public static class DocumentBuilderExtensions"); cb.AppendLine("{"); diff --git a/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs b/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs index 70e40bdc..9b5b8340 100644 --- a/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs +++ b/src/cs/vim/Vim.Format.CodeGen/ObjectModelTypeScriptGenerator.cs @@ -21,7 +21,9 @@ private static string ToTypeScriptType(string type) "Single" or "float" or "Double" or "double" or "Int32" or "int" => "number", "Int64" or "Long" or "long" => "bigint", "String" or "string" => "string", - _ => throw new ArgumentOutOfRangeException(nameof(type), type, $"Type {type} not supported") + "Vector3" => "Vector3", + "Vector4" => "Vector4", + "Matrix4x4" => "Matrix4x4" }; private static string ToTypeScriptArrayType(string type) @@ -235,6 +237,9 @@ private static string GetFieldGetter(this FieldInfo fieldInfo) "number" => "getNumber", "bigint" => "getBigInt", "string" => "getString", + "Vector3" => "getVector3", + "Vector4" => "getVector4", + "Matrix4x4" => "getMatrix4x4", _ => throw new ArgumentOutOfRangeException($"There's no getter function for {fieldInfo.FieldType.Name}") }; @@ -245,6 +250,9 @@ private static string GetArrayGetterName(this FieldInfo fieldInfo) => "number" => "getNumberArray", "bigint" => "getBigIntArray", "string" => "getStringArray", + "Vector3" => "getVector3Array", + "Vector4" => "getVector4Array", + "Matrix4x4" => "getMatrix4x4Array", _ => throw new ArgumentOutOfRangeException($"There's no getter function for {fieldInfo.FieldType.Name}") }; diff --git a/src/cs/vim/Vim.Format.Core/Attributes/EntityBufferAttribute.cs b/src/cs/vim/Vim.Format.Core/Attributes/EntityBufferAttribute.cs new file mode 100644 index 00000000..9e62fc25 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/Attributes/EntityBufferAttribute.cs @@ -0,0 +1,7 @@ +using System; + +namespace Vim.Format +{ + public class EntityBufferAttribute : Attribute + { } +} diff --git a/src/cs/vim/Vim.Format.Core/EntityColumnLoaderAttribute.cs b/src/cs/vim/Vim.Format.Core/Attributes/EntityColumnLoaderAttribute.cs similarity index 100% rename from src/cs/vim/Vim.Format.Core/EntityColumnLoaderAttribute.cs rename to src/cs/vim/Vim.Format.Core/Attributes/EntityColumnLoaderAttribute.cs diff --git a/src/cs/vim/Vim.Format.Core/TableNameAttribute.cs b/src/cs/vim/Vim.Format.Core/Attributes/TableNameAttribute.cs similarity index 100% rename from src/cs/vim/Vim.Format.Core/TableNameAttribute.cs rename to src/cs/vim/Vim.Format.Core/Attributes/TableNameAttribute.cs diff --git a/src/cs/vim/Vim.Format.Core/Attributes/VimSqlIgnoreAttribute.cs b/src/cs/vim/Vim.Format.Core/Attributes/VimSqlIgnoreAttribute.cs new file mode 100644 index 00000000..02db8073 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/Attributes/VimSqlIgnoreAttribute.cs @@ -0,0 +1,7 @@ +using System; + +namespace Vim.Format +{ + public class VimSqlIgnoreAttribute : Attribute + { } +} diff --git a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs index 3cce6b9f..191c3d7f 100644 --- a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs +++ b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Buffer.cs @@ -4,6 +4,7 @@ using System.Linq; using Vim.BFast; using Vim.LinqArray; +using Vim.Math3d; namespace Vim.Format { @@ -70,6 +71,12 @@ public static object GetDataColumnValue(this IBuffer dataColumn, string typePref return dataColumn.AsArray().ElementAtOrDefault(rowIndex); case VimConstants.DoubleColumnNameTypePrefix: return dataColumn.AsArray().ElementAtOrDefault(rowIndex); + case VimConstants.Vector3ColumnNameTypePrefix: + return dataColumn.AsArray().ElementAtOrDefault(rowIndex); + case VimConstants.Vector4ColumnNameTypePrefix: + return dataColumn.AsArray().ElementAtOrDefault(rowIndex); + case VimConstants.Matrix4x4ColumnNameTypePrefix: + return dataColumn.AsArray().ElementAtOrDefault(rowIndex); default: return null; } @@ -92,6 +99,12 @@ public static IBuffer CreateDefaultDataColumnBuffer(int length, string typePrefi return new float[length].ToBuffer(); case (VimConstants.DoubleColumnNameTypePrefix): return new double[length].ToBuffer(); + case (VimConstants.Vector3ColumnNameTypePrefix): + return new Vector3[length].ToBuffer(); + case (VimConstants.Vector4ColumnNameTypePrefix): + return new Vector4[length].ToBuffer(); + case (VimConstants.Matrix4x4ColumnNameTypePrefix): + return new Matrix4x4[length].ToBuffer(); default: throw new Exception($"{nameof(CreateDefaultDataColumnBuffer)} - {UnknownNamedBufferPrefix}"); } @@ -111,6 +124,12 @@ public static IBuffer CopyDataColumn(this IBuffer dataColumn, string typePrefix, return (dataColumn.Data as float[]).RemapData(remapping).ToBuffer(); case (VimConstants.ByteColumnNameTypePrefix): return (dataColumn.Data as byte[]).RemapData(remapping).ToBuffer(); + case (VimConstants.Vector3ColumnNameTypePrefix): + return (dataColumn.Data as Vector3[]).RemapData(remapping).ToBuffer(); + case (VimConstants.Vector4ColumnNameTypePrefix): + return (dataColumn.Data as Vector4[]).RemapData(remapping).ToBuffer(); + case (VimConstants.Matrix4x4ColumnNameTypePrefix): + return (dataColumn.Data as Matrix4x4[]).RemapData(remapping).ToBuffer(); default: throw new Exception($"{nameof(CopyDataColumn)} - {UnknownNamedBufferPrefix}"); } @@ -139,6 +158,12 @@ public static IBuffer ConcatDataColumnBuffers(this IBuffer thisBuffer, IBuffer o return thisBuffer.Concat(otherBuffer); case (VimConstants.DoubleColumnNameTypePrefix): return thisBuffer.Concat(otherBuffer); + case (VimConstants.Vector3ColumnNameTypePrefix): + return thisBuffer.Concat(otherBuffer); + case (VimConstants.Vector4ColumnNameTypePrefix): + return thisBuffer.Concat(otherBuffer); + case (VimConstants.Matrix4x4ColumnNameTypePrefix): + return thisBuffer.Concat(otherBuffer); default: throw new Exception($"{nameof(ConcatDataColumnBuffers)} - {UnknownNamedBufferPrefix}"); } diff --git a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs index d7cedece..241a55bd 100644 --- a/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs +++ b/src/cs/vim/Vim.Format.Core/ColumnExtensions.Reflection.cs @@ -75,6 +75,12 @@ public static IEnumerable GetRelationFields(this Type t) public static string GetEntityTableName(this Type t) => (t.GetCustomAttribute(typeof(TableNameAttribute)) as TableNameAttribute)?.Name; + public static bool IsEntityTableBuffer(this Type t) + => (t.GetCustomAttribute(typeof(EntityBufferAttribute)) as EntityBufferAttribute) != null; + + public static bool IsEntityTableVimSqlIgnore(this Type t) + => (t.GetCustomAttribute(typeof(VimSqlIgnoreAttribute)) as VimSqlIgnoreAttribute) != null; + public static (string IndexColumnName, string LocalFieldName) GetIndexColumnInfo(this FieldInfo fieldInfo) { if (!fieldInfo.Name.StartsWith("_")) diff --git a/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs b/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs index 0d826c14..70390e26 100644 --- a/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs +++ b/src/cs/vim/Vim.Format.Core/ColumnExtensions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; +using Vim.Math3d; namespace Vim.Format { @@ -17,6 +18,9 @@ public static readonly IReadOnlyCollection AllColumnInfos 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)), + new ColumnInfo(ColumnType.DataColumn, VimConstants.Vector3ColumnNameTypePrefix, typeof(Vector3)), + new ColumnInfo(ColumnType.DataColumn, VimConstants.Vector4ColumnNameTypePrefix, typeof(Vector4)), + new ColumnInfo(ColumnType.DataColumn, VimConstants.Matrix4x4ColumnNameTypePrefix, typeof(Matrix4x4)) }; public static readonly IReadOnlyDictionary TypePrefixToColumnTypeMap diff --git a/src/cs/vim/Vim.Format.Core/EntityTable.cs b/src/cs/vim/Vim.Format.Core/EntityTable.cs index 44360bf9..755f6ecc 100644 --- a/src/cs/vim/Vim.Format.Core/EntityTable.cs +++ b/src/cs/vim/Vim.Format.Core/EntityTable.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Linq; using Vim.BFast; using Vim.LinqArray; @@ -39,7 +38,7 @@ public IArray GetStringColumnValues(string columnName) ?.Select(Document.GetString) .ToIArray(); - public IArray GetDataColumnValues(string columnName) where T : unmanaged + public T[] GetDataColumnAsTypedArray(string columnName) where T : unmanaged { var type = typeof(T); @@ -51,12 +50,15 @@ public IArray GetDataColumnValues(string columnName) where T : unmanaged return null; if (type == typeof(short)) - return namedBuffer.GetColumnValues().Select(i => (short)i).ToIArray() as IArray; + return namedBuffer.GetColumnValues().Select(i => (short)i).Cast().ToArray(); if (type == typeof(bool)) - return namedBuffer.GetColumnValues().Select(b => b != 0).ToIArray() as IArray; + return namedBuffer.GetColumnValues().Select(b => b != 0).Cast().ToArray(); - return namedBuffer.GetColumnValues().ToIArray(); + return namedBuffer.GetColumnValues(); } + + public IArray GetDataColumnValues(string columnName) where T : unmanaged + => GetDataColumnAsTypedArray(columnName)?.ToIArray(); } } diff --git a/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs b/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs index bd1da0fd..b28e7e8f 100644 --- a/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs +++ b/src/cs/vim/Vim.Format.Core/EntityTableBuilder.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Vim.BFast; +using Vim.Math3d; namespace Vim.Format { @@ -93,6 +94,15 @@ public EntityTableBuilder AddDataColumn(string columnName, IEnumerable val public EntityTableBuilder AddDataColumn(string columnName, IEnumerable values) => AddDataColumn(columnName, values.Select(x => x ? (byte)1 : (byte)0).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 IEnumerable GetAllStrings() => StringColumns.Values.SelectMany(sc => sc) .Where(x => x != null); diff --git a/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs b/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs index 506cb3d3..3acf9f91 100644 --- a/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs +++ b/src/cs/vim/Vim.Format.Core/Geometry/MeshExtensions.cs @@ -447,7 +447,5 @@ public static IArray CornerDataToVertexData(this IMesh mesh, IArray dat return vertexData.ToIArray(); } #endregion - - } } diff --git a/src/cs/vim/Vim.Format.Core/Geometry/MeshSlicer.cs b/src/cs/vim/Vim.Format.Core/Geometry/MeshSlicer.cs new file mode 100644 index 00000000..1c29728f --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/Geometry/MeshSlicer.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using Vim.Math3d; + +namespace Vim.Format.Geometry +{ + public static class MeshSlicer + { + public delegate bool FilterTrianglesPredicate( + int vertexIndex0, + Vector3 vertex0, + int vertexIndex1, + Vector3 vertex1, + int vertexIndex2, + Vector3 vertex2); + + public static MeshSlicerResult FilterTriangles( + IReadOnlyList vertexBuffer, + IReadOnlyList indexBuffer, + FilterTrianglesPredicate predicate) + { + // BREAKDOWN + // + // vertexBuffer: [ ..., v0, v1, v2, v3, ..., v34, v35, v36, v37, ... ] + // + // indexBuffer: [ 34, 35, 36, 34, 36, 37 ..., 0, 1, 2, 0, 2, 3, ... ] + // + // predicate(indexBuffer): [ 34, 36, 37, 0, 1, 2, 0, 2, 3 ] <-- triangle 34, 35, 36 was rejected + // v v v v v v v v v + // newIndexBuffer: [ 0, 1, 2, 3, 4, 5, 3, 5, 6 ] + // | | | | | | / / / + // | | | | | | / / / + // | | | | | | / / / + // | | | | | |/ / / + // | | | | | /| / / + // | | | | _|__/ | / / + // | | | | / | | / / + // | | | |_/ | |_/ / + // | | | | | | / + // v v v v v v v + // newVertexBuffer: [ v34, v36, v37, v0, v1, v2, v3 ] + + var oldToNewIndexMap = new Dictionary(); + var newVertexBuffer = new List(); + var newIndexBuffer = new List(); + + void KeepVertexIndex(int oldVertexIndex, Vector3 vertex) + { + if (!oldToNewIndexMap.TryGetValue(oldVertexIndex, out var mappedVertexIndex)) + { + mappedVertexIndex = oldToNewIndexMap.Count; // 0, 1, 2, ... + oldToNewIndexMap.Add(oldVertexIndex, mappedVertexIndex); + newVertexBuffer.Add(vertex); + } + + newIndexBuffer.Add(mappedVertexIndex); + } + + // Filter the indices. + for (var i = 0; i < indexBuffer.Count; i += 3) + { + var vertexIndex0 = indexBuffer[i]; + var vertexIndex1 = indexBuffer[i + 1]; + var vertexIndex2 = indexBuffer[i + 2]; + + var v0 = vertexBuffer[vertexIndex0]; + var v1 = vertexBuffer[vertexIndex1]; + var v2 = vertexBuffer[vertexIndex2]; + + if (!predicate(vertexIndex0, v0, vertexIndex1, v1, vertexIndex2, v2)) + continue; + + KeepVertexIndex(vertexIndex0, v0); + KeepVertexIndex(vertexIndex1, v1); + KeepVertexIndex(vertexIndex2, v2); + } + + return new MeshSlicerResult(newVertexBuffer.ToArray(), newIndexBuffer.ToArray()); + } + + public static MeshSlicerResult SliceMesh( + IReadOnlyList vertexBuffer, + IReadOnlyList indexBuffer, + int indexBufferStart, + int indexBufferEnd) + { + // BREAKDOWN: + // + // vertexBuffer: [..., vA, vB, vC, vD, ..., vE, vF, vG, ...] + // (indices): ..., 54, 55, 56, 57, ..., 89, 90, 91, ... + // + // indexBuffer: [..., 89, 90, 91, 54, 55, 56, 54, 56, 57, ...] + // [ ^indexBufferStart indexBufferEnd^ ] + // oldIndexSlice: [ 89, 90, 91, 54, 55, 56, 54, 56, 57 ] + // + // oldToNewIndexMap... + // {oldIndex}: { 89, 90, 91, 54, 55, 56, 57 } + // {newIndex}: { 0, 1, 2, 3, 4, 5, 6 } <-- new indices are based on order of insertion of oldIndex into the map. + // + // newVertexBuffer: [ vE, vF, vG, vA, vB, vC, vD ] <-- vertices are added based on order of insertion of oldIndex into the map. + // + // oldIndexSlice --> [ 89, 90, 91, 54, 55, 56, 54, 56, 57 ] + // v v v v v v v v v <-- mapped using oldToNewIndexMap + // newIndexBuffer: [ 0, 1, 2, 3, 4, 5, 3, 5, 6 ] + + if (indexBufferStart < 0 || indexBufferStart >= indexBuffer.Count) + { + return MeshSlicerResult.Empty; + } + + if (indexBufferEnd < 0 + || indexBufferEnd >= indexBuffer.Count + || indexBufferEnd < indexBufferStart) + { + return MeshSlicerResult.Empty; + } + + // Read the indices. + var oldToNewIndexMap = new Dictionary(); + var newVertexBuffer = new List(); + + // Create a slice of the index buffer. + var oldIndexSlice = new int[indexBufferEnd - indexBufferStart + 1]; + for (var i = 0; i < oldIndexSlice.Length; i++) + { + var oldIndex = indexBuffer[indexBufferStart + i]; + oldIndexSlice[i] = oldIndex; + + if (!oldToNewIndexMap.ContainsKey(oldIndex)) + { + var newIndex = oldToNewIndexMap.Count; // 0, 1, 2, ... + oldToNewIndexMap.Add(oldIndex, newIndex); + + var vertex = vertexBuffer[oldIndex]; + newVertexBuffer.Add(vertex); + } + } + + // Create a new index buffer starting at 0. + var newIndexBuffer = new int[oldIndexSlice.Length]; + for (var i = 0; i < newIndexBuffer.Length; ++i) + { + var oldIndex = oldIndexSlice[i]; + var newIndex = oldToNewIndexMap[oldIndex]; + newIndexBuffer[i] = newIndex; + } + + return new MeshSlicerResult(newVertexBuffer.ToArray(), newIndexBuffer); + } + } + + public class MeshSlicerResult + { + public Vector3[] VertexBuffer { get; } + public int[] IndexBuffer { get; } + + public MeshSlicerResult(Vector3[] vertexBuffer, int[] indexBuffer) + { + VertexBuffer = vertexBuffer; + IndexBuffer = indexBuffer; + } + + public static MeshSlicerResult Empty + => new MeshSlicerResult(Array.Empty(), Array.Empty()); + + public bool IsEmpty + => VertexBuffer.Length == 0 || IndexBuffer.Length == 0; + } +} diff --git a/src/cs/vim/Vim.Format.Core/Serializer.cs b/src/cs/vim/Vim.Format.Core/Serializer.cs index 06dce92e..d45f66f6 100644 --- a/src/cs/vim/Vim.Format.Core/Serializer.cs +++ b/src/cs/vim/Vim.Format.Core/Serializer.cs @@ -6,6 +6,7 @@ using System.Text; using System.Text.RegularExpressions; using Vim.G3d; +using Vim.Math3d; using Vim.Util; namespace Vim.Format @@ -108,6 +109,21 @@ public static SerializableEntityTable ReadEntityTable( et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); break; } + case VimConstants.Vector3ColumnNameTypePrefix: + { + et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); + break; + } + case VimConstants.Vector4ColumnNameTypePrefix: + { + et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); + break; + } + case VimConstants.Matrix4x4ColumnNameTypePrefix: + { + et.DataColumns.Add(colBr.ReadEntityTableColumn(schemaOnly)); + break; + } // For flexibility, we ignore the columns which do not contain a recognized prefix. } } diff --git a/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj.DotSettings b/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj.DotSettings new file mode 100644 index 00000000..bd95c7d7 --- /dev/null +++ b/src/cs/vim/Vim.Format.Core/Vim.Format.Core.csproj.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/src/cs/vim/Vim.Format.Core/VimConstants.cs b/src/cs/vim/Vim.Format.Core/VimConstants.cs index 72867a68..2519ab94 100644 --- a/src/cs/vim/Vim.Format.Core/VimConstants.cs +++ b/src/cs/vim/Vim.Format.Core/VimConstants.cs @@ -68,6 +68,12 @@ public static class TableNames public const string ViewInViewSheet = "Vim.ViewInViewSheet"; public const string Site = "Vim.Site"; public const string Building = "Vim.Building"; + public const string Instance = "Vim.Instance"; + public const string Mesh = "Vim.Mesh"; + public const string MeshIndexBuffer = "Vim.MeshIndexBuffer"; + public const string MeshVertexBuffer = "Vim.MeshVertexBuffer"; + public const string LineShape = "Vim.LineShape"; + public const string LineShapeVertexBuffer = "Vim.LineShapeVertexBuffer"; } public static class VimConstants @@ -85,6 +91,9 @@ public static class VimConstants public const string UbyteColumNameTypePrefix = "ubyte:"; // unused for now public const string FloatColumnNameTypePrefix = "float:"; public const string DoubleColumnNameTypePrefix = "double:"; + public const string Vector3ColumnNameTypePrefix = "vector3:"; + public const string Vector4ColumnNameTypePrefix = "vector4:"; + public const string Matrix4x4ColumnNameTypePrefix = "matrix4x4:"; public const int NoEntityRelation = -1; public const long SyntheticElementId = -1; diff --git a/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs b/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs index 560e5887..92cf0650 100644 --- a/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs +++ b/src/cs/vim/Vim.Format.Tests/EntityTable_v2_Tests.cs @@ -1,6 +1,5 @@ using NUnit.Framework; using System.IO; -using System.Linq; using Vim.Format.ObjectModel; using Vim.LinqArray; using Vim.Util.Tests; diff --git a/src/cs/vim/Vim.Format.Tests/GeometricEntitiesTest.cs b/src/cs/vim/Vim.Format.Tests/GeometricEntitiesTest.cs new file mode 100644 index 00000000..e852b545 --- /dev/null +++ b/src/cs/vim/Vim.Format.Tests/GeometricEntitiesTest.cs @@ -0,0 +1,98 @@ +using NUnit.Framework; +using System.IO; +using Vim.BFast; +using Vim.Math3d; +using Vim.Util.Tests; + +namespace Vim.Format.Tests; + +[TestFixture] +public static class GeometricEntitiesTest +{ + [Test] + public static void TestRawReadWrite() + { + var ctx = new CallerTestContext(); + var dir = ctx.PrepareDirectory(); + + // Test Vector3 raw read/write + { + var vectorData = new Vector3[20]; + for (var i = 0; i < vectorData.Length; i++) + vectorData[i] = new Vector3(i, i * i, i * i * i); + + var vectorBuffer = vectorData.ToNamedBuffer("vectors"); + + var vectorFile = Path.Combine(dir, "vectors.buf"); + using (var fs = File.Open(vectorFile, FileMode.Create)) + { + vectorBuffer.Write(fs); + } + + using (var fs = File.OpenRead(vectorFile)) + { + var vectorsRead = fs.ReadArray(vectorData.Length); + Assert.Greater(vectorsRead.Length, 0); + + for (var i = 0; i < vectorsRead.Length; i++) + { + var vectorExpected = vectorData[i]; + var vectorActual = vectorsRead[i]; + Assert.IsTrue(vectorExpected.X == vectorActual.X); + Assert.IsTrue(vectorExpected.Y == vectorActual.Y); + Assert.IsTrue(vectorExpected.Z == vectorActual.Z); + } + } + } + + // Test Matrix4x4 raw read/write + { + var matrixData = new Matrix4x4[20]; + for (var i = 0; i < matrixData.Length; i++) + { + matrixData[i] = new Matrix4x4( + i, + i + 1, + i + 2, + i + 3, + i + 4, + i + 5, + i + 6, + i + 7, + i + 8, + i + 9, + i + 10, + i + 11, + i + 12, + i + 13, + i + 14, + i + 15); + } + + var matrixBuffer = matrixData.ToNamedBuffer("matrices"); + + var matrixFile = Path.Combine(dir, "matrices.buf"); + using (var fs = File.Open(matrixFile, FileMode.Create)) + { + matrixBuffer.Write(fs); + } + + using (var fs = File.OpenRead(matrixFile)) + { + var matricesRead = fs.ReadArray(matrixData.Length); + Assert.Greater(matricesRead.Length, 0); + for (var i = 0; i < matricesRead.Length; i++) + { + var matrixExpectedFloats = matrixData[i].ToFloats(); + Assert.Greater(matrixExpectedFloats.Length, 0); + var matrixActualFloats = matricesRead[i].ToFloats(); + + for (var j = 0; j < matrixExpectedFloats.Length; j++) + { + Assert.AreEqual(matrixExpectedFloats[j], matrixActualFloats[j]); + } + } + } + } + } +} diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs index 9b78cd85..19bf7bc0 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModel.cs @@ -14,6 +14,10 @@ public static class SchemaVersion // ReSharper disable MemberHidesStaticFromOuterClass public static class History { + // Schema additions + // TODO + public const string v5_6_0 = "5.6.0"; + // Schema additions // Vim.Level__double:ProjectElevation public const string v5_5_0 = "5.5.0"; @@ -171,7 +175,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_5_0; + public static SerializableVersion Current => v5_6_0; + public static SerializableVersion v5_6_0 => SerializableVersion.Parse(History.v5_6_0); public static SerializableVersion v5_5_0 => SerializableVersion.Parse(History.v5_5_0); public static SerializableVersion v5_4_0 => SerializableVersion.Parse(History.v5_4_0); public static SerializableVersion v5_3_0 => SerializableVersion.Parse(History.v5_3_0); @@ -934,6 +939,7 @@ public object GetStorageKey() /// An associative table binding a Shape to a View. /// [TableName(TableNames.ShapeInView)] + [Obsolete("Moved to LineShape")] public partial class ShapeInView : Entity, IStorageKey { public Relation _Shape; @@ -1264,12 +1270,12 @@ public AABox Box /// The ordering and number of Shapes matches the ordering and number of shapes in the G3D buffer. /// [TableName(TableNames.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)] + //[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)] + [Obsolete("Replaced with LineShape")] public partial class Shape : EntityWithElement - { - } + { } /// /// Represents a collection of shapes associated with an Element. @@ -1277,9 +1283,10 @@ public partial class Shape : EntityWithElement /// faces may have a number of curve loops which may designate the contour of the face and its holes. /// [TableName(TableNames.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)] + //[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)] + [Obsolete("Replaced with FaceMesh")] public partial class ShapeCollection : EntityWithElement { } @@ -1288,6 +1295,7 @@ public partial class ShapeCollection : EntityWithElement /// An associative table binding a Shape to a ShapeCollection. /// [TableName(TableNames.ShapeInShapeCollection)] + [Obsolete("Replaced with FaceMesh")] public partial class ShapeInShapeCollection : Entity, IStorageKey { public Relation _Shape; @@ -1767,6 +1775,146 @@ public partial class Building : EntityWithElement public Relation _Site; } + + TODO // Table names + /// + /// A group of instances which represents an element in a view. + /// + public partial class InstanceGroup : EntityWithElement + { + public int InstanceFlags; // None | Hidden | IsRoom | IsLevel ... // 32 + public Relation _View; // Optional for IFC case // 32 + public Relation _Transform; // 32 + public Relation _InstanceIndexStart; // 32 + public int InstanceIndexCount; // 32 + } + + /// + /// Contains sequences of instance indices. Referenced by instance group. + /// + public partial class InstanceIndex : Entity + { + public Relation _Instance; + } + + /// + /// An instance of a mesh with a local transform. + /// + public partial class Instance : Entity + { + public Relation _Mesh; + public Relation _Material; + public Relation _LocalTransform; + } + + /// + /// A mesh composed of vertex indices and vertices. + /// + public partial class Mesh : Entity + { + public Relation _MeshIndexBufferStart; + public int MeshIndexBufferCount; + public Relation _MeshVertexBufferStart; + public int MeshVertexBufferCount; + } + + /// + /// Contains sequences of vertex indices. Referenced by meshes. + /// + public partial class MeshIndexBuffer : Entity + { + // ex: [ ..., 10300, 10301, 10302, 10300, 10302, 10303, ...] <-- indexes into MeshVertexBuffer + public Relation _VertexIndex; + } + + /// + /// Contains sequences of vertices. Referenced by meshes. + /// + public partial class MeshVertexBuffer : Entity + { + public Vector3 Vertex; + } + + /// + /// Transformation matrices. + /// + public partial class Transform : Entity + { + public Matrix4x4 Matrix4x4; + } + + //[TableName(TableNames.Instance)] + //[VimSqlIgnore] + //public partial class Instance : EntityWithElement + //{ + // public Matrix4x4 Transform; + // public int InstanceFlags; + // public Relation _View; // Optional for IFC case + // public Relation _Material; + // public Relation _Mesh; + //} + + ///// + ///// Represents a mesh + ///// + //[TableName(TableNames.Mesh)] + //[VimSqlIgnore] + //public partial class Mesh : Entity + //{ + // public Relation _MeshIndexBufferStart; + // public Relation _MeshIndexBufferEnd; + // public Relation _MeshVertexBufferStart; + // public Relation _MeshVertexBufferEnd; + //} + + ///// + ///// Represents a continuous index buffer of triangular meshes. + ///// + //[TableName(TableNames.MeshIndexBuffer)] + //[EntityBuffer] + //[VimSqlIgnore] + //public partial class MeshIndexBuffer : Entity + //{ + // // ex: [ ..., 10300, 10301, 10302, 10300, 10302, 10303, ...] <-- indexes into the VertexBuffer + // public Relation _VertexIndex; + //} + + ///// + ///// Represents a continuous vertex buffer. + ///// + //[TableName(TableNames.MeshVertexBuffer)] + //[EntityBuffer] + //[VimSqlIgnore] + //public partial class MeshVertexBuffer : Entity + //{ + // public Vector3 Vertex; + //} + + /// + /// Represents a sequence of points connected by line segments + /// + [TableName(TableNames.LineShape)] + [VimSqlIgnore] + public partial class LineShape : EntityWithElement + { + public Vector4 Color; // [0..1f] per XYZW component. W component is alpha (0f = transparent, 1f = opaque). + public double Width; + public Relation _LineShapeVertexBufferStart; + public Relation _LineShapeVertexBufferEnd; + public Relation _View; + } + + /// + /// Represents the vertex buffer for LineShapes + /// + [TableName(TableNames.LineShapeVertexBuffer)] + [EntityBuffer] + [VimSqlIgnore] + public partial class LineShapeVertexBuffer : Entity + { + public Vector3 Vertex; + } + /// /// Helper functions for performing reflection over the object model /// diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs index c9d04f0c..9a4eb182 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelGenerated.cs @@ -1887,6 +1887,165 @@ public override bool FieldsAreEqual(object obj) } // end of class + // AUTO-GENERATED + public partial class Mesh + { + public Vim.Format.ObjectModel.MeshIndexList MeshIndexListStart => _MeshIndexBufferStart.Value; + public Vim.Format.ObjectModel.MeshIndexList MeshIndexListEnd => _MeshIndexBufferEnd.Value; + public Vim.Format.ObjectModel.View View => _View.Value; + public Vim.Format.ObjectModel.Material Material => _Material.Value; + public Vim.Format.ObjectModel.Element Element => _Element.Value; + public Mesh() + { + _MeshIndexBufferStart = new Relation(); + _MeshIndexBufferEnd = new Relation(); + _View = new Relation(); + _Material = new Relation(); + _Element = new Relation(); + } + + public override bool FieldsAreEqual(object obj) + { + if ((obj is Mesh other)) + { + var fieldsAreEqual = + (Index == other.Index) && + (_MeshIndexBufferStart?.Index == other._MeshIndexBufferStart?.Index) && + (_MeshIndexBufferEnd?.Index == other._MeshIndexBufferEnd?.Index) && + (_View?.Index == other._View?.Index) && + (_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 MeshIndexList + { + public Vim.Format.ObjectModel.MeshVertexList VertexIndex => _VertexIndex.Value; + public MeshIndexList() + { + _VertexIndex = new Relation(); + } + + public override bool FieldsAreEqual(object obj) + { + if ((obj is MeshIndexList other)) + { + var fieldsAreEqual = + (Index == other.Index) && + (_VertexIndex?.Index == other._VertexIndex?.Index); + if (!fieldsAreEqual) + { + return false; + } + + return true; + } + return false; + } + + } // end of class + + // AUTO-GENERATED + public partial class MeshVertexList + { + public MeshVertexList() + { + } + + public override bool FieldsAreEqual(object obj) + { + if ((obj is MeshVertexList other)) + { + var fieldsAreEqual = + (Index == other.Index) && + (Vertex == other.Vertex); + if (!fieldsAreEqual) + { + return false; + } + + return true; + } + return false; + } + + } // end of class + + // AUTO-GENERATED + public partial class LineShape + { + public Vim.Format.ObjectModel.LineShapeVertexBuffer LineShapeVertexBufferStart => _LineShapeVertexBufferStart.Value; + public Vim.Format.ObjectModel.LineShapeVertexBuffer LineShapeVertexBufferEnd => _LineShapeVertexBufferEnd.Value; + public Vim.Format.ObjectModel.View View => _View.Value; + public Vim.Format.ObjectModel.Element Element => _Element.Value; + public LineShape() + { + _LineShapeVertexBufferStart = new Relation(); + _LineShapeVertexBufferEnd = new Relation(); + _View = new Relation(); + _Element = new Relation(); + } + + public override bool FieldsAreEqual(object obj) + { + if ((obj is LineShape other)) + { + var fieldsAreEqual = + (Index == other.Index) && + (Color == other.Color) && + (Width == other.Width) && + (_LineShapeVertexBufferStart?.Index == other._LineShapeVertexBufferStart?.Index) && + (_LineShapeVertexBufferEnd?.Index == other._LineShapeVertexBufferEnd?.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 LineShapeVertexBuffer + { + public LineShapeVertexBuffer() + { + } + + public override bool FieldsAreEqual(object obj) + { + if ((obj is LineShapeVertexBuffer other)) + { + var fieldsAreEqual = + (Index == other.Index) && + (Vertex == other.Vertex); + if (!fieldsAreEqual) + { + return false; + } + + return true; + } + return false; + } + + } // end of class + public partial class DocumentModel { public ElementIndexMaps ElementIndexMaps { get; } @@ -3738,6 +3897,128 @@ public Building GetBuilding(int n) return r; } + + // FaceMesh + + public EntityTable FaceMeshEntityTable { get; } + + public IArray FaceMeshFaceMeshIndexBufferStartIndex { get; } + public int GetFaceMeshFaceMeshIndexBufferStartIndex(int index) => FaceMeshFaceMeshIndexBufferStartIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray FaceMeshFaceMeshIndexBufferEndIndex { get; } + public int GetFaceMeshFaceMeshIndexBufferEndIndex(int index) => FaceMeshFaceMeshIndexBufferEndIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray FaceMeshViewIndex { get; } + public int GetFaceMeshViewIndex(int index) => FaceMeshViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray FaceMeshMaterialIndex { get; } + public int GetFaceMeshMaterialIndex(int index) => FaceMeshMaterialIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray FaceMeshElementIndex { get; } + public int GetFaceMeshElementIndex(int index) => FaceMeshElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public int NumFaceMesh => FaceMeshEntityTable?.NumRows ?? 0; + public IArray FaceMeshList { get; } + public Mesh GetFaceMesh(int n) + { + if (n < 0) return null; + var r = new Mesh(); + r.Document = Document; + r.Index = n; + r._MeshIndexBufferStart = new Relation(GetFaceMeshFaceMeshIndexBufferStartIndex(n), GetFaceMeshIndexBuffer); + r._MeshIndexBufferEnd = new Relation(GetFaceMeshFaceMeshIndexBufferEndIndex(n), GetFaceMeshIndexBuffer); + r._View = new Relation(GetFaceMeshViewIndex(n), GetView); + r._Material = new Relation(GetFaceMeshMaterialIndex(n), GetMaterial); + r._Element = new Relation(GetFaceMeshElementIndex(n), GetElement); + return r; + } + + + // FaceMeshIndexBuffer + + public EntityTable FaceMeshIndexBufferEntityTable { get; } + + public IArray FaceMeshIndexBufferVertexIndexIndex { get; } + public int GetFaceMeshIndexBufferVertexIndexIndex(int index) => FaceMeshIndexBufferVertexIndexIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public int NumFaceMeshIndexBuffer => FaceMeshIndexBufferEntityTable?.NumRows ?? 0; + public IArray FaceMeshIndexBufferList { get; } + public MeshIndexList GetFaceMeshIndexBuffer(int n) + { + if (n < 0) return null; + var r = new MeshIndexList(); + r.Document = Document; + r.Index = n; + r._VertexIndex = new Relation(GetFaceMeshIndexBufferVertexIndexIndex(n), GetFaceMeshVertexBuffer); + return r; + } + + + // FaceMeshVertexBuffer + + public EntityTable FaceMeshVertexBufferEntityTable { get; } + + public IArray FaceMeshVertexBufferVertex { get; } + public Vector3 GetFaceMeshVertexBufferVertex(int index, Vector3 defaultValue = default) => FaceMeshVertexBufferVertex?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; + public int NumFaceMeshVertexBuffer => FaceMeshVertexBufferEntityTable?.NumRows ?? 0; + public IArray FaceMeshVertexBufferList { get; } + public MeshVertexList GetFaceMeshVertexBuffer(int n) + { + if (n < 0) return null; + var r = new MeshVertexList(); + r.Document = Document; + r.Index = n; + r.Vertex = FaceMeshVertexBufferVertex.ElementAtOrDefault(n); + return r; + } + + + // LineShape + + public EntityTable LineShapeEntityTable { get; } + + public IArray LineShapeColor { get; } + public Vector4 GetLineShapeColor(int index, Vector4 defaultValue = default) => LineShapeColor?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; + public IArray LineShapeWidth { get; } + public Double GetLineShapeWidth(int index, Double defaultValue = default) => LineShapeWidth?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; + public IArray LineShapeLineShapeVertexBufferStartIndex { get; } + public int GetLineShapeLineShapeVertexBufferStartIndex(int index) => LineShapeLineShapeVertexBufferStartIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray LineShapeLineShapeVertexBufferEndIndex { get; } + public int GetLineShapeLineShapeVertexBufferEndIndex(int index) => LineShapeLineShapeVertexBufferEndIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray LineShapeViewIndex { get; } + public int GetLineShapeViewIndex(int index) => LineShapeViewIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public IArray LineShapeElementIndex { get; } + public int GetLineShapeElementIndex(int index) => LineShapeElementIndex?.ElementAtOrDefault(index, EntityRelation.None) ?? EntityRelation.None; + public int NumLineShape => LineShapeEntityTable?.NumRows ?? 0; + public IArray LineShapeList { get; } + public LineShape GetLineShape(int n) + { + if (n < 0) return null; + var r = new LineShape(); + r.Document = Document; + r.Index = n; + r.Color = LineShapeColor.ElementAtOrDefault(n); + r.Width = LineShapeWidth.ElementAtOrDefault(n); + r._LineShapeVertexBufferStart = new Relation(GetLineShapeLineShapeVertexBufferStartIndex(n), GetLineShapeVertexBuffer); + r._LineShapeVertexBufferEnd = new Relation(GetLineShapeLineShapeVertexBufferEndIndex(n), GetLineShapeVertexBuffer); + r._View = new Relation(GetLineShapeViewIndex(n), GetView); + r._Element = new Relation(GetLineShapeElementIndex(n), GetElement); + return r; + } + + + // LineShapeVertexBuffer + + public EntityTable LineShapeVertexBufferEntityTable { get; } + + public IArray LineShapeVertexBufferVertex { get; } + public Vector3 GetLineShapeVertexBufferVertex(int index, Vector3 defaultValue = default) => LineShapeVertexBufferVertex?.ElementAtOrDefault(index, defaultValue) ?? defaultValue; + public int NumLineShapeVertexBuffer => LineShapeVertexBufferEntityTable?.NumRows ?? 0; + public IArray LineShapeVertexBufferList { get; } + public LineShapeVertexBuffer GetLineShapeVertexBuffer(int n) + { + if (n < 0) return null; + var r = new LineShapeVertexBuffer(); + r.Document = Document; + r.Index = n; + r.Vertex = LineShapeVertexBufferVertex.ElementAtOrDefault(n); + return r; + } + // All entity collections public Dictionary> AllEntities => new Dictionary>() { {"Vim.Asset", AssetList.ToEnumerable()}, @@ -3794,6 +4075,11 @@ public Building GetBuilding(int n) {"Vim.ViewInViewSheet", ViewInViewSheetList.ToEnumerable()}, {"Vim.Site", SiteList.ToEnumerable()}, {"Vim.Building", BuildingList.ToEnumerable()}, + {"Vim.FaceMesh", FaceMeshList.ToEnumerable()}, + {"Vim.FaceMeshIndexBuffer", FaceMeshIndexBufferList.ToEnumerable()}, + {"Vim.FaceMeshVertexBuffer", FaceMeshVertexBufferList.ToEnumerable()}, + {"Vim.LineShape", LineShapeList.ToEnumerable()}, + {"Vim.LineShapeVertexBuffer", LineShapeVertexBufferList.ToEnumerable()}, }; // Entity types from table names @@ -3852,6 +4138,11 @@ public Building GetBuilding(int n) {"Vim.ViewInViewSheet", typeof(ViewInViewSheet)}, {"Vim.Site", typeof(Site)}, {"Vim.Building", typeof(Building)}, + {"Vim.FaceMesh", typeof(Mesh)}, + {"Vim.FaceMeshIndexBuffer", typeof(MeshIndexList)}, + {"Vim.FaceMeshVertexBuffer", typeof(MeshVertexList)}, + {"Vim.LineShape", typeof(LineShape)}, + {"Vim.LineShapeVertexBuffer", typeof(LineShapeVertexBuffer)}, }; public DocumentModel(Document d, bool inParallel = true) { @@ -3912,6 +4203,11 @@ public DocumentModel(Document d, bool inParallel = true) ViewInViewSheetEntityTable = Document.GetTable("Vim.ViewInViewSheet"); SiteEntityTable = Document.GetTable("Vim.Site"); BuildingEntityTable = Document.GetTable("Vim.Building"); + FaceMeshEntityTable = Document.GetTable("Vim.FaceMesh"); + FaceMeshIndexBufferEntityTable = Document.GetTable("Vim.FaceMeshIndexBuffer"); + FaceMeshVertexBufferEntityTable = Document.GetTable("Vim.FaceMeshVertexBuffer"); + LineShapeEntityTable = Document.GetTable("Vim.LineShape"); + LineShapeVertexBufferEntityTable = Document.GetTable("Vim.LineShapeVertexBuffer"); // Initialize entity arrays AssetBufferName = AssetEntityTable?.GetStringColumnValues("string:BufferName") ?? Array.Empty().ToIArray(); @@ -4142,6 +4438,10 @@ public DocumentModel(Document d, bool inParallel = true) BuildingElevation = BuildingEntityTable?.GetDataColumnValues("double:Elevation") ?? Array.Empty().ToIArray(); BuildingTerrainElevation = BuildingEntityTable?.GetDataColumnValues("double:TerrainElevation") ?? Array.Empty().ToIArray(); BuildingAddress = BuildingEntityTable?.GetStringColumnValues("string:Address") ?? Array.Empty().ToIArray(); + FaceMeshVertexBufferVertex = FaceMeshVertexBufferEntityTable?.GetDataColumnValues("vector3:Vertex") ?? Array.Empty().ToIArray(); + LineShapeColor = LineShapeEntityTable?.GetDataColumnValues("vector4:Color") ?? Array.Empty().ToIArray(); + LineShapeWidth = LineShapeEntityTable?.GetDataColumnValues("double:Width") ?? Array.Empty().ToIArray(); + LineShapeVertexBufferVertex = LineShapeVertexBufferEntityTable?.GetDataColumnValues("vector3:Vertex") ?? Array.Empty().ToIArray(); // Initialize entity relational columns ParameterDescriptorDisplayUnitIndex = ParameterDescriptorEntityTable?.GetIndexColumnValues("index:Vim.DisplayUnit:DisplayUnit") ?? Array.Empty().ToIArray(); @@ -4244,6 +4544,16 @@ public DocumentModel(Document d, bool inParallel = true) 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(); + FaceMeshFaceMeshIndexBufferStartIndex = FaceMeshEntityTable?.GetIndexColumnValues("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart") ?? Array.Empty().ToIArray(); + FaceMeshFaceMeshIndexBufferEndIndex = FaceMeshEntityTable?.GetIndexColumnValues("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd") ?? Array.Empty().ToIArray(); + FaceMeshViewIndex = FaceMeshEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); + FaceMeshMaterialIndex = FaceMeshEntityTable?.GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty().ToIArray(); + FaceMeshElementIndex = FaceMeshEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); + FaceMeshIndexBufferVertexIndexIndex = FaceMeshIndexBufferEntityTable?.GetIndexColumnValues("index:Vim.FaceMeshVertexBuffer:VertexIndex") ?? Array.Empty().ToIArray(); + LineShapeLineShapeVertexBufferStartIndex = LineShapeEntityTable?.GetIndexColumnValues("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart") ?? Array.Empty().ToIArray(); + LineShapeLineShapeVertexBufferEndIndex = LineShapeEntityTable?.GetIndexColumnValues("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd") ?? Array.Empty().ToIArray(); + LineShapeViewIndex = LineShapeEntityTable?.GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty().ToIArray(); + LineShapeElementIndex = LineShapeEntityTable?.GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty().ToIArray(); // Initialize entity collections AssetList = NumAsset.Select(i => GetAsset(i)); @@ -4300,6 +4610,11 @@ public DocumentModel(Document d, bool inParallel = true) ViewInViewSheetList = NumViewInViewSheet.Select(i => GetViewInViewSheet(i)); SiteList = NumSite.Select(i => GetSite(i)); BuildingList = NumBuilding.Select(i => GetBuilding(i)); + FaceMeshList = NumFaceMesh.Select(i => GetFaceMesh(i)); + FaceMeshIndexBufferList = NumFaceMeshIndexBuffer.Select(i => GetFaceMeshIndexBuffer(i)); + FaceMeshVertexBufferList = NumFaceMeshVertexBuffer.Select(i => GetFaceMeshVertexBuffer(i)); + LineShapeList = NumLineShape.Select(i => GetLineShape(i)); + LineShapeVertexBufferList = NumLineShapeVertexBuffer.Select(i => GetLineShapeVertexBuffer(i)); // Initialize element index maps ElementIndexMaps = new ElementIndexMaps(this, inParallel); @@ -4483,6 +4798,21 @@ public EntityTableSet(SerializableEntityTable[] rawTables, string[] stringBuffer if (GetRawTableOrDefault("Vim.Building") is SerializableEntityTable buildingTable) BuildingTable = new BuildingTable(buildingTable, stringBuffer); + if (GetRawTableOrDefault("Vim.FaceMesh") is SerializableEntityTable facemeshTable) + FaceMeshTable = new FaceMeshTable(facemeshTable, stringBuffer); + + if (GetRawTableOrDefault("Vim.FaceMeshIndexBuffer") is SerializableEntityTable facemeshindexbufferTable) + FaceMeshIndexBufferTable = new FaceMeshIndexBufferTable(facemeshindexbufferTable, stringBuffer); + + if (GetRawTableOrDefault("Vim.FaceMeshVertexBuffer") is SerializableEntityTable facemeshvertexbufferTable) + FaceMeshVertexBufferTable = new FaceMeshVertexBufferTable(facemeshvertexbufferTable, stringBuffer); + + if (GetRawTableOrDefault("Vim.LineShape") is SerializableEntityTable lineshapeTable) + LineShapeTable = new LineShapeTable(lineshapeTable, stringBuffer); + + if (GetRawTableOrDefault("Vim.LineShapeVertexBuffer") is SerializableEntityTable lineshapevertexbufferTable) + LineShapeVertexBufferTable = new LineShapeVertexBufferTable(lineshapevertexbufferTable, stringBuffer); + // Initialize element index maps ElementIndexMaps = new ElementIndexMaps(this, inParallel); @@ -4596,6 +4926,16 @@ public EntityTableSet(SerializableEntityTable[] rawTables, string[] stringBuffer public Site GetSite(int index) => SiteTable?.Get(index); public BuildingTable BuildingTable { get; } // can be null public Building GetBuilding(int index) => BuildingTable?.Get(index); + public FaceMeshTable FaceMeshTable { get; } // can be null + public Mesh GetFaceMesh(int index) => FaceMeshTable?.Get(index); + public FaceMeshIndexBufferTable FaceMeshIndexBufferTable { get; } // can be null + public MeshIndexList GetFaceMeshIndexBuffer(int index) => FaceMeshIndexBufferTable?.Get(index); + public FaceMeshVertexBufferTable FaceMeshVertexBufferTable { get; } // can be null + public MeshVertexList GetFaceMeshVertexBuffer(int index) => FaceMeshVertexBufferTable?.Get(index); + public LineShapeTable LineShapeTable { get; } // can be null + public LineShape GetLineShape(int index) => LineShapeTable?.Get(index); + public LineShapeVertexBufferTable LineShapeVertexBufferTable { get; } // can be null + public LineShapeVertexBuffer GetLineShapeVertexBuffer(int index) => LineShapeVertexBufferTable?.Get(index); } // class EntityTableSet public partial class AssetTable : EntityTable_v2, IEnumerable @@ -7514,6 +7854,212 @@ public IEnumerator GetEnumerator() } } // class BuildingTable + public partial class FaceMeshTable : EntityTable_v2, IEnumerable + { + private readonly EntityTableSet _parentTableSet; // can be null + + public FaceMeshTable(SerializableEntityTable rawTable, string[] stringBuffer, EntityTableSet parentTableSet = null) : base(rawTable, stringBuffer) + { + _parentTableSet = parentTableSet; + Column_FaceMeshIndexBufferStartIndex = GetIndexColumnValues("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart") ?? Array.Empty(); + Column_FaceMeshIndexBufferEndIndex = GetIndexColumnValues("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd") ?? Array.Empty(); + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + Column_MaterialIndex = GetIndexColumnValues("index:Vim.Material:Material") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + + public int[] Column_FaceMeshIndexBufferStartIndex { get; } + public int GetFaceMeshIndexBufferStartIndex(int index) => Column_FaceMeshIndexBufferStartIndex.ElementAtOrDefault(index, EntityRelation.None); + public MeshIndexList GetFaceMeshIndexBufferStart(int index) => _GetReferencedFaceMeshIndexBufferStart(GetFaceMeshIndexBufferStartIndex(index)); + private MeshIndexList _GetReferencedFaceMeshIndexBufferStart(int referencedIndex) => _parentTableSet.GetFaceMeshIndexBuffer(referencedIndex); + public int[] Column_FaceMeshIndexBufferEndIndex { get; } + public int GetFaceMeshIndexBufferEndIndex(int index) => Column_FaceMeshIndexBufferEndIndex.ElementAtOrDefault(index, EntityRelation.None); + public MeshIndexList GetFaceMeshIndexBufferEnd(int index) => _GetReferencedFaceMeshIndexBufferEnd(GetFaceMeshIndexBufferEndIndex(index)); + private MeshIndexList _GetReferencedFaceMeshIndexBufferEnd(int referencedIndex) => _parentTableSet.GetFaceMeshIndexBuffer(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); + 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 Mesh Get(int index) + { + if (index < 0) return null; + var r = new Mesh(); + r.Index = index; + r._MeshIndexBufferStart = new Relation(GetFaceMeshIndexBufferStartIndex(index), _GetReferencedFaceMeshIndexBufferStart); + r._MeshIndexBufferEnd = new Relation(GetFaceMeshIndexBufferEndIndex(index), _GetReferencedFaceMeshIndexBufferEnd); + r._View = new Relation(GetViewIndex(index), _GetReferencedView); + 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 FaceMeshTable + + public partial class FaceMeshIndexBufferTable : EntityTable_v2, IEnumerable + { + private readonly EntityTableSet _parentTableSet; // can be null + + public FaceMeshIndexBufferTable(SerializableEntityTable rawTable, string[] stringBuffer, EntityTableSet parentTableSet = null) : base(rawTable, stringBuffer) + { + _parentTableSet = parentTableSet; + Column_VertexIndexIndex = GetIndexColumnValues("index:Vim.FaceMeshVertexBuffer:VertexIndex") ?? Array.Empty(); + } + + public int[] Column_VertexIndexIndex { get; } + public int GetVertexIndexIndex(int index) => Column_VertexIndexIndex.ElementAtOrDefault(index, EntityRelation.None); + public MeshVertexList GetVertexIndex(int index) => _GetReferencedVertexIndex(GetVertexIndexIndex(index)); + private MeshVertexList _GetReferencedVertexIndex(int referencedIndex) => _parentTableSet.GetFaceMeshVertexBuffer(referencedIndex); + // Object Getter + public MeshIndexList Get(int index) + { + if (index < 0) return null; + var r = new MeshIndexList(); + r.Index = index; + r._VertexIndex = new Relation(GetVertexIndexIndex(index), _GetReferencedVertexIndex); + return r; + } + // Enumerator + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class FaceMeshIndexBufferTable + + public partial class FaceMeshVertexBufferTable : EntityTable_v2, IEnumerable + { + private readonly EntityTableSet _parentTableSet; // can be null + + public FaceMeshVertexBufferTable(SerializableEntityTable rawTable, string[] stringBuffer, EntityTableSet parentTableSet = null) : base(rawTable, stringBuffer) + { + _parentTableSet = parentTableSet; + Column_Vertex = GetDataColumnValues("vector3:Vertex") ?? Array.Empty(); + } + + public Vector3[] Column_Vertex { get; } + public Vector3 GetVertex(int index, Vector3 @default = default) => Column_Vertex.ElementAtOrDefault(index, @default); + // Object Getter + public MeshVertexList Get(int index) + { + if (index < 0) return null; + var r = new MeshVertexList(); + r.Index = index; + r.Vertex = GetVertex(index); + return r; + } + // Enumerator + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class FaceMeshVertexBufferTable + + public partial class LineShapeTable : EntityTable_v2, IEnumerable + { + private readonly EntityTableSet _parentTableSet; // can be null + + public LineShapeTable(SerializableEntityTable rawTable, string[] stringBuffer, EntityTableSet parentTableSet = null) : base(rawTable, stringBuffer) + { + _parentTableSet = parentTableSet; + Column_Color = GetDataColumnValues("vector4:Color") ?? Array.Empty(); + Column_Width = GetDataColumnValues("double:Width") ?? Array.Empty(); + Column_LineShapeVertexBufferStartIndex = GetIndexColumnValues("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart") ?? Array.Empty(); + Column_LineShapeVertexBufferEndIndex = GetIndexColumnValues("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd") ?? Array.Empty(); + Column_ViewIndex = GetIndexColumnValues("index:Vim.View:View") ?? Array.Empty(); + Column_ElementIndex = GetIndexColumnValues("index:Vim.Element:Element") ?? Array.Empty(); + } + + public Vector4[] Column_Color { get; } + public Vector4 GetColor(int index, Vector4 @default = default) => Column_Color.ElementAtOrDefault(index, @default); + public Double[] Column_Width { get; } + public Double GetWidth(int index, Double @default = default) => Column_Width.ElementAtOrDefault(index, @default); + public int[] Column_LineShapeVertexBufferStartIndex { get; } + public int GetLineShapeVertexBufferStartIndex(int index) => Column_LineShapeVertexBufferStartIndex.ElementAtOrDefault(index, EntityRelation.None); + public LineShapeVertexBuffer GetLineShapeVertexBufferStart(int index) => _GetReferencedLineShapeVertexBufferStart(GetLineShapeVertexBufferStartIndex(index)); + private LineShapeVertexBuffer _GetReferencedLineShapeVertexBufferStart(int referencedIndex) => _parentTableSet.GetLineShapeVertexBuffer(referencedIndex); + public int[] Column_LineShapeVertexBufferEndIndex { get; } + public int GetLineShapeVertexBufferEndIndex(int index) => Column_LineShapeVertexBufferEndIndex.ElementAtOrDefault(index, EntityRelation.None); + public LineShapeVertexBuffer GetLineShapeVertexBufferEnd(int index) => _GetReferencedLineShapeVertexBufferEnd(GetLineShapeVertexBufferEndIndex(index)); + private LineShapeVertexBuffer _GetReferencedLineShapeVertexBufferEnd(int referencedIndex) => _parentTableSet.GetLineShapeVertexBuffer(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); + 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 LineShape Get(int index) + { + if (index < 0) return null; + var r = new LineShape(); + r.Index = index; + r.Color = GetColor(index); + r.Width = GetWidth(index); + r._LineShapeVertexBufferStart = new Relation(GetLineShapeVertexBufferStartIndex(index), _GetReferencedLineShapeVertexBufferStart); + r._LineShapeVertexBufferEnd = new Relation(GetLineShapeVertexBufferEndIndex(index), _GetReferencedLineShapeVertexBufferEnd); + 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 LineShapeTable + + public partial class LineShapeVertexBufferTable : EntityTable_v2, IEnumerable + { + private readonly EntityTableSet _parentTableSet; // can be null + + public LineShapeVertexBufferTable(SerializableEntityTable rawTable, string[] stringBuffer, EntityTableSet parentTableSet = null) : base(rawTable, stringBuffer) + { + _parentTableSet = parentTableSet; + Column_Vertex = GetDataColumnValues("vector3:Vertex") ?? Array.Empty(); + } + + public Vector3[] Column_Vertex { get; } + public Vector3 GetVertex(int index, Vector3 @default = default) => Column_Vertex.ElementAtOrDefault(index, @default); + // Object Getter + public LineShapeVertexBuffer Get(int index) + { + if (index < 0) return null; + var r = new LineShapeVertexBuffer(); + r.Index = index; + r.Vertex = GetVertex(index); + return r; + } + // Enumerator + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator GetEnumerator() + { + for (var i = 0; i < RowCount; ++i) + yield return Get(i); + } + } // class LineShapeVertexBufferTable + public static class DocumentBuilderExtensions { public static Func, EntityTableBuilder> GetTableBuilderFunc(this Type type) @@ -7572,6 +8118,8 @@ public static Func, EntityTableBuilder> GetTableBuilderFunc( if (type == typeof(ViewInViewSheet)) return ToViewInViewSheetTableBuilder; if (type == typeof(Site)) return ToSiteTableBuilder; if (type == typeof(Building)) return ToBuildingTableBuilder; + if (type == typeof(Mesh)) return ToFaceMeshTableBuilder; + if (type == typeof(LineShape)) return ToLineShapeTableBuilder; throw new ArgumentException(nameof(type)); } public static EntityTableBuilder ToAssetTableBuilder(this IEnumerable entities) @@ -8226,6 +8774,29 @@ public static EntityTableBuilder ToBuildingTableBuilder(this IEnumerable tb.AddIndexColumn("index:Vim.Element:Element", typedEntities.Select(x => x._Element?.Index ?? EntityRelation.None)); return tb; } + public static EntityTableBuilder ToFaceMeshTableBuilder(this IEnumerable entities) + { + var typedEntities = entities?.Cast() ?? Enumerable.Empty(); + var tb = new EntityTableBuilder("Vim.FaceMesh"); + tb.AddIndexColumn("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart", typedEntities.Select(x => x._MeshIndexBufferStart?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd", typedEntities.Select(x => x._MeshIndexBufferEnd?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.View:View", typedEntities.Select(x => x._View?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.Material:Material", typedEntities.Select(x => x._Material?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.Element:Element", typedEntities.Select(x => x._Element?.Index ?? EntityRelation.None)); + return tb; + } + public static EntityTableBuilder ToLineShapeTableBuilder(this IEnumerable entities) + { + var typedEntities = entities?.Cast() ?? Enumerable.Empty(); + var tb = new EntityTableBuilder("Vim.LineShape"); + tb.AddDataColumn("vector4:Color", typedEntities.Select(x => x.Color)); + tb.AddDataColumn("double:Width", typedEntities.Select(x => x.Width)); + tb.AddIndexColumn("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart", typedEntities.Select(x => x._LineShapeVertexBufferStart?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd", typedEntities.Select(x => x._LineShapeVertexBufferEnd?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.View:View", typedEntities.Select(x => x._View?.Index ?? EntityRelation.None)); + tb.AddIndexColumn("index:Vim.Element:Element", typedEntities.Select(x => x._Element?.Index ?? EntityRelation.None)); + return tb; + } } // DocumentBuilderExtensions public partial class ObjectModelBuilder @@ -8286,6 +8857,8 @@ public partial class ObjectModelBuilder {typeof(ViewInViewSheet), new EntityTableBuilder()}, {typeof(Site), new EntityTableBuilder()}, {typeof(Building), new EntityTableBuilder()}, + {typeof(Mesh), new EntityTableBuilder()}, + {typeof(LineShape), new EntityTableBuilder()}, }; } // ObjectModelBuilder } // namespace diff --git a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs index fd3c04c9..51e2ad04 100644 --- a/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs +++ b/src/cs/vim/Vim.Format/ObjectModel/ObjectModelStore.cs @@ -21,13 +21,51 @@ public class ObjectModelStore public DocumentBuilder ToDocumentBuilder(string generator, string versionString) { - return ObjectModelBuilder.ToDocumentBuilder(generator, versionString) + var db = ObjectModelBuilder.ToDocumentBuilder(generator, versionString); + AddEntityTableBuffers(db); + + return db .AddMeshes(Meshes.Select(g => g.Subdivide())) .AddInstances(Instances) .AddShapes(Shapes) .AddMaterials(CreateMaterialBuilders()); } + public List FaceMeshIndexBuffer { get; } = new List(); + public List FaceMeshVertexBuffer { get; } = new List(); + + public List LineShapeVertexBuffer { get; } = new List(); + + private void AddEntityTableBuffers(DocumentBuilder documentBuilder) + { +#if DEBUG + // Validate the index buffer and the vertex buffer + foreach (var index in FaceMeshIndexBuffer) + Debug.Assert(index >= 0 && index < FaceMeshVertexBuffer.Count); +#endif + + // Add the face mesh index buffer. + { + var tb = new EntityTableBuilder(TableNames.MeshIndexBuffer); + tb.AddIndexColumn($"index:{TableNames.MeshVertexBuffer}:{nameof(ObjectModel.MeshIndexList.VertexIndex)}", FaceMeshIndexBuffer); + documentBuilder.Tables.Add(tb.Name, tb); + } + + // Add the face mesh vertex buffer. + { + var tb = new EntityTableBuilder(TableNames.MeshVertexBuffer); + tb.AddDataColumn($"vector3:{nameof(ObjectModel.MeshVertexList.Vertex)}", FaceMeshVertexBuffer); + documentBuilder.Tables.Add(tb.Name, tb); + } + + // Add the line shape vertex buffer. + { + var tb = new EntityTableBuilder(TableNames.LineShapeVertexBuffer); + tb.AddDataColumn($"vector3:{nameof(ObjectModel.LineShapeVertexBuffer.Vertex)}", LineShapeVertexBuffer); + documentBuilder.Tables.Add(tb.Name, tb); + } + } + private IEnumerable CreateMaterialBuilders() => ObjectModelBuilder.GetEntities().Select(ConvertMaterialEntityToRenderableMaterial); diff --git a/src/ts/package-lock.json b/src/ts/package-lock.json index 79d6454f..88a69a8f 100644 --- a/src/ts/package-lock.json +++ b/src/ts/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "vim-format", - "version": "1.0.15-dev.2", + "version": "1.0.16-dev.2", "license": "MIT", "dependencies": { "pako": "^2.1.0" diff --git a/src/ts/src/entityTable.ts b/src/ts/src/entityTable.ts index b77f6674..9b1892b4 100644 --- a/src/ts/src/entityTable.ts +++ b/src/ts/src/entityTable.ts @@ -3,6 +3,7 @@ */ import { BFast, NumericArray, Range } from './bfast' +import { Vector3, Matrix4x4, Vector4 } from './structures' export class EntityTable { private readonly bfast: BFast @@ -42,6 +43,16 @@ export class EntityTable { return 2 // 2 bytes } + if (colName.startsWith('vector3:')) + { + return 4 * 3 // 4 bytes (float) times 3 (x,y,z) + } + + if (colName.startsWith('matrix4x4:')) + { + return 4 * 16 // 4 bytes (float) times 16 (4x4 matrix) + } + return 1 // default to 1 byte } @@ -170,4 +181,72 @@ export class EntityTable { } return result } + + async getVector3(elementIndex: number, columnName: string): Promise + { + const arrayBuffer = await this.bfast.getBuffer(columnName) + const floatView = new Float32Array(arrayBuffer) + + const startIndex = elementIndex * 3; // (x,y,z) => 3 + return { + x: floatView[startIndex], + y: floatView[startIndex + 1], + z: floatView[startIndex + 2] + } + } + + // TODO: Promise is a shortcut... should actually be Promise + async getVector3Array(columnName: string): Promise { + return await this.bfast.getBuffer(columnName) + } + + async getVector4(elementIndex: number, columnName: string): Promise + { + const arrayBuffer = await this.bfast.getBuffer(columnName) + const floatView = new Float32Array(arrayBuffer) + + const startIndex = elementIndex * 4; // (x,y,z,w) => 4 + return { + x: floatView[startIndex], + y: floatView[startIndex + 1], + z: floatView[startIndex + 2], + w: floatView[startIndex + 3] + } + } + + // TODO: Promise is a shortcut... should actually be Promise + async getVector4Array(columnName: string): Promise { + return await this.bfast.getBuffer(columnName) + } + + async getMatrix4x4(elementIndex: number, columnName: string): Promise + { + const arrayBuffer = await this.bfast.getBuffer(columnName) + const floatView = new Float32Array(arrayBuffer) + + const startIndex = elementIndex * 16; // (4x4) => 16 + return { + m11: floatView[startIndex], + m12: floatView[startIndex + 1], + m13: floatView[startIndex + 2], + m14: floatView[startIndex + 3], + m21: floatView[startIndex + 4], + m22: floatView[startIndex + 5], + m23: floatView[startIndex + 6], + m24: floatView[startIndex + 7], + m31: floatView[startIndex + 8], + m32: floatView[startIndex + 9], + m33: floatView[startIndex + 10], + m34: floatView[startIndex + 11], + m41: floatView[startIndex + 12], + m42: floatView[startIndex + 13], + m43: floatView[startIndex + 14], + m44: floatView[startIndex + 15], + } + } + + // TODO: Promise is a shortcut... should actually be Promise + async getMatrix4x4Array(columnName: string): Promise { + return await this.bfast.getBuffer(columnName) + } } diff --git a/src/ts/src/objectModel.ts b/src/ts/src/objectModel.ts index 3d543168..9da4eb9d 100644 --- a/src/ts/src/objectModel.ts +++ b/src/ts/src/objectModel.ts @@ -10569,6 +10569,723 @@ export class BuildingTable implements IBuildingTable { } +export interface IFaceMesh { + index: number + + faceMeshIndexBufferStartIndex?: number + faceMeshIndexBufferStart?: IFaceMeshIndexBuffer + faceMeshIndexBufferEndIndex?: number + faceMeshIndexBufferEnd?: IFaceMeshIndexBuffer + viewIndex?: number + view?: IView + materialIndex?: number + material?: IMaterial + elementIndex?: number + element?: IElement +} + +export interface IFaceMeshTable { + getCount(): Promise + get(faceMeshIndex: number): Promise + getAll(): Promise + + getFaceMeshIndexBufferStartIndex(faceMeshIndex: number): Promise + getAllFaceMeshIndexBufferStartIndex(): Promise + getFaceMeshIndexBufferStart(faceMeshIndex: number): Promise + getFaceMeshIndexBufferEndIndex(faceMeshIndex: number): Promise + getAllFaceMeshIndexBufferEndIndex(): Promise + getFaceMeshIndexBufferEnd(faceMeshIndex: number): Promise + getViewIndex(faceMeshIndex: number): Promise + getAllViewIndex(): Promise + getView(faceMeshIndex: number): Promise + getMaterialIndex(faceMeshIndex: number): Promise + getAllMaterialIndex(): Promise + getMaterial(faceMeshIndex: number): Promise + getElementIndex(faceMeshIndex: number): Promise + getAllElementIndex(): Promise + getElement(faceMeshIndex: number): Promise +} + +export class FaceMesh implements IFaceMesh { + index: number + + faceMeshIndexBufferStartIndex?: number + faceMeshIndexBufferStart?: IFaceMeshIndexBuffer + faceMeshIndexBufferEndIndex?: number + faceMeshIndexBufferEnd?: IFaceMeshIndexBuffer + viewIndex?: number + view?: IView + materialIndex?: number + material?: IMaterial + elementIndex?: number + element?: IElement + + static async createFromTable(table: IFaceMeshTable, index: number): Promise { + let result = new FaceMesh() + result.index = index + + await Promise.all([ + table.getFaceMeshIndexBufferStartIndex(index).then(v => result.faceMeshIndexBufferStartIndex = v), + table.getFaceMeshIndexBufferEndIndex(index).then(v => result.faceMeshIndexBufferEndIndex = v), + table.getViewIndex(index).then(v => result.viewIndex = v), + table.getMaterialIndex(index).then(v => result.materialIndex = v), + table.getElementIndex(index).then(v => result.elementIndex = v), + ]) + + return result + } +} + +export class FaceMeshTable implements IFaceMeshTable { + private document: VimDocument + private entityTable: EntityTable + + static async createFromDocument(document: VimDocument): Promise { + const entity = await document.entities.getBfast("Vim.FaceMesh") + + if (!entity) { + return undefined + } + + let table = new FaceMeshTable() + table.document = document + table.entityTable = new EntityTable(entity, document.strings) + + return table + } + + getCount(): Promise { + return this.entityTable.getCount() + } + + async get(faceMeshIndex: number): Promise { + return await FaceMesh.createFromTable(this, faceMeshIndex) + } + + async getAll(): Promise { + const localTable = await this.entityTable.getLocal() + + let faceMeshIndexBufferStartIndex: number[] | undefined + let faceMeshIndexBufferEndIndex: number[] | undefined + let viewIndex: number[] | undefined + let materialIndex: number[] | undefined + let elementIndex: number[] | undefined + + await Promise.all([ + (async () => { faceMeshIndexBufferStartIndex = (await localTable.getNumberArray("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart")) })(), + (async () => { faceMeshIndexBufferEndIndex = (await localTable.getNumberArray("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd")) })(), + (async () => { viewIndex = (await localTable.getNumberArray("index:Vim.View:View")) })(), + (async () => { materialIndex = (await localTable.getNumberArray("index:Vim.Material:Material")) })(), + (async () => { elementIndex = (await localTable.getNumberArray("index:Vim.Element:Element")) })(), + ]) + + let faceMesh: IFaceMesh[] = [] + + const rowCount = await this.getCount() + for (let i = 0; i < rowCount; i++) { + faceMesh.push({ + index: i, + faceMeshIndexBufferStartIndex: faceMeshIndexBufferStartIndex ? faceMeshIndexBufferStartIndex[i] : undefined, + faceMeshIndexBufferEndIndex: faceMeshIndexBufferEndIndex ? faceMeshIndexBufferEndIndex[i] : undefined, + viewIndex: viewIndex ? viewIndex[i] : undefined, + materialIndex: materialIndex ? materialIndex[i] : undefined, + elementIndex: elementIndex ? elementIndex[i] : undefined + }) + } + + return faceMesh + } + + async getFaceMeshIndexBufferStartIndex(faceMeshIndex: number): Promise { + return await this.entityTable.getNumber(faceMeshIndex, "index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart") + } + + async getAllFaceMeshIndexBufferStartIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferStart") + } + + async getFaceMeshIndexBufferStart(faceMeshIndex: number): Promise { + const index = await this.getFaceMeshIndexBufferStartIndex(faceMeshIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.faceMeshIndexBuffer?.get(index) + } + + async getFaceMeshIndexBufferEndIndex(faceMeshIndex: number): Promise { + return await this.entityTable.getNumber(faceMeshIndex, "index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd") + } + + async getAllFaceMeshIndexBufferEndIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.FaceMeshIndexBuffer:FaceMeshIndexBufferEnd") + } + + async getFaceMeshIndexBufferEnd(faceMeshIndex: number): Promise { + const index = await this.getFaceMeshIndexBufferEndIndex(faceMeshIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.faceMeshIndexBuffer?.get(index) + } + + async getViewIndex(faceMeshIndex: number): Promise { + return await this.entityTable.getNumber(faceMeshIndex, "index:Vim.View:View") + } + + async getAllViewIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.View:View") + } + + async getView(faceMeshIndex: number): Promise { + const index = await this.getViewIndex(faceMeshIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.view?.get(index) + } + + async getMaterialIndex(faceMeshIndex: number): Promise { + return await this.entityTable.getNumber(faceMeshIndex, "index:Vim.Material:Material") + } + + async getAllMaterialIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.Material:Material") + } + + async getMaterial(faceMeshIndex: number): Promise { + const index = await this.getMaterialIndex(faceMeshIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.material?.get(index) + } + + async getElementIndex(faceMeshIndex: number): Promise { + return await this.entityTable.getNumber(faceMeshIndex, "index:Vim.Element:Element") + } + + async getAllElementIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.Element:Element") + } + + async getElement(faceMeshIndex: number): Promise { + const index = await this.getElementIndex(faceMeshIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.element?.get(index) + } + +} + +export interface IFaceMeshIndexBuffer { + index: number + + vertexIndexIndex?: number + vertexIndex?: IFaceMeshVertexBuffer +} + +export interface IFaceMeshIndexBufferTable { + getCount(): Promise + get(faceMeshIndexBufferIndex: number): Promise + getAll(): Promise + + getVertexIndexIndex(faceMeshIndexBufferIndex: number): Promise + getAllVertexIndexIndex(): Promise + getVertexIndex(faceMeshIndexBufferIndex: number): Promise +} + +export class FaceMeshIndexBuffer implements IFaceMeshIndexBuffer { + index: number + + vertexIndexIndex?: number + vertexIndex?: IFaceMeshVertexBuffer + + static async createFromTable(table: IFaceMeshIndexBufferTable, index: number): Promise { + let result = new FaceMeshIndexBuffer() + result.index = index + + await Promise.all([ + table.getVertexIndexIndex(index).then(v => result.vertexIndexIndex = v), + ]) + + return result + } +} + +export class FaceMeshIndexBufferTable implements IFaceMeshIndexBufferTable { + private document: VimDocument + private entityTable: EntityTable + + static async createFromDocument(document: VimDocument): Promise { + const entity = await document.entities.getBfast("Vim.FaceMeshIndexBuffer") + + if (!entity) { + return undefined + } + + let table = new FaceMeshIndexBufferTable() + table.document = document + table.entityTable = new EntityTable(entity, document.strings) + + return table + } + + getCount(): Promise { + return this.entityTable.getCount() + } + + async get(faceMeshIndexBufferIndex: number): Promise { + return await FaceMeshIndexBuffer.createFromTable(this, faceMeshIndexBufferIndex) + } + + async getAll(): Promise { + const localTable = await this.entityTable.getLocal() + + let vertexIndexIndex: number[] | undefined + + await Promise.all([ + (async () => { vertexIndexIndex = (await localTable.getNumberArray("index:Vim.FaceMeshVertexBuffer:VertexIndex")) })(), + ]) + + let faceMeshIndexBuffer: IFaceMeshIndexBuffer[] = [] + + const rowCount = await this.getCount() + for (let i = 0; i < rowCount; i++) { + faceMeshIndexBuffer.push({ + index: i, + vertexIndexIndex: vertexIndexIndex ? vertexIndexIndex[i] : undefined + }) + } + + return faceMeshIndexBuffer + } + + async getVertexIndexIndex(faceMeshIndexBufferIndex: number): Promise { + return await this.entityTable.getNumber(faceMeshIndexBufferIndex, "index:Vim.FaceMeshVertexBuffer:VertexIndex") + } + + async getAllVertexIndexIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.FaceMeshVertexBuffer:VertexIndex") + } + + async getVertexIndex(faceMeshIndexBufferIndex: number): Promise { + const index = await this.getVertexIndexIndex(faceMeshIndexBufferIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.faceMeshVertexBuffer?.get(index) + } + +} + +export interface IFaceMeshVertexBuffer { + index: number + vertex?: Vector3 +} + +export interface IFaceMeshVertexBufferTable { + getCount(): Promise + get(faceMeshVertexBufferIndex: number): Promise + getAll(): Promise + + getVertex(faceMeshVertexBufferIndex: number): Promise + getAllVertex(): Promise +} + +export class FaceMeshVertexBuffer implements IFaceMeshVertexBuffer { + index: number + vertex?: Vector3 + + static async createFromTable(table: IFaceMeshVertexBufferTable, index: number): Promise { + let result = new FaceMeshVertexBuffer() + result.index = index + + await Promise.all([ + table.getVertex(index).then(v => result.vertex = v), + ]) + + return result + } +} + +export class FaceMeshVertexBufferTable implements IFaceMeshVertexBufferTable { + private entityTable: EntityTable + + static async createFromDocument(document: VimDocument): Promise { + const entity = await document.entities.getBfast("Vim.FaceMeshVertexBuffer") + + if (!entity) { + return undefined + } + + let table = new FaceMeshVertexBufferTable() + table.entityTable = new EntityTable(entity, document.strings) + + return table + } + + getCount(): Promise { + return this.entityTable.getCount() + } + + async get(faceMeshVertexBufferIndex: number): Promise { + return await FaceMeshVertexBuffer.createFromTable(this, faceMeshVertexBufferIndex) + } + + async getAll(): Promise { + const localTable = await this.entityTable.getLocal() + + let vertex: Vector3[] | undefined + + await Promise.all([ + (async () => { vertex = (await localTable.getVector3Array("vector3:Vertex")) })(), + ]) + + let faceMeshVertexBuffer: IFaceMeshVertexBuffer[] = [] + + const rowCount = await this.getCount() + for (let i = 0; i < rowCount; i++) { + faceMeshVertexBuffer.push({ + index: i, + vertex: vertex ? vertex[i] : undefined + }) + } + + return faceMeshVertexBuffer + } + + async getVertex(faceMeshVertexBufferIndex: number): Promise { + return (await this.entityTable.getVector3(faceMeshVertexBufferIndex, "vector3:Vertex")) + } + + async getAllVertex(): Promise { + return (await this.entityTable.getVector3Array("vector3:Vertex")) + } + +} + +export interface ILineShape { + index: number + color?: Vector4 + width?: number + + lineShapeVertexBufferStartIndex?: number + lineShapeVertexBufferStart?: ILineShapeVertexBuffer + lineShapeVertexBufferEndIndex?: number + lineShapeVertexBufferEnd?: ILineShapeVertexBuffer + viewIndex?: number + view?: IView + elementIndex?: number + element?: IElement +} + +export interface ILineShapeTable { + getCount(): Promise + get(lineShapeIndex: number): Promise + getAll(): Promise + + getColor(lineShapeIndex: number): Promise + getAllColor(): Promise + getWidth(lineShapeIndex: number): Promise + getAllWidth(): Promise + + getLineShapeVertexBufferStartIndex(lineShapeIndex: number): Promise + getAllLineShapeVertexBufferStartIndex(): Promise + getLineShapeVertexBufferStart(lineShapeIndex: number): Promise + getLineShapeVertexBufferEndIndex(lineShapeIndex: number): Promise + getAllLineShapeVertexBufferEndIndex(): Promise + getLineShapeVertexBufferEnd(lineShapeIndex: number): Promise + getViewIndex(lineShapeIndex: number): Promise + getAllViewIndex(): Promise + getView(lineShapeIndex: number): Promise + getElementIndex(lineShapeIndex: number): Promise + getAllElementIndex(): Promise + getElement(lineShapeIndex: number): Promise +} + +export class LineShape implements ILineShape { + index: number + color?: Vector4 + width?: number + + lineShapeVertexBufferStartIndex?: number + lineShapeVertexBufferStart?: ILineShapeVertexBuffer + lineShapeVertexBufferEndIndex?: number + lineShapeVertexBufferEnd?: ILineShapeVertexBuffer + viewIndex?: number + view?: IView + elementIndex?: number + element?: IElement + + static async createFromTable(table: ILineShapeTable, index: number): Promise { + let result = new LineShape() + result.index = index + + await Promise.all([ + table.getColor(index).then(v => result.color = v), + table.getWidth(index).then(v => result.width = v), + table.getLineShapeVertexBufferStartIndex(index).then(v => result.lineShapeVertexBufferStartIndex = v), + table.getLineShapeVertexBufferEndIndex(index).then(v => result.lineShapeVertexBufferEndIndex = v), + table.getViewIndex(index).then(v => result.viewIndex = v), + table.getElementIndex(index).then(v => result.elementIndex = v), + ]) + + return result + } +} + +export class LineShapeTable implements ILineShapeTable { + private document: VimDocument + private entityTable: EntityTable + + static async createFromDocument(document: VimDocument): Promise { + const entity = await document.entities.getBfast("Vim.LineShape") + + if (!entity) { + return undefined + } + + let table = new LineShapeTable() + table.document = document + table.entityTable = new EntityTable(entity, document.strings) + + return table + } + + getCount(): Promise { + return this.entityTable.getCount() + } + + async get(lineShapeIndex: number): Promise { + return await LineShape.createFromTable(this, lineShapeIndex) + } + + async getAll(): Promise { + const localTable = await this.entityTable.getLocal() + + let color: Vector4[] | undefined + let width: number[] | undefined + let lineShapeVertexBufferStartIndex: number[] | undefined + let lineShapeVertexBufferEndIndex: number[] | undefined + let viewIndex: number[] | undefined + let elementIndex: number[] | undefined + + await Promise.all([ + (async () => { color = (await localTable.getVector4Array("vector4:Color")) })(), + (async () => { width = (await localTable.getNumberArray("double:Width")) })(), + (async () => { lineShapeVertexBufferStartIndex = (await localTable.getNumberArray("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart")) })(), + (async () => { lineShapeVertexBufferEndIndex = (await localTable.getNumberArray("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd")) })(), + (async () => { viewIndex = (await localTable.getNumberArray("index:Vim.View:View")) })(), + (async () => { elementIndex = (await localTable.getNumberArray("index:Vim.Element:Element")) })(), + ]) + + let lineShape: ILineShape[] = [] + + const rowCount = await this.getCount() + for (let i = 0; i < rowCount; i++) { + lineShape.push({ + index: i, + color: color ? color[i] : undefined, + width: width ? width[i] : undefined, + lineShapeVertexBufferStartIndex: lineShapeVertexBufferStartIndex ? lineShapeVertexBufferStartIndex[i] : undefined, + lineShapeVertexBufferEndIndex: lineShapeVertexBufferEndIndex ? lineShapeVertexBufferEndIndex[i] : undefined, + viewIndex: viewIndex ? viewIndex[i] : undefined, + elementIndex: elementIndex ? elementIndex[i] : undefined + }) + } + + return lineShape + } + + async getColor(lineShapeIndex: number): Promise { + return (await this.entityTable.getVector4(lineShapeIndex, "vector4:Color")) + } + + async getAllColor(): Promise { + return (await this.entityTable.getVector4Array("vector4:Color")) + } + + async getWidth(lineShapeIndex: number): Promise { + return (await this.entityTable.getNumber(lineShapeIndex, "double:Width")) + } + + async getAllWidth(): Promise { + return (await this.entityTable.getNumberArray("double:Width")) + } + + async getLineShapeVertexBufferStartIndex(lineShapeIndex: number): Promise { + return await this.entityTable.getNumber(lineShapeIndex, "index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart") + } + + async getAllLineShapeVertexBufferStartIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferStart") + } + + async getLineShapeVertexBufferStart(lineShapeIndex: number): Promise { + const index = await this.getLineShapeVertexBufferStartIndex(lineShapeIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.lineShapeVertexBuffer?.get(index) + } + + async getLineShapeVertexBufferEndIndex(lineShapeIndex: number): Promise { + return await this.entityTable.getNumber(lineShapeIndex, "index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd") + } + + async getAllLineShapeVertexBufferEndIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.LineShapeVertexBuffer:LineShapeVertexBufferEnd") + } + + async getLineShapeVertexBufferEnd(lineShapeIndex: number): Promise { + const index = await this.getLineShapeVertexBufferEndIndex(lineShapeIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.lineShapeVertexBuffer?.get(index) + } + + async getViewIndex(lineShapeIndex: number): Promise { + return await this.entityTable.getNumber(lineShapeIndex, "index:Vim.View:View") + } + + async getAllViewIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.View:View") + } + + async getView(lineShapeIndex: number): Promise { + const index = await this.getViewIndex(lineShapeIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.view?.get(index) + } + + async getElementIndex(lineShapeIndex: number): Promise { + return await this.entityTable.getNumber(lineShapeIndex, "index:Vim.Element:Element") + } + + async getAllElementIndex(): Promise { + return await this.entityTable.getNumberArray("index:Vim.Element:Element") + } + + async getElement(lineShapeIndex: number): Promise { + const index = await this.getElementIndex(lineShapeIndex) + + if (index === undefined) { + return undefined + } + + return await this.document.element?.get(index) + } + +} + +export interface ILineShapeVertexBuffer { + index: number + vertex?: Vector3 +} + +export interface ILineShapeVertexBufferTable { + getCount(): Promise + get(lineShapeVertexBufferIndex: number): Promise + getAll(): Promise + + getVertex(lineShapeVertexBufferIndex: number): Promise + getAllVertex(): Promise +} + +export class LineShapeVertexBuffer implements ILineShapeVertexBuffer { + index: number + vertex?: Vector3 + + static async createFromTable(table: ILineShapeVertexBufferTable, index: number): Promise { + let result = new LineShapeVertexBuffer() + result.index = index + + await Promise.all([ + table.getVertex(index).then(v => result.vertex = v), + ]) + + return result + } +} + +export class LineShapeVertexBufferTable implements ILineShapeVertexBufferTable { + private entityTable: EntityTable + + static async createFromDocument(document: VimDocument): Promise { + const entity = await document.entities.getBfast("Vim.LineShapeVertexBuffer") + + if (!entity) { + return undefined + } + + let table = new LineShapeVertexBufferTable() + table.entityTable = new EntityTable(entity, document.strings) + + return table + } + + getCount(): Promise { + return this.entityTable.getCount() + } + + async get(lineShapeVertexBufferIndex: number): Promise { + return await LineShapeVertexBuffer.createFromTable(this, lineShapeVertexBufferIndex) + } + + async getAll(): Promise { + const localTable = await this.entityTable.getLocal() + + let vertex: Vector3[] | undefined + + await Promise.all([ + (async () => { vertex = (await localTable.getVector3Array("vector3:Vertex")) })(), + ]) + + let lineShapeVertexBuffer: ILineShapeVertexBuffer[] = [] + + const rowCount = await this.getCount() + for (let i = 0; i < rowCount; i++) { + lineShapeVertexBuffer.push({ + index: i, + vertex: vertex ? vertex[i] : undefined + }) + } + + return lineShapeVertexBuffer + } + + async getVertex(lineShapeVertexBufferIndex: number): Promise { + return (await this.entityTable.getVector3(lineShapeVertexBufferIndex, "vector3:Vertex")) + } + + async getAllVertex(): Promise { + return (await this.entityTable.getVector3Array("vector3:Vertex")) + } + +} + export class VimDocument { asset: IAssetTable | undefined displayUnit: IDisplayUnitTable | undefined @@ -10624,6 +11341,11 @@ export class VimDocument { viewInViewSheet: IViewInViewSheetTable | undefined site: ISiteTable | undefined building: IBuildingTable | undefined + faceMesh: IFaceMeshTable | undefined + faceMeshIndexBuffer: IFaceMeshIndexBufferTable | undefined + faceMeshVertexBuffer: IFaceMeshVertexBufferTable | undefined + lineShape: ILineShapeTable | undefined + lineShapeVertexBuffer: ILineShapeVertexBufferTable | undefined entities: BFast strings: string[] | undefined @@ -10695,6 +11417,11 @@ export class VimDocument { doc.viewInViewSheet = await ViewInViewSheetTable.createFromDocument(doc) doc.site = await SiteTable.createFromDocument(doc) doc.building = await BuildingTable.createFromDocument(doc) + doc.faceMesh = await FaceMeshTable.createFromDocument(doc) + doc.faceMeshIndexBuffer = await FaceMeshIndexBufferTable.createFromDocument(doc) + doc.faceMeshVertexBuffer = await FaceMeshVertexBufferTable.createFromDocument(doc) + doc.lineShape = await LineShapeTable.createFromDocument(doc) + doc.lineShapeVertexBuffer = await LineShapeVertexBufferTable.createFromDocument(doc) return doc }