Compare commits

...

2 Commits

Author SHA1 Message Date
David Kekesi e9d669c4dd do not merge - hack for exporting gridlines - each edge is a separate polyline 2024-10-31 18:15:08 +01:00
David Kekesi e4e31314d6 WIP 2024-10-31 13:09:35 +01:00
3 changed files with 147 additions and 11 deletions
+64 -10
View File
@@ -19,6 +19,10 @@ namespace {
vertexID, vertexID,
faceID, faceID,
colorID, colorID,
pointID,
closedID,
lengthID,
areaID,
}; };
///Serialisation field IDs ///Serialisation field IDs
@@ -26,6 +30,10 @@ namespace {
Identity{"vertices"}, Identity{"vertices"},
Identity{"faces"}, Identity{"faces"},
Identity{"colors"}, Identity{"colors"},
Identity{"value"},
Identity{"closed"},
Identity{"length"},
Identity{"area"},
}; };
} }
@@ -53,6 +61,13 @@ void Mesh::appendFace(const std::vector<double>& vertices) {
return: True if the package has added items to the inventory return: True if the package has added items to the inventory
--------------------------------------------------------------------*/ --------------------------------------------------------------------*/
bool Mesh::fillInventory(Inventory& inventory) const { 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; using enum Entry::Type;
inventory.merge(Inventory{ inventory.merge(Inventory{
{ {
@@ -60,9 +75,22 @@ bool Mesh::fillInventory(Inventory& inventory) const {
{ fieldID[faceID], faceID, element }, { fieldID[faceID], faceID, element },
{ fieldID[colorID], colorID, element }, { fieldID[colorID], colorID, element },
}, },
}.withType(&typeid(Mesh))); }.withType(&typeid(Mesh)));
return base::fillInventory(inventory); 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) return: The requested cargo (nullptr on failure)
--------------------------------------------------------------------*/ --------------------------------------------------------------------*/
Cargo::Unique Mesh::getCargo(const Inventory::Item& item) const { 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)) if (item.ownerType != &typeid(Mesh))
return base::getCargo(item); return base::getCargo(item);
using namespace active::serialise; using namespace active::serialise;
switch (item.index) { switch (item.index) {
case vertexID: case vertexID:
return std::make_unique<ContainerWrap<std::vector<double>>>(m_vertices); return std::make_unique<ContainerWrap<std::vector<double>>>(m_vertices);
case faceID: case faceID:
return std::make_unique<ContainerWrap<std::vector<int>>>(m_faces); return std::make_unique<ContainerWrap<std::vector<int>>>(m_faces);
case colorID: case colorID:
return std::make_unique<ContainerWrap<std::vector<int>>>(m_colors); return std::make_unique<ContainerWrap<std::vector<int>>>(m_colors);
default: default:
return nullptr; //Requested an unknown index 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<ContainerWrap<std::vector<double>>>(m_points);
case closedID:
return std::make_unique<ValueWrap<bool>>(isClosed);
case lengthID:
return std::make_unique<ValueWrap<double>>(length);
case areaID:
return std::make_unique<ValueWrap<double>>(area);
default:
return nullptr; //Requested an unknown index
}
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
+23 -1
View File
@@ -44,13 +44,23 @@ namespace speckle::primitive {
active::measure::LengthType unit = active::measure::LengthType::metre) : 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} {} 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<double>&& 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) // MARK: - Functions (const)
/*! /*!
Get the speckle type identifier Get the speckle type identifier
@return The speckle type (relevant objects should override as required) @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 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 @return True if the package has added items to the inventory
*/ */
bool fillInventory(active::serialise::Inventory& inventory) const override; 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 Get the specified cargo
@param item The inventory item to retrieve @param item The inventory item to retrieve
@return The requested cargo (nullptr on failure) @return The requested cargo (nullptr on failure)
*/ */
active::serialise::Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override; 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 Use a manager in (de)serialisation processes
@param management The management to use @param management The management to use
*/ */
void useManagement(active::serialise::Management* management) const override; void useManagement(active::serialise::Management* management) const override;
void setToPolyline() { isPolyline = true; }
private: private:
std::vector<double> m_vertices; std::vector<double> m_vertices;
std::vector<double> m_points;
std::vector<int> m_faces; std::vector<int> m_faces;
std::vector<int> m_colors; std::vector<int> m_colors;
record::attribute::Finish m_finish; record::attribute::Finish m_finish;
bool isPolyline = false;
bool isClosed = false;
double length = 2.0;
double area = 0.0;
}; };
} }
@@ -17,6 +17,7 @@
#include <ModelElement.hpp> #include <ModelElement.hpp>
#include <ModelMaterial.hpp> #include <ModelMaterial.hpp>
#include <ModelMeshBody.hpp> #include <ModelMeshBody.hpp>
#include <ModelEdge.hpp>
#include <Sight.hpp> #include <Sight.hpp>
#endif #endif
@@ -32,6 +33,8 @@ using namespace speckle::utility;
#include <array> #include <array>
#include <memory> #include <memory>
#include <stack>
namespace speckle::record::element { namespace speckle::record::element {
class ModelElement::Data { class ModelElement::Data {
@@ -240,6 +243,8 @@ void ModelElement::resetCache() {
--------------------------------------------------------------------*/ --------------------------------------------------------------------*/
ModelElement::Body* ModelElement::getBody() const { ModelElement::Body* ModelElement::getBody() const {
#ifdef ARCHICAD #ifdef ARCHICAD
ModelerAPI::Material tmpmat{};
if (m_data && m_data->m_cache) if (m_data && m_data->m_cache)
return m_data->m_cache.get(); return m_data->m_cache.get();
void* dummy = nullptr; void* dummy = nullptr;
@@ -271,6 +276,52 @@ ModelElement::Body* ModelElement::getBody() const {
ModelerAPI::MeshBody body{}; ModelerAPI::MeshBody body{};
elem.GetTessellatedBody(bodyIndex, &body); elem.GetTessellatedBody(bodyIndex, &body);
Int32 polyCount = body.GetPolygonCount(); Int32 polyCount = body.GetPolygonCount();
if (polyCount == 0)
{
std::vector<int> vertexIndices;
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());
}
vertexIndices.push_back(edge.GetVertexIndex2());
vertexIndices.push_back(edge.GetVertexIndex2());
for (int i = 0; i < vertexIndices.size(); i += 2) {
ModelerAPI::Vertex v1{};
ModelerAPI::Vertex v2{};
body.GetVertex(vertexIndices[i], &v1);
body.GetVertex(vertexIndices[i + 1], &v2);
std::vector<double> points{};
points.push_back(v1.x);
points.push_back(v1.y);
points.push_back(v1.z);
points.push_back(v2.x);
points.push_back(v2.y);
points.push_back(v2.z);
points.push_back(v2.x);
points.push_back(v2.y);
points.push_back(v2.z);
record::attribute::Finish f(tmpmat);
primitive::Mesh mesh(std::move(points), f);
mesh.setToPolyline();
elementBody->push_back(mesh);
points.clear();
}
}
for (Int32 polyIndex = 1; polyIndex <= polyCount; ++polyIndex) { for (Int32 polyIndex = 1; polyIndex <= polyCount; ++polyIndex) {
ModelerAPI::Polygon polygon{}; ModelerAPI::Polygon polygon{};
body.GetPolygon(polyIndex, &polygon); body.GetPolygon(polyIndex, &polygon);
@@ -281,6 +332,8 @@ ModelElement::Body* ModelElement::getBody() const {
if (faceFinish == nullptr) { if (faceFinish == nullptr) {
ModelerAPI::Material material{}; ModelerAPI::Material material{};
polygon.GetMaterial(&material); polygon.GetMaterial(&material);
///
tmpmat = material;
Finish finish{material}; Finish finish{material};
faceFinish = ModelElement::cacheFinish(finishID, finish); faceFinish = ModelElement::cacheFinish(finishID, finish);
} }
@@ -308,6 +361,13 @@ ModelElement::Body* ModelElement::getBody() const {
} }
for (auto& [materialName, mesh] : materialMeshMap) for (auto& [materialName, mesh] : materialMeshMap)
elementBody->push_back(std::move(mesh)); elementBody->push_back(std::move(mesh));
/*std::vector<double> points = {0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0};
record::attribute::Finish f(tmpmat);
primitive::Mesh mesh(std::move(points), f);
mesh.setToPolyline();
elementBody->push_back(mesh);*/
m_data = std::make_unique<Data>(); m_data = std::make_unique<Data>();
m_data->m_cache.reset(elementBody); m_data->m_cache.reset(elementBody);
return m_data->m_cache.get(); return m_data->m_cache.get();