diff --git a/MeshLib/MeshEditing/ElementValueModification.cpp b/MeshLib/MeshEditing/ElementValueModification.cpp index 6f54233b804637d45785cb459f9f1d7ebc9065dc..d1ec306f709327a2e4400899ea6ba7c40ce8bee1 100644 --- a/MeshLib/MeshEditing/ElementValueModification.cpp +++ b/MeshLib/MeshEditing/ElementValueModification.cpp @@ -21,88 +21,105 @@ #include "MeshLib/Mesh.h" #include "MeshLib/Elements/Element.h" - namespace MeshLib { -std::vector<unsigned> ElementValueModification::getMeshValues(const MeshLib::Mesh &mesh) +bool ElementValueModification::replace(MeshLib::Mesh &mesh, + std::string const& property_name, unsigned old_value, unsigned new_value, + bool replace_if_exists) { - const std::size_t nElements (mesh.getNElements()); - std::vector<unsigned> value_mapping; - for (unsigned i=0; i<nElements; ++i) - { - bool exists(false); - unsigned value (mesh.getElement(i)->getValue()); - const unsigned nValues (value_mapping.size()); - for (unsigned j=0; j<nValues; ++j) - { - if (value == value_mapping[j]) - { - exists = true; - break; - } - } - if (!exists) - value_mapping.push_back(value); - } + boost::optional<MeshLib::PropertyVector<int> &> optional_property_value_vec( + mesh.getProperties().getPropertyVector<int>(property_name) + ); - std::sort(value_mapping.begin(), value_mapping.end()); - return value_mapping; -} + if (!optional_property_value_vec) { + return false; + } -bool ElementValueModification::replace(MeshLib::Mesh &mesh, unsigned old_value, unsigned new_value, bool replace_if_exists) -{ - std::vector<unsigned> value_mapping (ElementValueModification::getMeshValues(mesh)); - - if (!replace_if_exists) - { - const unsigned nValues (value_mapping.size()); - for (unsigned j=0; j<nValues; ++j) - { - if (new_value == value_mapping[j]) - { - WARN ("ElementValueModification::replaceElementValue() - Replacement value is already taken, no changes have been made."); + MeshLib::PropertyVector<int> & property_value_vec( + optional_property_value_vec.get() + ); + const std::size_t n_property_values(property_value_vec.size()); + + if (!replace_if_exists) { + for (std::size_t i=0; i<n_property_values; ++i) { + if (property_value_vec[i] == new_value) { + WARN ("ElementValueModification::replaceElementValue() " + "- Replacement value \"%d\" is already taken, " + "no changes have been made.", new_value); return false; } } } - const std::size_t nElements (mesh.getNElements()); - std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements())); - for (unsigned i=0; i<nElements; ++i) - { - if (elements[i]->getValue() == old_value) - elements[i]->setValue(new_value); + + for (std::size_t i=0; i<n_property_values; ++i) { + if (property_value_vec[i] == old_value) + property_value_vec[i] = new_value; } + return true; } +bool ElementValueModification::replace(MeshLib::Mesh &mesh, + unsigned old_value, unsigned new_value, bool replace_if_exists) +{ + return replace(mesh, "MaterialIDs", old_value, new_value, replace_if_exists); +} + unsigned ElementValueModification::condense(MeshLib::Mesh &mesh) { - std::vector<unsigned> value_mapping (ElementValueModification::getMeshValues(mesh)); - std::vector<unsigned> reverse_mapping(value_mapping.back()+1, 0); + boost::optional<MeshLib::PropertyVector<int> &> + optional_property_value_vec( + mesh.getProperties().getPropertyVector<int>("MaterialIDs") + ); + + if (!optional_property_value_vec) { + return 0; + } + + MeshLib::PropertyVector<int> & property_value_vector( + optional_property_value_vec.get() + ); + std::vector<int> value_mapping( + getSortedPropertyValues(property_value_vector) + ); + + std::vector<int> reverse_mapping(value_mapping.back()+1, 0); const unsigned nValues (value_mapping.size()); for (unsigned i=0; i<nValues; ++i) reverse_mapping[value_mapping[i]] = i; - const std::size_t nElements (mesh.getNElements()); - std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements())); - for (unsigned i=0; i<nElements; ++i) - elements[i]->setValue(reverse_mapping[elements[i]->getValue()]); + std::size_t const n_property_values(property_value_vector.size()); + for (std::size_t i=0; i<n_property_values; ++i) + property_value_vector[i] = reverse_mapping[property_value_vector[i]]; return nValues; } unsigned ElementValueModification::setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, unsigned new_value) { - std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements())); - unsigned nValues = 0; - for (auto e : elements) { - if (e->getGeomType()!=ele_type) + boost::optional<MeshLib::PropertyVector<unsigned> &> + optional_property_value_vec( + mesh.getProperties().getPropertyVector<unsigned>("MaterialIDs") + ); + + if (!optional_property_value_vec) { + return 0; + } + + MeshLib::PropertyVector<unsigned> & property_value_vector( + optional_property_value_vec.get() + ); + + std::vector<MeshLib::Element*> const& elements(mesh.getElements()); + std::size_t cnt(0); + for (std::size_t k(0); k<elements.size(); k++) { + if (elements[k]->getGeomType()!=ele_type) continue; - e->setValue(new_value); - nValues++; + property_value_vector[k] = new_value; + cnt++; } - return nValues; + return cnt; } } // end namespace MeshLib diff --git a/MeshLib/MeshEditing/ElementValueModification.h b/MeshLib/MeshEditing/ElementValueModification.h index df72deaaf0514f470adb4aa0f1a8191cf25330c7..cb2a2128f2f8522c8baf2c867b51d04dd632e391 100644 --- a/MeshLib/MeshEditing/ElementValueModification.h +++ b/MeshLib/MeshEditing/ElementValueModification.h @@ -17,7 +17,11 @@ #include <vector> +#include <boost/optional.hpp> + #include "MeshLib/MeshEnums.h" +#include "MeshLib/Mesh.h" +#include "MeshLib/PropertyVector.h" namespace MeshLib { // forward declarations @@ -37,13 +41,40 @@ public: /// Returns true if successful or false if the value is already taken. static bool replace(MeshLib::Mesh &mesh, unsigned old_value, unsigned new_value, bool replace_if_exists = false); + static bool replace(MeshLib::Mesh &mesh, std::string const& property_name, + unsigned old_value, unsigned new_value, bool replace_if_exists = false); + /// Sets new value for all elements having the given element type /// Returns the number of elements having the given element type static unsigned setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, unsigned new_value); private: - /// Returns the values of elements within the mesh - static std::vector<unsigned> getMeshValues(const MeshLib::Mesh &mesh); + /// Returns sorted values of properties within the PropertyVector + /// These values are stored in a vector. + template <typename T> + static std::vector<T> getSortedPropertyValues( + MeshLib::PropertyVector<T> const& property_vector) + { + std::vector<T> value_mapping; + const std::size_t n_property_values(property_vector.size()); + for (std::size_t i=0; i<n_property_values; ++i) { + bool exists(false); + T const& value (property_vector[i]); + std::size_t const size(value_mapping.size()); + for (unsigned j=0; j<size; ++j) { + if (value == value_mapping[j]) { + exists = true; + break; + } + } + if (!exists) + value_mapping.push_back(value); + } + + std::sort(value_mapping.begin(), value_mapping.end()); + return value_mapping; + } + }; } // end namespace MeshLib