Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CNX-782-optimise-mesh-output #8

Merged
merged 3 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AddOns/Speckle/Sources/AddOn/Connector/RootObjectBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ RootObject RootObjectBuilder::GetRootObject(const std::vector<std::string>& elem
{
for (const auto& mesh : body.meshes)
{
int materialIndex = mesh.second.materialIndex;
int materialIndex = mesh.materialIndex;
if (collectedProxies.find(materialIndex) == collectedProxies.end())
{
RenderMaterialProxy renderMaterialProxy;
renderMaterialProxy.value = CONNECTOR.GetHostToSpeckleConverter().GetModelMaterial(materialIndex);
collectedProxies[materialIndex] = renderMaterialProxy;
}

collectedProxies[materialIndex].objects.push_back(mesh.second.applicationId);
collectedProxies[materialIndex].objects.push_back(mesh.applicationId);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "CheckError.h"
#include "ConverterUtils.h"
#include "SpeckleConversionException.h"
#include "MeshFace.h"

#include <AttributeIndex.hpp>
#include <ConvexPolygon.hpp>
Expand Down Expand Up @@ -76,6 +77,61 @@ namespace
}
return partIDs;
}

void AddHardMeshesToElementBody(const std::map<int, std::vector<MeshFace>>& 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<int, std::vector<MeshFace>>& materialMeshFaceMap, ElementBody& elementBody)
{
for (const auto& item : materialMeshFaceMap)
{
Mesh mesh{};
int vertexIndexCount = 0;
std::map<int, int> 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)
Expand Down Expand Up @@ -108,6 +164,9 @@ ElementBody HostToSpeckleConverter::GetElementBody(const std::string& elemId)
{
ModelerAPI::MeshBody body{};
elem.GetTessellatedBody(bodyIndex, &body);
bool isHardBody = body.HasSharpEdge();

std::map<int, std::vector<MeshFace>> materialMeshFaceMap;

// Get polygons
Int32 polyCount = body.GetPolygonCount();
Expand All @@ -116,7 +175,6 @@ ElementBody HostToSpeckleConverter::GetElementBody(const std::string& elemId)
ModelerAPI::Polygon polygon{};
body.GetPolygon(polyIndex, &polygon);

std::vector<double> vertices;
ModelerAPI::AttributeIndex matIdx{};
polygon.GetMaterialIndex(matIdx);
int materialIndex = matIdx.GetIndex();
Expand All @@ -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);
}

}
}

Expand Down
18 changes: 1 addition & 17 deletions AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
#include "ElementBody.h"

void ElementBody::AddFace(std::vector<double> 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<Mesh> displayValue;
for (const auto& m : body.meshes)
displayValue.push_back(m.second);

j = displayValue;
j = body.meshes;
}
6 changes: 1 addition & 5 deletions AddOns/Speckle/Sources/AddOn/DataTypes/ElementBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, Mesh> meshes;

void AddFace(std::vector<double> vertices, int materialIndex);
std::vector<Mesh> meshes;
};

void to_json(nlohmann::json& j, const ElementBody& body);
9 changes: 9 additions & 0 deletions AddOns/Speckle/Sources/AddOn/DataTypes/FaceVertex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

struct FaceVertex
{
double x;
double y;
double z;
int archicadVertexIndex;
};
13 changes: 0 additions & 13 deletions AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
#include "Mesh.h"

void Mesh::AddFace(std::vector<double> verticesToAdd)
{
int faceSize = static_cast<int>(verticesToAdd.size() / 3);
int lastVertexCount = static_cast<int>(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;
Expand Down
5 changes: 1 addition & 4 deletions AddOns/Speckle/Sources/AddOn/DataTypes/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ struct Mesh
std::vector<double> vertices;
std::vector<int> faces;
std::vector<int> colors;
std::map<int, int> 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<double> verticesToAdd);
};

void to_json(nlohmann::json& j, const Mesh& mesh);
Expand Down
10 changes: 10 additions & 0 deletions AddOns/Speckle/Sources/AddOn/DataTypes/MeshFace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "FaceVertex.h"
#include <vector>

struct MeshFace
{
std::vector<FaceVertex> vertices;
int size;
};