Exemple #1
0
int GModel::readPLY(const std::string &name)
{
  // this is crazy!?
  replaceCommaByDot(name);

  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  std::vector<MVertex*> vertexVector;
  std::map<int, std::vector<MElement*> > elements[5];
  std::map<int, std::vector<double> > properties;

  char buffer[256], str[256], str2[256], str3[256];
  std::string s1;
  int elementary = getMaxElementaryNumber(-1) + 1;
  int nbv = 0, nbf = 0;
  int nbprop = 0;
  int nbView = 0;
  std::vector<std::string> propName;
  while(!feof(fp)) {
    if(!fgets(buffer, sizeof(buffer), fp)) break;
    if(buffer[0] != '#'){ // skip comments
      sscanf(buffer, "%s %s", str, str2);
      if(!strcmp(str, "element") && !strcmp(str2, "vertex")){
	sscanf(buffer, "%s %s %d", str, str2, &nbv);
      }
      if(!strcmp(str, "format") && strcmp(str2, "ascii")){
	Msg::Error("Only reading of ascii PLY files implemented");
        fclose(fp);
	return 0;
      }
      if(!strcmp(str, "property") && strcmp(str2, "list")){
	nbprop++;
	sscanf(buffer, "%s %s %s", str, str2, str3);
	if (nbprop > 3) propName.push_back(s1+str3);
      }
      if(!strcmp(str, "element") && !strcmp(str2, "face")){
	sscanf(buffer, "%s %s %d", str, str2, &nbf);
      }
      if(!strcmp(str, "end_header")){
	nbView = nbprop -3;
	Msg::Info("%d elements", nbv);
	Msg::Info("%d triangles", nbf);
	Msg::Info("%d properties", nbView);

	vertexVector.resize(nbv);
	for(int i = 0; i < nbv; i++) {
	  double x,y,z;
	  char line[10000], *pEnd, *pEnd2, *pEnd3;
	  if(!fgets(line, sizeof(line), fp)){ fclose(fp); return 0; }
	  x = strtod(line, &pEnd);
	  y = strtod(pEnd, &pEnd2);
	  z = strtod(pEnd2, &pEnd3);
	  vertexVector[i] = new MVertex(x, y, z);

	  pEnd = pEnd3;
          std::vector<double> prop(nbView);
	  for (int k = 0; k < nbView; k++){
	    prop[k]=strtod(pEnd, &pEnd2);
	    pEnd = pEnd2;
	    properties[k].push_back(prop[k]);
	  }
	}

	for(int i = 0; i < nbf; i++) {
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  int n[3], nbe;
	  sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]);
	  std::vector<MVertex*> vertices;
	  if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; }
	  elements[0][elementary].push_back(new MTriangle(vertices));
	}

      }

    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertexVector);

#if defined(HAVE_POST)
  // create PViews here
  std::vector<GEntity*> _entities;
  getEntities(_entities);
  for (int iV=0; iV< nbView; iV++){
    PView *view = new PView();
    PViewDataList *data = dynamic_cast<PViewDataList*>(view->getData());
    for(unsigned int ii = 0; ii < _entities.size(); ii++){
	for(unsigned int i = 0; i < _entities[ii]->getNumMeshElements(); i++){
	  MElement *e = _entities[ii]->getMeshElement(i);
	  int numNodes = e->getNumVertices();
	  std::vector<double> x(numNodes), y(numNodes), z(numNodes);
	  std::vector<double> *out = data->incrementList(1, e->getType());
	  for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->x());
	  for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->y());
	  for(int nod = 0; nod < numNodes; nod++) out->push_back((e->getVertex(nod))->z());
	  std::vector<double> props;
	  int n[3];
	  n[0] = e->getVertex(0)->getNum()-1;
	  n[1] = e->getVertex(1)->getNum()-1;
	  n[2] = e->getVertex(2)->getNum()-1;
	  if(!getProperties(3, n, properties[iV], props)){ fclose(fp); return 0; }
	  for(int nod = 0; nod < numNodes; nod++) out->push_back(props[nod]);
	}
    }
    data->setName(propName[iV]);
    data->Time.push_back(0);
    data->setFileName("property.pos");
    data->finalize();
  }
#endif

  fclose(fp);

  return 1;
}
Exemple #2
0
int GModel::readDIFF(const std::string &name)
{
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  char str[256] = "XXX";
  std::map<int, std::vector<MElement*> > elements[10];
  std::map<int, std::map<int, std::string> > physicals[4];
  std::map<int, MVertex*> vertexMap;
  std::vector<MVertex*> vertexVector;

  {
    while(strstr(str, "Number of space dim. =") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }

    int dim;
    if(sscanf(str, "%*s %*s %*s %*s %*s %d", &dim) != 1){ fclose(fp); return 0; }
    Msg::Info("dimension %d", dim);

    int numElements;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Number of elements   =") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%*s %*s %*s %*s %d", &numElements) != 1){ fclose(fp); return 0; }
    Msg::Info("%d elements", numElements);

    int numVertices;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Number of nodes      =") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%*s %*s %*s %*s %d", &numVertices) != 1){ fclose(fp); return 0; }
    Msg::Info("%d vertices", numVertices);

    int numVerticesPerElement;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Max number of nodes in an element:")==NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%*s %*s %*s %*s %*s %*s %*s %d", &numVerticesPerElement) != 1){
      fclose(fp);
      return 0;
    }
    Msg::Info("numVerticesPerElement %d", numVerticesPerElement);

    bool several_subdomains;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    if(!strncmp(&str[2], "Only one material", 17) ||
       !strncmp(&str[2], "Only one subdomain", 18)){
      if(!strncmp(&str[37], "dpTRUE", 6) || !strncmp(&str[37], "true", 4) ||
         !strncmp(&str[36], "dpTRUE", 6) || !strncmp(&str[36], "true", 4)){
        several_subdomains = false;
      }
      else{
        several_subdomains = true;
      }
      Msg::Info("several_subdomains %x %s", several_subdomains, str);
    }

    int nbi;
    std::vector<int> bi;
    if(!fgets(str, sizeof(str), fp) || feof(fp)){ fclose(fp); return 0; }
    while(strstr(str, "Boundary indicators:") == NULL &&
          strstr(str, "boundary indicators:") == NULL){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    if(sscanf(str, "%d %*s %*s", &nbi) != 1){ fclose(fp); return 0; }
    Msg::Info("nbi %d", nbi);
    if(nbi != 0)
      bi.resize(nbi);
    std::string format_read_bi = "%*d %*s %*s";
    for(int i = 0; i < nbi; i++){
      if(format_read_bi[format_read_bi.size()-1] == 'd') {
        format_read_bi[format_read_bi.size()-1] = '*';
        format_read_bi += "d %d";
      }
      else
        format_read_bi += " %d";
      if(sscanf(str, format_read_bi.c_str(), &bi[i]) != 1){ fclose(fp); return 0; }
      Msg::Info("bi[%d]=%d", i, bi[i]);
    }

    while(str[0] != '#'){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    vertexVector.clear();
    vertexMap.clear();
    int minVertex = numVertices + 1, maxVertex = -1;
    int num = 0;
    std::vector<std::vector<int> > elementary(numVertices);

    Msg::ResetProgressMeter();
    for(int i = 0; i < numVertices; i++){
      if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; }
      double xyz[3];
      int tmp;
      if(sscanf(str, "%d ( %lf , %lf , %lf ) [%d]", &num,
                &xyz[0], &xyz[1], &xyz[2], &tmp) != 5){ fclose(fp); return 0; }
      elementary[i].resize(tmp + 1);
      elementary[i][0] = tmp;
      minVertex = std::min(minVertex, num);
      maxVertex = std::max(maxVertex, num);
      if(vertexMap.count(num))
        Msg::Warning("Skipping duplicate vertex %d", num);
      else
        vertexMap[num] = new MVertex(xyz[0], xyz[1], xyz[2], 0, num);
      if(numVertices > 100000)
        Msg::ProgressMeter(i + 1, numVertices, true, "Reading nodes");
      // If the vertex numbering is dense, tranfer the map into a
      // vector to speed up element creation
      if((int)vertexMap.size() == numVertices &&
         ((minVertex == 1 && maxVertex == numVertices) ||
          (minVertex == 0 && maxVertex == numVertices - 1))){
        Msg::Info("Vertex numbering is dense");
        vertexVector.resize(vertexMap.size() + 1);
        if(minVertex == 1)
          vertexVector[0] = 0;
        else
          vertexVector[numVertices] = 0;
        std::map<int, MVertex*>::const_iterator it = vertexMap.begin();
        for(; it != vertexMap.end(); ++it)
          vertexVector[it->first] = it->second;
        vertexMap.clear();
      }
      Msg::Info("%d ( %lf , %lf , %lf ) [%d]",i, xyz[0], xyz[1], xyz[2],
                elementary[i][0]);
      std::string format_read_bi = "%*d ( %*lf , %*lf , %*lf ) [%*d]";
      for(int j = 0; j < elementary[i][0]; j++){
        if(format_read_bi[format_read_bi.size() - 1] == 'd') {
          format_read_bi[format_read_bi.size() - 1] = '*';
          format_read_bi += "d %d";
        }
        else
          format_read_bi += " %d";
        if(sscanf(str, format_read_bi.c_str(), &(elementary[i][j + 1])) != 1){
          fclose(fp);
          return 0;
        }
        Msg::Info("elementary[%d][%d]=%d", i + 1, j + 1, elementary[i][j + 1]);
      }
    }
    while(str[0] != '#'){
      if(!fgets(str, sizeof(str), fp) || feof(fp))
        break;
    }
    std::vector<int> material(numElements);
    std::vector<std::vector<int> > ElementsNodes(numElements);
    for(int i = 0; i < numElements; i++){
      ElementsNodes[i].resize(numVerticesPerElement);
    }
    char eleTypec[20]="";
    std::string eleType;
    Msg::ResetProgressMeter();
    std::vector<int> mapping;
    for(int i = 1; i <= numElements; i++){
      if(!fgets(str, sizeof(str), fp)){ fclose(fp); return 0; }
      int num = 0, type, physical = 0, partition = 0;
      int indices[60];
      if(sscanf(str, "%*d %s %d", eleTypec, &material[i-1]) != 2){ fclose(fp); return 0; }
      eleType = std::string(eleTypec);
      int k2; // local number for the element
      int NoVertices; // number of vertices per element
      if(eleType == "ElmT3n2D"){
        NoVertices = 3;
        static int map[3] = {0, 1, 2}; // identical to gmsh
        mapping=std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TRI_3;
      }
      else if(eleType == "ElmT6n2D"){
        NoVertices = 6;
        static int map[6] = {0, 1, 2, 3, 4, 5}; // identical to gmsh
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TRI_6;
      }
      else if(eleType == "ElmB4n2D"){
        NoVertices = 4;
        static int map[4] = {0, 1, 3, 2}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_QUA_4;
      }
      else if(eleType == "ElmB8n2D"){
        NoVertices = 8;
        static int map[8] = {0, 1, 3, 2, 4, 6, 7, 5}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_QUA_8;
      }
      else if(eleType == "ElmB9n2D"){
        NoVertices = 9;
        static int map[9] = {0, 4, 1, 7, 8, 5, 3, 6, 2}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_QUA_9;
      }
      else if(eleType == "ElmT4n3D"){
        NoVertices = 4;
        static int map[4] = {0, 1, 2, 3}; // identical to gmsh
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TET_4;
      }
      else if(eleType == "ElmT10n3D"){
        NoVertices = 10;
        static int map[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // local numbering
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_TET_10;
      }
      else if(eleType == "ElmB8n3D"){
        NoVertices = 8;
        static int map[8] = {4, 5, 0, 1, 7, 6, 3, 2};
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_HEX_8;
      }
      else if(eleType == "ElmB20n3D"){
        NoVertices = 20;
        static int map[20] = {4, 5, 0, 1, 7, 6, 3, 2, 16, 8, 19, 13, 15, 12,
                              14, 17, 18, 9, 11};
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_HEX_20;
      }
      else if(eleType == "ElmB27n3D"){
        NoVertices = 27;
        static int map[27] = {4, 16, 5, 10, 21, 12, 0, 8, 1, 17, 25, 18, 22,
                              26, 23, 9, 20, 11, 7, 19, 6, 15, 24, 14, 3, 13, 2};
        mapping = std::vector<int>(map, map + sizeof(map) / sizeof(int));
        type = MSH_HEX_27;
      }
      else{
        fclose(fp);
        return 0;
      }
      std::string format_read_vertices = "%*d %*s %*d";
      for(int k = 0; k < NoVertices; k++){
        if(format_read_vertices[format_read_vertices.size()-2] != '*') {
          format_read_vertices[format_read_vertices.size()-1] = '*';
          format_read_vertices += "d %d";
        }
        else
          format_read_vertices += " %d";
        k2 = mapping[k];
        if(sscanf(str, format_read_vertices.c_str(), &ElementsNodes[i-1][k2]) != 1){
          fclose(fp);
          return 0;
        }
      }
      mapping.clear();
      for(int j = 0; j < NoVertices; j++)
        indices[j] = ElementsNodes[i - 1][j];
      std::vector<MVertex*> vertices;
      if(vertexVector.size()){
        if(!getVertices(numVerticesPerElement, indices, vertexVector, vertices)){
          fclose(fp);
          return 0;
        }
      }
      else{
        if(!getVertices(numVerticesPerElement, indices, vertexMap, vertices)){
          fclose(fp);
          return 0;
        }
      }

      MElementFactory f;
      MElement *e = f.create(type, vertices, num, partition);
      if(!e){
        Msg::Error("Unknown type of element %d", type);
        fclose(fp);
        return 0;
      }
      int reg = elementary[i-1][1];
      switch(e->getType()){
      case TYPE_PNT : elements[0][reg].push_back(e); break;
      case TYPE_LIN : elements[1][reg].push_back(e); break;
      case TYPE_TRI : elements[2][reg].push_back(e); break;
      case TYPE_QUA : elements[3][reg].push_back(e); break;
      case TYPE_TET : elements[4][reg].push_back(e); break;
      case TYPE_HEX : elements[5][reg].push_back(e); break;
      case TYPE_PRI : elements[6][reg].push_back(e); break;
      case TYPE_PYR : elements[7][reg].push_back(e); break;
      default : Msg::Error("Wrong type of element"); fclose(fp); return 0;
      }
      int dim = e->getDim();
      if(physical && (!physicals[dim].count(reg) ||
                      !physicals[dim][reg].count(physical)))
        physicals[dim][reg][physical] = "unnamed";
      if(partition) getMeshPartitions().insert(partition);

      if(numElements > 100000)
        Msg::ProgressMeter(i + 1, numElements, true, "Reading elements");
    }
  }

  // store the elements in their associated elementary entity. If the
  // entity does not exist, create a new (discrete) one.
  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);

  // associate the correct geometrical entity with each mesh vertex
  _associateEntityWithMeshVertices();

  // store the vertices in their associated geometrical entity
  if(vertexVector.size())
    _storeVerticesInEntities(vertexVector);
  else
    _storeVerticesInEntities(vertexMap);

  // store the physical tags
  for(int i = 0; i < 4; i++)
    _storePhysicalTagsInEntities(i, physicals[i]);

  fclose(fp);
  return 1;
}
Exemple #3
0
int GModel::readSTL(const std::string &name, double tolerance)
{
  FILE *fp = Fopen(name.c_str(), "rb");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  // store triplets of points for each solid found in the file
  std::vector<std::vector<SPoint3> > points;
  SBoundingBox3d bbox;

  // "solid", or binary data header
  char buffer[256];
  if(!fgets(buffer, sizeof(buffer), fp)){ fclose(fp); return 0; }

  bool binary = strncmp(buffer, "solid", 5) && strncmp(buffer, "SOLID", 5);

  // ASCII STL
  if(!binary){
    points.resize(1);
    while(!feof(fp)) {
      // "facet normal x y z" or "endsolid"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      if(!strncmp(buffer, "endsolid", 8) ||
         !strncmp(buffer, "ENDSOLID", 8)){
        // "solid"
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        if(!strncmp(buffer, "solid", 5) ||
           !strncmp(buffer, "SOLID", 5)){
          points.resize(points.size() + 1);
          // "facet normal x y z"
          if(!fgets(buffer, sizeof(buffer), fp)) break;
        }
      }
      // "outer loop"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      // "vertex x y z"
      for(int i = 0; i < 3; i++){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        char s1[256];
        double x, y, z;
        if(sscanf(buffer, "%s %lf %lf %lf", s1, &x, &y, &z) != 4) break;
        SPoint3 p(x, y, z);
        points.back().push_back(p);
        bbox += p;
      }
      // "endloop"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      // "endfacet"
      if(!fgets(buffer, sizeof(buffer), fp)) break;
    }
   }

  // check if we could parse something
  bool empty = true;
  for(unsigned int i = 0; i < points.size(); i++){
    if(points[i].size()){
      empty = false;
      break;
    }
  }
  if(empty) points.clear();

  // binary STL (we also try to read in binary mode if the header told
  // us the format was ASCII but we could not read any vertices)
  if(binary || empty){
    if(binary)
      Msg::Info("Mesh is in binary format");
    else
      Msg::Info("Wrong ASCII header or empty file: trying binary read");
    rewind(fp);
    while(!feof(fp)) {
      char header[80];
      if(!fread(header, sizeof(char), 80, fp)) break;
      unsigned int nfacets = 0;
      size_t ret = fread(&nfacets, sizeof(unsigned int), 1, fp);
      bool swap = false;
      if(nfacets > 100000000){
        Msg::Info("Swapping bytes from binary file");
        swap = true;
        SwapBytes((char*)&nfacets, sizeof(unsigned int), 1);
      }
      if(ret && nfacets){
        points.resize(points.size() + 1);
        char *data = new char[nfacets * 50 * sizeof(char)];
        ret = fread(data, sizeof(char), nfacets * 50, fp);
        if(ret == nfacets * 50){
          for(unsigned int i = 0; i < nfacets; i++) {
            float *xyz = (float *)&data[i * 50 * sizeof(char)];
            if(swap) SwapBytes((char*)xyz, sizeof(float), 12);
            for(int j = 0; j < 3; j++){
              SPoint3 p(xyz[3 + 3 * j], xyz[3 + 3 * j + 1], xyz[3 + 3 * j + 2]);
              points.back().push_back(p);
              bbox += p;
            }
          }
        }
        delete [] data;
      }
    }
  }

  std::vector<GFace*> faces;
  for(unsigned int i = 0; i < points.size(); i++){
    if(points[i].empty()){
      Msg::Error("No facets found in STL file for solid %d", i);
      fclose(fp);
      return 0;
    }
    if(points[i].size() % 3){
      Msg::Error("Wrong number of points (%d) in STL file for solid %d",
                 points[i].size(), i);
      fclose(fp);
      return 0;
    }
    Msg::Info("%d facets in solid %d", points[i].size() / 3, i);
    // create face
    GFace *face = new discreteFace(this, getMaxElementaryNumber(2) + 1);
    faces.push_back(face);
    add(face);
  }

  // create triangles using unique vertices
  double eps = norm(SVector3(bbox.max(), bbox.min())) * tolerance;
  std::vector<MVertex*> vertices;
  for(unsigned int i = 0; i < points.size(); i++)
    for(unsigned int j = 0; j < points[i].size(); j++)
      vertices.push_back(new MVertex(points[i][j].x(), points[i][j].y(),
                                     points[i][j].z()));
  MVertexPositionSet pos(vertices);

  std::set<MFace,Less_Face> unique;
  int nbDuplic = 0;
  for(unsigned int i = 0; i < points.size(); i ++){
    for(unsigned int j = 0; j < points[i].size(); j += 3){
      MVertex *v[3];
      for(int k = 0; k < 3; k++){
        double x = points[i][j + k].x();
        double y = points[i][j + k].y();
        double z = points[i][j + k].z();
        v[k] = pos.find(x, y, z, eps);
      }
      MFace mf (v[0], v[1], v[2]);
      if (unique.find(mf) == unique.end()){
	faces[i]->triangles.push_back(new MTriangle(v[0], v[1], v[2]));
	unique.insert(mf);
      }
      else{
	nbDuplic++;
      }
    }
  }
  if (nbDuplic)
    Msg::Warning("%d duplicate triangles in STL file", nbDuplic);

  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertices); // will delete unused vertices

  fclose(fp);
  return 1;
}
Exemple #4
0
int GModel::readPLY2(const std::string &name)
{
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  std::vector<MVertex*> vertexVector;
  std::map<int, std::vector<MElement*> > elements[5];

  char buffer[256];
  int elementary = getMaxElementaryNumber(-1) + 1;
  int nbv, nbf;
  while(!feof(fp)) {
    if(!fgets(buffer, sizeof(buffer), fp)) break;
    if(buffer[0] != '#'){ // skip comments
      sscanf(buffer, "%d", &nbv);
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      sscanf(buffer, "%d", &nbf);
      Msg::Info("%d vertices", nbv);
      Msg::Info("%d triangles", nbf);
      vertexVector.resize(nbv);
      for(int i = 0; i < nbv; i++) {
	if(!fgets(buffer, sizeof(buffer), fp)) break;
	double x, y, z;
	int nb = sscanf(buffer, "%lf %lf %lf", &x, &y, &z);
	if (nb !=3){
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  sscanf(buffer, "%lf",  &y);
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  sscanf(buffer, "%lf",  &z);
	}
	vertexVector[i] = new MVertex(x, y, z);
      }
      for(int i = 0; i < nbf; i++) {
	if(!fgets(buffer, sizeof(buffer), fp)) break;
	int n[3], nbe;
	int nb = sscanf(buffer, "%d %d %d %d", &nbe, &n[0], &n[1], &n[2]);
	if (nb !=4){
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  sscanf(buffer, "%d",  &n[0]);
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  sscanf(buffer, "%d",  &n[1]);
	  if(!fgets(buffer, sizeof(buffer), fp)) break;
	  sscanf(buffer, "%d",  &n[2]);
	}
	std::vector<MVertex*> vertices;
	if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; }
	elements[0][elementary].push_back(new MTriangle(vertices));
      }
    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertexVector);

  fclose(fp);
  return 1;
}
Exemple #5
0
int GModel::readMESH(const std::string &name)
{
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  char buffer[256];
  if(!fgets(buffer, sizeof(buffer), fp)){ fclose(fp); return 0; }

  char str[256];
  int format;
  sscanf(buffer, "%s %d", str, &format);
  if(format == 3){
    Msg::Error("Medit mesh import only available for ASCII files");
    fclose(fp);
    return 0;
  }

  std::vector<MVertex*> vertexVector;
  std::map<int, std::vector<MElement*> > elements[5];

  while(!feof(fp)) {
    if(!fgets(buffer, 256, fp)) break;
    if(buffer[0] != '#'){ // skip comments and empty lines
      str[0]='\0';
      sscanf(buffer, "%s", str);
      if(!strcmp(str, "Dimension")){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
      }
      else if(!strcmp(str, "Vertices")){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbv;
        sscanf(buffer, "%d", &nbv);
        Msg::Info("%d vertices", nbv);
        vertexVector.resize(nbv);
        for(int i = 0; i < nbv; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int dum;
          double x, y, z;
          sscanf(buffer, "%lf %lf %lf %d", &x, &y, &z, &dum);
          vertexVector[i] = new MVertex(x, y, z);
        }
      }
      else if(!strcmp(str, "Edges")){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d edges", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[2], cl;
          sscanf(buffer, "%d %d %d", &n[0], &n[1], &cl);
          for(int j = 0; j < 2; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(2, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[0][cl].push_back(new MLine(vertices));
        }
      }
      else if(!strcmp(str, "EdgesP2")){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d edges", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[3], cl;
          sscanf(buffer, "%d %d %d %d", &n[0], &n[1], &n[2], &cl);
          for(int j = 0; j < 3; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[0][cl].push_back(new MLine3(vertices));
        }
      }
      else if(!strcmp(str, "Triangles")){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d triangles", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[3], cl;
          sscanf(buffer, "%d %d %d %d", &n[0], &n[1], &n[2], &cl);
          for(int j = 0; j < 3; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(3, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[1][cl].push_back(new MTriangle(vertices));
        }
      }
      else if(!strcmp(str, "TrianglesP2")){
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d triangles", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[6], cl;
          sscanf(buffer, "%d %d %d %d %d %d %d",
                 &n[0], &n[1], &n[2], &n[3], &n[4], &n[5], &cl);
          for(int j = 0; j < 6; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(6, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[1][cl].push_back(new MTriangle6(vertices));
        }
      }
      else if(!strcmp(str, "Quadrilaterals")) {
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d quadrangles", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[4], cl;
          sscanf(buffer, "%d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &cl);
          for(int j = 0; j < 4; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(4, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[2][cl].push_back(new MQuadrangle(vertices));
        }
      }
      else if(!strcmp(str, "Tetrahedra")) {
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d tetrahedra", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[4], cl;
          sscanf(buffer, "%d %d %d %d %d", &n[0], &n[1], &n[2], &n[3], &cl);
          for(int j = 0; j < 4; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(4, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[3][cl].push_back(new MTetrahedron(vertices));
        }
      }
      else if(!strcmp(str, "TetrahedraP2")) {
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d tetrahedra", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[10], cl;
          sscanf(buffer, "%d %d %d %d %d %d %d %d %d %d %d", &n[0], &n[1], &n[2],
                 &n[3],&n[4], &n[5], &n[6], &n[7], &n[9], &n[8], &cl);
          for(int j = 0; j < 10; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(10, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[3][cl].push_back(new MTetrahedron10(vertices));
        }
      }
      else if(!strcmp(str, "Hexahedra")) {
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int nbe;
        sscanf(buffer, "%d", &nbe);
        Msg::Info("%d hexahedra", nbe);
        for(int i = 0; i < nbe; i++) {
          if(!fgets(buffer, sizeof(buffer), fp)) break;
          int n[8], cl;
          sscanf(buffer, "%d %d %d %d %d %d %d %d %d", &n[0], &n[1], &n[2], &n[3],
                 &n[4], &n[5], &n[6], &n[7], &cl);
          for(int j = 0; j < 8; j++) n[j]--;
          std::vector<MVertex*> vertices;
          if(!getVertices(8, n, vertexVector, vertices)){ fclose(fp); return 0; }
          elements[4][cl].push_back(new MHexahedron(vertices));
        }
      }
    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertexVector);

  fclose(fp);
  return 1;
}
Exemple #6
0
int GModel::readMED(const std::string &name)
{
  med_idt fid = MEDouvrir((char*)name.c_str(), MED_LECTURE);
  if(fid < 0) {
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  med_int v[3], vf[3];
  MEDversionDonner(&v[0], &v[1], &v[2]);
  MEDversionLire(fid, &vf[0], &vf[1], &vf[2]);
  Msg::Info("Reading MED file V%d.%d.%d using MED library V%d.%d.%d",
            vf[0], vf[1], vf[2], v[0], v[1], v[2]);
  if(vf[0] < 2 || (vf[0] == 2 && vf[1] < 2)){
    Msg::Error("Cannot read MED file older than V2.2");
    return 0;
  }

  std::vector<std::string> meshNames;
  for(int i = 0; i < MEDnMaa(fid); i++){
    char meshName[MED_TAILLE_NOM + 1], meshDesc[MED_TAILLE_DESC + 1];
    med_int spaceDim;
    med_maillage meshType;
#if (MED_MAJOR_NUM == 3)
    med_int meshDim, nStep;
    char dtUnit[MED_SNAME_SIZE + 1];
    char axisName[3 * MED_SNAME_SIZE + 1], axisUnit[3 * MED_SNAME_SIZE + 1];
    med_sorting_type sortingType;
    med_axis_type axisType;
    if(MEDmeshInfo(fid, i + 1, meshName, &spaceDim, &meshDim, &meshType, meshDesc,
                   dtUnit, &sortingType, &nStep, &axisType, axisName, axisUnit) < 0){
#else
    if(MEDmaaInfo(fid, i + 1, meshName, &spaceDim, &meshType, meshDesc) < 0){
#endif
      Msg::Error("Unable to read mesh information");
      return 0;
    }
    meshNames.push_back(meshName);
  }

  if(MEDfermer(fid) < 0){
    Msg::Error("Unable to close file '%s'", (char*)name.c_str());
    return 0;
  }

  int ret = 1;
  for(unsigned int i = 0; i < meshNames.size(); i++){
    // we use the filename as a kind of "partition" indicator, allowing to
    // complete a model part by part (used e.g. in DDM, since MED does not store
    // a partition index)
    GModel *m = findByName(meshNames[i], name);
    if(!m) m = new GModel(meshNames[i]);
    ret = m->readMED(name, i);
    if(!ret) return 0;
  }
  return ret;
}

int GModel::readMED(const std::string &name, int meshIndex)
{
  med_idt fid = MEDouvrir((char*)name.c_str(), MED_LECTURE);
  if(fid < 0){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  int numMeshes = MEDnMaa(fid);
  if(meshIndex >= numMeshes){
    Msg::Info("Could not find mesh %d in MED file", meshIndex);
    return 0;
  }

  checkPointMaxNumbers();
  GModel::setCurrent(this); // make sure we increment max nums in this model

  // read mesh info
  char meshName[MED_TAILLE_NOM + 1], meshDesc[MED_TAILLE_DESC + 1];
  med_int spaceDim, nStep = 1;
  med_maillage meshType;
#if (MED_MAJOR_NUM == 3)
  med_int meshDim;
  char dtUnit[MED_SNAME_SIZE + 1];
  char axisName[3 * MED_SNAME_SIZE + 1], axisUnit[3 * MED_SNAME_SIZE + 1];
  med_sorting_type sortingType;
  med_axis_type axisType;
  if(MEDmeshInfo(fid, meshIndex + 1, meshName, &spaceDim, &meshDim, &meshType, meshDesc,
                 dtUnit, &sortingType, &nStep, &axisType, axisName, axisUnit) < 0){
#else
  if(MEDmaaInfo(fid, meshIndex + 1, meshName, &spaceDim, &meshType, meshDesc) < 0){
#endif
    Msg::Error("Unable to read mesh information");
    return 0;
  }

  // FIXME: we should support multi-step MED3 meshes (probably by
  // storing each mesh as a separate model, with a naming convention
  // e.g. meshName_step%d). This way we could also handle multi-mesh
  // time sequences in MED3.
  if(nStep > 1)
    Msg::Warning("Discarding %d last meshes in multi-step MED mesh", nStep - 1);

  setName(meshName);
  setFileName(name);
  if(meshType == MED_NON_STRUCTURE){
    Msg::Info("Reading %d-D unstructured mesh <<%s>>", spaceDim, meshName);
  }
  else{
    Msg::Error("Reading structured MED meshes is not supported");
    return 0;
  }
  med_int vf[3];
  MEDversionLire(fid, &vf[0], &vf[1], &vf[2]);

  // read nodes
#if (MED_MAJOR_NUM == 3)
  med_bool changeOfCoord, geoTransform;
  med_int numNodes = MEDmeshnEntity(fid, meshName, MED_NO_DT, MED_NO_IT, MED_NODE,
                                    MED_NO_GEOTYPE, MED_COORDINATE, MED_NO_CMODE,
                                    &changeOfCoord, &geoTransform);
#else
  med_int numNodes = MEDnEntMaa(fid, meshName, MED_COOR, MED_NOEUD, MED_NONE,
                                MED_NOD);
#endif
  if(numNodes < 0){
    Msg::Error("Could not read number of MED nodes");
    return 0;
  }
  if(numNodes == 0){
    Msg::Error("No nodes in MED mesh");
    return 0;
  }
  std::vector<MVertex*> verts(numNodes);
  std::vector<med_float> coord(spaceDim * numNodes);
#if (MED_MAJOR_NUM == 3)
  if(MEDmeshNodeCoordinateRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE,
                             &coord[0]) < 0){
#else
  std::vector<char> coordName(spaceDim * MED_TAILLE_PNOM + 1);
  std::vector<char> coordUnit(spaceDim * MED_TAILLE_PNOM + 1);
  med_repere rep;
  if(MEDcoordLire(fid, meshName, spaceDim, &coord[0], MED_FULL_INTERLACE,
                  MED_ALL, 0, 0, &rep, &coordName[0], &coordUnit[0]) < 0){
#endif
    Msg::Error("Could not read MED node coordinates");
    return 0;
  }

  std::vector<med_int> nodeTags(numNodes);
#if (MED_MAJOR_NUM == 3)
  if(MEDmeshEntityNumberRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_NODE,
                           MED_NO_GEOTYPE, &nodeTags[0]) < 0)
#else
  if(MEDnumLire(fid, meshName, &nodeTags[0], numNodes, MED_NOEUD, MED_NONE) < 0)
#endif
    nodeTags.clear();

  for(int i = 0; i < numNodes; i++)
    verts[i] = new MVertex(coord[spaceDim * i],
                           (spaceDim > 1) ? coord[spaceDim * i + 1] : 0.,
                           (spaceDim > 2) ? coord[spaceDim * i + 2] : 0.,
                           0, nodeTags.empty() ? 0 : nodeTags[i]);

  // read elements (loop over all possible MSH element types)
  for(int mshType = 0; mshType < MSH_NUM_TYPE; mshType++){
    med_geometrie_element type = msh2medElementType(mshType);
    if(type == MED_NONE) continue;
#if (MED_MAJOR_NUM == 3)
    med_bool changeOfCoord;
    med_bool geoTransform;
    med_int numEle = MEDmeshnEntity(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                                    type, MED_CONNECTIVITY, MED_NODAL, &changeOfCoord,
                                    &geoTransform);
#else
    med_int numEle = MEDnEntMaa(fid, meshName, MED_CONN, MED_MAILLE, type, MED_NOD);
#endif
    if(numEle <= 0) continue;
    int numNodPerEle = type % 100;
    std::vector<med_int> conn(numEle * numNodPerEle);
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshElementConnectivityRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                                    type, MED_NODAL, MED_FULL_INTERLACE, &conn[0]) < 0){
#else
    if(MEDconnLire(fid, meshName, spaceDim, &conn[0], MED_FULL_INTERLACE, 0, MED_ALL,
                   MED_MAILLE, type, MED_NOD) < 0){
#endif
      Msg::Error("Could not read MED elements");
      return 0;
    }
    std::vector<med_int> fam(numEle, 0);
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshEntityFamilyNumberRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                                   type, &fam[0]) < 0){
#else
    if(MEDfamLire(fid, meshName, &fam[0], numEle, MED_MAILLE, type) < 0){
#endif
      Msg::Info("No family number for elements: using 0 as default family number");
    }
    std::vector<med_int> eleTags(numEle);
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshEntityNumberRd(fid, meshName, MED_NO_DT, MED_NO_IT, MED_CELL,
                             type, &eleTags[0]) < 0)
#else
    if(MEDnumLire(fid, meshName, &eleTags[0], numEle, MED_MAILLE, type) < 0)
#endif
      eleTags.clear();
    std::map<int, std::vector<MElement*> > elements;
    MElementFactory factory;
    for(int j = 0; j < numEle; j++){
      std::vector<MVertex*> v(numNodPerEle);
      for(int k = 0; k < numNodPerEle; k++)
        v[k] = verts[conn[numNodPerEle * j + med2mshNodeIndex(type, k)] - 1];
      MElement *e = factory.create(mshType, v, eleTags.empty() ? 0 : eleTags[j]);
      if(e) elements[-fam[j]].push_back(e);
    }
    _storeElementsInEntities(elements);
  }
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(verts);

  // read family info
  med_int numFamilies = MEDnFam(fid, meshName);
  if(numFamilies < 0){
    Msg::Error("Could not read MED families");
    return 0;
  }
  for(int i = 0; i < numFamilies; i++){
#if (MED_MAJOR_NUM == 3)
    med_int numAttrib = (vf[0] == 2) ? MEDnFamily23Attribute(fid, meshName, i + 1) : 0;
    med_int numGroups = MEDnFamilyGroup(fid, meshName, i + 1);
#else
    med_int numAttrib = MEDnAttribut(fid, meshName, i + 1);
    med_int numGroups = MEDnGroupe(fid, meshName, i + 1);
#endif
    if(numAttrib < 0 || numGroups < 0){
      Msg::Error("Could not read MED groups or attributes");
      return 0;
    }
    std::vector<med_int> attribId(numAttrib + 1);
    std::vector<med_int> attribVal(numAttrib + 1);
    std::vector<char> attribDes(MED_TAILLE_DESC * numAttrib + 1);
    std::vector<char> groupNames(MED_TAILLE_LNOM * numGroups + 1);
    char familyName[MED_TAILLE_NOM + 1];
    med_int familyNum;
#if (MED_MAJOR_NUM == 3)
    if(vf[0] == 2){ // MED2 file
      if(MEDfamily23Info(fid, meshName, i + 1, familyName, &attribId[0],
                         &attribVal[0], &attribDes[0], &familyNum,
                         &groupNames[0]) < 0){
        Msg::Error("Could not read info for MED2 family %d", i + 1);
        continue;
      }
    }
    else{
      if(MEDfamilyInfo(fid, meshName, i + 1, familyName, &familyNum,
                       &groupNames[0]) < 0){
        Msg::Error("Could not read info for MED3 family %d", i + 1);
        continue;
      }
    }
#else
    if(MEDfamInfo(fid, meshName, i + 1, familyName, &familyNum, &attribId[0],
                  &attribVal[0], &attribDes[0], &numAttrib, &groupNames[0],
                  &numGroups) < 0){
      Msg::Error("Could not read info for MED family %d", i + 1);
      continue;
    }
#endif
    // family tags are unique (for all dimensions)
    GEntity *ge;
    if((ge = getRegionByTag(-familyNum))){}
    else if((ge = getFaceByTag(-familyNum))){}
    else if((ge = getEdgeByTag(-familyNum))){}
    else ge = getVertexByTag(-familyNum);
    if(ge){
      elementaryNames[std::pair<int, int>(ge->dim(), -familyNum)] = familyName;
      if(numGroups > 0){
        for(int j = 0; j < numGroups; j++){
          char tmp[MED_TAILLE_LNOM + 1];
          strncpy(tmp, &groupNames[j * MED_TAILLE_LNOM], MED_TAILLE_LNOM);
          tmp[MED_TAILLE_LNOM] = '\0';
          // don't use same physical number across dimensions, as e.g. getdp
          // does not support this
          int pnum = setPhysicalName(tmp, ge->dim(), getMaxPhysicalNumber(-1) + 1);
          if(std::find(ge->physicals.begin(), ge->physicals.end(), pnum) ==
             ge->physicals.end())
            ge->physicals.push_back(pnum);
        }
      }
    }
  }

  // check if we need to read some post-processing data later
#if (MED_MAJOR_NUM == 3)
  bool postpro = (MEDnField(fid) > 0) ? true : false;
#else
  bool postpro = (MEDnChamp(fid, 0) > 0) ? true : false;
#endif

  if(MEDfermer(fid) < 0){
    Msg::Error("Unable to close file '%s'", (char*)name.c_str());
    return 0;
  }

  return postpro ? 2 : 1;
}

template<class T>
static void fillElementsMED(med_int family, std::vector<T*> &elements,
                            std::vector<med_int> &conn, std::vector<med_int> &fam,
                            med_geometrie_element &type)
{
  if(elements.empty()) return;
  type = msh2medElementType(elements[0]->getTypeForMSH());
  if(type == MED_NONE){
    Msg::Warning("Unsupported element type in MED format");
    return;
  }
  for(unsigned int i = 0; i < elements.size(); i++){
    elements[i]->setVolumePositive();
    for(int j = 0; j < elements[i]->getNumVertices(); j++)
      conn.push_back(elements[i]->getVertex(med2mshNodeIndex(type, j))->getIndex());
    fam.push_back(family);
  }
}

static void writeElementsMED(med_idt &fid, char *meshName, std::vector<med_int> &conn,
                             std::vector<med_int> &fam, med_geometrie_element type)
{
  if(fam.empty()) return;
#if (MED_MAJOR_NUM == 3)
  if(MEDmeshElementWr(fid, meshName, MED_NO_DT, MED_NO_IT, 0., MED_CELL, type,
                      MED_NODAL, MED_FULL_INTERLACE, (med_int)fam.size(),
                      &conn[0], MED_FALSE, 0, MED_FALSE, 0, MED_TRUE, &fam[0]) < 0)
#else
  if(MEDelementsEcr(fid, meshName, (med_int)3, &conn[0], MED_FULL_INTERLACE,
                    0, MED_FAUX, 0, MED_FAUX, &fam[0], (med_int)fam.size(),
                    MED_MAILLE, type, MED_NOD) < 0)
#endif
    Msg::Error("Could not write MED elements");
}

int GModel::writeMED(const std::string &name, bool saveAll, double scalingFactor)
{
  med_idt fid = MEDouvrir((char*)name.c_str(), MED_CREATION);
  if(fid < 0){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  // write header
  if(MEDfichDesEcr(fid, (char*)"MED file generated by Gmsh") < 0){
    Msg::Error("Unable to write MED descriptor");
    return 0;
  }

  char *meshName = (char*)getName().c_str();

  // Gmsh always writes 3D unstructured meshes
#if (MED_MAJOR_NUM == 3)
  char dtUnit[MED_SNAME_SIZE + 1] = "";
  char axisName[3 * MED_SNAME_SIZE + 1] = "";
  char axisUnit[3 * MED_SNAME_SIZE + 1] = "";
  if(MEDmeshCr(fid, meshName, 3, 3, MED_UNSTRUCTURED_MESH, "Mesh created with Gmsh",
               dtUnit, MED_SORT_DTIT, MED_CARTESIAN, axisName, axisUnit) < 0){
#else
  if(MEDmaaCr(fid, meshName, 3, MED_NON_STRUCTURE,
              (char*)"Mesh created with Gmsh") < 0){
#endif
    Msg::Error("Could not create MED mesh");
    return 0;
  }

  // if there are no physicals we save all the elements
  if(noPhysicalGroups()) saveAll = true;

  // index the vertices we save in a continuous sequence (MED
  // connectivity is given in terms of vertex indices)
  indexMeshVertices(saveAll);

  // get a vector containing all the geometrical entities in the
  // model (the ordering of the entities must be the same as the one
  // used during the indexing of the vertices)
  std::vector<GEntity*> entities;
  getEntities(entities);

  std::map<GEntity*, int> families;
  // write the families
  {
    // always create a "0" family, with no groups or attributes
#if (MED_MAJOR_NUM == 3)
    if(MEDfamilyCr(fid, meshName, "F_0", 0, 0, "") < 0)
#else
    if(MEDfamCr(fid, meshName, (char*)"F_0", 0, 0, 0, 0, 0, 0, 0) < 0)
#endif
      Msg::Error("Could not create MED family 0");

    // create one family per elementary entity, with one group per
    // physical entity and no attributes
    for(unsigned int i = 0; i < entities.size(); i++){
      if(saveAll || entities[i]->physicals.size()){
        int num = - ((int)families.size() + 1);
        families[entities[i]] = num;
        std::ostringstream fs;
        fs << entities[i]->dim() << "D_" << entities[i]->tag();
        std::string familyName = "F_" + fs.str();
        std::string groupName;
        for(unsigned j = 0; j < entities[i]->physicals.size(); j++){
          std::string tmp = getPhysicalName
            (entities[i]->dim(), entities[i]->physicals[j]);
          if(tmp.empty()){ // create unique name
            std::ostringstream gs;
            gs << entities[i]->dim() << "D_" << entities[i]->physicals[j];
            groupName += "G_" + gs.str();
          }
          else
            groupName += tmp;
          groupName.resize((j + 1) * MED_TAILLE_LNOM, ' ');
        }
#if (MED_MAJOR_NUM == 3)
        if(MEDfamilyCr(fid, meshName, familyName.c_str(),
                       (med_int)num, (med_int)entities[i]->physicals.size(),
                       groupName.c_str()) < 0)
#else
        if(MEDfamCr(fid, meshName, (char*)familyName.c_str(),
                    (med_int)num, 0, 0, 0, 0, (char*)groupName.c_str(),
                    (med_int)entities[i]->physicals.size()) < 0)
#endif
          Msg::Error("Could not create MED family %d", num);
      }
    }
  }

  // write the nodes
  {
    std::vector<med_float> coord;
    std::vector<med_int> fam;
    for(unsigned int i = 0; i < entities.size(); i++){
      for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
        MVertex *v = entities[i]->mesh_vertices[j];
        if(v->getIndex() >= 0){
          coord.push_back(v->x() * scalingFactor);
          coord.push_back(v->y() * scalingFactor);
          coord.push_back(v->z() * scalingFactor);
          fam.push_back(0); // we never create node families
        }
      }
    }
    if(fam.empty()){
      Msg::Error("No nodes to write in MED mesh");
      return 0;
    }
#if (MED_MAJOR_NUM == 3)
    if(MEDmeshNodeWr(fid, meshName, MED_NO_DT, MED_NO_IT, 0., MED_FULL_INTERLACE,
                     (med_int)fam.size(), &coord[0], MED_FALSE, "", MED_FALSE, 0,
                     MED_TRUE, &fam[0]) < 0)
#else
    char coordName[3 * MED_TAILLE_PNOM + 1] =
      "x               y               z               ";
    char coordUnit[3 * MED_TAILLE_PNOM + 1] =
      "unknown         unknown         unknown         ";
    if(MEDnoeudsEcr(fid, meshName, (med_int)3, &coord[0], MED_FULL_INTERLACE,
                    MED_CART, coordName, coordUnit, 0, MED_FAUX, 0, MED_FAUX,
                    &fam[0], (med_int)fam.size()) < 0)
#endif
      Msg::Error("Could not write nodes");
  }

  // write the elements
  {
    { // points
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(viter it = firstVertex(); it != lastVertex(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->points, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // lines
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(eiter it = firstEdge(); it != lastEdge(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->lines, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // triangles
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(fiter it = firstFace(); it != lastFace(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->triangles, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // quads
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(fiter it = firstFace(); it != lastFace(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->quadrangles, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // tets
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->tetrahedra, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // hexas
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->hexahedra, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // prisms
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->prisms, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
    { // pyramids
      med_geometrie_element typ = MED_NONE;
      std::vector<med_int> conn, fam;
      for(riter it = firstRegion(); it != lastRegion(); it++)
        if(saveAll || (*it)->physicals.size())
          fillElementsMED(families[*it], (*it)->pyramids, conn, fam, typ);
      writeElementsMED(fid, meshName, conn, fam, typ);
    }
  }

  if(MEDfermer(fid) < 0){
    Msg::Error("Unable to close file '%s'", (char*)name.c_str());
    return 0;
  }

  return 1;
}

#else

int GModel::readMED(const std::string &name)
{
  Msg::Error("Gmsh must be compiled with MED support to read '%s'",
             name.c_str());
  return 0;
}
Exemple #7
0
int GModel::readGEOM(const std::string &name)
{
  // this is a format (from geomview?) that Bruno Levy's Graphite code
  // can write
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  int numNodes, numElements, dummy;
  if(fscanf(fp, "%d %d %d", &numNodes, &numElements, &dummy) != 3){
    fclose(fp);
    return 0;
  }

  if(!numNodes || !numElements){
    Msg::Warning("No vertices or elements found");
    fclose(fp);
    return 0;
  }

  Msg::Info("%d vertices, %d elements", numNodes, numElements);

  std::vector<MVertex*> vertexVector;
  std::map<int, std::vector<MElement*> > elements[1];

  vertexVector.resize(numNodes);
  for(int i = 0; i < numNodes; i++) {
    double x, y, z;
    if(fscanf(fp, "%lf %lf %lf", &x, &y, &z) != 3) break;
    vertexVector[i] = new MVertex(x, y, z);
  }

  for(int i = 0; i < numElements; i++) {
    int N, n[3];
    if(fscanf(fp, "%d", &N) != 1) break;
    switch(N){
    case 3:
      {
        if(fscanf(fp, "%d %d %d", &n[0], &n[1], &n[2]) != 3) break;
        for(int i = 0; i < 3; i++) n[i]--;
        std::vector<MVertex*> vertices;
        if(!getVertices(3, n, vertexVector, vertices)) break;
        elements[0][1].push_back(new MTriangle(vertices));
      }
      break;
    default:
      Msg::Error("Unknown element type in .geom reader");
      break;
    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertexVector);

  fclose(fp);
  return 1;
}
Exemple #8
0
int GModel::readBDF(const std::string &name)
{
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  char buffer[256];
  std::map<int, MVertex*> vertexMap;
  std::map<int, std::vector<MElement*> > elements[7];

  // nodes can be defined after elements, so parse the file twice

  while(!feof(fp)) {
    for(unsigned int i = 0; i < sizeof(buffer); i++) buffer[i] = '\0';
    if(!fgets(buffer, sizeof(buffer), fp)) break;
    if(buffer[0] != '$'){ // skip comments
      if(!strncmp(buffer, "GRID", 4)){
        int num;
        double x, y, z;
        if(!readVertexBDF(fp, buffer, 4, &num, &x, &y, &z)) break;
        vertexMap[num] = new MVertex(x, y, z, 0, num);
      }
    }
  }
  Msg::Info("%d vertices", vertexMap.size());

  rewind(fp);
  while(!feof(fp)) {
    for(unsigned int i = 0; i < sizeof(buffer); i++) buffer[i] = '\0';
    if(!fgets(buffer, sizeof(buffer), fp)) break;
    if(buffer[0] != '$'){ // skip comments
      int num, region;
      std::vector<MVertex*> vertices;
      if(!strncmp(buffer, "CBAR", 4)){
        if(readElementBDF(fp, buffer, 4, 2, num, region, vertices, vertexMap))
          elements[0][region].push_back(new MLine(vertices, num));
      }
      else if(!strncmp(buffer, "CROD", 4)){
        if(readElementBDF(fp, buffer, 4, 2, num, region, vertices, vertexMap))
          elements[0][region].push_back(new MLine(vertices, num));
      }
      else if(!strncmp(buffer, "CBEAM", 5)){
        if(readElementBDF(fp, buffer, 5, 2, num, region, vertices, vertexMap))
          elements[0][region].push_back(new MLine(vertices, num));
      }
      else if(!strncmp(buffer, "CTRIA3", 6)){
        if(readElementBDF(fp, buffer, 6, 3, num, region, vertices, vertexMap))
          elements[1][region].push_back(new MTriangle(vertices, num));
      }
      else if(!strncmp(buffer, "CTRIA6", 6)){
        if(readElementBDF(fp, buffer, 6, 6, num, region, vertices, vertexMap))
          elements[1][region].push_back(new MTriangle6(vertices, num));
      }
      else if(!strncmp(buffer, "CQUAD4", 6)){
        if(readElementBDF(fp, buffer, 6, 4, num, region, vertices, vertexMap))
          elements[2][region].push_back(new MQuadrangle(vertices, num));
      }
      else if(!strncmp(buffer, "CQUAD8", 6)){
        if(readElementBDF(fp, buffer, 6, 8, num, region, vertices, vertexMap))
          elements[2][region].push_back(new MQuadrangle8(vertices, num));
      }
      else if(!strncmp(buffer, "CQUAD", 5)){
        if(readElementBDF(fp, buffer, 5, -4, num, region, vertices, vertexMap)){
          if(vertices.size() == 9)
            elements[2][region].push_back(new MQuadrangle9(vertices, num));
          else if(vertices.size() == 8)
            elements[2][region].push_back(new MQuadrangle8(vertices, num));
          else
            elements[2][region].push_back(new MQuadrangle(vertices, num));
        }
      }
      else if(!strncmp(buffer, "CTETRA", 6)){
        if(readElementBDF(fp, buffer, 6, -4, num, region, vertices, vertexMap)){
          if(vertices.size() == 10)
            elements[3][region].push_back
              (new MTetrahedron10(vertices[0], vertices[1], vertices[2], vertices[3],
                                  vertices[4], vertices[5], vertices[6], vertices[7],
                                  vertices[9], vertices[8], num));
          else
            elements[3][region].push_back(new MTetrahedron(vertices, num));
        }
      }
      else if(!strncmp(buffer, "CHEXA", 5)){
        if(readElementBDF(fp, buffer, 5, -8, num, region, vertices, vertexMap)){
          if(vertices.size() == 20)
            elements[4][region].push_back
              (new MHexahedron20(vertices[0], vertices[1], vertices[2], vertices[3],
                                 vertices[4], vertices[5], vertices[6], vertices[7],
                                 vertices[8], vertices[11], vertices[12], vertices[9],
                                 vertices[13], vertices[10], vertices[14], vertices[15],
                                 vertices[16], vertices[19], vertices[17], vertices[18],
                                 num));
          else
            elements[4][region].push_back(new MHexahedron(vertices, num));
        }
      }
      else if(!strncmp(buffer, "CPENTA", 6)){
        if(readElementBDF(fp, buffer, 6, -6, num, region, vertices, vertexMap)){
          if(vertices.size() == 15)
            elements[5][region].push_back
              (new MPrism15(vertices[0], vertices[1], vertices[2], vertices[3],
                            vertices[4], vertices[5], vertices[6], vertices[8],
                            vertices[9], vertices[7], vertices[10], vertices[11],
                            vertices[12], vertices[14], vertices[13], num));
          else
            elements[5][region].push_back(new MPrism(vertices, num));
        }
      }
      else if(!strncmp(buffer, "CPYRAM", 6)){
        if(readElementBDF(fp, buffer, 6, 5, num, region, vertices, vertexMap))
          elements[6][region].push_back(new MPyramid(vertices, num));
      }
    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(vertexMap);

  fclose(fp);
  return 1;
}
int GModel::readACTRAN(const std::string &name)
{
  FILE *fp = Fopen(name.c_str(), "r");
  if(!fp){
    Msg::Error("Unable to open file '%s'", name.c_str());
    return 0;
  }

  char buffer[256];
  if(!fgets(buffer, sizeof(buffer), fp)){ fclose(fp); return 0; }

  if(strncmp(buffer, "BEGIN ACTRAN", 12)){
    Msg::Error("Did not find ACTRAN header");
    fclose(fp); return 0;
  }

  _vertexMapCache.clear();
  std::map<int, std::vector<MElement*> > elements[3];
  int nbv = 0, nbe = 0, dim = 0;

  while(!feof(fp)) {
    if(!fgets(buffer, 256, fp)) break;
    char str[256], str2[256];
    sscanf(buffer, "%s %s", str, str2);
    if(!strcmp(str, "BEGIN") && !strcmp(str2, "MESH")){
      if(!fgets(buffer, sizeof(buffer), fp)) break;
      sscanf(buffer, "%d %d %d", &nbv, &nbe, &dim);
      if(dim == 3 || dim == 2)
        Msg::Info("ACTRAN mesh dimension %d", dim);
      else{
        Msg::Error("Cannot read ACTRAN mesh of dimension %d", dim);
        break;
      }
    }
    else if(!strcmp(str, "BEGIN") && !strcmp(str2, "NODE")){
      Msg::Info("%d vertices", nbv);
      for(int i = 0; i < nbv; i++) {
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int num;
        double x, y, z = 0.;
        if(dim == 3)
          sscanf(buffer, "%d %lf %lf %lf", &num, &x, &y, &z);
        else
          sscanf(buffer, "%d %lf %lf", &num, &x, &y);
        _vertexMapCache[num] = new MVertex(x, y, z, 0, num);
      }
    }
    else if(!strcmp(str, "BEGIN") && !strcmp(str2, "ELEMENT")){
      Msg::Info("%d elements", nbe);
      for(int i = 0; i < nbe; i++) {
        if(!fgets(buffer, sizeof(buffer), fp)) break;
        int num, type, reg, n[8];
        sscanf(buffer, "%d %d %d", &num, &type, &reg);
        std::vector<MVertex*> vertices;
        if(type == 2){
          sscanf(buffer, "%d %d %d %d %d", &num, &type, &reg,
                 &n[0], &n[1]);
          if(!getVertices(this, 2, n, vertices)) break;
          elements[0][reg].push_back(new MLine(vertices, num));
        }
        else if(type == 4){
          sscanf(buffer, "%d %d %d %d %d %d", &num, &type, &reg,
                 &n[0], &n[1], &n[2]);
          if(!getVertices(this, 3, n, vertices)) break;
          elements[0][reg].push_back(new MTriangle(vertices, num));
        }
        else if(type == 8){
          sscanf(buffer, "%d %d %d %d %d %d %d", &num, &type, &reg,
                 &n[0], &n[1], &n[2], &n[3]);
          if(!getVertices(this, 4, n, vertices)) break;
          elements[1][reg].push_back(new MTetrahedron(vertices, num));
        }
        else{
          Msg::Error("Unknown type %d for element %d", type, num);
        }
      }
    }
  }

  for(int i = 0; i < (int)(sizeof(elements) / sizeof(elements[0])); i++)
    _storeElementsInEntities(elements[i]);
  _associateEntityWithMeshVertices();
  _storeVerticesInEntities(_vertexMapCache);

  fclose(fp);
  return 1;
}