Skip to content
Snippets Groups Projects
Commit 25ffd8b0 authored by Norihiro Watanabe's avatar Norihiro Watanabe
Browse files

rewrote BoundaryElementsAlongPolyline which works independently from node order of edges

parent eba8cce0
No related branches found
No related tags found
No related merge requests found
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
#include "GeoLib/Polyline.h" #include "GeoLib/Polyline.h"
#include "MeshLib/Mesh.h" #include "MeshLib/Mesh.h"
#include "MeshLib/Node.h"
#include "MeshLib/Elements/Element.h" #include "MeshLib/Elements/Element.h"
#include "MeshLib/Elements/Line.h"
#include "MeshLib/MeshSearcher.h" #include "MeshLib/MeshSearcher.h"
#include "MeshGeoToolsLib/MeshNodeSearcher.h" #include "MeshGeoToolsLib/MeshNodeSearcher.h"
...@@ -24,21 +26,13 @@ namespace MeshGeoToolsLib ...@@ -24,21 +26,13 @@ namespace MeshGeoToolsLib
BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Polyline const& ply) BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const& mesh, MeshNodeSearcher &mshNodeSearcher, GeoLib::Polyline const& ply)
: _mesh(mesh), _ply(ply) : _mesh(mesh), _ply(ply)
{ {
// search nodes located along the polyline // search nodes and elements located along the polyline
auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply); auto node_ids_on_poly = mshNodeSearcher.getMeshNodeIDsAlongPolyline(ply);
std::vector<std::size_t> work_node_ids(node_ids_on_poly); auto ele_ids_near_ply = MeshLib::getConnectedElementIDs(_mesh, node_ids_on_poly);
if (ply.isClosed())
work_node_ids.push_back(work_node_ids[0]);
// search edges // check all edges of the elements near the polyline
for (unsigned i=0; i<work_node_ids.size()-1; i++) { for (auto ele_id : ele_ids_near_ply) {
std::vector<std::size_t> edge_nodeIDs = {work_node_ids[i], work_node_ids[i+1]}; auto* e = _mesh.getElement(ele_id);
// find a shared element
auto* node1 = mesh.getNode(edge_nodeIDs[0]);
auto* node2 = mesh.getNode(edge_nodeIDs[1]);
auto it = std::find_first_of(node1->getElements().begin(), node1->getElements().end(), node2->getElements().begin(), node2->getElements().end());
assert (it!=node1->getElements().end());
auto* e = *it;
// skip internal elements // skip internal elements
bool isOuterElement = false; bool isOuterElement = false;
for (unsigned i=0; i<e->getNNeighbors(); i++) { for (unsigned i=0; i<e->getNNeighbors(); i++) {
...@@ -49,24 +43,47 @@ BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const ...@@ -49,24 +43,47 @@ BoundaryElementsAlongPolyline::BoundaryElementsAlongPolyline(MeshLib::Mesh const
} }
if (!isOuterElement) if (!isOuterElement)
continue; continue;
// find edges on polyline // find edges on the polyline
for (unsigned i=0; i<e->getNEdges(); i++) { for (unsigned i=0; i<e->getNEdges(); i++) {
auto* edge = e->getEdge(i); auto* edge = e->getEdge(i);
// check // check if an edge node is on the polyline (if yes, store a distance)
size_t cnt_match = 0; std::vector<std::size_t> vec_matched_node_distance_along_ply;
for (size_t j=0; j<edge->getNNodes(); j++) { for (size_t j=0; j<edge->getNNodes(); j++) {
if (std::find(edge_nodeIDs.begin(), edge_nodeIDs.end(), edge->getNodeIndex(j)) != edge_nodeIDs.end()) auto itr = std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), edge->getNodeIndex(j));
cnt_match++; if (itr != node_ids_on_poly.end())
vec_matched_node_distance_along_ply.push_back(std::distance(node_ids_on_poly.begin(), itr));
else else
break; break;
} }
// update the list // the edge is picked if its all nodes are on the polyline
if (cnt_match==edge->getNNodes()) { if (vec_matched_node_distance_along_ply.size()==edge->getNNodes()) {
_boundary_elements.push_back(const_cast<MeshLib::Element*>(edge)); MeshLib::Element* picked_ele = const_cast<MeshLib::Element*>(edge);
break; // The first node of the edge should be always closer to the beginning of the polyline than other nodes.
// Otherwise, create a new element with reversed local node index
if (vec_matched_node_distance_along_ply.front() > vec_matched_node_distance_along_ply.back()
|| (ply.isClosed() && vec_matched_node_distance_along_ply.back() == node_ids_on_poly.size()-1)) {
MeshLib::Node** new_nodes = new MeshLib::Node*[edge->getNNodes()];
std::reverse_copy(edge->getNodes(), edge->getNodes()+edge->getNNodes(), new_nodes);
picked_ele = new MeshLib::Line(new_nodes);
delete edge;
}
_boundary_elements.push_back(picked_ele);
} else {
delete edge;
} }
} }
} }
// sort picked edges according to a distance of their first node along the polyline
std::sort(_boundary_elements.begin(), _boundary_elements.end(),
[&](MeshLib::Element*e1, MeshLib::Element*e2)
{
std::size_t dist1 = std::distance(node_ids_on_poly.begin(),
std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), e1->getNodeIndex(0)));
std::size_t dist2 = std::distance(node_ids_on_poly.begin(),
std::find(node_ids_on_poly.begin(), node_ids_on_poly.end(), e2->getNodeIndex(0)));
return (dist1 < dist2);
});
} }
BoundaryElementsAlongPolyline::~BoundaryElementsAlongPolyline() BoundaryElementsAlongPolyline::~BoundaryElementsAlongPolyline()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment