From 1e81b0cf0f64797d4baa19f031141187e646ae28 Mon Sep 17 00:00:00 2001 From: reiter Date: Mon, 18 May 2026 11:31:11 +0200 Subject: [PATCH 1/2] refactor: move point data class to ViennaCore --- CMakeLists.txt | 1 + include/viennals/lsCalculateNormalVectors.hpp | 2 +- include/viennals/lsDomain.hpp | 3 +- include/viennals/lsMesh.hpp | 3 +- include/viennals/lsPointData.hpp | 454 ------------------ python/pyWrap.hpp | 1 - tests/FileWriter/FileWriter.cpp | 1 - tests/Serialize/Serialize.cpp | 1 - 8 files changed, 4 insertions(+), 462 deletions(-) delete mode 100644 include/viennals/lsPointData.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b957927c..31be8cc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,6 +112,7 @@ include(cmake/vtk.cmake) CPMAddPackage( NAME ViennaCore VERSION 2.1.2 + GIT_TAG point-data GIT_REPOSITORY "https://github.com/ViennaTools/ViennaCore" OPTIONS "VIENNACORE_FORMAT_EXCLUDE build/" EXCLUDE_FROM_ALL ${VIENNALS_BUILD_PYTHON}) diff --git a/include/viennals/lsCalculateNormalVectors.hpp b/include/viennals/lsCalculateNormalVectors.hpp index 6c229df0..fd8f8473 100644 --- a/include/viennals/lsCalculateNormalVectors.hpp +++ b/include/viennals/lsCalculateNormalVectors.hpp @@ -24,7 +24,7 @@ enum class NormalCalculationMethodEnum { /// This algorithm is used to compute the normal vectors for all points /// with level set values <= maxValue (default 0.5). The result is saved in -/// the lsPointData of the lsDomain and can be retrieved with +/// the PointData of the lsDomain and can be retrieved with /// lsDomain.getPointData().getVectorData("Normals"). /// /// The algorithm uses central differences to compute gradients and normalizes diff --git a/include/viennals/lsDomain.hpp b/include/viennals/lsDomain.hpp index 28633455..6592294e 100644 --- a/include/viennals/lsDomain.hpp +++ b/include/viennals/lsDomain.hpp @@ -8,9 +8,8 @@ #include #include -#include - #include +#include #include #include diff --git a/include/viennals/lsMesh.hpp b/include/viennals/lsMesh.hpp index 007bc70b..387d50dc 100644 --- a/include/viennals/lsMesh.hpp +++ b/include/viennals/lsMesh.hpp @@ -6,8 +6,7 @@ #include #include -#include - +#include #include #include diff --git a/include/viennals/lsPointData.hpp b/include/viennals/lsPointData.hpp deleted file mode 100644 index 4bcadfa1..00000000 --- a/include/viennals/lsPointData.hpp +++ /dev/null @@ -1,454 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -namespace viennals { - -using namespace viennacore; - -/// This class holds data associated with points in space. -template = lsConcepts::assignable> -class PointData { -public: - typedef std::vector ScalarDataType; - typedef std::vector> VectorDataType; - -private: - std::vector scalarData; - std::vector scalarDataLabels; - std::vector vectorData; - std::vector vectorDataLabels; - - template , - const typename VectorType::value_type *, - typename VectorType::value_type *>> - static ReturnType indexPointerOrNull(VectorType &v, int index) { - if (index >= 0 && index < v.size()) - return &(v[index]); - else - VIENNACORE_LOG_WARNING("PointData: Tried to access out of bounds index! " - "Returning nullptr instead."); - return nullptr; - } - - template - static void appendTranslateData(DataType ¤tData, const DataType &source, - const std::vector &indices) { - currentData.reserve(currentData.size() + indices.size()); - for (unsigned int index : indices) { - currentData.push_back(source[index]); - } - } - -public: - template static auto New(Args &&...args) { - return SmartPointer::New(std::forward(args)...); - } - - /// insert new scalar data array - void insertNextScalarData(const ScalarDataType &scalars, - const std::string &label = "Scalars") { - scalarData.push_back(scalars); - scalarDataLabels.push_back(label); - } - - /// insert new scalar data array - void insertNextScalarData(ScalarDataType &&scalars, - const std::string &label = "Scalars") { - scalarData.push_back(std::move(scalars)); - scalarDataLabels.push_back(label); - } - - /// insert new vector data array - void insertNextVectorData(const VectorDataType &vectors, - const std::string &label = "Vectors") { - vectorData.push_back(vectors); - vectorDataLabels.push_back(label); - } - - /// insert new vector data array - void insertNextVectorData(VectorDataType &&vectors, - const std::string &label = "Vectors") { - vectorData.push_back(std::move(vectors)); - vectorDataLabels.push_back(label); - } - - /// insert or replace scalar data array - void insertReplaceScalarData(const ScalarDataType &scalars, - const std::string &label = "Scalars") { - if (int i = getScalarDataIndex(label); i != -1) { - scalarData[i] = scalars; - } else { - insertNextScalarData(scalars, label); - } - } - - /// insert or replace scalar data array - void insertReplaceScalarData(ScalarDataType &&scalars, - const std::string &label = "Scalars") { - if (int i = getScalarDataIndex(label); i != -1) { - scalarData[i] = std::move(scalars); - } else { - insertNextScalarData(std::move(scalars), label); - } - } - - /// insert or replace vector data array - void insertReplaceVectorData(const VectorDataType &vectors, - const std::string &label = "Vectors") { - if (int i = getVectorDataIndex(label); i != -1) { - vectorData[i] = vectors; - } else { - insertNextVectorData(vectors, label); - } - } - - /// insert new vector data array - void insertReplaceVectorData(VectorDataType &&vectors, - std::string label = "Vectors") { - if (int i = getVectorDataIndex(label); i != -1) { - vectorData[i] = std::move(vectors); - } else { - insertNextVectorData(std::move(vectors), label); - } - } - - /// get the number of different scalar data arrays saved - unsigned getScalarDataSize() const { return scalarData.size(); } - - /// get the number of different vector data arrays saved - unsigned getVectorDataSize() const { return vectorData.size(); } - - ScalarDataType *getScalarData(int index) { - return indexPointerOrNull(scalarData, index); - } - - const ScalarDataType *getScalarData(int index) const { - return indexPointerOrNull(scalarData, index); - } - - ScalarDataType *getScalarData(const std::string &searchLabel, - bool noWarning = false) { - if (int i = getScalarDataIndex(searchLabel); i != -1) { - return &(scalarData[i]); - } - if (!noWarning) { - VIENNACORE_LOG_WARNING( - "PointData attempted to access scalar data labeled '" + searchLabel + - "', which does not exist. Returning nullptr instead."); - } - return nullptr; - } - - const ScalarDataType *getScalarData(const std::string &searchLabel, - bool noWarning = false) const { - if (int i = getScalarDataIndex(searchLabel); i != -1) { - return &(scalarData[i]); - } - if (!noWarning) { - VIENNACORE_LOG_WARNING( - "PointData attempted to access scalar data labeled '" + searchLabel + - "', which does not exist. Returning nullptr instead."); - } - return nullptr; - } - - int getScalarDataIndex(const std::string &searchLabel) const { - for (int i = 0; i < scalarDataLabels.size(); ++i) { - if (scalarDataLabels[i] == searchLabel) { - return i; - } - } - return -1; - } - - std::string getScalarDataLabel(int index) const { - return (index >= 0 && index < scalarDataLabels.size()) - ? scalarDataLabels[index] - : ""; - } - - void setScalarDataLabel(int index, std::string newLabel) { - scalarDataLabels[index] = std::move(newLabel); - } - - /// Delete the scalar data at index. - void eraseScalarData(int index) { - scalarData.erase(scalarData.begin() + index); - scalarDataLabels.erase(scalarDataLabels.begin() + index); - } - - VectorDataType *getVectorData(int index) { - return indexPointerOrNull(vectorData, index); - } - - const VectorDataType *getVectorData(int index) const { - return indexPointerOrNull(vectorData, index); - } - - VectorDataType *getVectorData(const std::string &searchLabel, - bool noWarning = false) { - if (int i = getVectorDataIndex(searchLabel); i != -1) { - return &(vectorData[i]); - } - if (!noWarning) { - VIENNACORE_LOG_WARNING( - "PointData attempted to access vector data labeled '" + searchLabel + - "', which does not exist. Returning nullptr instead."); - } - return nullptr; - } - - const VectorDataType *getVectorData(const std::string &searchLabel, - bool noWarning = false) const { - if (int i = getVectorDataIndex(searchLabel); i != -1) { - return &(vectorData[i]); - } - if (!noWarning) { - VIENNACORE_LOG_WARNING( - "PointData attempted to access vector data labeled '" + searchLabel + - "', which does not exist. Returning nullptr instead."); - } - return nullptr; - } - - int getVectorDataIndex(const std::string &searchLabel) const { - for (int i = 0; i < vectorDataLabels.size(); ++i) { - if (vectorDataLabels[i] == searchLabel) { - return i; - } - } - return -1; - } - - std::string getVectorDataLabel(int index) const { - return (index >= 0 && index < vectorDataLabels.size()) - ? vectorDataLabels[index] - : ""; - } - - void setVectorDataLabel(int index, std::string newLabel) { - vectorDataLabels[index] = std::move(newLabel); - } - - /// Delete the vector data at index. - void eraseVectorData(int index) { - vectorData.erase(vectorData.begin() + index); - vectorDataLabels.erase(vectorDataLabels.begin() + index); - } - - /// Append the passed PointData to this one. - void append(const PointData &passedData) { - scalarData.insert(scalarData.end(), passedData.scalarData.begin(), - passedData.scalarData.end()); - scalarDataLabels.insert(scalarDataLabels.end(), - passedData.scalarDataLabels.begin(), - passedData.scalarDataLabels.end()); - vectorData.insert(vectorData.end(), passedData.vectorData.begin(), - passedData.vectorData.end()); - vectorDataLabels.insert(vectorDataLabels.end(), - passedData.vectorDataLabels.begin(), - passedData.vectorDataLabels.end()); - } - - /// Add data in the passed source pointData into this data according to the - /// indices passed. The index of the indices vector corresponds to the index - /// of this data, while the values of indices correspond to the index in - /// source. - void translateFromData(const PointData &source, - const std::vector &indices) { - // scalars - for (unsigned j = 0; j < source.getScalarDataSize(); ++j) { - insertNextScalarData(ScalarDataType(), source.getScalarDataLabel(j)); - auto currentData = --scalarData.end(); - appendTranslateData(*currentData, source.scalarData[j], indices); - } - - // vectors - for (unsigned j = 0; j < source.getVectorDataSize(); ++j) { - insertNextVectorData(VectorDataType(), source.getVectorDataLabel(j)); - auto currentData = --vectorData.end(); - appendTranslateData(*currentData, source.vectorData[j], indices); - } - } - - /// Same as translateFromData, but the indices are given as a vector, as - /// is the case when collecting indices during parallel algorithms. - void translateFromMultiData( - const PointData &source, - const std::vector> &indicesVector) { - // scalars - for (unsigned j = 0; j < source.getScalarDataSize(); ++j) { - insertNextScalarData(ScalarDataType(), source.getScalarDataLabel(j)); - auto currentData = --scalarData.end(); - for (const auto &i : indicesVector) { - appendTranslateData(*currentData, source.scalarData[j], i); - } - } - - // vectors - for (unsigned j = 0; j < source.getVectorDataSize(); ++j) { - insertNextVectorData(VectorDataType(), source.getVectorDataLabel(j)); - auto currentData = --vectorData.end(); - for (const auto &i : indicesVector) { - appendTranslateData(*currentData, source.vectorData[j], i); - } - } - } - - /// Delete all data stored in this object. - void clear() { - scalarData.clear(); - scalarDataLabels.clear(); - vectorData.clear(); - vectorDataLabels.clear(); - } - - /// Return whether this object is empty. - bool empty() { return scalarData.empty() && vectorData.empty(); } - - /// Serialize PointData into a binary stream. - std::ostream &serialize(std::ostream &stream) { - // HEADER - // identifier: "PointData" - // 4 byte: number of scalar data sets - // 4 byte: number of vector data sets - stream << "lsPointData"; - uint32_t numberOfScalarData = scalarData.size(); - uint32_t numberOfVectorData = vectorData.size(); - stream.write(reinterpret_cast(&numberOfScalarData), - sizeof(uint32_t)); - stream.write(reinterpret_cast(&numberOfVectorData), - sizeof(uint32_t)); - - // Scalar Data - { - auto labelIt = scalarDataLabels.begin(); - // iterate over all scalar data sets - for (auto data : scalarData) { - // write name of scalar data and size of set - uint32_t sizeOfName = labelIt->length(); - stream.write(reinterpret_cast(&sizeOfName), sizeof(uint32_t)); - stream << *labelIt; - uint32_t numberOfValues = data.size(); - stream.write(reinterpret_cast(&numberOfValues), - sizeof(uint32_t)); - // iterate over scalars in data set - for (auto value : data) { - stream.write(reinterpret_cast(&value), - sizeof(typename ScalarDataType::value_type)); - } - ++labelIt; - } - } - - // Vector Data - { - auto labelIt = vectorDataLabels.begin(); - // iterate over all vector data sets - for (auto data : vectorData) { - // write name of vector data and size of set - uint32_t sizeOfName = labelIt->length(); - stream.write(reinterpret_cast(&sizeOfName), sizeof(uint32_t)); - stream << *labelIt; - uint32_t numberOfVectors = data.size(); - stream.write(reinterpret_cast(&numberOfVectors), - sizeof(uint32_t)); - // iterate over vectors in data set - for (auto vector : data) { - // over values in vector - for (auto value : vector) { - stream.write( - reinterpret_cast(&value), - sizeof(typename VectorDataType::value_type::value_type)); - } - } - ++labelIt; - } - } - - return stream; - } - - /// Deserialize PointData from a binary stream. - std::istream &deserialize(std::istream &stream) { - char identifier[11]; - stream.read(identifier, 11); - if (std::memcmp(identifier, "lsPointData", 11) != 0) { - Logger::getInstance() - .addError("Reading PointData from stream failed. Header could " - "not be found.") - .print(); - return stream; - } - - // read number of data sets - unsigned numberOfScalarData = 0; - unsigned numberOfVectorData = 0; - stream.read(reinterpret_cast(&numberOfScalarData), - sizeof(uint32_t)); - stream.read(reinterpret_cast(&numberOfVectorData), - sizeof(uint32_t)); - - // read scalar data - for (unsigned i = 0; i < numberOfScalarData; ++i) { - uint32_t sizeOfName; - stream.read(reinterpret_cast(&sizeOfName), sizeof(uint32_t)); - std::vector dataLabel(sizeOfName); - stream.read(dataLabel.data(), sizeOfName); - uint32_t numberOfValues; - stream.read(reinterpret_cast(&numberOfValues), sizeof(uint32_t)); - ScalarDataType scalarData; - scalarData.resize(numberOfValues); - // read all scalar values into the data - for (auto &value : scalarData) { - stream.read(reinterpret_cast(&value), - sizeof(typename ScalarDataType::value_type)); - } - // now add this scalar data to current PointData - insertNextScalarData(scalarData, - std::string(dataLabel.begin(), dataLabel.end())); - } - - // read vector data - for (unsigned i = 0; i < numberOfVectorData; ++i) { - uint32_t sizeOfName; - stream.read(reinterpret_cast(&sizeOfName), sizeof(uint32_t)); - std::vector dataLabel(sizeOfName); - stream.read(dataLabel.data(), sizeOfName); - uint32_t numberOfValues; - stream.read(reinterpret_cast(&numberOfValues), sizeof(uint32_t)); - VectorDataType vectorData; - vectorData.resize(numberOfValues); - // read all vector values into the vector data - for (auto &vector : vectorData) { - for (auto &value : vector) { - stream.read(reinterpret_cast(&value), - sizeof(typename VectorDataType::value_type::value_type)); - } - } - // now add this scalar data to current PointData - insertNextVectorData(vectorData, - std::string(dataLabel.begin(), dataLabel.end())); - } - - return stream; - } -}; - -// add all template specialisations for this class -PRECOMPILE_PRECISION(PointData); - -} // namespace viennals diff --git a/python/pyWrap.hpp b/python/pyWrap.hpp index 3053e999..5da4b68f 100644 --- a/python/pyWrap.hpp +++ b/python/pyWrap.hpp @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/FileWriter/FileWriter.cpp b/tests/FileWriter/FileWriter.cpp index bb03d452..ab555451 100644 --- a/tests/FileWriter/FileWriter.cpp +++ b/tests/FileWriter/FileWriter.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/Serialize/Serialize.cpp b/tests/Serialize/Serialize.cpp index 952a7441..483aedc0 100644 --- a/tests/Serialize/Serialize.cpp +++ b/tests/Serialize/Serialize.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include From 75c7321c552888f476b1f72a4403e3e8f75d49a4 Mon Sep 17 00:00:00 2001 From: reiter Date: Thu, 21 May 2026 10:23:58 +0200 Subject: [PATCH 2/2] feat: mesh helper functions for material ids and normals --- CMakeLists.txt | 3 +-- include/viennals/lsMesh.hpp | 15 ++++++++++++++- include/viennals/lsToDiskMesh.hpp | 4 ++-- include/viennals/lsToHullMesh.hpp | 4 ++-- include/viennals/lsToMultiSurfaceMesh.hpp | 6 ++++-- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31be8cc9..b8a52249 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,8 +111,7 @@ include(cmake/vtk.cmake) CPMAddPackage( NAME ViennaCore - VERSION 2.1.2 - GIT_TAG point-data + VERSION 2.2.1 GIT_REPOSITORY "https://github.com/ViennaTools/ViennaCore" OPTIONS "VIENNACORE_FORMAT_EXCLUDE build/" EXCLUDE_FROM_ALL ${VIENNALS_BUILD_PYTHON}) diff --git a/include/viennals/lsMesh.hpp b/include/viennals/lsMesh.hpp index 387d50dc..4f1b3868 100644 --- a/include/viennals/lsMesh.hpp +++ b/include/viennals/lsMesh.hpp @@ -31,6 +31,9 @@ template class Mesh { Vec3D minimumExtent{}; Vec3D maximumExtent{}; + constexpr static const char *materialIdsLabel = "MaterialIds"; + constexpr static const char *normalsLabel = "Normals"; + private: // iterator typedef using VectorIt = typename PointData::VectorDataType::iterator; @@ -98,6 +101,16 @@ template class Mesh { const PointData &getCellData() const { return cellData; } + // helper function to get normals + std::vector> *getNormals(const char *label = normalsLabel) { + return cellData.getVectorData(label); + } + + // helper function to get material ids + std::vector *getMaterialIds(const char *label = materialIdsLabel) { + return cellData.getScalarData(label); + } + unsigned insertNextNode(const Vec3D &node) { nodes.push_back(node); return nodes.size() - 1; @@ -325,4 +338,4 @@ template class Mesh { // add all template specialisations for this class PRECOMPILE_PRECISION(Mesh); -} // namespace viennals \ No newline at end of file +} // namespace viennals diff --git a/include/viennals/lsToDiskMesh.hpp b/include/viennals/lsToDiskMesh.hpp index baee36f7..9385ebde 100644 --- a/include/viennals/lsToDiskMesh.hpp +++ b/include/viennals/lsToDiskMesh.hpp @@ -235,8 +235,8 @@ template class ToDiskMesh { } mesh->cellData.insertNextScalarData(values, "LSValues"); - mesh->cellData.insertNextVectorData(normals, "Normals"); - mesh->cellData.insertNextScalarData(materialIds, "MaterialIds"); + mesh->cellData.insertNextVectorData(normals, Mesh::normalsLabel); + mesh->cellData.insertNextScalarData(materialIds, Mesh::materialIdsLabel); mesh->minimumExtent = minimumExtent; mesh->maximumExtent = maximumExtent; } diff --git a/include/viennals/lsToHullMesh.hpp b/include/viennals/lsToHullMesh.hpp index 8252a826..a2af22c5 100644 --- a/include/viennals/lsToHullMesh.hpp +++ b/include/viennals/lsToHullMesh.hpp @@ -149,7 +149,7 @@ template class ToHullMesh { if (boundaryNodes.size() < 2) return; - auto matIds = multiMesh->cellData.getScalarData("MaterialIds"); + auto matIds = multiMesh->getMaterialIds(); for (size_t i = 0; i < boundaryNodes.size() - 1; ++i) { double mid = (boundaryNodes[i].first + boundaryNodes[i + 1].first) * 0.5; @@ -387,7 +387,7 @@ template class ToHullMesh { std::swap(nodes[1], nodes[2]); multiMesh->insertNextTriangle({nodes[0], nodes[1], nodes[2]}); - auto matIds = multiMesh->cellData.getScalarData("MaterialIds"); + auto matIds = multiMesh->getMaterialIds(); if (matIds) matIds->push_back(matId); } diff --git a/include/viennals/lsToMultiSurfaceMesh.hpp b/include/viennals/lsToMultiSurfaceMesh.hpp index 4c377ca5..7ce37d59 100644 --- a/include/viennals/lsToMultiSurfaceMesh.hpp +++ b/include/viennals/lsToMultiSurfaceMesh.hpp @@ -975,8 +975,10 @@ class ToMultiSurfaceMesh : public ToSurfaceMesh { this->scaleMesh(levelSets.front()->getGrid().getGridDelta()); - mesh->cellData.insertNextScalarData(currentMaterials, "MaterialIds"); - mesh->cellData.insertNextVectorData(currentNormals, "Normals"); + mesh->cellData.insertNextScalarData(currentMaterials, + Mesh::materialIdsLabel); + mesh->cellData.insertNextVectorData(currentNormals, + Mesh::normalsLabel); mesh->triangles.shrink_to_fit(); mesh->nodes.shrink_to_fit(); }