From 791e9f072ffef984e4e23a4f25866b5a68ce6cf3 Mon Sep 17 00:00:00 2001 From: David Kekesi Date: Fri, 11 Oct 2024 17:10:05 +0200 Subject: [PATCH] finish proxies wip --- .../Record/Collection/ProjectCollection.cpp | 10 +-- SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp | 10 +-- SpeckleLib/Speckle/Primitive/Mesh/Mesh.h | 19 +++-- .../Speckle/Record/Attribute/Finish.cpp | 69 +++++++++++++++---- SpeckleLib/Speckle/Record/Element/Element.cpp | 6 +- 5 files changed, 85 insertions(+), 29 deletions(-) diff --git a/SpeckleConnector/Connector/Record/Collection/ProjectCollection.cpp b/SpeckleConnector/Connector/Record/Collection/ProjectCollection.cpp index 5ecbc69..f491fe3 100644 --- a/SpeckleConnector/Connector/Record/Collection/ProjectCollection.cpp +++ b/SpeckleConnector/Connector/Record/Collection/ProjectCollection.cpp @@ -128,10 +128,12 @@ bool ProjectCollection::addMaterialProxy(const speckle::database::BIMIndex& mate --------------------------------------------------------------------*/ bool ProjectCollection::addMaterialProxy(const ModelerAPI::Material& material, const speckle::database::BIMRecordID& objectID) { auto finishID = Guid::fromInt(material.GenerateHashValue()); - if (m_finishes->find(finishID) != m_finishes->end()) - return false; - auto finish = std::make_unique(material); - return m_finishes->insert({finishID, std::move(finish)}).second; + auto iter = m_finishes->find(finishID); + if (iter == m_finishes->end()) { + auto finish = std::make_unique(material); + iter = m_finishes->insert({ finishID, std::move(finish) }).first; + } + return addMaterialProxy(finishID, objectID); } //ProjectCollection::addMaterialProxy #endif diff --git a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp index 5251c28..b07ea0f 100644 --- a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp +++ b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.cpp @@ -10,6 +10,7 @@ using namespace active::serialise; using namespace speckle::primitive; +using namespace speckle::serialise; namespace { @@ -65,14 +66,13 @@ Cargo::Unique Mesh::getCargo(const Inventory::Item& item) const { using namespace active::serialise; switch (item.index) { case vertexID: - return std::make_unique>>(vertices); + return std::make_unique>>(m_vertices); case faceID: - return std::make_unique>>(faces); + return std::make_unique>>(m_faces); case colorID: - return std::make_unique>>(colors); + return std::make_unique>>(m_colors); case proxyID: - return nullptr; //Activate the following line when the mesh material is available to add to the collector - //return std::make_unique(getBIMID(), material); + return std::make_unique(getBIMID(), m_material); default: return nullptr; //Requested an unknown index } diff --git a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h index 93f2788..993f653 100644 --- a/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h +++ b/SpeckleLib/Speckle/Primitive/Mesh/Mesh.h @@ -4,6 +4,10 @@ #include "Speckle/Database/Content/BIMRecord.h" #include "Speckle/Utility/String.h" +#ifdef ARCHICAD +#include "ModelMaterial.hpp" +#endif + namespace speckle::primitive { /*! @@ -22,7 +26,7 @@ namespace speckle::primitive { Default constructor @param unit The mesh unit type */ - Mesh(active::measure::LengthType unit = active::measure::LengthType::metre) : base{unit} {} + Mesh(active::measure::LengthType unit = active::measure::LengthType::metre) : base{ utility::Guid{true}, utility::Guid{}, unit } {} /*! Constructor @param vertices The mesh vertices @@ -30,9 +34,9 @@ namespace speckle::primitive { @param colors The mesh face colours @param unit The mesh unit type */ - Mesh(std::vector&& vertices, std::vector&& faces, std::vector&& colors, + Mesh(std::vector&& vertices, std::vector&& faces, std::vector&& colors, const ModelerAPI::Material& material, active::measure::LengthType unit = active::measure::LengthType::metre) : - base{unit}, vertices {std::move(vertices)}, faces{std::move(faces)}, colors{std::move(colors)} {} + base{ unit }, m_vertices{ std::move(vertices) }, m_faces{ std::move(faces) }, m_colors{ std::move(colors) }, m_material{ material } {} // MARK: - Functions (const) @@ -58,9 +62,12 @@ namespace speckle::primitive { active::serialise::Cargo::Unique getCargo(const active::serialise::Inventory::Item& item) const override; private: - std::vector vertices; - std::vector faces; - std::vector colors; + std::vector m_vertices; + std::vector m_faces; + std::vector m_colors; +#ifdef ARCHICAD + ModelerAPI::Material m_material; +#endif }; } diff --git a/SpeckleLib/Speckle/Record/Attribute/Finish.cpp b/SpeckleLib/Speckle/Record/Attribute/Finish.cpp index 448b9d4..49976db 100644 --- a/SpeckleLib/Speckle/Record/Attribute/Finish.cpp +++ b/SpeckleLib/Speckle/Record/Attribute/Finish.cpp @@ -2,6 +2,7 @@ #include "Active/Serialise/Item/Wrapper/ValueWrap.h" #include "Active/Serialise/Management/Management.h" +#include "Active/Serialise/CargoHold.h" #include "Active/Utility/BufferOut.h" #include "Speckle/Serialise/Collection/FinishCollector.h" #include "Speckle/Utility/Guid.h" @@ -37,12 +38,20 @@ namespace { ///Serialisation fields enum FieldIndex { - surfaceColourID, + diffuseID, + opacityID, + emissiveID, + metalnessID, + roughnessID, }; ///Serialisation field IDs static std::array fieldID = { - Identity{"surfaceColour"}, + Identity{"diffuse"}, + Identity{"opacity"}, + Identity{"emissive"}, + Identity{"metalness"}, + Identity{"roughness"}, }; #ifdef ARCHICAD @@ -55,6 +64,28 @@ namespace { colour.f_blue = modelColour.blue; } //copyModelerColor #endif + + int32_t ARGBToInt(double alpha, double red, double green, double blue) { + // Convert double (0.0 - 1.0) to uint8_t (0 - 255) + uint8_t a = static_cast(std::round(alpha * 255.0)); + uint8_t r = static_cast(std::round(red * 255.0)); + uint8_t g = static_cast(std::round(green * 255.0)); + uint8_t b = static_cast(std::round(blue * 255.0)); + + // Pack ARGB into a single 32-bit integer + return (a << 24) | (r << 16) | (g << 8) | b; + } + + int32_t ARGBToInt(double alpha, const API_RGBColor& color) { + // Convert double (0.0 - 1.0) to uint8_t (0 - 255) + uint8_t a = static_cast(std::round(alpha * 255.0)); + uint8_t r = static_cast(std::round(color.f_red * 255.0)); + uint8_t g = static_cast(std::round(color.f_green * 255.0)); + uint8_t b = static_cast(std::round(color.f_blue * 255.0)); + + // Pack ARGB into a single 32-bit integer + return (a << 24) | (r << 16) | (g << 8) | b; + } } /*-------------------------------------------------------------------- @@ -96,13 +127,13 @@ Finish::Finish(const ModelerAPI::Material& material) { String{material.GetName()}.writeUTF8(active::utility::BufferOut{attr.header.name}); attr.header.guid = Guid{Guid::fromInt(material.GenerateHashValue())}; attr.material.mtype = static_cast(material.GetType()); - attr.material.ambientPc = material.GetAmbientReflection(); - attr.material.diffusePc = material.GetDiffuseReflection(); - attr.material.specularPc = material.GetSpecularReflection(); - attr.material.transpPc = material.GetTransparency(); - attr.material.shine = material.GetShining(); - attr.material.transpAtt = material.GetTransparencyAttenuation(); - attr.material.emissionAtt = material.GetEmissionAttenuation(); + attr.material.ambientPc = static_cast(material.GetAmbientReflection() * 100); + attr.material.diffusePc = static_cast(material.GetDiffuseReflection() * 100); + attr.material.specularPc = static_cast(material.GetSpecularReflection() * 100); + attr.material.transpPc = static_cast(material.GetTransparency() * 100); + attr.material.shine = static_cast(material.GetShining() * 10000); + attr.material.transpAtt = static_cast(material.GetTransparencyAttenuation() * 400); + attr.material.emissionAtt = static_cast(material.GetEmissionAttenuation() * 65535); copyModelerColor(material.GetSurfaceColor(), attr.material.surfaceRGB); copyModelerColor(material.GetSpecularColor(), attr.material.specularRGB); copyModelerColor(material.GetEmissionColor(), attr.material.emissionRGB); @@ -162,7 +193,11 @@ bool Finish::fillInventory(Inventory& inventory) const { using enum Entry::Type; inventory.merge(Inventory{ { - { fieldID[surfaceColourID], surfaceColourID, element }, //TODO: implement other fields + { fieldID[diffuseID], diffuseID, element }, + { fieldID[opacityID], opacityID, element }, + { fieldID[emissiveID], emissiveID, element }, + { fieldID[metalnessID], metalnessID, element }, + { fieldID[roughnessID], roughnessID, element }, }, }.withType(&typeid(Finish))); return base::fillInventory(inventory); @@ -182,8 +217,18 @@ Cargo::Unique Finish::getCargo(const Inventory::Item& item) const { confirmData(); using namespace active::serialise; switch (item.index) { - case surfaceColourID: - return nullptr; //TODO: lookup surface colour + case diffuseID: { + auto opacity = 1.0 - m_data->root.transpPc; + return std::make_unique>(ARGBToInt(opacity, m_data->root.surfaceRGB)); + } + case opacityID: + return std::make_unique>(1.0); + case emissiveID: + return std::make_unique>(ARGBToInt(0.0, 0.0, 0.0, 0.0)); + case metalnessID: + return std::make_unique>(1.0); + case roughnessID: + return std::make_unique>(1.0); default: return nullptr; //Requested an unknown index } diff --git a/SpeckleLib/Speckle/Record/Element/Element.cpp b/SpeckleLib/Speckle/Record/Element/Element.cpp index d9ebf92..ae55843 100644 --- a/SpeckleLib/Speckle/Record/Element/Element.cpp +++ b/SpeckleLib/Speckle/Record/Element/Element.cpp @@ -8,6 +8,7 @@ #include "Speckle/SpeckleResource.h" #include "Speckle/Utility/Guid.h" +#ifdef ARCHICAD #include "Sight.hpp" #include "Model.hpp" #include "ModelMaterial.hpp" @@ -15,6 +16,7 @@ #include "exp.h" #include "ModelMeshBody.hpp" #include "ConvexPolygon.hpp" +#endif using namespace active::serialise; using namespace speckle::environment; @@ -206,11 +208,11 @@ Element::Body* Element::getBody() const { double alpha = material.GetTransparency(); ModelerAPI::Color color = material.GetSurfaceColor(); - colors.push_back(ARGBToInt(alpha, color.red, color.green, color.blue)); + //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))); + elementBody->push_back(primitive::Mesh(std::move(vertices), std::move(faces), std::move(colors), material)); } } }