16 FILE *in= fopen(filename,
"rt");
19 printf(
"[error] loading mesh '%s'...\n", filename);
23 printf(
"loading mesh '%s'...\n", filename);
25 std::vector<Point> wpositions;
28 char line_buffer[1024];
33 if(!fgets(line_buffer,
sizeof(line_buffer), in))
40 line_buffer[
sizeof(line_buffer) -1]= 0;
43 char *line= line_buffer;
44 while(*line && isspace(*line))
52 if(sscanf(line,
"v %f %f %f", &x, &y, &z) != 3)
54 wpositions.push_back(
Point(x, y, z) );
58 else if(line[0] ==
'f')
63 for(line= line +1; ; line= line + next)
71 if(sscanf(line,
" %d/%d/%d %n", &wp.back(), &wt, &wn, &next) == 3)
73 else if(sscanf(line,
" %d/%d %n", &wp.back(), &wt, &next) == 2)
75 else if(sscanf(line,
" %d//%d %n", &wp.back(), &wn, &next) == 2)
77 else if(sscanf(line,
" %d %n", &wp.back(), &next) == 1)
84 for(
unsigned v= 2; v +1 < wp.size(); v++)
86 unsigned idv[3]= { 0, v -1, v };
87 for(
unsigned i= 0; i < 3; i++)
90 int p= (wp[k] < 0) ?
int(wpositions.size()) + wp[k] : wp[k] -1;
94 assert(p <
int(wpositions.size()));
95 positions.push_back(wpositions[p]);
104 printf(
"[error] loading mesh '%s'...\n%s\n\n", filename, line_buffer);
106 printf(
"mesh '%s': %d positions\n", filename,
int(positions.size()));
117 FILE *in= fopen(filename,
"rt");
120 printf(
"[error] loading indexed mesh '%s'...\n", filename);
124 printf(
"loading indexed mesh '%s'...\n", filename);
128 char line_buffer[1024];
133 if(!fgets(line_buffer,
sizeof(line_buffer), in))
140 line_buffer[
sizeof(line_buffer) -1]= 0;
143 char *line= line_buffer;
144 while(*line && isspace(*line))
152 if(sscanf(line,
"v %f %f %f", &x, &y, &z) != 3)
154 positions.push_back(
Point(x, y, z) );
158 else if(line[0] ==
'f')
163 for(line= line +1; ; line= line + next)
171 if(sscanf(line,
" %d/%d/%d %n", &wp.back(), &wt, &wn, &next) == 3)
173 else if(sscanf(line,
" %d/%d %n", &wp.back(), &wt, &next) == 2)
175 else if(sscanf(line,
" %d//%d %n", &wp.back(), &wn, &next) == 2)
177 else if(sscanf(line,
" %d %n", &wp.back(), &next) == 1)
184 for(
unsigned v= 2; v +1 < wp.size(); v++)
186 unsigned idv[3]= { 0, v -1, v };
187 for(
unsigned i= 0; i < 3; i++)
190 int p= (wp[k] < 0) ?
int(positions.size()) + wp[k] : wp[k] -1;
193 assert(p <
int(positions.size()));
194 indices.push_back(p);
203 printf(
"[error] loading indexed mesh '%s'...\n%s\n\n", filename, line_buffer);
205 printf(
"indexed mesh '%s': %d positions, %d indices\n", filename,
int(positions.size()),
int(indices.size()));
211bool read_materials_mtl(
const char *filename,
Materials& materials )
213 FILE *in= fopen(filename,
"rt");
216 printf(
"[error] loading materials '%s'...\n", filename);
220 printf(
"loading materials '%s'...\n", filename);
224 char line_buffer[1024];
229 if(!fgets(line_buffer,
sizeof(line_buffer), in))
236 line_buffer[
sizeof(line_buffer) -1]= 0;
239 char *line= line_buffer;
240 while(*line && isspace(*line))
245 if(sscanf(line,
"newmtl %[^\r\n]", tmp) == 1)
252 if(material ==
nullptr)
258 if(sscanf(line,
"Kd %f %f %f", &r, &g, &b) == 3)
260 else if(sscanf(line,
"Ks %f %f %f", &r, &g, &b) == 3)
262 else if(sscanf(line,
"Ke %f %f %f", &r, &g, &b) == 3)
266 else if(line[0] ==
'N')
269 if(sscanf(line,
"Ns %f", &n) == 1)
271 if(sscanf(line,
"Ni %f", &n) == 1)
274 else if(line[0] ==
'T')
277 if(sscanf(line,
"Tf %f %f %f", &r, &g, &b) == 3)
281 else if(line[0] ==
'm')
283 if(sscanf(line,
"map_Kd %[^\r\n]", tmp) == 1)
286 else if(sscanf(line,
"map_Ks %[^\r\n]", tmp) == 1)
289 else if(sscanf(line,
"map_Ns %[^\r\n]", tmp) == 1)
297 printf(
"[error] parsing line :\n%s\n", line_buffer);
306 FILE *in= fopen(filename,
"rt");
309 printf(
"[error] loading materials '%s'...\n", filename);
313 printf(
"loading materials '%s'...\n", filename);
319 char line_buffer[1024];
324 if(!fgets(line_buffer,
sizeof(line_buffer), in))
331 line_buffer[
sizeof(line_buffer) -1]= 0;
334 char *line= line_buffer;
335 while(*line && isspace(*line))
343 for(line= line +1; ; line= line + next)
351 if(sscanf(line,
" %d/%d/%d %n", &wp.back(), &wt, &wn, &next) == 3)
353 else if(sscanf(line,
" %d/%d %n", &wp.back(), &wt, &next) == 2)
355 else if(sscanf(line,
" %d//%d %n", &wp.back(), &wn, &next) == 2)
357 else if(sscanf(line,
" %d %n", &wp.back(), &next) == 1)
364 if(material_id == -1)
368 for(
unsigned v= 2; v +1 < wp.size(); v++)
370 indices.push_back(material_id);
372 else if(line[0] ==
'm')
374 if(sscanf(line,
"mtllib %[^\r\n]", tmp) == 1)
376 std::string materials_filename;
377 if(tmp[0] !=
'/' && tmp[1] !=
':')
378 materials_filename= normalize_filename(pathname(filename) + tmp);
380 materials_filename= std::string(tmp);
383 if(!read_materials_mtl( materials_filename.c_str(), materials ))
388 else if(line[0] ==
'u')
390 if(sscanf(line,
"usemtl %[^\r\n]", tmp) == 1)
391 material_id= materials.
find(tmp);
398 printf(
"[error] loading materials '%s'...\n%s\n\n", filename, line_buffer);
412 vertex( ) : material(-1), position(-1), texcoord(-1), normal(-1) {}
413 vertex(
const int m,
const int p,
const int t,
const int n ) : material(m), position(p), texcoord(t), normal(n) {}
416 bool operator< (
const vertex& b )
const
418 if(material != b.material)
return material < b.material;
419 if(position != b.position)
return position < b.position;
420 if(texcoord != b.texcoord)
return texcoord < b.texcoord;
421 if(normal != b.normal)
return normal < b.normal;
427int MeshIOData::find_object(
const char *name )
429 for(
unsigned i= 0; i < object_names.size(); i++)
430 if(object_names[i] == name)
436std::vector<MeshIOGroup> MeshIOData::groups(
const std::vector<int>& properties )
438 std::vector<int> remap( properties.size() );
439 for(
unsigned i= 0; i < remap.size(); i++)
442 std::stable_sort(remap.begin(), remap.end(),
443 [&](
const int a,
const int b)
445 return properties[a] < properties[b];
449 std::vector<unsigned> tmp;
450 tmp.reserve(indices.size());
451 for(
unsigned i= 0; i < remap.size(); i++)
454 tmp.push_back( indices[3*
id] );
455 tmp.push_back( indices[3*
id+1] );
456 tmp.push_back( indices[3*
id+2] );
459 std::swap(indices, tmp);
462 std::vector<MeshIOGroup> groups;
465 int id= properties[remap[0]];
468 for(
unsigned i= 1; i < remap.size(); i++)
470 if(properties[remap[i]] !=
id)
472 groups.push_back({ id, first, count });
474 id= properties[remap[i]];
483 groups.push_back({ id, first, count });
487 std::vector<int> tmp;
488 tmp.reserve(remap.size());
489 for(
unsigned i= 0; i < remap.size(); i++)
490 tmp.push_back( material_indices[remap[i]] );
492 std::swap(material_indices, tmp);
496 for(
unsigned i= 0; i < remap.size(); i++)
497 tmp.push_back( object_indices[remap[i]] );
499 std::swap(object_indices, tmp);
507 FILE *in= fopen(filename,
"rt");
510 printf(
"[error] loading indexed mesh '%s'...\n", filename);
514 printf(
"loading indexed mesh '%s'...\n", filename);
516 std::vector<Point> wpositions;
517 std::vector<Point> wtexcoords;
518 std::vector<Vector> wnormals;
524 std::map<vertex, unsigned> remap;
529 char line_buffer[1024];
534 if(!fgets(line_buffer,
sizeof(line_buffer), in))
541 line_buffer[
sizeof(line_buffer) -1]= 0;
544 char *line= line_buffer;
545 while(*line && isspace(*line))
553 if(sscanf(line,
"v %f %f %f", &x, &y, &z) != 3)
555 wpositions.push_back(
Point(x, y, z) );
557 else if(line[1] ==
'n')
559 if(sscanf(line,
"vn %f %f %f", &x, &y, &z) != 3)
561 wnormals.push_back(
Vector(x, y, z) );
563 else if(line[1] ==
't')
565 if(sscanf(line,
"vt %f %f", &x, &y) != 2)
567 wtexcoords.push_back(
Point(x, y, 0) );
570 else if(line[0] ==
'f')
577 for(line= line +1; ; line= line + next)
585 if(sscanf(line,
" %d/%d/%d %n", &wp.back(), &wt.back(), &wn.back(), &next) == 3)
587 else if(sscanf(line,
" %d/%d %n", &wp.back(), &wt.back(), &next) == 2)
589 else if(sscanf(line,
" %d//%d %n", &wp.back(), &wn.back(), &next) == 2)
591 else if(sscanf(line,
" %d %n", &wp.back(), &next) == 1)
598 if(material_id == -1)
603 object_id= data.find_object(
"default");
606 object_id= data.object_names.size();
607 data.object_names.push_back(
"default");
612 for(
unsigned v= 2; v +1 < wp.size(); v++)
614 data.material_indices.push_back(material_id);
615 data.object_indices.push_back(object_id);
617 unsigned idv[3]= { 0, v -1, v };
618 for(
unsigned i= 0; i < 3; i++)
622 int p= (wp[k] < 0) ?
int(wpositions.size()) + wp[k] : wp[k] -1;
623 int t= (wt[k] < 0) ?
int(wtexcoords.size()) + wt[k] : wt[k] -1;
624 int n= (wn[k] < 0) ?
int(wnormals.size()) + wn[k] : wn[k] -1;
629 auto found= remap.insert( std::make_pair(
vertex(material_id, p, t, n),
unsigned(remap.size())) );
633 if(t != -1) data.texcoords.push_back(wtexcoords[t]);
634 if(n != -1) data.normals.push_back(wnormals[n]);
635 data.positions.push_back(wpositions[p]);
639 assert(found.first->second < data.positions.size());
640 data.indices.push_back(found.first->second);
645 else if(line[0] ==
'm')
647 if(sscanf(line,
"mtllib %[^\r\n]", tmp) == 1)
649 std::string materials_filename;
650 if(tmp[0] !=
'/' && tmp[1] !=
':')
651 materials_filename= normalize_filename(pathname(filename) + tmp);
653 materials_filename= std::string(tmp);
656 read_materials_mtl( materials_filename.c_str(), data.materials );
660 else if(line[0] ==
'u')
662 if(sscanf(line,
"usemtl %[^\r\n]", tmp) == 1)
663 material_id= data.materials.
find(tmp);
666 else if(line[0] ==
'o')
668 if(sscanf(line,
"o %s", tmp) == 1)
670 object_id= data.find_object(tmp);
673 object_id= data.object_names.size();
674 data.object_names.push_back(tmp);
681 else if(line[0] ==
'g')
684 if(sscanf(line,
"g %s", tmp) == 1)
686 object_id= data.find_object(tmp);
689 object_id= data.object_names.size();
690 data.object_names.push_back(tmp);
693 printf(
"object '%s': %d\n", tmp, object_id);
703 printf(
"[error] loading indexed mesh '%s'...\n%s\n\n", filename, line_buffer);
707 printf(
" %d indices, %d positions %d texcoords %d normals\n",
708 int(data.indices.size()),
int(data.positions.size()),
int(data.texcoords.size()),
int(data.normals.size()));
709 printf(
" %d materials, %d textures\n", data.materials.
count(), data.materials.
filename_count());
722#pragma omp parallel for
723 for(
int i= 0; i < n; i++)
Color Black()
utilitaire. renvoie une couleur noire.
Image read_image(const char *filename, const bool flipY)
charge une image .bmp .tga .jpeg .png ou .hdr
bool read_indexed_positions(const char *filename, std::vector< Point > &positions, std::vector< unsigned > &indices)
bool read_positions(const char *filename, std::vector< Point > &positions)
bool read_images(const Materials &materials, std::vector< Image > &images)
bool read_meshio_data(const char *filename, MeshIOData &data)
bool read_materials(const char *filename, Materials &materials, std::vector< int > &indices)
representation d'une couleur (rgba) transparente ou opaque.
int diffuse_texture
indice de la texture de la couleur de base, ou -1.
float ns
concentration des reflets, exposant pour les reflets blinn-phong.
int ns_texture
indice de la texture, ou -1.
Color transmission
transmission, "couleur" des objets transparents.
Color emission
pour une source de lumiere.
float ni
indice de refraction, cf coefficients de Fresnel.
Color diffuse
couleur diffuse / de base.
Color specular
couleur du reflet.
int specular_texture
indice de la texture, ou -1.
int insert(const Material &material, const char *name)
ajoute une matiere.
int filename_count() const
renvoie le nombre de noms de fichiers de textures.
int find(const char *name)
recherche une matiere avec son nom. renvoie son indice dans materials, ou -1.
int insert_texture(const char *filename)
ajoute une texture / nom du fichier.
const char * filename(const int id) const
renvoie le nom de fichier d'une texture.
int count() const
nombre de matieres.
const Material & material(const int id) const
renvoie la ieme matiere.
int default_material_index()
indice de la matiere par defaut dans le tableau materials.
representation d'un point 3d.
representation d'un vecteur 3d.