From e4e31314d60015469b9a2dee9d5e60dd13899e0f Mon Sep 17 00:00:00 2001 From: David Kekesi Date: Thu, 31 Oct 2024 13:09:35 +0100 Subject: [PATCH] WIP --- SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp | 74 ++++++++++++++++--- SpeckleLib/Speckle/Primitive/Mesh/Mesh.h | 24 +++++- .../Speckle/Record/Element/ModelElement.cpp | 44 +++++++++++ 3 files changed, 131 insertions(+), 11 deletions(-) diff --git a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp index 1e0e9e4..f646d28 100644 --- a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp +++ b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp @@ -19,6 +19,10 @@ namespace { vertexID, faceID, colorID, + pointID, + closedID, + lengthID, + areaID, }; ///Serialisation field IDs @@ -26,6 +30,10 @@ namespace { Identity{"vertices"}, Identity{"faces"}, Identity{"colors"}, + Identity{"value"}, + Identity{"closed"}, + Identity{"length"}, + Identity{"area"}, }; } @@ -53,6 +61,13 @@ void Mesh::appendFace(const std::vector& vertices) { return: True if the package has added items to the inventory --------------------------------------------------------------------*/ bool Mesh::fillInventory(Inventory& inventory) const { + if (isPolyline) + return fillInventoryPolyline(inventory); + else + return fillInventoryMesh(inventory); +} //Mesh::fillInventory + +bool Mesh::fillInventoryMesh(Inventory& inventory) const { using enum Entry::Type; inventory.merge(Inventory{ { @@ -60,9 +75,22 @@ bool Mesh::fillInventory(Inventory& inventory) const { { fieldID[faceID], faceID, element }, { fieldID[colorID], colorID, element }, }, - }.withType(&typeid(Mesh))); + }.withType(&typeid(Mesh))); return base::fillInventory(inventory); -} //Mesh::fillInventory +} + +bool Mesh::fillInventoryPolyline(Inventory& inventory) const { + using enum Entry::Type; + inventory.merge(Inventory{ + { + { fieldID[pointID], pointID, element }, + { fieldID[closedID], closedID, element }, + { fieldID[lengthID], lengthID, element }, + { fieldID[areaID], areaID, element }, + }, + }.withType(&typeid(Mesh))); + return base::fillInventory(inventory); +} /*-------------------------------------------------------------------- @@ -73,20 +101,46 @@ bool Mesh::fillInventory(Inventory& inventory) const { return: The requested cargo (nullptr on failure) --------------------------------------------------------------------*/ Cargo::Unique Mesh::getCargo(const Inventory::Item& item) const { + if (isPolyline) + return getCargoPolyline(item); + else + return getCargoMesh(item); + +} //Mesh::getCargo + +Cargo::Unique Mesh::getCargoMesh(const Inventory::Item& item) const { if (item.ownerType != &typeid(Mesh)) return base::getCargo(item); using namespace active::serialise; switch (item.index) { case vertexID: - return std::make_unique>>(m_vertices); - case faceID: - return std::make_unique>>(m_faces); - case colorID: - return std::make_unique>>(m_colors); - default: - return nullptr; //Requested an unknown index + return std::make_unique>>(m_vertices); + case faceID: + return std::make_unique>>(m_faces); + case colorID: + return std::make_unique>>(m_colors); + default: + return nullptr; //Requested an unknown index } -} //Mesh::getCargo +} + +Cargo::Unique Mesh::getCargoPolyline(const Inventory::Item& item) const { + if (item.ownerType != &typeid(Mesh)) + return base::getCargo(item); + using namespace active::serialise; + switch (item.index) { + case pointID: + return std::make_unique>>(m_points); + case closedID: + return std::make_unique>(isClosed); + case lengthID: + return std::make_unique>(length); + case areaID: + return std::make_unique>(area); + default: + return nullptr; //Requested an unknown index + } +} /*-------------------------------------------------------------------- diff --git a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h index 59497ef..768356a 100644 --- a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h +++ b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h @@ -43,6 +43,10 @@ namespace speckle::primitive { Mesh(std::vector&& vertices, std::vector&& faces, std::vector&& colors, const record::attribute::Finish& finish, active::measure::LengthType unit = active::measure::LengthType::metre) : base{utility::Guid{true}, utility::Guid{}, unit}, m_vertices{std::move(vertices)}, m_faces{std::move(faces)}, m_colors{std::move(colors)}, m_finish{finish} {} + + Mesh(std::vector&& points, const record::attribute::Finish& finish, + active::measure::LengthType unit = active::measure::LengthType::metre) : + base{ utility::Guid{true}, utility::Guid{}, unit }, m_points{ std::move(points) }, m_finish{ finish } {} // MARK: - Functions (const) @@ -50,7 +54,13 @@ namespace speckle::primitive { Get the speckle type identifier @return The speckle type (relevant objects should override as required) */ - speckle::utility::String getSpeckleType() const override { return "Objects.Geometry.Mesh"; } + speckle::utility::String getSpeckleType() const override + { + if (isPolyline) + return "Objects.Geometry.Polyline"; + else + return "Objects.Geometry.Mesh"; + } /*! Append a single face to the Mesh given by the vertices @@ -66,23 +76,35 @@ namespace speckle::primitive { @return True if the package has added items to the inventory */ bool fillInventory(active::serialise::Inventory& inventory) const override; + bool fillInventoryMesh(active::serialise::Inventory& inventory) const; + bool fillInventoryPolyline(active::serialise::Inventory& inventory) const; /*! Get the specified cargo @param item The inventory item to retrieve @return The requested cargo (nullptr on failure) */ active::serialise::Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override; + active::serialise::Cargo::Unique getCargoMesh(const active::serialise::Inventory::Item& item) const; + active::serialise::Cargo::Unique getCargoPolyline(const active::serialise::Inventory::Item& item) const; /*! Use a manager in (de)serialisation processes @param management The management to use */ void useManagement(active::serialise::Management* management) const override; + + void setToPolyline() { isPolyline = true; } private: std::vector m_vertices; + std::vector m_points; std::vector m_faces; std::vector m_colors; record::attribute::Finish m_finish; + + bool isPolyline = false; + bool isClosed = false; + double length = 2.0; + double area = 0.0; }; } diff --git a/SpeckleLib/Speckle/Record/Element/ModelElement.cpp b/SpeckleLib/Speckle/Record/Element/ModelElement.cpp index 8f42eb2..2616c41 100644 --- a/SpeckleLib/Speckle/Record/Element/ModelElement.cpp +++ b/SpeckleLib/Speckle/Record/Element/ModelElement.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #endif @@ -240,6 +241,8 @@ void ModelElement::resetCache() { --------------------------------------------------------------------*/ ModelElement::Body* ModelElement::getBody() const { #ifdef ARCHICAD + ModelerAPI::Material tmpmat{}; + if (m_data && m_data->m_cache) return m_data->m_cache.get(); void* dummy = nullptr; @@ -271,6 +274,36 @@ ModelElement::Body* ModelElement::getBody() const { ModelerAPI::MeshBody body{}; elem.GetTessellatedBody(bodyIndex, &body); Int32 polyCount = body.GetPolygonCount(); + + if (polyCount == 0) + { + std::vector vertexIndices; + std::vector points; + Int32 edgeCount = body.GetEdgeCount(); + ModelerAPI::Edge edge{}; + for (Int32 edgeIndex = 1; edgeIndex <= edgeCount; ++edgeIndex) + { + body.GetEdge(edgeIndex, &edge); + vertexIndices.push_back(edge.GetVertexIndex1()); + } + vertexIndices.push_back(edge.GetVertexIndex2()); + + for (int i : vertexIndices) { + ModelerAPI::Vertex vertex{}; + body.GetVertex(i, &vertex); + // Collect vertices (as doubles for now, but should be changed to Vertex type) + points.push_back(vertex.x); + points.push_back(vertex.y); + points.push_back(vertex.z); + } + + record::attribute::Finish f(tmpmat); + primitive::Mesh mesh(std::move(points), f); + mesh.setToPolyline(); + elementBody->push_back(mesh); + } + + for (Int32 polyIndex = 1; polyIndex <= polyCount; ++polyIndex) { ModelerAPI::Polygon polygon{}; body.GetPolygon(polyIndex, &polygon); @@ -281,6 +314,8 @@ ModelElement::Body* ModelElement::getBody() const { if (faceFinish == nullptr) { ModelerAPI::Material material{}; polygon.GetMaterial(&material); + /// + tmpmat = material; Finish finish{material}; faceFinish = ModelElement::cacheFinish(finishID, finish); } @@ -308,6 +343,15 @@ ModelElement::Body* ModelElement::getBody() const { } for (auto& [materialName, mesh] : materialMeshMap) elementBody->push_back(std::move(mesh)); + + //std::vector points = { 0, 0, 0, 1, 0, 0, 1, 1, 0 }; + //Guid finishID{ Guid::fromInt(5) }; + //auto faceFinish = ModelElement::getFinish(finishID); + //record::attribute::Finish f(tmpmat); + //primitive::Mesh mesh(std::move(points), f); + //mesh.setToPolyline(); + //elementBody->push_back(mesh); + m_data = std::make_unique(); m_data->m_cache.reset(elementBody); return m_data->m_cache.get();