| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <Python.h> |
| | #include <SMDSAbs_ElementType.hxx> |
| | #include <SMDS_MeshElement.hxx> |
| | #include <SMESHDS_Group.hxx> |
| | #include <SMESHDS_Mesh.hxx> |
| | #include <SMESH_Group.hxx> |
| | #include <SMESH_Mesh.hxx> |
| | #include <TopoDS.hxx> |
| | #include <TopoDS_Face.hxx> |
| | #include <TopoDS_Shape.hxx> |
| | #include <algorithm> |
| | #include <stdexcept> |
| |
|
| |
|
| | #include "Mod/Fem/App/FemMesh.h" |
| | #include <Base/PlacementPy.h> |
| | #include <Base/PyWrapParseTupleAndKeywords.h> |
| | #include <Base/QuantityPy.h> |
| | #include <Base/VectorPy.h> |
| | #include <Mod/Part/App/TopoShape.h> |
| | #include <Mod/Part/App/TopoShapeEdgePy.h> |
| | #include <Mod/Part/App/TopoShapeFacePy.h> |
| | #include <Mod/Part/App/TopoShapePy.h> |
| | #include <Mod/Part/App/TopoShapeSolidPy.h> |
| | #include <Mod/Part/App/TopoShapeVertexPy.h> |
| |
|
| | |
| | |
| | #include "FemMeshPy.h" |
| | #include "FemMeshPy.cpp" |
| | #include "HypothesisPy.h" |
| | |
| |
|
| |
|
| | using namespace Fem; |
| |
|
| | |
| | std::string FemMeshPy::representation() const |
| | { |
| | std::stringstream str; |
| | getFemMeshPtr()->getSMesh()->Dump(str); |
| | return str.str(); |
| | } |
| |
|
| | PyObject* FemMeshPy::PyMake(struct _typeobject*, PyObject*, PyObject*) |
| | { |
| | |
| | return new FemMeshPy(new FemMesh); |
| | } |
| |
|
| | |
| | int FemMeshPy::PyInit(PyObject* args, PyObject* ) |
| | { |
| | PyObject* pcObj = nullptr; |
| | if (!PyArg_ParseTuple(args, "|O", &pcObj)) { |
| | return -1; |
| | } |
| |
|
| | try { |
| | |
| | if (!pcObj) { |
| | return 0; |
| | } |
| | if (PyObject_TypeCheck(pcObj, &(FemMeshPy::Type))) { |
| | getFemMeshPtr()->operator=(*static_cast<FemMeshPy*>(pcObj)->getFemMeshPtr()); |
| | } |
| | else { |
| | PyErr_Format( |
| | PyExc_TypeError, |
| | "Cannot create a FemMesh out of a '%s'", |
| | pcObj->ob_type->tp_name |
| | ); |
| | return -1; |
| | } |
| | } |
| | catch (const Base::Exception& e) { |
| | e.setPyException(); |
| | return -1; |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return -1; |
| | } |
| | catch (const Py::Exception&) { |
| | return -1; |
| | } |
| |
|
| | return 0; |
| | } |
| |
|
| |
|
| | |
| |
|
| | PyObject* FemMeshPy::setShape(PyObject* args) |
| | { |
| | PyObject* pcObj; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->getShape(); |
| | getFemMeshPtr()->getSMesh()->ShapeToMesh(shape); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::addHypothesis(PyObject* args) |
| | { |
| | PyObject* hyp; |
| | PyObject* shp = nullptr; |
| | |
| | |
| | if (!PyArg_ParseTuple(args, "O|O!", &hyp, &(Part::TopoShapePy::Type), &shp)) { |
| | return nullptr; |
| | } |
| |
|
| | TopoDS_Shape shape; |
| | if (!shp) { |
| | shape = getFemMeshPtr()->getSMesh()->GetShapeToMesh(); |
| | } |
| | else { |
| | shape = static_cast<Part::TopoShapePy*>(shp)->getTopoShapePtr()->getShape(); |
| | } |
| |
|
| | try { |
| | Py::Object obj(hyp); |
| | Fem::Hypothesis attr(obj.getAttr("this")); |
| | SMESH_HypothesisPtr thesis = attr.extensionObject()->getHypothesis(); |
| | getFemMeshPtr()->addHypothesis(shape, thesis); |
| | } |
| | catch (const Py::Exception&) { |
| | return nullptr; |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::setStandardHypotheses(PyObject* args) |
| | { |
| | if (!PyArg_ParseTuple(args, "")) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | getFemMeshPtr()->setStandardHypotheses(); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::compute(PyObject* args) |
| | { |
| | if (!PyArg_ParseTuple(args, "")) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | getFemMeshPtr()->compute(); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::addNode(PyObject* args) |
| | { |
| | double x, y, z; |
| | int i = -1; |
| | if (PyArg_ParseTuple(args, "ddd", &x, &y, &z)) { |
| | try { |
| | SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); |
| | SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); |
| | SMDS_MeshNode* node = meshDS->AddNode(x, y, z); |
| | if (!node) { |
| | throw std::runtime_error("Failed to add node"); |
| | } |
| | return Py::new_reference_to(Py::Long(node->GetID())); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | } |
| | PyErr_Clear(); |
| |
|
| | if (PyArg_ParseTuple(args, "dddi", &x, &y, &z, &i)) { |
| | try { |
| | SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); |
| | SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); |
| | SMDS_MeshNode* node = meshDS->AddNodeWithID(x, y, z, i); |
| | if (!node) { |
| | throw std::runtime_error("Failed to add node"); |
| | } |
| | return Py::new_reference_to(Py::Long(node->GetID())); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | } |
| | PyErr_SetString( |
| | PyExc_TypeError, |
| | "addNode() accepts:\n" |
| | "-- addNode(x,y,z)\n" |
| | "-- addNode(x,y,z,ElemId)\n" |
| | ); |
| | return nullptr; |
| | } |
| |
|
| | PyObject* FemMeshPy::addEdge(PyObject* args) |
| | { |
| | SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); |
| | SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); |
| |
|
| | int n1, n2; |
| | if (PyArg_ParseTuple(args, "ii", &n1, &n2)) { |
| | try { |
| | const SMDS_MeshNode* node1 = meshDS->FindNode(n1); |
| | const SMDS_MeshNode* node2 = meshDS->FindNode(n2); |
| | if (!node1 || !node2) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | SMDS_MeshEdge* edge = meshDS->AddEdge(node1, node2); |
| | if (!edge) { |
| | throw std::runtime_error("Failed to add edge"); |
| | } |
| | return Py::new_reference_to(Py::Long(edge->GetID())); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | } |
| | PyErr_Clear(); |
| |
|
| | PyObject* obj; |
| | int ElementId = -1; |
| | if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) { |
| | Py::List list(obj); |
| | std::vector<const SMDS_MeshNode*> Nodes; |
| | for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { |
| | Py::Long NoNr(*it); |
| | const SMDS_MeshNode* node = meshDS->FindNode(NoNr); |
| | if (!node) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | Nodes.push_back(node); |
| | } |
| |
|
| | SMDS_MeshEdge* edge = nullptr; |
| | if (ElementId != -1) { |
| | switch (Nodes.size()) { |
| | case 2: |
| | edge = meshDS->AddEdgeWithID(Nodes[0], Nodes[1], ElementId); |
| | if (!edge) { |
| | throw std::runtime_error("Failed to add edge with given ElementId"); |
| | } |
| | break; |
| | case 3: |
| | edge = meshDS->AddEdgeWithID(Nodes[0], Nodes[1], Nodes[2], ElementId); |
| | if (!edge) { |
| | throw std::runtime_error("Failed to add edge with given ElementId"); |
| | } |
| | break; |
| | default: |
| | throw std::runtime_error("Unknown node count, [2|3] are allowed"); |
| | |
| | } |
| | } |
| | else { |
| | switch (Nodes.size()) { |
| | case 2: |
| | edge = meshDS->AddEdge(Nodes[0], Nodes[1]); |
| | if (!edge) { |
| | throw std::runtime_error("Failed to add edge"); |
| | } |
| | break; |
| | case 3: |
| | edge = meshDS->AddEdge(Nodes[0], Nodes[1], Nodes[2]); |
| | if (!edge) { |
| | throw std::runtime_error("Failed to add edge"); |
| | } |
| | break; |
| | default: |
| | throw std::runtime_error("Unknown node count, [2|3] are allowed"); |
| | |
| | } |
| | } |
| | return Py::new_reference_to(Py::Long(edge->GetID())); |
| | } |
| | PyErr_SetString( |
| | PyExc_TypeError, |
| | "addEdge accepts:\n" |
| | "-- int,int\n" |
| | "-- [2|3],[int]\n" |
| | ); |
| | return nullptr; |
| | } |
| |
|
| | PyObject* FemMeshPy::addFace(PyObject* args) |
| | { |
| | SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); |
| | SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); |
| |
|
| | int n1, n2, n3; |
| | if (PyArg_ParseTuple(args, "iii", &n1, &n2, &n3)) { |
| | |
| | try { |
| | const SMDS_MeshNode* node1 = meshDS->FindNode(n1); |
| | const SMDS_MeshNode* node2 = meshDS->FindNode(n2); |
| | const SMDS_MeshNode* node3 = meshDS->FindNode(n3); |
| | if (!node1 || !node2 || !node3) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face"); |
| | } |
| | return Py::new_reference_to(Py::Long(face->GetID())); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | } |
| | PyErr_Clear(); |
| |
|
| | PyObject* obj; |
| | int ElementId = -1; |
| | if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) { |
| | Py::List list(obj); |
| | std::vector<const SMDS_MeshNode*> Nodes; |
| | for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { |
| | Py::Long NoNr(*it); |
| | const SMDS_MeshNode* node = meshDS->FindNode(NoNr); |
| | if (!node) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | Nodes.push_back(node); |
| | } |
| |
|
| | SMDS_MeshFace* face = nullptr; |
| | if (ElementId != -1) { |
| | switch (Nodes.size()) { |
| | case 3: |
| | face = meshDS->AddFaceWithID(Nodes[0], Nodes[1], Nodes[2], ElementId); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add triangular face with given ElementId"); |
| | } |
| | break; |
| | case 4: |
| | face = meshDS->AddFaceWithID(Nodes[0], Nodes[1], Nodes[2], Nodes[3], ElementId); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face with given ElementId"); |
| | } |
| | break; |
| | case 6: |
| | face = meshDS->AddFaceWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | ElementId |
| | ); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face with given ElementId"); |
| | } |
| | break; |
| | case 8: |
| | face = meshDS->AddFaceWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | ElementId |
| | ); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face with given ElementId"); |
| | } |
| | break; |
| | default: |
| | throw std::runtime_error( |
| | "Unknown node count, [3|4|6|8] are allowed" |
| | ); |
| | } |
| | } |
| | else { |
| | switch (Nodes.size()) { |
| | case 3: |
| | face = meshDS->AddFace(Nodes[0], Nodes[1], Nodes[2]); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add triangular face"); |
| | } |
| | break; |
| | case 4: |
| | face = meshDS->AddFace(Nodes[0], Nodes[1], Nodes[2], Nodes[3]); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face"); |
| | } |
| | break; |
| | case 6: |
| | face = meshDS->AddFace(Nodes[0], Nodes[1], Nodes[2], Nodes[3], Nodes[4], Nodes[5]); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face"); |
| | } |
| | break; |
| | case 8: |
| | face = meshDS->AddFace( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7] |
| | ); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add face"); |
| | } |
| | break; |
| | default: |
| | throw std::runtime_error( |
| | "Unknown node count, [4|5|6|8] are allowed" |
| | ); |
| | } |
| | } |
| |
|
| | return Py::new_reference_to(Py::Long(face->GetID())); |
| | } |
| | PyErr_SetString( |
| | PyExc_TypeError, |
| | "addFace accepts:\n" |
| | "-- int,int,int\n" |
| | "-- [3|4|6|8 int],[int]\n" |
| | ); |
| | return nullptr; |
| | } |
| |
|
| | PyObject* FemMeshPy::addQuad(PyObject* args) |
| | { |
| | int n1, n2, n3, n4; |
| | if (!PyArg_ParseTuple(args, "iiii", &n1, &n2, &n3, &n4)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); |
| | SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); |
| | const SMDS_MeshNode* node1 = meshDS->FindNode(n1); |
| | const SMDS_MeshNode* node2 = meshDS->FindNode(n2); |
| | const SMDS_MeshNode* node3 = meshDS->FindNode(n3); |
| | const SMDS_MeshNode* node4 = meshDS->FindNode(n4); |
| | if (!node1 || !node2 || !node3 || !node4) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3, node4); |
| | if (!face) { |
| | throw std::runtime_error("Failed to add quad"); |
| | } |
| | return Py::new_reference_to(Py::Long(face->GetID())); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::addVolume(PyObject* args) |
| | { |
| | SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh(); |
| | SMESHDS_Mesh* meshDS = mesh->GetMeshDS(); |
| |
|
| | int n1, n2, n3, n4; |
| | if (PyArg_ParseTuple(args, "iiii", &n1, &n2, &n3, &n4)) { |
| | try { |
| | const SMDS_MeshNode* node1 = meshDS->FindNode(n1); |
| | const SMDS_MeshNode* node2 = meshDS->FindNode(n2); |
| | const SMDS_MeshNode* node3 = meshDS->FindNode(n3); |
| | const SMDS_MeshNode* node4 = meshDS->FindNode(n4); |
| | if (!node1 || !node2 || !node3 || !node4) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | SMDS_MeshVolume* vol = meshDS->AddVolume(node1, node2, node3, node4); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add volume"); |
| | } |
| | return Py::new_reference_to(Py::Long(vol->GetID())); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | } |
| | PyErr_Clear(); |
| |
|
| | PyObject* obj; |
| | int ElementId = -1; |
| | if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId)) { |
| | Py::List list(obj); |
| | std::vector<const SMDS_MeshNode*> Nodes; |
| | for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { |
| | Py::Long NoNr(*it); |
| | const SMDS_MeshNode* node = meshDS->FindNode(NoNr); |
| | if (!node) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | Nodes.push_back(node); |
| | } |
| |
|
| | SMDS_MeshVolume* vol = nullptr; |
| | if (ElementId != -1) { |
| | switch (Nodes.size()) { |
| | case 4: |
| | vol = meshDS->AddVolumeWithID(Nodes[0], Nodes[1], Nodes[2], Nodes[3], ElementId); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Tet4 volume with given ElementId"); |
| | } |
| | break; |
| | case 5: |
| | vol = meshDS->AddVolumeWithID(Nodes[0], Nodes[1], Nodes[2], Nodes[3], Nodes[4], ElementId); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Pyra5 volume with given ElementId"); |
| | } |
| | break; |
| | case 6: |
| | vol = meshDS->AddVolumeWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | ElementId |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Penta6 volume with given ElementId"); |
| | } |
| | break; |
| | case 8: |
| | vol = meshDS->AddVolumeWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | ElementId |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Hexa8 volume with given ElementId"); |
| | } |
| | break; |
| | case 10: |
| | vol = meshDS->AddVolumeWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | ElementId |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Tet10 volume with given ElementId"); |
| | } |
| | break; |
| | case 13: |
| | vol = meshDS->AddVolumeWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | Nodes[10], |
| | Nodes[11], |
| | Nodes[12], |
| | ElementId |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Pyra13 volume with given ElementId"); |
| | } |
| | break; |
| | case 15: |
| | vol = meshDS->AddVolumeWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | Nodes[10], |
| | Nodes[11], |
| | Nodes[12], |
| | Nodes[13], |
| | Nodes[14], |
| | ElementId |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Penta15 volume with given ElementId"); |
| | } |
| | break; |
| | case 20: |
| | vol = meshDS->AddVolumeWithID( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | Nodes[10], |
| | Nodes[11], |
| | Nodes[12], |
| | Nodes[13], |
| | Nodes[14], |
| | Nodes[15], |
| | Nodes[16], |
| | Nodes[17], |
| | Nodes[18], |
| | Nodes[19], |
| | ElementId |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Hexa20 volume with given ElementId"); |
| | } |
| | break; |
| | default: |
| | throw std::runtime_error( |
| | "Unknown node count, [4|5|6|8|10|13|15|20] are allowed" |
| | ); |
| | |
| | } |
| | } |
| | else { |
| | switch (Nodes.size()) { |
| | case 4: |
| | vol = meshDS->AddVolume(Nodes[0], Nodes[1], Nodes[2], Nodes[3]); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Tet4 volume"); |
| | } |
| | break; |
| | case 5: |
| | vol = meshDS->AddVolume(Nodes[0], Nodes[1], Nodes[2], Nodes[3], Nodes[4]); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Pyra5 volume"); |
| | } |
| | break; |
| | case 6: |
| | vol = meshDS->AddVolume(Nodes[0], Nodes[1], Nodes[2], Nodes[3], Nodes[4], Nodes[5]); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Penta6 volume"); |
| | } |
| | break; |
| | case 8: |
| | vol = meshDS->AddVolume( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7] |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Hexa8 volume"); |
| | } |
| | break; |
| | case 10: |
| | vol = meshDS->AddVolume( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9] |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Tet10 volume"); |
| | } |
| | break; |
| | case 13: |
| | vol = meshDS->AddVolume( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | Nodes[10], |
| | Nodes[11], |
| | Nodes[12] |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Pyra13 volume"); |
| | } |
| | break; |
| | case 15: |
| | vol = meshDS->AddVolume( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | Nodes[10], |
| | Nodes[11], |
| | Nodes[12], |
| | Nodes[13], |
| | Nodes[14] |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Penta15 volume"); |
| | } |
| | break; |
| | case 20: |
| | vol = meshDS->AddVolume( |
| | Nodes[0], |
| | Nodes[1], |
| | Nodes[2], |
| | Nodes[3], |
| | Nodes[4], |
| | Nodes[5], |
| | Nodes[6], |
| | Nodes[7], |
| | Nodes[8], |
| | Nodes[9], |
| | Nodes[10], |
| | Nodes[11], |
| | Nodes[12], |
| | Nodes[13], |
| | Nodes[14], |
| | Nodes[15], |
| | Nodes[16], |
| | Nodes[17], |
| | Nodes[18], |
| | Nodes[19] |
| | ); |
| | if (!vol) { |
| | throw std::runtime_error("Failed to add Hexa20 volume"); |
| | } |
| | break; |
| | default: |
| | throw std::runtime_error( |
| | "Unknown node count, [4|5|6|8|10|13|15|20] are allowed" |
| | ); |
| | |
| | } |
| | } |
| |
|
| | return Py::new_reference_to(Py::Long(vol->GetID())); |
| | } |
| | PyErr_SetString( |
| | PyExc_TypeError, |
| | "addVolume accepts:\n" |
| | "-- int,int,int,int\n" |
| | "-- [4|5|6|8|10|13|15|20 int],[int]\n" |
| | ); |
| | return nullptr; |
| | } |
| |
|
| | PyObject* FemMeshPy::addEdgeList(PyObject* args) |
| | { |
| | PyObject* nodesObj = nullptr; |
| | PyObject* npObj = nullptr; |
| | ; |
| | if (!PyArg_ParseTuple(args, "O!O!", &PyList_Type, &nodesObj, &PyList_Type, &npObj)) { |
| | return nullptr; |
| | } |
| |
|
| | Py::List nodesList(nodesObj); |
| | Py::List npList(npObj); |
| | SMESHDS_Mesh* meshDS = getFemMeshPtr()->getSMesh()->GetMeshDS(); |
| |
|
| | std::vector<const SMDS_MeshNode*> nodes; |
| | for (Py::List::iterator it = nodesList.begin(); it != nodesList.end(); ++it) { |
| | Py::Long n(*it); |
| | const SMDS_MeshNode* node = meshDS->FindNode(static_cast<int>(n)); |
| | if (!node) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | nodes.push_back(node); |
| | } |
| |
|
| | std::vector<const SMDS_MeshNode*>::iterator nodeIt = nodes.begin(); |
| | SMDS_MeshEdge* edge = nullptr; |
| | Py::List result; |
| | int np = 0; |
| | for (Py::List::iterator it = npList.begin(); it != npList.end(); ++it, nodeIt += np) { |
| | np = Py::Long(*it); |
| | std::vector<const SMDS_MeshNode*> nodesElem(nodeIt, nodeIt + np); |
| | switch (np) { |
| | case 2: |
| | edge = meshDS->AddEdge(nodesElem[0], nodesElem[1]); |
| | break; |
| | case 3: |
| | edge = meshDS->AddEdge(nodesElem[0], nodesElem[1], nodesElem[2]); |
| | break; |
| | default: |
| | PyErr_SetString(PyExc_TypeError, "Unknown node count, [2|3] are allowed"); |
| | return nullptr; |
| | } |
| | if (edge) { |
| | result.append(Py::Long(edge->GetID())); |
| | } |
| | else { |
| | PyErr_SetString(PyExc_TypeError, "Failed to add edge"); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | return Py::new_reference_to(result); |
| | } |
| |
|
| |
|
| | PyObject* FemMeshPy::addFaceList(PyObject* args) |
| | { |
| | PyObject* nodesObj = nullptr; |
| | PyObject* npObj = nullptr; |
| | ; |
| | if (!PyArg_ParseTuple(args, "O!O!", &PyList_Type, &nodesObj, &PyList_Type, &npObj)) { |
| | return nullptr; |
| | } |
| |
|
| | Py::List nodesList(nodesObj); |
| | Py::List npList(npObj); |
| | SMESHDS_Mesh* meshDS = getFemMeshPtr()->getSMesh()->GetMeshDS(); |
| |
|
| | std::vector<const SMDS_MeshNode*> nodes; |
| | for (Py::List::iterator it = nodesList.begin(); it != nodesList.end(); ++it) { |
| | Py::Long n(*it); |
| | const SMDS_MeshNode* node = meshDS->FindNode(static_cast<int>(n)); |
| | if (!node) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | nodes.push_back(node); |
| | } |
| |
|
| | std::vector<const SMDS_MeshNode*>::iterator nodeIt = nodes.begin(); |
| | SMDS_MeshFace* face = nullptr; |
| | Py::List result; |
| | int np = 0; |
| | for (Py::List::iterator it = npList.begin(); it != npList.end(); ++it, nodeIt += np) { |
| | np = Py::Long(*it); |
| | std::vector<const SMDS_MeshNode*> nodesElem(nodeIt, nodeIt + np); |
| | switch (np) { |
| | case 3: |
| | face = meshDS->AddFace(nodesElem[0], nodesElem[1], nodesElem[2]); |
| | break; |
| | case 4: |
| | face = meshDS->AddFace(nodesElem[0], nodesElem[1], nodesElem[2], nodesElem[3]); |
| | break; |
| | case 6: |
| | face = meshDS->AddFace( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5] |
| | ); |
| | break; |
| | case 8: |
| | face = meshDS->AddFace( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5], |
| | nodesElem[6], |
| | nodesElem[7] |
| | ); |
| | break; |
| | default: |
| | PyErr_SetString(PyExc_TypeError, "Unknown node count, [3|4|6|8] are allowed"); |
| | return nullptr; |
| | } |
| | if (face) { |
| | result.append(Py::Long(face->GetID())); |
| | } |
| | else { |
| | PyErr_SetString(PyExc_TypeError, "Failed to add face"); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | return Py::new_reference_to(result); |
| | } |
| |
|
| |
|
| | PyObject* FemMeshPy::addVolumeList(PyObject* args) |
| | { |
| | PyObject* nodesObj = nullptr; |
| | PyObject* npObj = nullptr; |
| | ; |
| | if (!PyArg_ParseTuple(args, "O!O!", &PyList_Type, &nodesObj, &PyList_Type, &npObj)) { |
| | return nullptr; |
| | } |
| |
|
| | Py::List nodesList(nodesObj); |
| | Py::List npList(npObj); |
| | SMESHDS_Mesh* meshDS = getFemMeshPtr()->getSMesh()->GetMeshDS(); |
| |
|
| | std::vector<const SMDS_MeshNode*> nodes; |
| | for (Py::List::iterator it = nodesList.begin(); it != nodesList.end(); ++it) { |
| | Py::Long n(*it); |
| | const SMDS_MeshNode* node = meshDS->FindNode(static_cast<int>(n)); |
| | if (!node) { |
| | throw std::runtime_error("Failed to get node of the given indices"); |
| | } |
| | nodes.push_back(node); |
| | } |
| |
|
| | std::vector<const SMDS_MeshNode*>::iterator nodeIt = nodes.begin(); |
| | SMDS_MeshVolume* vol = nullptr; |
| | Py::List result; |
| | int np = 0; |
| | for (Py::List::iterator it = npList.begin(); it != npList.end(); ++it, nodeIt += np) { |
| | np = Py::Long(*it); |
| | std::vector<const SMDS_MeshNode*> nodesElem(nodeIt, nodeIt + np); |
| | switch (np) { |
| | case 4: |
| | vol = meshDS->AddVolume(nodesElem[0], nodesElem[1], nodesElem[2], nodesElem[3]); |
| | break; |
| | case 5: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4] |
| | ); |
| | break; |
| | case 6: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5] |
| | ); |
| | break; |
| | case 8: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5], |
| | nodesElem[6], |
| | nodesElem[7] |
| | ); |
| | break; |
| | case 10: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5], |
| | nodesElem[6], |
| | nodesElem[7], |
| | nodesElem[8], |
| | nodesElem[9] |
| | ); |
| | break; |
| | case 13: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5], |
| | nodesElem[6], |
| | nodesElem[7], |
| | nodesElem[8], |
| | nodesElem[9], |
| | nodesElem[10], |
| | nodesElem[11], |
| | nodesElem[12] |
| | ); |
| | break; |
| | case 15: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5], |
| | nodesElem[6], |
| | nodesElem[7], |
| | nodesElem[8], |
| | nodesElem[9], |
| | nodesElem[10], |
| | nodesElem[11], |
| | nodesElem[12], |
| | nodesElem[13], |
| | nodesElem[14] |
| | ); |
| | break; |
| | case 20: |
| | vol = meshDS->AddVolume( |
| | nodesElem[0], |
| | nodesElem[1], |
| | nodesElem[2], |
| | nodesElem[3], |
| | nodesElem[4], |
| | nodesElem[5], |
| | nodesElem[6], |
| | nodesElem[7], |
| | nodesElem[8], |
| | nodesElem[9], |
| | nodesElem[10], |
| | nodesElem[11], |
| | nodesElem[12], |
| | nodesElem[13], |
| | nodesElem[14], |
| | nodesElem[15], |
| | nodesElem[16], |
| | nodesElem[17], |
| | nodesElem[18], |
| | nodesElem[19] |
| | ); |
| | break; |
| | default: |
| | PyErr_SetString(PyExc_TypeError, "Unknown node count, [4|5|6|8|10|13|15|20] are allowed"); |
| | return nullptr; |
| | } |
| | if (vol) { |
| | result.append(Py::Long(vol->GetID())); |
| | } |
| | else { |
| | PyErr_SetString(PyExc_TypeError, "Failed to add face"); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | return Py::new_reference_to(result); |
| | } |
| |
|
| |
|
| | PyObject* FemMeshPy::copy(PyObject* args) const |
| | { |
| | if (!PyArg_ParseTuple(args, "")) { |
| | return nullptr; |
| | } |
| |
|
| | const FemMesh& mesh = *getFemMeshPtr(); |
| | return new FemMeshPy(new FemMesh(mesh)); |
| | } |
| |
|
| | PyObject* FemMeshPy::read(PyObject* args) |
| | { |
| | char* Name; |
| | if (!PyArg_ParseTuple(args, "et", "utf-8", &Name)) { |
| | return nullptr; |
| | } |
| | std::string EncodedName = std::string(Name); |
| | PyMem_Free(Name); |
| |
|
| | try { |
| | getFemMeshPtr()->read(EncodedName.c_str()); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::write(PyObject* args) const |
| | { |
| | char* Name; |
| | if (!PyArg_ParseTuple(args, "et", "utf-8", &Name)) { |
| | return nullptr; |
| | } |
| | std::string EncodedName = std::string(Name); |
| | PyMem_Free(Name); |
| |
|
| | try { |
| | getFemMeshPtr()->write(EncodedName.c_str()); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | namespace |
| | { |
| |
|
| | std::map<std::string, ABAQUS_VolumeVariant> volVariantPyMap = { |
| | {"standard", ABAQUS_VolumeVariant::Standard}, |
| | {"reduced", ABAQUS_VolumeVariant::Reduced}, |
| | {"incompatible", ABAQUS_VolumeVariant::Incompatible}, |
| | {"modified", ABAQUS_VolumeVariant::Modified}, |
| | {"fluid", ABAQUS_VolumeVariant::Fluid} |
| | }; |
| |
|
| | std::map<std::string, ABAQUS_FaceVariant> faceVariantPyMap = { |
| | {"shell", ABAQUS_FaceVariant::Shell}, |
| | {"shell reduced", ABAQUS_FaceVariant::Shell_Reduced}, |
| | {"membrane", ABAQUS_FaceVariant::Membrane}, |
| | {"membrane reduced", ABAQUS_FaceVariant::Membrane_Reduced}, |
| | {"stress", ABAQUS_FaceVariant::Stress}, |
| | {"stress reduced", ABAQUS_FaceVariant::Stress_Reduced}, |
| | {"strain", ABAQUS_FaceVariant::Strain}, |
| | {"strain reduced", ABAQUS_FaceVariant::Strain_Reduced}, |
| | {"axisymmetric", ABAQUS_FaceVariant::Axisymmetric}, |
| | {"axisymmetric reduced", ABAQUS_FaceVariant::Axisymmetric_Reduced} |
| | }; |
| |
|
| | std::map<std::string, ABAQUS_EdgeVariant> edgeVariantPyMap = { |
| | {"beam", ABAQUS_EdgeVariant::Beam}, |
| | {"beam reduced", ABAQUS_EdgeVariant::Beam_Reduced}, |
| | {"truss", ABAQUS_EdgeVariant::Truss}, |
| | {"network", ABAQUS_EdgeVariant::Network} |
| | }; |
| |
|
| | } |
| |
|
| | PyObject* FemMeshPy::writeABAQUS(PyObject* args, PyObject* kwd) const |
| | { |
| | char* Name; |
| | int elemParam; |
| | PyObject* groupParam; |
| | const char* volVariant = "standard"; |
| | const char* faceVariant = "shell"; |
| | const char* edgeVariant = "beam"; |
| |
|
| | const std::array<const char*, 7> kwlist { |
| | "fileName", |
| | "elemParam", |
| | "groupParam", |
| | "volVariant", |
| | "faceVariant", |
| | "edgeVariant", |
| | nullptr |
| | }; |
| |
|
| | if (!Base::Wrapped_ParseTupleAndKeywords( |
| | args, |
| | kwd, |
| | "etiO!|sss", |
| | kwlist, |
| | "utf-8", |
| | &Name, |
| | &elemParam, |
| | &PyBool_Type, |
| | &groupParam, |
| | &volVariant, |
| | &faceVariant, |
| | &edgeVariant |
| | )) { |
| | return nullptr; |
| | } |
| |
|
| | std::string EncodedName = std::string(Name); |
| | PyMem_Free(Name); |
| | bool grpParam = Base::asBoolean(groupParam); |
| | auto itVol = volVariantPyMap.find(volVariant); |
| | auto itFace = faceVariantPyMap.find(faceVariant); |
| | auto itEdge = edgeVariantPyMap.find(edgeVariant); |
| |
|
| | if (itVol == volVariantPyMap.end() || itFace == faceVariantPyMap.end() |
| | || itEdge == edgeVariantPyMap.end()) { |
| | PyErr_SetString(PyExc_ValueError, "Invalid variant value"); |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | getFemMeshPtr()->writeABAQUS( |
| | EncodedName.c_str(), |
| | elemParam, |
| | grpParam, |
| | itVol->second, |
| | itFace->second, |
| | itEdge->second |
| | ); |
| | } |
| | catch (const std::exception& e) { |
| | PyErr_SetString(Base::PyExc_FC_GeneralError, e.what()); |
| | return nullptr; |
| | } |
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::setTransform(PyObject* args) |
| | { |
| | PyObject* ptr; |
| | if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &ptr)) { |
| | return nullptr; |
| | } |
| |
|
| | Base::Placement* placement = static_cast<Base::PlacementPy*>(ptr)->getPlacementPtr(); |
| | Base::Matrix4D mat = placement->toMatrix(); |
| | getFemMeshPtr()->transformGeometry(mat); |
| | Py_Return; |
| | } |
| |
|
| |
|
| | PyObject* FemMeshPy::getFacesByFace(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh = static_cast<Part::TopoShapeFacePy*>(pW)->getTopoShapePtr()->getShape(); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Face is empty"); |
| | return nullptr; |
| | } |
| |
|
| | const TopoDS_Face& fc = TopoDS::Face(sh); |
| |
|
| | Py::List ret; |
| | std::list<int> resultSet = getFemMeshPtr()->getFacesByFace(fc); |
| | for (std::list<int>::const_iterator it = resultSet.begin(); it != resultSet.end(); ++it) { |
| | ret.append(Py::Long(*it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| |
|
| | PyObject* FemMeshPy::getEdgesByEdge(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeEdgePy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh = static_cast<Part::TopoShapeEdgePy*>(pW)->getTopoShapePtr()->getShape(); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Edge is empty"); |
| | return nullptr; |
| | } |
| |
|
| | const TopoDS_Edge& fc = TopoDS::Edge(sh); |
| |
|
| | Py::List ret; |
| | std::list<int> resultSet = getFemMeshPtr()->getEdgesByEdge(fc); |
| | for (std::list<int>::const_iterator it = resultSet.begin(); it != resultSet.end(); ++it) { |
| | ret.append(Py::Long(*it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getVolumesByFace(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh = static_cast<Part::TopoShapeFacePy*>(pW)->getTopoShapePtr()->getShape(); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Face is empty"); |
| | return nullptr; |
| | } |
| |
|
| | const TopoDS_Face& fc = TopoDS::Face(sh); |
| |
|
| | Py::List ret; |
| | std::list<std::pair<int, int>> resultSet = getFemMeshPtr()->getVolumesByFace(fc); |
| | for (std::list<std::pair<int, int>>::const_iterator it = resultSet.begin(); |
| | it != resultSet.end(); |
| | ++it) { |
| | Py::Tuple vol_face(2); |
| | vol_face.setItem(0, Py::Long(it->first)); |
| | vol_face.setItem(1, Py::Long(it->second)); |
| | ret.append(vol_face); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getccxVolumesByFace(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh = static_cast<Part::TopoShapeFacePy*>(pW)->getTopoShapePtr()->getShape(); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Face is empty"); |
| | return nullptr; |
| | } |
| |
|
| | const TopoDS_Face& fc = TopoDS::Face(sh); |
| |
|
| | Py::List ret; |
| | std::map<int, int> resultSet = getFemMeshPtr()->getccxVolumesByFace(fc); |
| | for (std::map<int, int>::const_iterator it = resultSet.begin(); it != resultSet.end(); ++it) { |
| | Py::Tuple vol_face(2); |
| | vol_face.setItem(0, Py::Long(it->first)); |
| | vol_face.setItem(1, Py::Long(it->second)); |
| | ret.append(vol_face); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getNodeById(PyObject* args) const |
| | { |
| | int id; |
| | if (!PyArg_ParseTuple(args, "i", &id)) { |
| | return nullptr; |
| | } |
| |
|
| | Base::Matrix4D Mtrx = getFemMeshPtr()->getTransform(); |
| | const SMDS_MeshNode* aNode = getFemMeshPtr()->getSMesh()->GetMeshDS()->FindNode(id); |
| |
|
| | if (aNode) { |
| | Base::Vector3d vec(aNode->X(), aNode->Y(), aNode->Z()); |
| | vec = Mtrx * vec; |
| | return new Base::VectorPy(vec); |
| | } |
| | else { |
| | PyErr_SetString(PyExc_ValueError, "No valid node ID"); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getNodesBySolid(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeSolidPy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh |
| | = static_cast<Part::TopoShapeSolidPy*>(pW)->getTopoShapePtr()->getShape(); |
| | const TopoDS_Solid& fc = TopoDS::Solid(sh); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Solid is empty"); |
| | return nullptr; |
| | } |
| | Py::List ret; |
| | std::set<int> resultSet = getFemMeshPtr()->getNodesBySolid(fc); |
| | for (int it : resultSet) { |
| | ret.append(Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getNodesByFace(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeFacePy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh = static_cast<Part::TopoShapeFacePy*>(pW)->getTopoShapePtr()->getShape(); |
| | const TopoDS_Face& fc = TopoDS::Face(sh); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Face is empty"); |
| | return nullptr; |
| | } |
| | Py::List ret; |
| | std::set<int> resultSet = getFemMeshPtr()->getNodesByFace(fc); |
| | for (int it : resultSet) { |
| | ret.append(Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getNodesByEdge(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeEdgePy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh = static_cast<Part::TopoShapeEdgePy*>(pW)->getTopoShapePtr()->getShape(); |
| | const TopoDS_Edge& fc = TopoDS::Edge(sh); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Edge is empty"); |
| | return nullptr; |
| | } |
| | Py::List ret; |
| | std::set<int> resultSet = getFemMeshPtr()->getNodesByEdge(fc); |
| | for (int it : resultSet) { |
| | ret.append(Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getNodesByVertex(PyObject* args) const |
| | { |
| | PyObject* pW; |
| | if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapeVertexPy::Type), &pW)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | const TopoDS_Shape& sh |
| | = static_cast<Part::TopoShapeVertexPy*>(pW)->getTopoShapePtr()->getShape(); |
| | const TopoDS_Vertex& fc = TopoDS::Vertex(sh); |
| | if (sh.IsNull()) { |
| | PyErr_SetString(PyExc_ValueError, "Vertex is empty"); |
| | return nullptr; |
| | } |
| | Py::List ret; |
| | std::set<int> resultSet = getFemMeshPtr()->getNodesByVertex(fc); |
| | for (int it : resultSet) { |
| | ret.append(Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | PyObject* FemMeshPy::getElementNodes(PyObject* args) const |
| | { |
| | int id; |
| | if (!PyArg_ParseTuple(args, "i", &id)) { |
| | return nullptr; |
| | } |
| |
|
| | try { |
| | std::list<int> resultSet = getFemMeshPtr()->getElementNodes(id); |
| | Py::Tuple ret(resultSet.size()); |
| | int index = 0; |
| | for (std::list<int>::const_iterator it = resultSet.begin(); it != resultSet.end(); ++it) { |
| | ret.setItem(index++, Py::Long(*it)); |
| | } |
| |
|
| | return Py::new_reference_to(ret); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | using pairStrElemType = std::pair<std::string, SMDSAbs_ElementType>; |
| |
|
| | const std::vector<pairStrElemType> 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) const |
| | { |
| | 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<int> elemList = getFemMeshPtr()->getNodeElements(id, elemType); |
| | Py::Tuple result(elemList.size()); |
| | int index = 0; |
| | for (int it : elemList) { |
| | result.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(result); |
| | } |
| |
|
| | PyObject* FemMeshPy::getGroupName(PyObject* args) const |
| | { |
| | int id; |
| | if (!PyArg_ParseTuple(args, "i", &id)) { |
| | return nullptr; |
| | } |
| |
|
| | SMESH_Group* group = getFemMeshPtr()->getSMesh()->GetGroup(id); |
| | if (!group) { |
| | PyErr_SetString(PyExc_ValueError, "No group for given id"); |
| | return nullptr; |
| | } |
| | return PyUnicode_FromString(group->GetName()); |
| | } |
| |
|
| | PyObject* FemMeshPy::getGroupElementType(PyObject* args) const |
| | { |
| | int id; |
| | if (!PyArg_ParseTuple(args, "i", &id)) { |
| | return nullptr; |
| | } |
| |
|
| | SMESH_Group* group = getFemMeshPtr()->getSMesh()->GetGroup(id); |
| | if (!group) { |
| | PyErr_SetString(PyExc_ValueError, "No group for given id"); |
| | return nullptr; |
| | } |
| |
|
| | 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) const |
| | { |
| | int id; |
| | if (!PyArg_ParseTuple(args, "i", &id)) { |
| | return nullptr; |
| | } |
| |
|
| | SMESH_Group* group = getFemMeshPtr()->getSMesh()->GetGroup(id); |
| | if (!group) { |
| | PyErr_SetString(PyExc_ValueError, "No group for given id"); |
| | return nullptr; |
| | } |
| |
|
| | std::set<int> ids; |
| | SMDS_ElemIteratorPtr aElemIter = group->GetGroupDS()->GetElements(); |
| | while (aElemIter->more()) { |
| | const SMDS_MeshElement* aElement = aElemIter->next(); |
| | ids.insert(aElement->GetID()); |
| | } |
| |
|
| | Py::Tuple tuple(ids.size()); |
| | int index = 0; |
| | for (int it : ids) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(tuple); |
| | } |
| |
|
| | |
| | |
| | |
| |
|
| | PyObject* FemMeshPy::addGroup(PyObject* args) const |
| | { |
| | |
| | char* Name; |
| | char* typeString; |
| | int theId = -1; |
| | if (!PyArg_ParseTuple(args, "etet|i", "utf-8", &Name, "utf-8", &typeString, &theId)) { |
| | return nullptr; |
| | } |
| |
|
| | std::string EncodedName = std::string(Name); |
| | PyMem_Free(Name); |
| | std::string EncodedTypeString = std::string(typeString); |
| | PyMem_Free(typeString); |
| |
|
| | int retId = -1; |
| |
|
| | try { |
| | retId = getFemMeshPtr()->addGroup(EncodedTypeString, EncodedName, theId); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| | std::cout << "Added Group: Name: \'" << EncodedName << "\' Type: \'" << EncodedTypeString |
| | << "\' id: " << retId << std::endl; |
| |
|
| | return PyLong_FromLong(retId); |
| | } |
| |
|
| | PyObject* FemMeshPy::addGroupElements(PyObject* args) const |
| | { |
| | int id; |
| | |
| | |
| | |
| | PyObject* pList; |
| | PyObject* pItem; |
| | Py_ssize_t n; |
| |
|
| | if (!PyArg_ParseTuple(args, "iO!", &id, &PyList_Type, &pList)) { |
| | PyErr_SetString(PyExc_TypeError, "AddGroupElements: 2nd Parameter must be a list."); |
| | return nullptr; |
| | } |
| |
|
| | std::set<Py_ssize_t> ids; |
| | n = PyList_Size(pList); |
| | std::cout << "AddGroupElements: num elements: " << n << " sizeof: " << sizeof(n) << std::endl; |
| | for (Py_ssize_t i = 0; i < n; i++) { |
| | pItem = PyList_GetItem(pList, i); |
| | if (!PyLong_Check(pItem)) { |
| | PyErr_SetString(PyExc_TypeError, "AddGroupElements: List items must be integers."); |
| | return nullptr; |
| | } |
| | ids.insert(PyLong_AsSsize_t(pItem)); |
| | |
| | |
| | } |
| |
|
| | |
| | std::set<int> int_ids; |
| | for (Py_ssize_t it : ids) { |
| | int_ids.insert(Py_SAFE_DOWNCAST(it, Py_ssize_t, int)); |
| | } |
| |
|
| | try { |
| | getFemMeshPtr()->addGroupElements(id, int_ids); |
| | } |
| | catch (Standard_Failure& e) { |
| | PyErr_SetString(Base::PyExc_FC_CADKernelError, e.GetMessageString()); |
| | return nullptr; |
| | } |
| |
|
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::removeGroup(PyObject* args) const |
| | { |
| | int theId; |
| | if (!PyArg_ParseTuple(args, "i", &theId)) { |
| | return nullptr; |
| | } |
| | return PyBool_FromLong((long)(getFemMeshPtr()->removeGroup(theId))); |
| | } |
| |
|
| | PyObject* FemMeshPy::renameGroup(PyObject* args) const |
| | { |
| | int id; |
| | const char* name; |
| | if (!PyArg_ParseTuple(args, "is", &id, &name)) { |
| | return nullptr; |
| | } |
| |
|
| | getFemMeshPtr()->renameGroup(id, name); |
| |
|
| | Py_Return; |
| | } |
| |
|
| | PyObject* FemMeshPy::getElementType(PyObject* args) const |
| | { |
| | int id; |
| | if (!PyArg_ParseTuple(args, "i", &id)) { |
| | return nullptr; |
| | } |
| |
|
| | |
| | SMDSAbs_ElementType elemType = getFemMeshPtr()->getSMesh()->GetElementType(id, true); |
| | |
| | if (elemType == SMDSAbs_All) { |
| | elemType = getFemMeshPtr()->getSMesh()->GetElementType(id, false); |
| | } |
| |
|
| | 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(typeStr); |
| | } |
| |
|
| | PyObject* FemMeshPy::getIdByElementType(PyObject* args) const |
| | { |
| | const char* typeStr; |
| | if (!PyArg_ParseTuple(args, "s", &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::set<int> ids; |
| | SMDS_ElemIteratorPtr aElemIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->elementsIterator( |
| | elemType |
| | ); |
| | while (aElemIter->more()) { |
| | const SMDS_MeshElement* aElem = aElemIter->next(); |
| | ids.insert(aElem->GetID()); |
| | } |
| |
|
| | Py::Tuple tuple(ids.size()); |
| | int index = 0; |
| | for (int it : ids) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return Py::new_reference_to(tuple); |
| | } |
| |
|
| | |
| |
|
| | Py::Dict FemMeshPy::getNodes() const |
| | { |
| | |
| | |
| | Py::Dict dict; |
| |
|
| | |
| | Base::Matrix4D Mtrx = getFemMeshPtr()->getTransform(); |
| |
|
| | SMDS_NodeIteratorPtr aNodeIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator(); |
| | while (aNodeIter->more()) { |
| | const SMDS_MeshNode* aNode = aNodeIter->next(); |
| | Base::Vector3d vec(aNode->X(), aNode->Y(), aNode->Z()); |
| | |
| | vec = Mtrx * vec; |
| | int id = aNode->GetID(); |
| |
|
| | dict[Py::Long(id)] = Py::asObject(new Base::VectorPy(vec)); |
| | } |
| |
|
| | return dict; |
| | } |
| |
|
| | Py::Long FemMeshPy::getNodeCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbNodes()); |
| | } |
| |
|
| | Py::Tuple FemMeshPy::getEdges() const |
| | { |
| | std::set<int> ids; |
| | SMDS_EdgeIteratorPtr aEdgeIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->edgesIterator(); |
| | while (aEdgeIter->more()) { |
| | const SMDS_MeshEdge* aEdge = aEdgeIter->next(); |
| | ids.insert(aEdge->GetID()); |
| | } |
| |
|
| | Py::Tuple tuple(ids.size()); |
| | int index = 0; |
| | for (int it : ids) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return tuple; |
| | } |
| |
|
| | Py::Tuple FemMeshPy::getEdgesOnly() const |
| | { |
| | std::set<int> resultSet = getFemMeshPtr()->getEdgesOnly(); |
| | Py::Tuple tuple(resultSet.size()); |
| | int index = 0; |
| | for (int it : resultSet) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return tuple; |
| | } |
| |
|
| | Py::Long FemMeshPy::getEdgeCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbEdges()); |
| | } |
| |
|
| | Py::Tuple FemMeshPy::getFaces() const |
| | { |
| | std::set<int> ids; |
| | SMDS_FaceIteratorPtr aFaceIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->facesIterator(); |
| | while (aFaceIter->more()) { |
| | const SMDS_MeshFace* aFace = aFaceIter->next(); |
| | ids.insert(aFace->GetID()); |
| | } |
| |
|
| | Py::Tuple tuple(ids.size()); |
| | int index = 0; |
| | for (int it : ids) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return tuple; |
| | } |
| |
|
| | Py::Tuple FemMeshPy::getFacesOnly() const |
| | { |
| | std::set<int> resultSet = getFemMeshPtr()->getFacesOnly(); |
| | Py::Tuple tuple(resultSet.size()); |
| | int index = 0; |
| | for (int it : resultSet) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return tuple; |
| | } |
| |
|
| | Py::Long FemMeshPy::getFaceCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbFaces()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getTriangleCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbTriangles()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getQuadrangleCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbQuadrangles()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getPolygonCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbPolygons()); |
| | } |
| |
|
| | Py::Tuple FemMeshPy::getVolumes() const |
| | { |
| | std::set<int> ids; |
| | SMDS_VolumeIteratorPtr aVolIter = getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator(); |
| | while (aVolIter->more()) { |
| | const SMDS_MeshVolume* aVol = aVolIter->next(); |
| | ids.insert(aVol->GetID()); |
| | } |
| |
|
| | Py::Tuple tuple(ids.size()); |
| | int index = 0; |
| | for (int it : ids) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return tuple; |
| | } |
| |
|
| | Py::Long FemMeshPy::getVolumeCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbVolumes()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getTetraCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbTetras()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getHexaCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbHexas()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getPyramidCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbPyramids()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getPrismCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbPrisms()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getPolyhedronCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbPolyhedrons()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getSubMeshCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbSubMesh()); |
| | } |
| |
|
| | Py::Long FemMeshPy::getGroupCount() const |
| | { |
| | return Py::Long(getFemMeshPtr()->getSMesh()->NbGroup()); |
| | } |
| |
|
| | Py::Tuple FemMeshPy::getGroups() const |
| | { |
| | std::list<int> groupIDs = getFemMeshPtr()->getSMesh()->GetGroupIds(); |
| |
|
| | Py::Tuple tuple(groupIDs.size()); |
| | int index = 0; |
| | for (int it : groupIDs) { |
| | tuple.setItem(index++, Py::Long(it)); |
| | } |
| |
|
| | return tuple; |
| | } |
| |
|
| | Py::Object FemMeshPy::getVolume() const |
| | { |
| | return Py::asObject(new Base::QuantityPy(new Base::Quantity(getFemMeshPtr()->getVolume()))); |
| | } |
| |
|
| | |
| |
|
| | PyObject* FemMeshPy::getCustomAttributes(const char* ) const |
| | { |
| | return nullptr; |
| | } |
| |
|
| | int FemMeshPy::setCustomAttributes(const char* , PyObject* ) |
| | { |
| | return 0; |
| | } |
| |
|