28 #define USE_MULTI_BLOC
34 using namespace StrUtils;
35 using namespace FileUtils;
37 template<
typename IndexType >
41 if (type==2 || type==3 || type==9)
44 else if (type==4 || type==5)
51 template<
typename IndexType >
52 std::vector<IndexType>
get_index(
char* buffer, IndexType d)
55 char* token = strtok(buffer,
" ");
56 token = strtok(NULL,
" ");
58 unsigned long type =
static_cast<unsigned long>(atol(token));
62 throw "MSH Reader: Error there is an unknown element or a not implemented yet element";
64 if (
dimensions(type)!=
static_cast<unsigned long>(d))
65 throw "MSH Reader: Error there is 2D elements with 3D Elements";
87 token = strtok(NULL,
" ");
88 std::vector<IndexType> indexes;
90 unsigned long nb = atol(token);
93 throw "MSH Reader: Wrong number of tags, it should be between 2 and 4 included";
95 for(
unsigned long i(0); i<nb+temp; i++)
97 token = strtok(NULL,
" ");
100 indexes.push_back(
static_cast<IndexType
>(atol(token)-1));
108 template<
typename CoordType,
113 std::vector< std::vector<CoordType> >& points_coords,
114 std::vector< std::vector<CoordNType> >& normals_coords,
115 std::vector< std::vector<CoordCType> >& vertex_color_coords,
116 std::vector< std::vector<IndexType> >& line_indices,
117 std::vector< std::vector<CoordCType> >& lines_color_coords,
118 std::vector< std::vector<IndexType> >& face_indices,
119 std::vector< std::vector<CoordCType> >& face_color_coords,
124 file = fopen(file_path.c_str(),
"r");
127 std::cerr <<
"MSH Reader : Unable to open " << file_path << std::endl;
139 #ifndef USE_MULTI_BLOC
140 bool found_multi_nodes =
false;
141 bool found_multi_elements =
false;
143 const unsigned int T_MAX = 256;
146 while(fgets(buffer, T_MAX, file) != NULL)
149 if (strcmp(buffer,
"$Nodes\n")==0)
151 #ifndef USE_MULTI_BLOC
152 if (!found_multi_nodes)
153 found_multi_nodes =
true;
156 std::cerr <<
"You can't have multiple Nodes blocks" << std::endl;
161 if (fgets(buffer, T_MAX, file) == NULL)
163 std::cerr <<
"MSH Reader: Error in the file structure ($EndNodes missing ?)" << std::endl;
168 nb_param_reads = sscanf(buffer,
"%ld", &number);
170 if (nb_param_reads < 1)
172 std::cerr <<
"MSH Reader: Error in the file structure ($Nodes tag with no number associated)" << std::endl;
181 else if (strcmp(buffer,
"$Elements\n")==0)
183 #ifndef USE_MULTI_BLOC
184 if (!found_multi_elements)
185 found_multi_elements =
true;
188 std::cerr <<
"You can't have multiple Nodes blocks" << std::endl;
193 if (fgets(buffer, T_MAX, file) == NULL)
195 std::cerr <<
"MSH Reader: Error in the file structure ($EndElements missing ?)" << std::endl;
200 nb_param_reads = sscanf(buffer,
"%ld", &number);
202 if (nb_param_reads < 1)
204 std::cerr <<
"MSH Reader: Error in the file structure ($Nodes tag with no number associated)" << std::endl;
209 nb_elements += number;
211 if (fgets(buffer, T_MAX, file) == NULL)
213 std::cerr <<
"MSH Reader: Error in the file structure ($EndElements missing ?)" << std::endl;
222 nb_param_reads = sscanf(buffer,
"%ld %ld", &number, &number);
223 if (nb_param_reads != 2)
225 std::cerr <<
"MSH Reader: Error in the element declaration" << std::endl;
230 dim =
static_cast<IndexType
>(
dimensions(number));
234 std::cerr <<
"MSH Reader: Error the element is not recognized or not supported yet" << std::endl;
242 else if (!(strcmp(buffer,
"$NodeData\n")!=0 && strcmp(buffer,
"$ElementData\n")!=0))
244 const char* types[] = {
"NodeData",
"ElementData"};
247 if (strcmp(buffer,
"$NodeData\n")==0)
257 if (fgets(buffer, T_MAX, file) == NULL)
259 std::cerr <<
"MSH Reader: Error in the file structure ($End" << types[type] <<
" missing ?)" << std::endl;
264 nb_param_reads = sscanf(buffer,
"%ld", &number);
266 if (nb_param_reads < 1)
268 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" tag with no string tag associated)" << std::endl;
272 bool found_color =
false;
273 bool found_normal =
false;
275 for(
int i=0; i<number; i++)
278 if (fgets(buffer, T_MAX, file) == NULL)
280 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" with wrong number of string datas)" << std::endl;
285 if (strcmp(buffer,
"\"Color\"\n")==0 ||
286 strcmp(buffer,
"\"color\"\n")==0 ||
287 strcmp(buffer,
"\"COLOR\"\n")==0 ||
288 strcmp(buffer,
"\"Colour\"\n")==0 ||
289 strcmp(buffer,
"\"colour\"\n")==0 ||
290 strcmp(buffer,
"\"COLOUR\"\n")==0 ||
291 strcmp(buffer,
"\"Colors\"\n")==0 ||
292 strcmp(buffer,
"\"colors\"\n")==0 ||
293 strcmp(buffer,
"\"COLORS\"\n")==0 )
296 if (strcmp(buffer,
"\"Normal\"\n")==0 ||
297 strcmp(buffer,
"\"normal\"\n")==0 ||
298 strcmp(buffer,
"\"NORMAL\"\n")==0 ||
299 strcmp(buffer,
"\"Normals\"\n")==0 ||
300 strcmp(buffer,
"\"normals\"\n")==0 ||
301 strcmp(buffer,
"\"NORMALS\"\n")==0)
305 if (found_color && found_normal)
307 std::cerr <<
"MSH Reader: Color and normal values declared in the same data block" << std::endl;
312 if (found_color || found_normal)
315 if (fgets(buffer, T_MAX, file) == NULL)
317 std::cerr <<
"MSH Reader: Error in the file structure ($End" << types[type] <<
" missing ?)" << std::endl;
322 nb_param_reads = sscanf(buffer,
"%ld", &number);
324 if (nb_param_reads != 1)
326 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" tag with no real tag associated)" << std::endl;
331 for(
int i=0; i<number; i++)
334 if (fgets(buffer, T_MAX, file) == NULL)
336 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" with wrong number of real datas)" << std::endl;
342 if (fgets(buffer, T_MAX, file) == NULL)
344 std::cerr <<
"MSH Reader: Error in the file structure ($End" << types[type] <<
" missing ?)" << std::endl;
349 nb_param_reads = sscanf(buffer,
"%ld", &number);
351 if (nb_param_reads != 1)
353 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" tag with no integer tag associated)" << std::endl;
358 for(
int i=0; i<number; i++)
361 if (fgets(buffer, T_MAX, file) == NULL)
363 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" with wrong number of real datas)" << std::endl;
369 nb_param_reads = sscanf(buffer,
"%ld", &number);
371 if (nb_param_reads != 1)
373 std::cerr <<
"MSH Reader: Error in the file structure ($" << types[type] <<
" tag with no integer tag associated)" << std::endl;
382 nb_p_color += number;
385 nb_p_normal += number;
389 nb_e_color += number;
396 if ((nb_points!=nb_p_color && nb_p_color!=0) || (nb_elements!=nb_e_color && nb_e_color!=0) || (nb_points!=nb_p_normal && nb_p_normal!=0))
398 std::cerr <<
"MSH Reader: Error in the file, all nodes or elements should have or not color" << std::endl;
402 points_coords.resize(nb_points);
403 normals_coords.resize(nb_p_normal);
404 vertex_color_coords.resize(nb_p_color);
408 face_indices.resize(nb_elements);
409 face_color_coords.resize(nb_e_color);
414 line_indices.resize(nb_elements);
415 lines_color_coords.resize(nb_e_color);
423 template<
typename CoordType,
428 std::vector< std::vector<CoordType> >& points_coords,
429 std::vector< std::vector<CoordNType> >& normals_coords,
430 std::vector< std::vector<CoordCType> >& vertex_color_coords,
431 std::vector< std::vector<IndexType> >& line_indices,
432 std::vector< std::vector<CoordCType> >& lines_color_coords,
433 std::vector< std::vector<IndexType> >& face_indices,
434 std::vector< std::vector<CoordCType> >& face_color_coords,
435 std::vector< std::vector < std::vector<double> > >& field_attributes,
436 std::vector< std::string >& field_names)
441 std::cerr <<
"MSH Reader: File extension is inappropriate" << std::endl;
444 points_coords.clear();
445 normals_coords.clear();
446 vertex_color_coords.clear();
447 face_indices.clear();
448 face_color_coords.clear();
449 line_indices.clear();
450 lines_color_coords.clear();
452 field_attributes.clear();
457 if (!
init_vectors(file_path, points_coords, normals_coords, vertex_color_coords, line_indices, lines_color_coords, face_indices, face_color_coords, dim))
459 std::cerr <<
"Error during initialization" << std::endl;
463 const long T_MAX = 256;
467 FILE* file = fopen(file_path.c_str(),
"r");
471 std::cerr <<
"MSH Reader: Unable to open file : " << file_path << std::endl;
475 while( fgets(buffer, T_MAX, file) != NULL)
478 if (strcmp(buffer,
"$MeshFormat\n")==0)
481 if (fgets(buffer, T_MAX, file) == NULL)
483 std::cerr <<
"MSH Reader: Error in the file structure ($EndMeshFormat missing ?)" << std::endl;
491 number_param = sscanf(buffer,
"%f %u %u", &version, &type, &size);
495 std::cerr <<
"MSH Reader: The " << version <<
" version is not supported yet" << std::endl;
502 std::cerr <<
"MSH Reader: Only the ASCII file type is supported" << std::endl;
508 if (size !=
sizeof(
double))
510 std::cerr <<
"MSH Reader: The size of the elements should be " <<
sizeof(double) <<
" and not " << size << std::endl;
515 if (fgets(buffer, T_MAX, file) == NULL || strcmp(buffer,
"$EndMeshFormat\n")!=0)
517 std::cerr <<
"MSH Reader: Error in the file structure ($EndMeshFormat missing)" << std::endl;
525 else if (strcmp(buffer,
"$Nodes\n")==0)
528 if (fgets(buffer, T_MAX, file)==NULL)
530 std::cerr <<
"MSH Reader: Error in the file structure ($EndNodes missing ?)" << std::endl;
535 std::vector<double> temp_pts;
538 number_param = sscanf(buffer,
"%ld", &temp);
539 if (number_param != 1)
541 std::cerr <<
"MSH Reader: Error in the number of nodes" << std::endl;
547 for(
long i(0); i<temp; ++i)
549 if (fgets(buffer, T_MAX, file) == NULL)
551 std::cerr <<
"MSH Reader: Error in the file, no node associated to a $Node tag" << std::endl;
558 number_param = sscanf(buffer,
"%ld %lf %lf %lf", &index, &temp_pts[0], &temp_pts[1], &temp_pts[2]);
559 if (number_param != 4)
561 std::cerr <<
"MSH Reader: Error in the file, wrong node declaration" << std::endl;
567 if (index-1 <
static_cast<long>(points_coords.size()))
568 points_coords[index-1] = std::vector<CoordType>(temp_pts.begin(), temp_pts.end());
571 std::cerr <<
"MSH Reader: Error in the node index, " << points_coords.size() <<
" declared and there is the " << index <<
" declared." << std::endl;
577 if (fgets(buffer, T_MAX, file)==NULL || (strcmp(buffer,
"$EndNodes")!=0 && strcmp(buffer,
"$EndNodes\n")!=0))
579 std::cerr <<
"MSH Reader: Error in the file structure ($EndNodes missing)" << std::endl;
587 else if (strcmp(buffer,
"$Elements\n")==0)
590 if (fgets(buffer, T_MAX, file)==NULL)
592 std::cerr <<
"MSH Reader: Error in the file structure ($EndElements missing ?)" << std::endl;
598 number_param = sscanf(buffer,
"%ld", &temp);
599 if (number_param != 1)
601 std::cerr <<
"MSH Reader: Error in the number of elements" << std::endl;
607 for(
long i(0); i<temp; ++i)
609 if (fgets(buffer, T_MAX, file) == NULL)
611 std::cerr <<
"MSH Reader: Error in the file, no element associated to a $Elements tag" << std::endl;
616 number_param = sscanf(buffer,
"%ld", &index);
620 std::cerr <<
"MSH Reader: Error in the file, wrong declaration of an element" << std::endl;
627 std::vector<IndexType> temp = std::move(get_index<IndexType>(buffer, dim));
633 if (index-1 <
static_cast<long>(face_indices.size()))
634 face_indices[index-1] = temp;
638 std::cerr <<
"MSH Reader: Error in the 2D elements index, " << face_indices.size() <<
" declared and there is the " << index <<
" declared." << std::endl;
648 if (index-1 <
static_cast<long>(line_indices.size()))
649 line_indices[index-1] = temp;
653 std::cerr <<
"MSH Reader: Error in the 2D elements index, " << line_indices.size() <<
" declared and there is the " << index <<
" declared." << std::endl;
661 std::cerr << e << std::endl;
667 buffer[strlen(buffer)-1]=
'\0';
669 if (fgets(buffer, T_MAX, file)==NULL || (strcmp(buffer,
"$EndElements")!=0 && strcmp(buffer,
"$EndElements\n")!=0))
671 std::cerr <<
"MSH Reader: Error in the file structure ($EndElements missing)" << std::endl;
679 else if (!(strcmp(buffer,
"$NodeData\n")!=0 && strcmp(buffer,
"$ElementData\n")!=0))
681 const char* types[] = {
"NodeData",
"ElementData"};
682 unsigned short type, data = 2;
684 if (strcmp(buffer,
"$NodeData\n")==0)
691 if (fgets(buffer, T_MAX, file)==NULL)
693 std::cerr <<
"MSH Reader: Error in the file structure ($End" << types[type] <<
" missing ?)" << std::endl;
699 number_param = sscanf(buffer,
"%ld", ¶ms);
700 if (number_param != 1)
702 std::cerr <<
"MSH Reader: Error in the file, wrong" << types[type] <<
" declaration in the number of string parameters" << std::endl;
707 for(
long i(0); i<=params; ++i)
709 if (fgets(buffer, T_MAX, file)==NULL)
711 std::cerr <<
"MSH Reader: Error in the file, wrong number of string parameters in " << types[type] << std::endl;
717 if (strcmp(buffer,
"\"Color\"\n")==0 ||
718 strcmp(buffer,
"\"color\"\n")==0 ||
719 strcmp(buffer,
"\"COLOR\"\n")==0 ||
720 strcmp(buffer,
"\"Colour\"\n")==0 ||
721 strcmp(buffer,
"\"colour\"\n")==0 ||
722 strcmp(buffer,
"\"COLOUR\"\n")==0 ||
723 strcmp(buffer,
"\"Colors\"\n")==0 ||
724 strcmp(buffer,
"\"colors\"\n")==0 ||
725 strcmp(buffer,
"\"COLORS\"\n")==0 )
729 else if (strcmp(buffer,
"\"Normal\"\n")==0 ||
730 strcmp(buffer,
"\"normal\"\n")==0 ||
731 strcmp(buffer,
"\"NORMAL\"\n")==0 ||
732 strcmp(buffer,
"\"Normals\"\n")==0 ||
733 strcmp(buffer,
"\"normals\"\n")==0 ||
734 strcmp(buffer,
"\"NORMALS\"\n")==0)
741 buffer[strlen(buffer)-1] =
'\0';
742 std::string a = (type==0)?
"POINT_DATA_":
"ELEMENT_DATA_";
743 a += std::string(buffer).substr(1, std::string(buffer).size()-2);
744 field_names.push_back(a);
751 number_param = sscanf(buffer,
"%ld", ¶ms);
754 std::cerr <<
"MSH Reader: Error in the file, wrong " << types[type] <<
" declaration in the number of real parameters" << std::endl;
759 for(
long i(0); i<=params; ++i)
761 if (fgets(buffer, T_MAX, file)==NULL)
763 std::cerr <<
"MSH Reader: Error in the file, wrong number of real parameters in " << types[type] << std::endl;
771 number_param = sscanf(buffer,
"%ld", ¶ms);
774 std::cerr <<
"MSH Reader: Error in the file, wrong " << types[type] <<
" declaration in the number of integer parameters" << std::endl;
779 for(
long i(0); i<params; ++i)
781 if (fgets(buffer, T_MAX, file)==NULL)
783 std::cerr <<
"MSH Reader: Error in the file, wrong number of integer parameters in " << types[type] << std::endl;
789 number_param = sscanf(buffer,
"%ld", ¶ms);
792 std::cerr <<
"MSH Reader: Error in the file, wrong number of integer parameters in " << types[type] << std::endl;
797 std::vector<CoordCType> temp_vector_c;
798 std::vector<CoordNType> temp_vector_n;
799 std::vector< std::vector<double> > temp_vector_f;
800 temp_vector_f.clear();
801 double temp1, temp2, temp3;
803 for(
long i(0); i<params; i++)
805 if (fgets(buffer, T_MAX, file)==NULL)
807 std::cerr <<
"MSH Reader: Error in the file, wrong number of integer parameters in " << types[type] << std::endl;
814 temp_vector_c.clear();
815 temp_vector_c.reserve(3);
818 temp_vector_n.clear();
819 temp_vector_n.reserve(3);
826 number_param = sscanf(buffer,
"%ld %lf %lf %lf", &index, &temp1, &temp2, &temp3);
827 if (number_param<1 || number_param>4)
829 std::cerr <<
"MSH Reader: Error in the file, wrong number of arguments for integer parameters in " << type << std::endl;
837 temp_vector_c.push_back(
static_cast<CoordCType
>(temp1));
838 if (number_param > 1)
839 temp_vector_c.push_back(
static_cast<CoordCType
>(temp2));
840 if (number_param > 2)
841 temp_vector_c.push_back(
static_cast<CoordCType
>(temp3));
844 temp_vector_n.push_back(
static_cast<CoordNType
>(temp1));
845 if (number_param > 1)
846 temp_vector_n.push_back(
static_cast<CoordNType
>(temp2));
847 if (number_param > 2)
848 temp_vector_n.push_back(
static_cast<CoordNType
>(temp3));
851 if (
static_cast< long >(temp_vector_f.size()) < index)
852 temp_vector_f.resize(index);
853 temp_vector_f[index-1].push_back(temp1);
854 if (number_param > 1)
855 temp_vector_f[index-1].push_back(temp2);
856 if (number_param > 2)
857 temp_vector_f[index-1].push_back(temp3);
869 if (index - 1 <
static_cast<long>(face_color_coords.size()))
870 face_color_coords[index-1] = temp_vector_c;
873 std::cerr <<
"MSH Reader: Wrong index usage in 2D element color, " << index <<
" used when the size is " << face_color_coords.size() << std::endl << buffer << std::endl;
885 if (index - 1 <
static_cast<long>(lines_color_coords.size()))
886 lines_color_coords[index-1] = temp_vector_c;
889 std::cerr <<
"MSH Reader: Wrong index usage in 3D element color, " << index <<
" used when the size is " << lines_color_coords.size() << std::endl;
903 if (index - 1 <
static_cast<long>(vertex_color_coords.size()))
904 vertex_color_coords[index-1] = temp_vector_c;
907 std::cerr <<
"MSH Reader: Wrong index usage in node color, " << index <<
" used when the size is " << vertex_color_coords.size() << std::endl;
915 if (index - 1 <
static_cast<long>(normals_coords.size()))
916 normals_coords[index-1] = temp_vector_n;
919 std::cerr <<
"MSH Reader: Wrong index usage in node normal, " << index <<
" used when the size is " << normals_coords.size() << std::endl;
926 if (!temp_vector_f.empty())
927 field_attributes.push_back(temp_vector_f);
930 strcat(s, types[type]);
934 if (fgets(buffer, T_MAX, file)==NULL || (strcmp(buffer, s)!=0 && strcmp(buffer, strcat(buffer,
"\n"))!=0))
936 std::cerr <<
"MSH Reader: Error in the file, missing $End" << types[type] << std::endl;