diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index 4f2314b2885c..b139689310b5 100644 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -524,6 +524,45 @@ std::map FemMesh::getccxVolumesByFace(const TopoDS_Face &face) const return result; } +std::set FemMesh::getNodesBySolid(const TopoDS_Solid &solid) const +{ + std::set result; + + Bnd_Box box; + BRepBndLib::Add(solid, box); + // limit where the mesh node belongs to the solid: + double limit = box.SquareExtent()/10000.0; + //double limit = BRep_Tool::Tolerance(solid); // does not compile --> no matching function for call to 'BRep_Tool::Tolerance(const TopoDS_Solid&)' + box.Enlarge(limit); + + // get the current transform of the FemMesh + const Base::Matrix4D Mtrx(getTransform()); + + SMDS_NodeIteratorPtr aNodeIter = myMesh->GetMeshDS()->nodesIterator(); + while (aNodeIter->more()) { + const SMDS_MeshNode* aNode = aNodeIter->next(); + Base::Vector3d vec(aNode->X(),aNode->Y(),aNode->Z()); + // Apply the matrix to hold the BoundBox in absolute space. + vec = Mtrx * vec; + + if (!box.IsOut(gp_Pnt(vec.x,vec.y,vec.z))) { + // create a vertex + BRepBuilderAPI_MakeVertex aBuilder(gp_Pnt(vec.x,vec.y,vec.z)); + TopoDS_Shape s = aBuilder.Vertex(); + // measure distance + BRepExtrema_DistShapeShape measure(solid,s); + measure.Perform(); + if (!measure.IsDone() || measure.NbSolution() < 1) + continue; + + if (measure.Value() < limit) + result.insert(aNode->GetID()); + } + } + + return result; +} + std::set FemMesh::getNodesByFace(const TopoDS_Face &face) const { std::set result; diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index e8e845ea73ec..79d53fcfcb70 100644 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -39,6 +39,7 @@ class TopoDS_Shape; class TopoDS_Face; class TopoDS_Edge; class TopoDS_Vertex; +class TopoDS_Solid; namespace Fem { @@ -87,6 +88,8 @@ class AppFemExport FemMesh : public Data::ComplexGeoData //@{ /// retrieving by region growing std::set getSurfaceNodes(long ElemId, short FaceId, float Angle=360)const; + /// retrieving by solid + std::set getNodesBySolid(const TopoDS_Solid &solid) const; /// retrieving by face std::set getNodesByFace(const TopoDS_Face &face) const; /// retrieving by edge diff --git a/src/Mod/Fem/App/FemMeshPy.xml b/src/Mod/Fem/App/FemMeshPy.xml index 77bc9405da2a..378ccc95e6a6 100755 --- a/src/Mod/Fem/App/FemMeshPy.xml +++ b/src/Mod/Fem/App/FemMeshPy.xml @@ -99,6 +99,11 @@ Get the node position vector by an Node-ID + + + Return a list of node IDs which belong to a TopoSolid + + Return a list of node IDs which belong to a TopoFace diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index f77dba51fbd7..2a3f0e2ec88b 100644 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include #include @@ -611,6 +612,34 @@ PyObject* FemMeshPy::getNodeById(PyObject *args) } } +PyObject* FemMeshPy::getNodesBySolid(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeSolidPy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + const TopoDS_Solid& fc = TopoDS::Solid(sh); + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Solid is empty"); + return 0; + } + Py::List ret; + std::set resultSet = getFemMeshPtr()->getNodesBySolid(fc); + for (std::set::const_iterator it = resultSet.begin();it!=resultSet.end();++it) + ret.append(Py::Int(*it)); + + 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::getNodesByFace(PyObject *args) { PyObject *pW;