diff --git a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp index 23b0f83..fa060e0 100644 --- a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp +++ b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp @@ -30,6 +30,21 @@ namespace { } +/*-------------------------------------------------------------------- + Append a single face to the Mesh given by the vertices + --------------------------------------------------------------------*/ +void Mesh::appendFace(const std::vector& vertices) { + if (vertices.empty()) + return; + + m_vertices.insert(m_vertices.end(), vertices.begin(), vertices.end()); + int lastVertexIndex = m_faces.empty() ? -1 : m_faces.back(); + int faceSize = vertices.size() / 3; + m_faces.push_back(faceSize); + for (int i = 0; i < faceSize; i++) + m_faces.push_back(++lastVertexIndex); +} + /*-------------------------------------------------------------------- Fill an inventory with the package items diff --git a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h index 7c4853a..c9a8e9a 100644 --- a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h +++ b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h @@ -29,10 +29,19 @@ namespace speckle::primitive { Mesh(active::measure::LengthType unit = active::measure::LengthType::metre) : base{utility::Guid{true}, utility::Guid{}, unit} {} /*! Constructor + @param unit The mesh unit type + @param material The mesh material + */ + Mesh(const ModelerAPI::Material& material, + active::measure::LengthType unit = active::measure::LengthType::metre) : + base{ utility::Guid{true}, utility::Guid{}, unit }, m_material{ material } {} + /*! + Constructor + @param unit The mesh unit type @param vertices The mesh vertices @param faces The mesh faces (the number of indices in the face followed by the vertex indices) @param colors The mesh face colours - @param unit The mesh unit type + @param material The mesh material */ Mesh(std::vector&& vertices, std::vector&& faces, std::vector&& colors, const ModelerAPI::Material& material, active::measure::LengthType unit = active::measure::LengthType::metre) : @@ -45,6 +54,12 @@ namespace speckle::primitive { @return The speckle type (relevant objects should override as required) */ speckle::utility::String getSpeckleType() const override { return "Objects.Geometry.Mesh"; } + + /*! + Append a single face to the Mesh given by the vertices + @param vertices The vertices to append + */ + void appendFace(const std::vector& vertices); // MARK: - Serialisation diff --git a/SpeckleLib/Speckle/Record/Element/Element.cpp b/SpeckleLib/Speckle/Record/Element/Element.cpp index 5aa28e4..805cc8d 100644 --- a/SpeckleLib/Speckle/Record/Element/Element.cpp +++ b/SpeckleLib/Speckle/Record/Element/Element.cpp @@ -141,7 +141,6 @@ Element::Body* Element::getBody() const { return m_data->m_cache.get(); } - void* dummy = nullptr; GSErrCode err = ACAPI_Sight_GetCurrentWindowSight(&dummy); if (err != NoError) @@ -161,6 +160,9 @@ Element::Body* Element::getBody() const { auto elementBody = new Element::Body(); + // Map to collect meshes per material name + std::map materialMeshMap; + Int32 nElements = acModel.GetElementCount(); for (Int32 iElement = 1; iElement <= nElements; iElement++) { @@ -178,51 +180,54 @@ Element::Body* Element::getBody() const { Int32 polyCount = body.GetPolygonCount(); for (Int32 polyIndex = 1; polyIndex <= polyCount; ++polyIndex) { - ModelerAPI::Polygon polygon{}; + ModelerAPI::Polygon polygon{}; body.GetPolygon(polyIndex, &polygon); ModelerAPI::Material material{}; polygon.GetMaterial(&material); + auto materialName = material.GetName(); + if (materialMeshMap.find(materialName) == materialMeshMap.end()) { + materialMeshMap[materialName] = primitive::Mesh(material); + } + Int32 convexPolyCount = polygon.GetConvexPolygonCount(); for (Int32 convPolyIndex = 1; convPolyIndex <= convexPolyCount; ++convPolyIndex) { std::vector vertices; - std::vector faces; - std::vector colors; - ModelerAPI::ConvexPolygon convexPolygon{}; polygon.GetConvexPolygon(convPolyIndex, &convexPolygon); Int32 vertexCount = convexPolygon.GetVertexCount(); - faces.push_back(vertexCount); for (Int32 vertexIndex = 1; vertexIndex <= vertexCount; ++vertexIndex) { ModelerAPI::Vertex vertex{}; body.GetVertex(convexPolygon.GetVertexIndex(vertexIndex), &vertex); - // TODO: change vertices array to hold Vertex instead of double values + // Collect vertices (as doubles for now, but should be changed to Vertex type) vertices.push_back(vertex.x); vertices.push_back(vertex.y); vertices.push_back(vertex.z); - - //double alpha = material.GetTransparency(); - //ModelerAPI::Color color = material.GetSurfaceColor(); - //colors.push_back(ARGBToInt(alpha, color.red, color.green, color.blue)); - - faces.push_back(vertexIndex - 1); } - elementBody->push_back(primitive::Mesh(std::move(vertices), std::move(faces), std::move(colors), material)); + + materialMeshMap[materialName].appendFace(std::move(vertices)); } } } } + + for (auto& [materialName, mesh] : materialMeshMap) + { + elementBody->push_back(std::move(mesh)); + } + m_data->m_cache.reset(elementBody); return m_data->m_cache.get(); #endif } + /*-------------------------------------------------------------------- Fill an inventory with the package items