OGS
MeshToolsLib::MeshRevision Class Reference

Detailed Description

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

Definition at line 24 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 979 of file MeshRevision.cpp.

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

References _mesh.

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 1068 of file MeshRevision.cpp.

1070{
1071 const std::vector<MeshLib::Node*>& nodes(_mesh.getNodes());
1072 const std::size_t nNodes(_mesh.getNumberOfNodes());
1073 std::vector<std::size_t> id_map(nNodes);
1074 const double half_eps(eps / 2.0);
1075 const double sqr_eps(eps * eps);
1076 std::iota(id_map.begin(), id_map.end(), 0);
1077
1078 GeoLib::Grid<MeshLib::Node> const grid(nodes.begin(), nodes.end(), 64);
1079
1080 for (std::size_t k = 0; k < nNodes; ++k)
1081 {
1082 MeshLib::Node const* const node(nodes[k]);
1083 if (node->getID() != k)
1084 {
1085 continue;
1086 }
1087 std::vector<std::vector<MeshLib::Node*> const*> const node_vectors(
1088 grid.getPntVecsOfGridCellsIntersectingCube(*node, half_eps));
1089
1090 const std::size_t nVectors(node_vectors.size());
1091 for (std::size_t i = 0; i < nVectors; ++i)
1092 {
1093 const std::vector<MeshLib::Node*>& cell_vector(*node_vectors[i]);
1094 const std::size_t nGridCellNodes(cell_vector.size());
1095 for (std::size_t j = 0; j < nGridCellNodes; ++j)
1096 {
1097 MeshLib::Node const* const test_node(cell_vector[j]);
1098 // are node indices already identical (i.e. nodes will be
1099 // collapsed)
1100 if (id_map[node->getID()] == id_map[test_node->getID()])
1101 {
1102 continue;
1103 }
1104
1105 // if test_node has already been collapsed to another node x,
1106 // ignore it (if the current node would need to be collapsed
1107 // with x it would already have happened when x was tested)
1108 if (test_node->getID() != id_map[test_node->getID()])
1109 {
1110 continue;
1111 }
1112
1113 // calc distance
1114 if (MathLib::sqrDist(*node, *test_node) < sqr_eps)
1115 {
1116 WARN("nodes {} and {} can be collapsed", *node, *test_node);
1117 id_map[test_node->getID()] = node->getID();
1118 }
1119 }
1120 }
1121 }
1122 return id_map;
1123}
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:19

References _mesh, MathLib::Point3dWithID::getID(), GeoLib::Grid< POINT >::getPntVecsOfGridCellsIntersectingCube(), MathLib::sqrDist(), and WARN().

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 1125 of file MeshRevision.cpp.

1127{
1128 const std::vector<MeshLib::Node*>& nodes(_mesh.getNodes());
1129 const std::size_t nNodes(nodes.size());
1130 std::vector<MeshLib::Node*> new_nodes;
1131 new_nodes.reserve(nNodes);
1132 for (std::size_t k = 0; k < nNodes; ++k)
1133 {
1134 // all nodes that have not been collapsed with other nodes are copied
1135 // into new array
1136 if (nodes[k]->getID() == id_map[k])
1137 {
1138 std::size_t const id(new_nodes.size());
1139 new_nodes.push_back(new MeshLib::Node(
1140 (*nodes[k])[0], (*nodes[k])[1], (*nodes[k])[2], id));
1141 nodes[k]->setID(id); // the node in the old array gets the index of
1142 // the same node in the new array
1143 }
1144 // the other nodes are not copied and get the index of the nodes they
1145 // will have been collapsed with
1146 else
1147 {
1148 nodes[k]->setID(nodes[id_map[k]]->getID());
1149 }
1150 }
1151 return new_nodes;
1152}

References _mesh.

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 981 of file MeshRevision.cpp.

982{
983 std::vector<std::size_t> const id_map = collapseNodeIndices(eps);
984 std::size_t const nNodes = id_map.size();
985 unsigned count(0);
986 for (std::size_t i = 0; i < nNodes; ++i)
987 {
988 if (i != id_map[i])
989 {
990 count++;
991 }
992 }
993 return count;
994}
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 996 of file MeshRevision.cpp.

999{
1000 if (this->_mesh.getNumberOfElements() == 0)
1001 {
1002 return nullptr;
1003 }
1004
1005 std::vector<MeshLib::Element*> const& elements(this->_mesh.getElements());
1006 auto const node_ids = collapseNodeIndices(eps);
1007 std::vector<MeshLib::Node*> new_nodes =
1008 this->constructNewNodesArray(node_ids);
1009 std::vector<MeshLib::Element*> new_elements;
1010 std::vector<std::size_t> element_ids;
1011
1012 for (std::size_t k(0); k < elements.size(); ++k)
1013 {
1014 MeshLib::Element const* const elem(elements[k]);
1015 unsigned const n_unique_nodes(getNumberOfUniqueNodes(elem));
1016 if (n_unique_nodes == elem->getNumberOfBaseNodes() &&
1017 elem->getDimension() >= min_elem_dim)
1018 {
1019 ElementErrorCode const e = elem->validate();
1021 {
1022 std::size_t const n_new_elements(
1023 subdivideElement(elem, new_nodes, new_elements));
1024 if (n_new_elements == 0)
1025 {
1026 ERR("Element {:d} has unknown element type.", k);
1027 _mesh.resetNodeIDs();
1028 BaseLib::cleanupVectorElements(new_nodes, new_elements);
1029 return nullptr;
1030 }
1031 element_ids.insert(element_ids.end(), n_new_elements, k);
1032 }
1033 else
1034 {
1035 new_elements.push_back(MeshLib::copyElement(elem, new_nodes));
1036 element_ids.push_back(k);
1037 }
1038 }
1039 else if (n_unique_nodes < elem->getNumberOfBaseNodes() &&
1040 n_unique_nodes > 1)
1041 {
1042 std::size_t const n_new_elements(reduceElement(
1043 elem, n_unique_nodes, new_nodes, new_elements, min_elem_dim));
1044 element_ids.insert(element_ids.end(), n_new_elements, k);
1045 }
1046 else
1047 {
1048 ERR("Something is wrong, more unique nodes than actual nodes");
1049 }
1050 }
1051
1052 auto const& props = _mesh.getProperties();
1053 MeshLib::Properties const new_properties =
1054 copyProperties(props, node_ids, element_ids);
1055
1056 _mesh.resetNodeIDs();
1057 if (!new_elements.empty())
1058 {
1059 return new MeshLib::Mesh(new_mesh_name, new_nodes, new_elements,
1060 true /* compute_element_neighbors */,
1061 new_properties);
1062 }
1063
1064 BaseLib::cleanupVectorElements(new_nodes, new_elements);
1065 return nullptr;
1066}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
std::vector< MeshLib::Node * > constructNewNodesArray(const std::vector< std::size_t > &id_map) const
void cleanupVectorElements(std::vector< T * > &items)
Definition Algorithm.h:274
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::Element::getNumberOfBaseNodes(), NonCoplanar, 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 64 of file MeshRevision.h.

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


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