OGS
MeshToolsLib::MeshRevision Class Reference

Detailed Description

Collapses nodes with a distance smaller min_distance and reduces elements accordingly.

Definition at line 35 of file MeshRevision.h.

#include <MeshRevision.h>

Collaboration diagram for MeshToolsLib::MeshRevision:
[legend]

Public Member Functions

 MeshRevision (MeshLib::Mesh &mesh)
 
unsigned getNumberOfCollapsibleNodes (double eps=std::numeric_limits< double >::epsilon()) const
 Returns the number of potentially collapsible nodes.
 
std::vector< std::size_t > collapseNodeIndices (double eps) const
 
MeshLib::MeshsimplifyMesh (const std::string &new_mesh_name, double eps, unsigned min_elem_dim=1) const
 

Private Member Functions

std::vector< MeshLib::Node * > constructNewNodesArray (const std::vector< std::size_t > &id_map) const
 

Private Attributes

MeshLib::Mesh_mesh
 The original mesh used for constructing the class.
 

Constructor & Destructor Documentation

◆ MeshRevision()

MeshToolsLib::MeshRevision::MeshRevision ( MeshLib::Mesh & mesh)
explicit

Constructor

Parameters
meshThe mesh which is being revised. Note that node IDs in mesh are changed during computation but are reset after the algorithms implemented here are finished

Definition at line 1005 of file MeshRevision.cpp.

1005: _mesh(mesh) {}
MeshLib::Mesh & _mesh
The original mesh used for constructing the class.

Member Function Documentation

◆ collapseNodeIndices()

std::vector< std::size_t > MeshToolsLib::MeshRevision::collapseNodeIndices ( double eps) const

Designates nodes to be collapsed by setting their ID to the index of the node they will get merged with.

Definition at line 1094 of file MeshRevision.cpp.

1096{
1097 const std::vector<MeshLib::Node*>& nodes(_mesh.getNodes());
1098 const std::size_t nNodes(_mesh.getNumberOfNodes());
1099 std::vector<std::size_t> id_map(nNodes);
1100 const double half_eps(eps / 2.0);
1101 const double sqr_eps(eps * eps);
1102 std::iota(id_map.begin(), id_map.end(), 0);
1103
1104 GeoLib::Grid<MeshLib::Node> const grid(nodes.begin(), nodes.end(), 64);
1105
1106 for (std::size_t k = 0; k < nNodes; ++k)
1107 {
1108 MeshLib::Node const* const node(nodes[k]);
1109 if (node->getID() != k)
1110 {
1111 continue;
1112 }
1113 std::vector<std::vector<MeshLib::Node*> const*> const node_vectors(
1114 grid.getPntVecsOfGridCellsIntersectingCube(*node, half_eps));
1115
1116 const std::size_t nVectors(node_vectors.size());
1117 for (std::size_t i = 0; i < nVectors; ++i)
1118 {
1119 const std::vector<MeshLib::Node*>& cell_vector(*node_vectors[i]);
1120 const std::size_t nGridCellNodes(cell_vector.size());
1121 for (std::size_t j = 0; j < nGridCellNodes; ++j)
1122 {
1123 MeshLib::Node const* const test_node(cell_vector[j]);
1124 // are node indices already identical (i.e. nodes will be
1125 // collapsed)
1126 if (id_map[node->getID()] == id_map[test_node->getID()])
1127 {
1128 continue;
1129 }
1130
1131 // if test_node has already been collapsed to another node x,
1132 // ignore it (if the current node would need to be collapsed
1133 // with x it would already have happened when x was tested)
1134 if (test_node->getID() != id_map[test_node->getID()])
1135 {
1136 continue;
1137 }
1138
1139 // calc distance
1140 if (MathLib::sqrDist(*node, *test_node) < sqr_eps)
1141 {
1142 id_map[test_node->getID()] = node->getID();
1143 }
1144 }
1145 }
1146 }
1147 return id_map;
1148}
std::vector< Node * > const & getNodes() const
Get the nodes-vector for the mesh.
Definition Mesh.h:106
std::size_t getNumberOfNodes() const
Get the number of nodes.
Definition Mesh.h:100
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:26

References _mesh, MathLib::Point3dWithID::getID(), MeshLib::Mesh::getNodes(), MeshLib::Mesh::getNumberOfNodes(), GeoLib::Grid< POINT >::getPntVecsOfGridCellsIntersectingCube(), and MathLib::sqrDist().

Referenced by getNumberOfCollapsibleNodes(), MeshAnalysisDialog::on_startButton_pressed(), and simplifyMesh().

◆ constructNewNodesArray()

std::vector< MeshLib::Node * > MeshToolsLib::MeshRevision::constructNewNodesArray ( const std::vector< std::size_t > & id_map) const
private

Constructs a new node vector for the resulting mesh by removing all nodes whose ID indicates they need to be merged/removed.

Definition at line 1150 of file MeshRevision.cpp.

1152{
1153 const std::vector<MeshLib::Node*>& nodes(_mesh.getNodes());
1154 const std::size_t nNodes(nodes.size());
1155 std::vector<MeshLib::Node*> new_nodes;
1156 new_nodes.reserve(nNodes);
1157 for (std::size_t k = 0; k < nNodes; ++k)
1158 {
1159 // all nodes that have not been collapsed with other nodes are copied
1160 // into new array
1161 if (nodes[k]->getID() == id_map[k])
1162 {
1163 std::size_t const id(new_nodes.size());
1164 new_nodes.push_back(new MeshLib::Node(
1165 (*nodes[k])[0], (*nodes[k])[1], (*nodes[k])[2], id));
1166 nodes[k]->setID(id); // the node in the old array gets the index of
1167 // the same node in the new array
1168 }
1169 // the other nodes are not copied and get the index of the nodes they
1170 // will have been collapsed with
1171 else
1172 {
1173 nodes[k]->setID(nodes[id_map[k]]->getID());
1174 }
1175 }
1176 return new_nodes;
1177}

References _mesh, and MeshLib::Mesh::getNodes().

Referenced by simplifyMesh().

◆ getNumberOfCollapsibleNodes()

unsigned MeshToolsLib::MeshRevision::getNumberOfCollapsibleNodes ( double eps = std::numeric_limits<double>::epsilon()) const

Returns the number of potentially collapsible nodes.

Definition at line 1007 of file MeshRevision.cpp.

1008{
1009 std::vector<std::size_t> const id_map = collapseNodeIndices(eps);
1010 std::size_t const nNodes = id_map.size();
1011 unsigned count(0);
1012 for (std::size_t i = 0; i < nNodes; ++i)
1013 {
1014 if (i != id_map[i])
1015 {
1016 count++;
1017 }
1018 }
1019 return count;
1020}
std::vector< std::size_t > collapseNodeIndices(double eps) const

References collapseNodeIndices().

Referenced by MeshToolsLib::MeshValidation::existCollapsibleNodes().

◆ simplifyMesh()

MeshLib::Mesh * MeshToolsLib::MeshRevision::simplifyMesh ( const std::string & new_mesh_name,
double eps,
unsigned min_elem_dim = 1 ) const

Create a new mesh where all nodes with a distance < eps from each other are collapsed. Elements are adjusted accordingly and elements with nonplanar faces are subdivided into geometrically correct elements.

Parameters
new_mesh_nameNew name.
epsMinimum distance for nodes not to be collapsed
min_elem_dimMinimum dimension of elements to be inserted into new mesh (i.e. min_elem_dim=3 will prevent the new mesh to contain 2D elements)

Definition at line 1022 of file MeshRevision.cpp.

1025{
1026 if (this->_mesh.getNumberOfElements() == 0)
1027 {
1028 return nullptr;
1029 }
1030
1031 std::vector<MeshLib::Element*> const& elements(this->_mesh.getElements());
1032 auto const node_ids = collapseNodeIndices(eps);
1033 std::vector<MeshLib::Node*> new_nodes =
1034 this->constructNewNodesArray(node_ids);
1035 std::vector<MeshLib::Element*> new_elements;
1036 std::vector<std::size_t> element_ids;
1037
1038 for (std::size_t k(0); k < elements.size(); ++k)
1039 {
1040 MeshLib::Element const* const elem(elements[k]);
1041 unsigned const n_unique_nodes(getNumberOfUniqueNodes(elem));
1042 if (n_unique_nodes == elem->getNumberOfBaseNodes() &&
1043 elem->getDimension() >= min_elem_dim)
1044 {
1045 ElementErrorCode const e = elem->validate();
1047 {
1048 std::size_t const n_new_elements(
1049 subdivideElement(elem, new_nodes, new_elements));
1050 if (n_new_elements == 0)
1051 {
1052 ERR("Element {:d} has unknown element type.", k);
1054 BaseLib::cleanupVectorElements(new_nodes, new_elements);
1055 return nullptr;
1056 }
1057 element_ids.insert(element_ids.end(), n_new_elements, k);
1058 }
1059 else
1060 {
1061 new_elements.push_back(MeshLib::copyElement(elem, new_nodes));
1062 element_ids.push_back(k);
1063 }
1064 }
1065 else if (n_unique_nodes < elem->getNumberOfBaseNodes() &&
1066 n_unique_nodes > 1)
1067 {
1068 std::size_t const n_new_elements(reduceElement(
1069 elem, n_unique_nodes, new_nodes, new_elements, min_elem_dim));
1070 element_ids.insert(element_ids.end(), n_new_elements, k);
1071 }
1072 else
1073 {
1074 ERR("Something is wrong, more unique nodes than actual nodes");
1075 }
1076 }
1077
1078 auto const& props = _mesh.getProperties();
1079 MeshLib::Properties const new_properties =
1080 copyProperties(props, node_ids, element_ids);
1081
1083 if (!new_elements.empty())
1084 {
1085 return new MeshLib::Mesh(new_mesh_name, new_nodes, new_elements,
1086 true /* compute_element_neighbors */,
1087 new_properties);
1088 }
1089
1090 BaseLib::cleanupVectorElements(new_nodes, new_elements);
1091 return nullptr;
1092}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
Collects error flags for mesh elements.
std::vector< Element * > const & getElements() const
Get the element-vector for the mesh.
Definition Mesh.h:109
void resetNodeIDs()
Resets the IDs of all mesh-nodes to their position in the node vector.
Definition Mesh.cpp:159
Properties & getProperties()
Definition Mesh.h:134
std::size_t getNumberOfElements() const
Get the number of elements.
Definition Mesh.h:97
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition Properties.h:36
std::vector< MeshLib::Node * > constructNewNodesArray(const std::vector< std::size_t > &id_map) const
void cleanupVectorElements(std::vector< T * > &items)
Definition Algorithm.h:256
Element * copyElement(Element const *const element, const std::vector< Node * > &nodes, std::vector< std::size_t > const *const id_map)
std::size_t reduceElement(MeshLib::Element const *const element, unsigned const n_unique_nodes, std::vector< MeshLib::Node * > const &nodes, std::vector< MeshLib::Element * > &elements, unsigned const min_elem_dim)
unsigned getNumberOfUniqueNodes(MeshLib::Element const *const element)
std::size_t subdivideElement(MeshLib::Element const *const element, std::vector< MeshLib::Node * > const &nodes, std::vector< MeshLib::Element * > &elements)
MeshLib::Properties copyProperties(MeshLib::Properties const &props, std::vector< std::size_t > const &node_ids, std::vector< std::size_t > const &elem_ids)

References _mesh, BaseLib::cleanupVectorElements(), collapseNodeIndices(), constructNewNodesArray(), MeshLib::copyElement(), ERR(), MeshLib::Element::getDimension(), MeshLib::Mesh::getElements(), MeshLib::Element::getNumberOfBaseNodes(), MeshLib::Mesh::getNumberOfElements(), MeshLib::Mesh::getProperties(), NonCoplanar, MeshLib::Mesh::resetNodeIDs(), and MeshLib::Element::validate().

Referenced by MeshToolsLib::convertSurfaceToMesh(), and main().

Member Data Documentation

◆ _mesh

MeshLib::Mesh& MeshToolsLib::MeshRevision::_mesh
private

The original mesh used for constructing the class.

Definition at line 75 of file MeshRevision.h.

Referenced by collapseNodeIndices(), constructNewNodesArray(), and simplifyMesh().


The documentation for this class was generated from the following files: