Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////
/// 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;
}