From 8a9368065bb9a61f990a42e01e346ab6110ce65f Mon Sep 17 00:00:00 2001 From: kekesidavid Date: Thu, 16 Jan 2025 14:21:09 +0100 Subject: [PATCH] CNX-782-optimise-mesh-output (#8) * soft and hard Meshes * removed headers * removed unused code --- .../AddOn/Connector/RootObjectBuilder.cpp | 4 +- .../HostToSpeckle/GetElementBody.cpp | 96 +++++++++++++++++-- .../Sources/AddOn/DataTypes/ElementBody.cpp | 18 +--- .../Sources/AddOn/DataTypes/ElementBody.h | 6 +- .../Sources/AddOn/DataTypes/FaceVertex.h | 9 ++ .../Speckle/Sources/AddOn/DataTypes/Mesh.cpp | 13 --- AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.h | 5 +- .../Sources/AddOn/DataTypes/MeshFace.h | 10 ++ 8 files changed, 112 insertions(+), 49 deletions(-) create mode 100644 AddOns/Speckle/Sources/AddOn/DataTypes/FaceVertex.h create mode 100644 AddOns/Speckle/Sources/AddOn/DataTypes/MeshFace.h diff --git a/AddOns/Speckle/Sources/AddOn/Connector/RootObjectBuilder.cpp b/AddOns/Speckle/Sources/AddOn/Connector/RootObjectBuilder.cpp index 7b4f7a5..f22aed3 100644 --- a/AddOns/Speckle/Sources/AddOn/Connector/RootObjectBuilder.cpp +++ b/AddOns/Speckle/Sources/AddOn/Connector/RootObjectBuilder.cpp @@ -67,7 +67,7 @@ RootObject RootObjectBuilder::GetRootObject(const std::vector& elem { for (const auto& mesh : body.meshes) { - int materialIndex = mesh.second.materialIndex; + int materialIndex = mesh.materialIndex; if (collectedProxies.find(materialIndex) == collectedProxies.end()) { RenderMaterialProxy renderMaterialProxy; @@ -75,7 +75,7 @@ RootObject RootObjectBuilder::GetRootObject(const std::vector& elem collectedProxies[materialIndex] = renderMaterialProxy; } - collectedProxies[materialIndex].objects.push_back(mesh.second.applicationId); + collectedProxies[materialIndex].objects.push_back(mesh.applicationId); } } diff --git a/AddOns/Speckle/Sources/AddOn/Converter/HostToSpeckle/GetElementBody.cpp b/AddOns/Speckle/Sources/AddOn/Converter/HostToSpeckle/GetElementBody.cpp index bd087b5..ad9dcf0 100644 --- a/AddOns/Speckle/Sources/AddOn/Converter/HostToSpeckle/GetElementBody.cpp +++ b/AddOns/Speckle/Sources/AddOn/Converter/HostToSpeckle/GetElementBody.cpp @@ -5,6 +5,7 @@ #include "CheckError.h" #include "ConverterUtils.h" #include "SpeckleConversionException.h" +#include "MeshFace.h" #include #include @@ -76,6 +77,61 @@ namespace } return partIDs; } + + void AddHardMeshesToElementBody(const std::map>& materialMeshFaceMap, ElementBody& elementBody) + { + for (const auto& item : materialMeshFaceMap) + { + Mesh mesh{}; + int currVertex = 0; + mesh.materialIndex = item.first; + for (const auto& face : item.second) + { + mesh.faces.push_back(face.size); + for (const auto& v : face.vertices) + { + mesh.faces.push_back(currVertex); + currVertex++; + + mesh.vertices.push_back(v.x); + mesh.vertices.push_back(v.y); + mesh.vertices.push_back(v.z); + } + } + elementBody.meshes.push_back(mesh); + } + } + + void AddSoftMeshesToElementBody(const std::map>& materialMeshFaceMap, ElementBody& elementBody) + { + for (const auto& item : materialMeshFaceMap) + { + Mesh mesh{}; + int vertexIndexCount = 0; + std::map vertexIndexMap; + + mesh.materialIndex = item.first; + for (const auto& face : item.second) + { + mesh.faces.push_back(face.size); + for (const auto& v : face.vertices) + { + bool newIndex = (vertexIndexMap.count(v.archicadVertexIndex) == 0); + if (newIndex) + { + vertexIndexMap[v.archicadVertexIndex] = vertexIndexCount; + vertexIndexCount++; + mesh.vertices.push_back(v.x); + mesh.vertices.push_back(v.y); + mesh.vertices.push_back(v.z); + } + + mesh.faces.push_back(vertexIndexMap[v.archicadVertexIndex]); + } + } + elementBody.meshes.push_back(mesh); + } + } } ElementBody HostToSpeckleConverter::GetElementBody(const std::string& elemId) @@ -108,6 +164,9 @@ ElementBody HostToSpeckleConverter::GetElementBody(const std::string& elemId) { ModelerAPI::MeshBody body{}; elem.GetTessellatedBody(bodyIndex, &body); + bool isHardBody = body.HasSharpEdge(); + + std::map> materialMeshFaceMap; // Get polygons Int32 polyCount = body.GetPolygonCount(); @@ -116,7 +175,6 @@ ElementBody HostToSpeckleConverter::GetElementBody(const std::string& elemId) ModelerAPI::Polygon polygon{}; body.GetPolygon(polyIndex, &polygon); - std::vector vertices; ModelerAPI::AttributeIndex matIdx{}; polygon.GetMaterialIndex(matIdx); int materialIndex = matIdx.GetIndex(); @@ -129,21 +187,43 @@ ElementBody HostToSpeckleConverter::GetElementBody(const std::string& elemId) polygon.GetConvexPolygon(convPolyIndex, &convexPolygon); // Get vertices + MeshFace mFace{}; Int32 vertexCount = convexPolygon.GetVertexCount(); + mFace.size = vertexCount; for (Int32 vertexIndex = 1; vertexIndex <= vertexCount; ++vertexIndex) { ModelerAPI::Vertex vertex{}; - body.GetVertex(convexPolygon.GetVertexIndex(vertexIndex), &vertex); - - vertices.push_back(vertex.x); - vertices.push_back(vertex.y); - vertices.push_back(vertex.z); + FaceVertex fVert{}; + fVert.archicadVertexIndex = convexPolygon.GetVertexIndex(vertexIndex); + body.GetVertex(fVert.archicadVertexIndex, &vertex); + fVert.x = vertex.x; + fVert.y = vertex.y; + fVert.z = vertex.z; + mFace.vertices.push_back(fVert); } + materialMeshFaceMap[materialIndex].push_back(mFace); + } + } - elementBody.AddFace(vertices, materialIndex); - vertices.clear(); + // Add Meshes to elementBody + // This logic is potentially buggy + // We need to find a better way to decide if an edge is soft or hard + if (apiElem.header.type.typeID == API_ObjectID) + { + if (isHardBody) + { + AddHardMeshesToElementBody(materialMeshFaceMap, elementBody); + } + else + { + AddSoftMeshesToElementBody(materialMeshFaceMap, elementBody); } } + else + { + AddHardMeshesToElementBody(materialMeshFaceMap, elementBody); + } + } } diff --git a/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.cpp b/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.cpp index 0d96c4d..663bc39 100644 --- a/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.cpp +++ b/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.cpp @@ -1,22 +1,6 @@ #include "ElementBody.h" -void ElementBody::AddFace(std::vector vertices, int materialIndex) -{ - if (meshes.find(materialIndex) == meshes.end()) - { - Mesh mesh; - mesh.materialIndex = materialIndex; - meshes[materialIndex] = mesh; - } - - meshes[materialIndex].AddFace(vertices); -} - void to_json(nlohmann::json& j, const ElementBody& body) { - std::vector displayValue; - for (const auto& m : body.meshes) - displayValue.push_back(m.second); - - j = displayValue; + j = body.meshes; } diff --git a/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.h b/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.h index c13aa68..02717ff 100644 --- a/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.h +++ b/AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.h @@ -6,11 +6,7 @@ struct ElementBody { - // the int value refers to an Archicad materialIndex - // we store 1 Mesh for each Material in the Body - std::map meshes; - - void AddFace(std::vector vertices, int materialIndex); + std::vector meshes; }; void to_json(nlohmann::json& j, const ElementBody& body); diff --git a/AddOns/Speckle/Sources/AddOn/DataTypes/FaceVertex.h b/AddOns/Speckle/Sources/AddOn/DataTypes/FaceVertex.h new file mode 100644 index 0000000..b690763 --- /dev/null +++ b/AddOns/Speckle/Sources/AddOn/DataTypes/FaceVertex.h @@ -0,0 +1,9 @@ +#pragma once + +struct FaceVertex +{ + double x; + double y; + double z; + int archicadVertexIndex; +}; diff --git a/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.cpp b/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.cpp index 920115e..6d6941d 100644 --- a/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.cpp +++ b/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.cpp @@ -1,18 +1,5 @@ #include "Mesh.h" -void Mesh::AddFace(std::vector verticesToAdd) -{ - int faceSize = static_cast(verticesToAdd.size() / 3); - int lastVertexCount = static_cast(vertices.size() / 3); - faces.push_back(faceSize); - - for (const auto& v : verticesToAdd) - vertices.push_back(v); - - for (int i = 0; i < faceSize; i++) - faces.push_back(lastVertexCount + i); -} - void to_json(nlohmann::json& j, const Mesh& mesh) { j["speckle_type"] = mesh.speckle_type; diff --git a/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.h b/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.h index d57d621..b52915f 100644 --- a/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.h +++ b/AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.h @@ -11,11 +11,8 @@ struct Mesh std::vector vertices; std::vector faces; std::vector colors; + std::map archcicadVertexIndexMap; int materialIndex = 0; - - // if face size is 4 you have to provide 12 double values in the vertices array - // x, y, z values for each vertex - void AddFace(std::vector verticesToAdd); }; void to_json(nlohmann::json& j, const Mesh& mesh); diff --git a/AddOns/Speckle/Sources/AddOn/DataTypes/MeshFace.h b/AddOns/Speckle/Sources/AddOn/DataTypes/MeshFace.h new file mode 100644 index 0000000..7d07b5a --- /dev/null +++ b/AddOns/Speckle/Sources/AddOn/DataTypes/MeshFace.h @@ -0,0 +1,10 @@ +#pragma once + +#include "FaceVertex.h" +#include + +struct MeshFace +{ + std::vector vertices; + int size; +};