diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index 68870c4274..47a7c9e1f7 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -1066,6 +1066,22 @@ std::list FemMesh::getElementNodes(int id) const for (int i = 0; i < elem->NbNodes(); i++) result.push_back(elem->GetNode(i)->GetID()); } + + return result; +} + +std::list FemMesh::getNodeElements(int id, SMDSAbs_ElementType type) const +{ + std::list result; + const SMDS_MeshNode* node = myMesh->GetMeshDS()->FindNode(id); + if (node) { + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(type); + while (it->more()) { + const SMDS_MeshElement* elem = it->next(); + result.push_back(elem->GetID()); + } + } + return result; } diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index 72d3894f93..eac622822c 100644 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -100,6 +101,8 @@ public: std::set getNodesByVertex(const TopoDS_Vertex &vertex) const; /// retrieving node IDs by element ID std::list getElementNodes(int id) const; + /// retrieving elements IDs by node ID + std::list getNodeElements(int id, SMDSAbs_ElementType type=SMDSAbs_All) const; /// retrieving face IDs number by face std::list getFacesByFace(const TopoDS_Face &face) const; /// retrieving edge IDs number by edge diff --git a/src/Mod/Fem/App/FemMeshPy.xml b/src/Mod/Fem/App/FemMeshPy.xml index 93c28a17cd..293d7a5af3 100755 --- a/src/Mod/Fem/App/FemMeshPy.xml +++ b/src/Mod/Fem/App/FemMeshPy.xml @@ -143,6 +143,11 @@ Return a tuple of node IDs to a given element ID + + + Return a tuple of specific element IDs associated to a given node ID + + Return a string of group name to a given group ID diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index e5c8cb8dfa..10afaea6c6 100644 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -925,6 +925,45 @@ PyObject* FemMeshPy::getElementNodes(PyObject *args) } } +using pairStrElemType = std::pair; + +const std::vector vecTypeName = { + {"All", SMDSAbs_All}, + {"Node", SMDSAbs_Node}, + {"Edge", SMDSAbs_Edge}, + {"Face", SMDSAbs_Face}, + {"Volume", SMDSAbs_Volume}, + {"0DElement", SMDSAbs_0DElement}, + {"Ball", SMDSAbs_Ball}, +}; + +PyObject* FemMeshPy::getNodeElements(PyObject* args) +{ + int id; + const char* typeStr = "All"; + if (!PyArg_ParseTuple(args, "i|s", &id, &typeStr)) + return nullptr; + + auto it = std::find_if(vecTypeName.begin(), vecTypeName.end(), [=](const pairStrElemType& x) { + return x.first == typeStr; + }); + + if (it == vecTypeName.end()) { + PyErr_SetString(PyExc_ValueError, "Invalid element type"); + return nullptr; + } + + SMDSAbs_ElementType elemType = it->second; + std::list elemList = getFemMeshPtr()->getNodeElements(id, elemType); + Py::Tuple result(elemList.size()); + int index = 0; + for (std::list::iterator it = elemList.begin(); it != elemList.end(); ++it) { + result.setItem(index++, Py::Long(*it)); + } + + return Py::new_reference_to(result); +} + PyObject* FemMeshPy::getGroupName(PyObject *args) { int id; @@ -950,19 +989,15 @@ PyObject* FemMeshPy::getGroupElementType(PyObject *args) PyErr_SetString(PyExc_ValueError, "No group for given id"); return nullptr; } - SMDSAbs_ElementType aElementType = group->GetGroupDS()->GetType(); - const char* typeString = ""; - switch(aElementType) { - case SMDSAbs_All : typeString = "All"; break; - case SMDSAbs_Node : typeString = "Node"; break; - case SMDSAbs_Edge : typeString = "Edge"; break; - case SMDSAbs_Face : typeString = "Face"; break; - case SMDSAbs_Volume : typeString = "Volume"; break; - case SMDSAbs_0DElement : typeString = "0DElement"; break; - case SMDSAbs_Ball : typeString = "Ball"; break; - default : typeString = "Unknown"; break; - } - return PyUnicode_FromString(typeString); + + SMDSAbs_ElementType elemType = group->GetGroupDS()->GetType(); + auto it = std::find_if(vecTypeName.begin(), vecTypeName.end(), [=](const pairStrElemType& x) { + return x.second == elemType; + }); + + const char* typeStr = it != vecTypeName.end() ? it->first.c_str() : "Unknown"; + + return PyUnicode_FromString(typeStr); } PyObject* FemMeshPy::getGroupElements(PyObject *args) @@ -1088,56 +1123,42 @@ PyObject* FemMeshPy::getElementType(PyObject *args) return nullptr; // An element ... - SMDSAbs_ElementType aElementType = getFemMeshPtr()->getSMesh()->GetElementType(id, true); + SMDSAbs_ElementType elemType = getFemMeshPtr()->getSMesh()->GetElementType(id, true); // ... or a node - if (aElementType == SMDSAbs_All) - aElementType = getFemMeshPtr()->getSMesh()->GetElementType(id, false); + if (elemType == SMDSAbs_All) + elemType = getFemMeshPtr()->getSMesh()->GetElementType(id, false); - const char* typeString = ""; - switch(aElementType) { - case SMDSAbs_Node : typeString = "Node"; break; - case SMDSAbs_Edge : typeString = "Edge"; break; - case SMDSAbs_Face : typeString = "Face"; break; - case SMDSAbs_Volume : typeString = "Volume"; break; - case SMDSAbs_0DElement : typeString = "0DElement"; break; - case SMDSAbs_Ball : typeString = "Ball"; break; - default: { + auto it = std::find_if(vecTypeName.begin()+1, vecTypeName.end(), [=](const pairStrElemType& x) { + return x.second == elemType; + }); + + const char* typeStr = it != vecTypeName.end() ? it->first.c_str() : nullptr; + if (!typeStr) { PyErr_SetString(PyExc_ValueError, "No node or element for given id"); return nullptr; } - } - return PyUnicode_FromString(typeString); + return PyUnicode_FromString(typeStr); } PyObject* FemMeshPy::getIdByElementType(PyObject *args) { - char* str; - if (!PyArg_ParseTuple(args, "s", &str)) + const char* typeStr; + if (!PyArg_ParseTuple(args, "s", &typeStr)) return nullptr; - SMDSAbs_ElementType aElementType = SMDSAbs_All; - if (strcmp(str, "Node") == 0) { - aElementType = SMDSAbs_Node; - } - else if (strcmp(str, "Edge") == 0) { - aElementType = SMDSAbs_Edge; - } - else if (strcmp(str, "Face") == 0) { - aElementType = SMDSAbs_Face; - } - else if (strcmp(str, "Volume") == 0) { - aElementType = SMDSAbs_Volume; - } - else if (strcmp(str, "0DElement") == 0) { - aElementType = SMDSAbs_0DElement; - } - else if (strcmp(str, "Ball") == 0) { - aElementType = SMDSAbs_Ball; + auto it = std::find_if(vecTypeName.begin(), vecTypeName.end(), [=](const pairStrElemType& x) { + return x.first == typeStr; + }); + + if (it == vecTypeName.end()) { + PyErr_SetString(PyExc_ValueError, "Invalid element type"); + return nullptr; } + SMDSAbs_ElementType elemType = it->second; std::set ids; - SMDS_ElemIteratorPtr aElemIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->elementsIterator(aElementType); + SMDS_ElemIteratorPtr aElemIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->elementsIterator(elemType); while (aElemIter->more()) { const SMDS_MeshElement* aElem = aElemIter->next(); ids.insert(aElem->GetID());