/////////////////////////////////////////////////////////////////////////////// /// To be used with STL set /////////////////////////////////////////////////////////////////////////////// bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2) { return e1.getVtkId()<e2.getVtkId(); /*if(e1.myX<e2.myX) return true; else if(e1.myX==e2.myX) { if(e1.myY<e2.myY) return true; else if(e1.myY==e2.myY) return (e1.myZ<e2.myZ); else return false; } else return false;*/ }
PyObject* FemMeshPy::addNode(PyObject *args) { double x,y,z; if (!PyArg_ParseTuple(args, "ddd",&x,&y,&z)) return 0; 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::Int(node->GetID())); } catch (const std::exception& e) { PyErr_SetString(PyExc_Exception, e.what()); return 0; } }
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::Int(node->GetID())); } catch (const std::exception& e) { PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); return 0; } } 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::Int(node->GetID())); } catch (const std::exception& e) { PyErr_SetString(Base::BaseExceptionFreeCADError, e.what()); return 0; } } PyErr_SetString(PyExc_TypeError, "addNode() accepts:\n" "-- addNode(x,y,z)\n" "-- addNode(x,y,z,ElemId)\n"); return 0; }
/*! Create a volume (prism or hexahedron) by duplication of a face. * Designed for use in creation of flat elements separating volume domains. * A face separating two domains is shared by two volume cells. * All the nodes are already created (for the two faces). * Each original Node is associated to corresponding nodes in the domains. * Some nodes may be duplicated for more than two domains, when domain separations intersect. * In that case, even some of the nodes to use for the original face may be changed. * @param vtkVolId: vtk id of a volume containing the face, to get an orientation for the face. * @param domain1: domain of the original face * @param domain2: domain of the duplicated face * @param originalNodes: the vtk node ids of the original face * @param nodeDomains: map(original id --> map(domain --> duplicated node id)) * @return ok if success. */ SMDS_MeshCell* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2, std::set<int>& originalNodes, std::map<int, std::map<int, int> >& nodeDomains, std::map<int, std::map<long, int> >& nodeQuadDomains) { //MESSAGE("extrudeVolumeFromFace " << vtkVolId); vector<vtkIdType> orderedOriginals; orderedOriginals.clear(); set<int>::const_iterator it = originalNodes.begin(); for (; it != originalNodes.end(); ++it) orderedOriginals.push_back(*it); int dim = 0; int nbNodes = this->getOrderedNodesOfFace(vtkVolId, dim, orderedOriginals); vector<vtkIdType> orderedNodes; bool isQuadratic = false; switch (orderedOriginals.size()) { case 3: if (dim == 2) isQuadratic = true; break; case 6: case 8: isQuadratic = true; break; default: isQuadratic = false; break; } if (isQuadratic) { long dom1 = domain1; long dom2 = domain2; long dom1_2; // for nodeQuadDomains if (domain1 < domain2) dom1_2 = dom1 + INT_MAX * dom2; else dom1_2 = dom2 + INT_MAX * dom1; //cerr << "dom1=" << dom1 << " dom2=" << dom2 << " dom1_2=" << dom1_2 << endl; int ima = orderedOriginals.size(); int mid = orderedOriginals.size() / 2; //cerr << "ima=" << ima << " mid=" << mid << endl; for (int i = 0; i < mid; i++) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); for (int i = 0; i < mid; i++) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); for (int i = mid; i < ima; i++) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); for (int i = mid; i < ima; i++) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); for (int i = 0; i < mid; i++) { int oldId = orderedOriginals[i]; int newId; if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2)) newId = nodeQuadDomains[oldId][dom1_2]; else { double *coords = this->GetPoint(oldId); SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]); newId = newNode->getVtkId(); if (! nodeQuadDomains.count(oldId)) { std::map<long, int> emptyMap; nodeQuadDomains[oldId] = emptyMap; } nodeQuadDomains[oldId][dom1_2] = newId; } orderedNodes.push_back(newId); } } else { for (int i = 0; i < nbNodes; i++) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]); if (dim == 3) for (int i = 0; i < nbNodes; i++) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); else for (int i = nbNodes-1; i >= 0; i--) orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]); } if (dim == 3) { SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes); return vol; } else if (dim == 2) { SMDS_MeshFace *face = _mesh->AddFaceFromVtkIds(orderedNodes); return face; } // TODO update sub-shape list of elements and nodes return 0; }