Ejemplo n.º 1
0
int		save_args(t_main *data, int argv, char **argc)
{
	int		k;
	int		l;
	int		m;
	char	**nums;

	INIT_VAR;
	if (!(int_data(data)))
		return (0);
	while (++k < argv)
	{
		if (!ft_strcmp(argc[k], "-v") || !ft_strcmp(argc[k], "-c"))
			continue ;
		l = -1;
		nums = ft_strsplit(argc[k], ' ');
		while (nums[++l])
		{
			L_A[m] = ft_atoi(nums[l]);
			m++;
		}
		while (--l >= 0)
			free(nums[l]);
		free(nums);
	}
	S_A = m;
	return (1);
}
Ejemplo n.º 2
0
ErrorCode ReadGmsh::load_file(const char* filename,
                              const EntityHandle*,
                              const FileOptions&,
                              const ReaderIface::SubsetList* subset_list,
                              const Tag* file_id_tag)
{
  int num_material_sets = 0;
  const int* material_set_list = 0;
  int zero = 0;
  if (subset_list) {
    if (subset_list->tag_list_length > 1 && 
        !strcmp(subset_list->tag_list[0].tag_name, MATERIAL_SET_TAG_NAME)) {
      MB_SET_ERR(MB_UNSUPPORTED_OPERATION, "GMsh supports subset read only by material ID");
    }
    material_set_list = subset_list->tag_list[0].tag_values;
    num_material_sets = subset_list->tag_list[0].num_tag_values;
  }

  geomSets.clear();
  ErrorCode result = mdbImpl->tag_get_handle(GLOBAL_ID_TAG_NAME, 1, MB_TYPE_INTEGER,
                                             globalId, MB_TAG_DENSE | MB_TAG_CREAT, &zero);
  if (MB_SUCCESS != result)
    return result;

  // Create set for more convenient check for material set ids
  std::set<int> blocks;
  for (const int* mat_set_end = material_set_list + num_material_sets;
       material_set_list != mat_set_end; ++material_set_list)
    blocks.insert(*material_set_list);
  
  // Map of ID->handle for nodes
  std::map<long, EntityHandle> node_id_map;
  int data_size = 8;

  // Open file and hand off pointer to tokenizer
  FILE* file_ptr = fopen(filename, "r");
  if (!file_ptr) {
    MB_SET_ERR(MB_FILE_DOES_NOT_EXIST, filename << ": " << strerror(errno));
  }
  FileTokenizer tokens(file_ptr, readMeshIface);

  // Determine file format version
  const char* const start_tokens[] = {"$NOD", "$MeshFormat", 0};
  int format_version = tokens.match_token(start_tokens);
  if (!format_version)
    return MB_FILE_DOES_NOT_EXIST;

  // If version 2.0, read additional header info
  if (2 == format_version) {
    double version;
    if (!tokens.get_doubles(1, &version))
      return MB_FILE_WRITE_ERROR;

    if (version != 2.0 && version != 2.1 && version != 2.2) {
      MB_SET_ERR(MB_FILE_DOES_NOT_EXIST, filename << ": unknown format version: " << version);
      return MB_FILE_DOES_NOT_EXIST;
    }

    int file_format;
    if (!tokens.get_integers(1, &file_format) || !tokens.get_integers(1,
        &data_size) || !tokens.match_token("$EndMeshFormat"))
           return MB_FILE_WRITE_ERROR;
           // If physical entities in the gmsh file -> discard this
    const char* const phys_tokens[] = { "$Nodes", "$PhysicalNames", 0 };
    int hasPhys = tokens.match_token(phys_tokens);

    if (hasPhys == 2) {
      long num_phys;
      if (!tokens.get_long_ints(1, &num_phys))
        return MB_FILE_WRITE_ERROR;
      for (long loop_phys = 0; loop_phys < num_phys; loop_phys++) {
        long physDim;
        long physGroupNum;
        //char const * physName;
        if (!tokens.get_long_ints(1, &physDim))
          return MB_FILE_WRITE_ERROR;
        if (!tokens.get_long_ints(1, &physGroupNum))
          return MB_FILE_WRITE_ERROR;
        const char * ptc = tokens.get_string();
        if (!ptc)
          return MB_FILE_WRITE_ERROR;
        // try to get to the end of the line, without reporting errors
        // really, we need to skip this
        while(!tokens.get_newline(false))
          ptc = tokens.get_string();
      }
      if (!tokens.match_token("$EndPhysicalNames") || !tokens.match_token(
          "$Nodes"))
        return MB_FILE_WRITE_ERROR;
    }
  }

  // Read number of nodes
  long num_nodes;
  if (!tokens.get_long_ints(1, &num_nodes))
    return MB_FILE_WRITE_ERROR;

  // Allocate nodes
  std::vector<double*> coord_arrays;
  EntityHandle handle = 0;
  result = readMeshIface->get_node_coords(3, num_nodes, MB_START_ID,
                                          handle, coord_arrays);
  if (MB_SUCCESS != result)
    return result;

  // Read nodes
  double *x = coord_arrays[0],
         *y = coord_arrays[1],
         *z = coord_arrays[2];
  for (long i = 0; i < num_nodes; ++i, ++handle) {
    long id;
    if (!tokens.get_long_ints(1, &id) ||
        !tokens.get_doubles(1, x++) ||
        !tokens.get_doubles(1, y++) ||
        !tokens.get_doubles(1, z++))
      return MB_FILE_WRITE_ERROR;

    if (!node_id_map.insert(std::pair<long, EntityHandle>(id, handle)).second) {
      MB_SET_ERR(MB_FILE_WRITE_ERROR, "Duplicate node ID at line " << tokens.line_number());
    }
  }

  // Create reverse map from handle to id
  std::vector<int> ids(num_nodes);
  std::vector<int>::iterator id_iter = ids.begin();
  std::vector<EntityHandle> handles(num_nodes);
  std::vector<EntityHandle>::iterator h_iter = handles.begin();
  for (std::map<long, EntityHandle>::iterator i = node_id_map.begin();
      i != node_id_map.end(); ++i, ++id_iter, ++h_iter) {
    *id_iter = i->first;
    * h_iter = i->second;
  }
  // Store IDs in tags
  result = mdbImpl->tag_set_data(globalId, &handles[0], num_nodes, &ids[0]);
  if (MB_SUCCESS != result)
    return result;
  if (file_id_tag) {
    result = mdbImpl->tag_set_data(*file_id_tag, &handles[0], num_nodes, &ids[0]);
    if (MB_SUCCESS != result) 
      return result;
  }
  ids.clear();
  handles.clear();

  // Get tokens signifying end of node data and start of elements
  if (!tokens.match_token(format_version == 1 ? "$ENDNOD" : "$EndNodes") ||
      !tokens.match_token(format_version == 1 ? "$ELM" : "$Elements"))
    return MB_FILE_WRITE_ERROR;

  // Get element count
  long num_elem;
  if (!tokens.get_long_ints(1, &num_elem))
    return MB_FILE_WRITE_ERROR;

  // Lists of data accumulated for elements
  std::vector<EntityHandle> connectivity;
  std::vector<int> mat_set_list, geom_set_list, part_set_list, id_list;
  // Temporary, per-element data
  std::vector<int> int_data(5), tag_data(2);
  std::vector<long> tmp_conn;
  int curr_elem_type = -1;
  for (long i = 0; i < num_elem; ++i) {
    // Read element description
    // File format 1.0
    if (1 == format_version) {
      if (!tokens.get_integers(5, &int_data[0]))
        return MB_FILE_WRITE_ERROR;
      tag_data[0] = int_data[2];
      tag_data[1] = int_data[3];
      if ((unsigned)tag_data[1] < GmshUtil::numGmshElemType &&
           GmshUtil::gmshElemTypes[tag_data[1]].num_nodes != (unsigned)int_data[4]) {
        MB_SET_ERR(MB_FILE_WRITE_ERROR, "Invalid node count for element type at line " << tokens.line_number());
      }
    }
    // File format 2.0
    else {
      if (!tokens.get_integers(3, &int_data[0]))
        return MB_FILE_WRITE_ERROR;
      tag_data.resize(int_data[2]);
      if (!tokens.get_integers(tag_data.size(), &tag_data[0]))
        return MB_FILE_WRITE_ERROR;
    }

    // If a list of material sets was specified in the
    // argument list, skip any elements for which the
    // material set is not specified or is not in the
    // passed list.
    if (!blocks.empty() && (tag_data.empty() ||
        blocks.find(tag_data[0]) != blocks.end()))
      continue;

    // If the next element is not the same type as the last one,
    // create a sequence for the block of elements we've read
    // to this point (all of the same type), and clear accumulated
    // data.
    if (int_data[1] != curr_elem_type) {
      if (!id_list.empty()) { // First iteration
        result = create_elements(GmshUtil::gmshElemTypes[curr_elem_type],
                                 id_list,
                                 mat_set_list,
                                 geom_set_list,
                                 part_set_list,
                                 connectivity,
                                 file_id_tag);
        if (MB_SUCCESS != result)
          return result;
      }

      id_list.clear();
      mat_set_list.clear();
      geom_set_list.clear();
      part_set_list.clear();
      connectivity.clear();
      curr_elem_type = int_data[1];
      if ((unsigned)curr_elem_type >= GmshUtil::numGmshElemType ||
          GmshUtil::gmshElemTypes[curr_elem_type].mb_type == MBMAXTYPE) {
        MB_SET_ERR(MB_FILE_WRITE_ERROR, "Unsupported element type " << curr_elem_type << " at line " << tokens.line_number());
      }
      tmp_conn.resize(GmshUtil::gmshElemTypes[curr_elem_type].num_nodes);
    }

    // Store data from element description
    id_list.push_back(int_data[0]);
    part_set_list.push_back(tag_data.size() > 2 ? tag_data[2] : 0);
    geom_set_list.push_back(tag_data.size() > 1 ? tag_data[1] : 0);
     mat_set_list.push_back(tag_data.size() > 0 ? tag_data[0] : 0);

    // Get element connectivity
    if (!tokens.get_long_ints(tmp_conn.size(), &tmp_conn[0]))
      return MB_FILE_WRITE_ERROR;

    // Convert connectivity from IDs to handles
    for (unsigned j = 0; j < tmp_conn.size(); ++j) {
      std::map<long, EntityHandle>::iterator k = node_id_map.find(tmp_conn[j]);
      if (k == node_id_map.end()) {
        MB_SET_ERR(MB_FILE_WRITE_ERROR, "Invalid node ID at line " << tokens.line_number());
      }
      connectivity.push_back(k->second);
    }
  } // for (num_nodes)

  // Create entity sequence for last element(s).
  if (!id_list.empty()) {
    result = create_elements(GmshUtil::gmshElemTypes[curr_elem_type],
                             id_list,
                             mat_set_list,
                             geom_set_list,
                             part_set_list,
                             connectivity,
                             file_id_tag);
    if (MB_SUCCESS != result)
      return result;
  }

  // Construct parent-child relations for geometric sets.
  // Note:  At the time this comment was written, the following
  //        function was not implemented.
  result = create_geometric_topology();
  geomSets.clear();
  return result;
}