diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index 515b7a5e7..00bca3d89 100755 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -404,14 +404,50 @@ std::set FemMesh::getSurfaceNodes(long ElemId, short FaceId, float Angle) return result; } -/* That function returns map containing volume ID and face number +/*! That function returns map containing volume ID and face ID. + */ +std::map FemMesh::getVolumesByFace(const TopoDS_Face &face) const +{ + std::map result; + std::set nodes_on_face = getNodesByFace(face); + + SMDS_VolumeIteratorPtr vol_iter = myMesh->GetMeshDS()->volumesIterator(); + while (vol_iter->more()) { + const SMDS_MeshVolume* vol = vol_iter->next(); + int numFaces = vol->NbFaces(); + SMDS_ElemIteratorPtr face_iter = vol->facesIterator(); + + while (face_iter->more()) { + const SMDS_MeshFace* face = static_cast(face_iter->next()); + int numNodes = face->NbNodes(); + + std::set face_nodes; + for (int i=0; iGetNode(i)->GetID()); + } + + std::vector element_face_nodes; + std::set_intersection(nodes_on_face.begin(), nodes_on_face.end(), face_nodes.begin(), face_nodes.end(), + std::back_insert_iterator >(element_face_nodes)); + + if (element_face_nodes.size() == numNodes) { + result[vol->GetID()] = face->GetID(); + break; + } + } + } + + return result; +} + +/*! That function returns map containing volume ID and face number * as per CalculiX definition for tetrahedral elements. See CalculiX * documentation for the details. */ std::map FemMesh::getccxVolumesByFace(const TopoDS_Face &face) const { std::map result; - std::set nodes_on_face = FemMesh::getNodesByFace(face); + std::set nodes_on_face = getNodesByFace(face); static std::map > elem_order; if (elem_order.empty()) { diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index 52f7ffd52..e5d73413d 100755 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -93,6 +93,8 @@ public: std::set getNodesByEdge(const TopoDS_Edge &edge) const; /// retrieving by vertex std::set getNodesByVertex(const TopoDS_Vertex &vertex) const; + /// retrieving volume IDs and face IDs number by face + std::map getVolumesByFace(const TopoDS_Face &face) const; /// retrieving volume IDs and CalculiX face number by face std::map getccxVolumesByFace(const TopoDS_Face &face) const; //@} diff --git a/src/Mod/Fem/App/FemMeshPy.xml b/src/Mod/Fem/App/FemMeshPy.xml index 1e2133a7c..43281e32d 100755 --- a/src/Mod/Fem/App/FemMeshPy.xml +++ b/src/Mod/Fem/App/FemMeshPy.xml @@ -84,9 +84,14 @@ Make a copy of this FEM mesh. + + + Return a dict of volume IDs and face IDs which belong to a TopoFace + + - Return a list of volume IDs which belong to a TopoFace + Return a dict of volume IDs and ccx face numbers which belong to a TopoFace diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index df601a858..f23f65373 100755 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -514,6 +514,39 @@ PyObject* FemMeshPy::setTransform(PyObject *args) Py_Return; } +PyObject* FemMeshPy::getVolumesByFace(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); + return 0; + } + + const TopoDS_Face& fc = TopoDS::Face(sh); + + Py::List ret; + std::map resultSet = getFemMeshPtr()->getVolumesByFace(fc); + for (std::map::const_iterator it = resultSet.begin();it!=resultSet.end();++it) { + Py::Tuple vol_face(2); + vol_face.setItem(0, Py::Int(it->first)); + vol_face.setItem(1, Py::Int(it->second)); + ret.append(vol_face); + } + + return Py::new_reference_to(ret); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + return 0; + } +} + PyObject* FemMeshPy::getccxVolumesByFace(PyObject *args) { PyObject *pW; @@ -522,22 +555,23 @@ PyObject* FemMeshPy::getccxVolumesByFace(PyObject *args) try { const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; - const TopoDS_Face& fc = TopoDS::Face(sh); if (sh.IsNull()) { PyErr_SetString(Base::BaseExceptionFreeCADError, "Face is empty"); return 0; } + + const TopoDS_Face& fc = TopoDS::Face(sh); + Py::List ret; std::map resultSet = getFemMeshPtr()->getccxVolumesByFace(fc); for (std::map::const_iterator it = resultSet.begin();it!=resultSet.end();++it) { - Py::List vol_face; - vol_face.append(Py::Int(it->first)); - vol_face.append(Py::Int(it->second)); - ret.append(vol_face); - } + Py::Tuple vol_face(2); + vol_face.setItem(0, Py::Int(it->first)); + vol_face.setItem(1, Py::Int(it->second)); + ret.append(vol_face); + } return Py::new_reference_to(ret); - } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught();