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); }
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; }