From a15ea4ca18845ad68fd33e2eb58c19a986d32124 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Tue, 24 Mar 2015 19:22:05 +0100 Subject: [PATCH] Fem: add Support for loads and supports on edges to CalculiX file --- src/Mod/Fem/App/FemMesh.cpp | 56 ++++++++++++++++++++++++++----- src/Mod/Fem/App/FemMesh.h | 3 ++ src/Mod/Fem/App/FemMeshPy.xml | 5 +++ src/Mod/Fem/App/FemMeshPyImp.cpp | 43 ++++++++++++++++++++---- src/Mod/Fem/MechanicalAnalysis.py | 8 ++--- 5 files changed, 96 insertions(+), 19 deletions(-) diff --git a/src/Mod/Fem/App/FemMesh.cpp b/src/Mod/Fem/App/FemMesh.cpp index a1faf8af7..f4c693b50 100755 --- a/src/Mod/Fem/App/FemMesh.cpp +++ b/src/Mod/Fem/App/FemMesh.cpp @@ -443,6 +443,46 @@ std::set FemMesh::getSurfaceNodes(const TopoDS_Face &face)const return result; } +std::set FemMesh::getSurfaceNodes(const TopoDS_Edge &edge)const +{ + + std::set result; + + Bnd_Box box; + BRepBndLib::Add(edge, box); + // limit where the mesh node belongs to the edge: + double limit = box.SquareExtent()/10000.0; + box.Enlarge(limit); + + // get the actuall 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(edge,s); + measure.Perform(); + if (!measure.IsDone() || measure.NbSolution() < 1) + continue; + + if(measure.Value() < limit) + result.insert(aNode->GetID()); + + } + } + + return result; +} + void FemMesh::readNastran(const std::string &Filename) @@ -1058,7 +1098,7 @@ struct Fem::FemMesh::FemMeshInfo FemMesh::getInfo(void) const{ return rtrn; -} +} // for(unsigned int i=0;iGetMeshDS()->volumesIterator(); //Calculate Mesh Volume @@ -1156,8 +1196,8 @@ Base::Quantity FemMesh::getVolume(void)const volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z)); } - - return Base::Quantity(volume,Unit::Volume); - - + + return Base::Quantity(volume,Unit::Volume); + + } \ No newline at end of file diff --git a/src/Mod/Fem/App/FemMesh.h b/src/Mod/Fem/App/FemMesh.h index 0d2cf3bed..2942aa84d 100755 --- a/src/Mod/Fem/App/FemMesh.h +++ b/src/Mod/Fem/App/FemMesh.h @@ -37,6 +37,7 @@ class SMESH_Mesh; class SMESH_Hypothesis; class TopoDS_Shape; class TopoDS_Face; +class TopoDS_Edge; namespace Fem { @@ -87,6 +88,8 @@ public: std::set getSurfaceNodes(long ElemId,short FaceId, float Angle=360)const; /// retrivinb by face std::set getSurfaceNodes(const TopoDS_Face &face)const; + /// retrivinb by edge + std::set getSurfaceNodes(const TopoDS_Edge &edge)const; //@} /** @name Placement control */ diff --git a/src/Mod/Fem/App/FemMeshPy.xml b/src/Mod/Fem/App/FemMeshPy.xml index 7f90ec03d..b837d8a79 100755 --- a/src/Mod/Fem/App/FemMeshPy.xml +++ b/src/Mod/Fem/App/FemMeshPy.xml @@ -94,6 +94,11 @@ Return a list of node IDs which belong to a TopoFace + + + Return a list of node IDs which belong to a TopoEdge + + Dictionary of Nodes by ID (int ID:Vector()) diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index 4fbacf26f..b6a5c5d95 100755 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include "Mod/Fem/App/FemMesh.h" @@ -534,9 +535,9 @@ PyObject* FemMeshPy::getNodeById(PyObject *args) PyObject* FemMeshPy::getNodesByFace(PyObject *args) { PyObject *pW; - if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) - return 0; - + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) + return 0; + try { const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; const TopoDS_Face& fc = TopoDS::Face(sh); @@ -548,18 +549,46 @@ PyObject* FemMeshPy::getNodesByFace(PyObject *args) std::set resultSet = getFemMeshPtr()->getSurfaceNodes(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) { + catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); + PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); return 0; - } + } } +PyObject* FemMeshPy::getNodesByEdge(PyObject *args) +{ + PyObject *pW; + if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeEdgePy::Type), &pW)) + return 0; + + try { + const TopoDS_Shape& sh = static_cast(pW)->getTopoShapePtr()->_Shape; + const TopoDS_Edge& fc = TopoDS::Edge(sh); + if (sh.IsNull()) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "Edge is empty"); + return 0; + } + Py::List ret; + std::set resultSet = getFemMeshPtr()->getSurfaceNodes(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; + } + +} // ===== Atributes ============================================================ diff --git a/src/Mod/Fem/MechanicalAnalysis.py b/src/Mod/Fem/MechanicalAnalysis.py index e5060968f..e2f20b544 100644 --- a/src/Mod/Fem/MechanicalAnalysis.py +++ b/src/Mod/Fem/MechanicalAnalysis.py @@ -411,8 +411,8 @@ class _JobControlTaskPanel: print ' Face Support (fixed face) on: ', f n = MeshObject.FemMesh.getNodesByFace(fo) elif fo.ShapeType == 'Edge': - print ' Line Support (fixed edge) on: ', f, ' --> not supported yet' - #n = MeshObject.FemMesh.getNodesByEdge(fo) # ToDo + print ' Line Support (fixed edge) on: ', f + n = MeshObject.FemMesh.getNodesByEdge(fo) elif fo.ShapeType == 'Vertex': print ' Point Support (fixed vertex) on: ', f, ' --> not supported yet' #n = MeshObject.FemMesh.getNodesByVertex(fo) # ToDo @@ -434,8 +434,8 @@ class _JobControlTaskPanel: print ' AreaLoad (face load) on: ', f n = MeshObject.FemMesh.getNodesByFace(fo) elif fo.ShapeType == 'Edge': - print ' Line Load (edge load) on: ', f, ' --> not supported yet' - #n = MeshObject.FemMesh.getNodesByEdge(fo) # ToDo + print ' Line Load (edge load) on: ', f + n = MeshObject.FemMesh.getNodesByEdge(fo) elif fo.ShapeType == 'Vertex': print ' Point Load (vertex load) on: ', f, ' --> not supported yet' #n = MeshObject.FemMesh.getNodesByVertex(fo) # ToDo