Skip to content

Commit

Permalink
CNX-782-optimise-mesh-output (#8)
Browse files Browse the repository at this point in the history
* soft and hard Meshes

* removed headers

* removed unused code
  • Loading branch information
kekesidavid authored Jan 16, 2025
1 parent f490ec8 commit 8a93680
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 49 deletions.
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 @@ -67,15 +67,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;
};

0 comments on commit 8a93680

Please sign in to comment.