From 5d0a4e1ad9a9cc619f3006b0c94e99a36c7c6b45 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Thu, 23 Nov 2017 06:12:17 +0100 Subject: [PATCH] FEM: mesh api, add EdgesOnly and FacesOnly --- src/Mod/Fem/App/FemMesh.cpp | 96 ++++++++++++++++++++++++++++++++ src/Mod/Fem/App/FemMesh.h | 6 +- src/Mod/Fem/App/FemMeshPy.xml | 12 ++++ src/Mod/Fem/App/FemMeshPyImp.cpp | 25 +++++++++ 4 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index d51897fa39..88bb626fd0 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -860,6 +860,102 @@ std::list FemMesh::getElementNodes(int id) const return result; } +std::set FemMesh::getEdgesOnly(void) const +{ + std::set resultIDs; + + // edges + SMDS_EdgeIteratorPtr aEdgeIter = myMesh->GetMeshDS()->edgesIterator(); + while (aEdgeIter->more()) { + const SMDS_MeshEdge* aEdge = aEdgeIter->next(); + std::list enodes = getElementNodes(aEdge->GetID()); + std::set aEdgeNodes(enodes.begin(), enodes.end()); // convert list to set + bool edgeBelongsToAFace = false; + + // faces + SMDS_FaceIteratorPtr aFaceIter = myMesh->GetMeshDS()->facesIterator(); + while (aFaceIter->more()) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + std::list fnodes = getElementNodes(aFace->GetID()); + std::set aFaceNodes(fnodes.begin(), fnodes.end()); // convert list to set + + // if aEdgeNodes is not a subset of any aFaceNodes --> aEdge does not belong to any Face + std::vector inodes; + std::set_intersection(aFaceNodes.begin(), aFaceNodes.end(), + aEdgeNodes.begin(), aEdgeNodes.end(), + std::back_inserter(inodes)); + std::set intersection_nodes(inodes.begin(), inodes.end()); // convert vector to set + if (aEdgeNodes == intersection_nodes) { + edgeBelongsToAFace = true; + break; + } + } + if (edgeBelongsToAFace == false) + resultIDs.insert(aEdge->GetID()); + } + + return resultIDs; +} + +std::set FemMesh::getFacesOnly(void) const +{ + // How it works ATM: + // for each face + // get the face nodes + // for each volume + // get the volume nodes + // if the face nodes are a subset of the volume nodes + // add the face to the volume faces and break + // if face not belongs to a volume + // add it to faces only + // + // This means it is iterated over a lot of volumes many times, this is quite expensive ! + // + // TODO make this faster + // Idea: + // for each volume + // get the faces and add them to the volume faces + // for each face + // if not in volume faces + // add it to the faces only + // + // but the volume faces does not seam know their global mesh ID, I could not found any method in SMESH + + std::set resultIDs; + + // faces + SMDS_FaceIteratorPtr aFaceIter = myMesh->GetMeshDS()->facesIterator(); + while (aFaceIter->more()) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + std::list fnodes = getElementNodes(aFace->GetID()); + std::set aFaceNodes(fnodes.begin(), fnodes.end()); // convert list to set + bool faceBelongsToAVolume = false; + + // volumes + SMDS_VolumeIteratorPtr aVolIter = myMesh->GetMeshDS()->volumesIterator(); + while (aVolIter->more()) { + const SMDS_MeshVolume* aVol = aVolIter->next(); + std::list vnodes = getElementNodes(aVol->GetID()); + std::set aVolNodes(vnodes.begin(), vnodes.end()); // convert list to set + + // if aFaceNodes is not a subset of any aVolNodes --> aFace does not belong to any Volume + std::vector inodes; + std::set_intersection(aVolNodes.begin(), aVolNodes.end(), + aFaceNodes.begin(), aFaceNodes.end(), + std::back_inserter(inodes)); + std::set intersection_nodes(inodes.begin(), inodes.end()); // convert vector to set + if (aFaceNodes == intersection_nodes) { + faceBelongsToAVolume = true; + break; + } + } + if (faceBelongsToAVolume == false) + resultIDs.insert(aFace->GetID()); + } + + return resultIDs; +} + void FemMesh::readNastran(const std::string &Filename) { Base::TimeInfo Start; diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index 13c1aa95f2..29de41fee2 100644 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -104,7 +104,11 @@ public: std::list > getVolumesByFace(const TopoDS_Face &face) const; /// retrieving volume IDs and CalculiX face number by face std::map getccxVolumesByFace(const TopoDS_Face &face) const; - //@} + /// retrieving IDs of edges not belonging to any face (and thus not belonging to any volume too) + std::set getEdgesOnly(void) const; + /// retrieving IDs of faces not belonging to any volume + std::set getFacesOnly(void) const; + //@} /** @name Placement control */ //@{ diff --git a/src/Mod/Fem/App/FemMeshPy.xml b/src/Mod/Fem/App/FemMeshPy.xml index c5975f3dab..9f71374cb4 100755 --- a/src/Mod/Fem/App/FemMeshPy.xml +++ b/src/Mod/Fem/App/FemMeshPy.xml @@ -162,6 +162,12 @@ + + + Tuple of edge IDs which does not belong to any face (and thus not belong to any volume too) + + + Number of edges in the Mesh. @@ -174,6 +180,12 @@ + + + Tuple of face IDs which does not belong to any volume + + + Number of Faces in the Mesh. diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index 4038215154..12d64f06f3 100644 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -22,6 +22,7 @@ #include "PreCompiled.h" +#include #include #include @@ -1029,6 +1030,18 @@ Py::Tuple FemMeshPy::getEdges(void) const return tuple; } +Py::Tuple FemMeshPy::getEdgesOnly(void) const +{ + std::set resultSet = getFemMeshPtr()->getEdgesOnly(); + Py::Tuple tuple(resultSet.size()); + int index = 0; + for (std::set::iterator it = resultSet.begin(); it != resultSet.end(); ++it) { + tuple.setItem(index++, Py::Long(*it)); + } + + return tuple; +} + Py::Long FemMeshPy::getEdgeCount(void) const { return Py::Long(getFemMeshPtr()->getSMesh()->NbEdges()); @@ -1052,6 +1065,18 @@ Py::Tuple FemMeshPy::getFaces(void) const return tuple; } +Py::Tuple FemMeshPy::getFacesOnly(void) const +{ + std::set resultSet = getFemMeshPtr()->getFacesOnly(); + Py::Tuple tuple(resultSet.size()); + int index = 0; + for (std::set::iterator it = resultSet.begin(); it != resultSet.end(); ++it) { + tuple.setItem(index++, Py::Long(*it)); + } + + return tuple; +} + Py::Long FemMeshPy::getFaceCount(void) const { return Py::Long(getFemMeshPtr()->getSMesh()->NbFaces());