Pipeline graphique
 Tout Structures de données Espaces de nommage Fichiers Fonctions Variables Définitions de type Ã‰numérations Valeurs énumérées Macros
ReadMesh.cpp
Aller à la documentation de ce fichier.
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <stdlib.h>
6 #include <math.h>
7 #include <algorithm>
8 #include "ReadMesh.h"
9 
10 #define SAFE_DELETE(x) { if (x!=NULL) { delete x; x=NULL; } }
11 #define SAFE_ARRAY_DELETE(x) { if (x!=NULL) { delete [] x; x=NULL; } }
12 
13 namespace MeshLoad {
14  // mesh file keyword
15  const int nKeyWord = 21;
16  typedef enum {
23  } KeyWord;
24  const char KeyWordStr[nKeyWord][32] = {
25  "MeshVersionFormatted", "Dimension", "Vertices", "Triangles",
26  "Quadrilaterals", "Tetrahedra", "Hexahedra",
27  "Edges", "Corners", "RequiredVertices", "Ridges", "RequiredEdges",
28  "Normals", "Tangents",
29  "NormalAtVertices", "NormalAtTriangleVertices", "NormalAtQuadrilateralsVertices", "NormalAtEdges",
30  "End", "Comment", "Error"
31  };
36  Normals, Tangents,
38  End, Comment, Error
39  };
40  // mesh material keyword
41  const int nMeKeyWord = 6;
43  const char MeKeyWordStr[nMeKeyWord][12] = { "NbMaterial", "NbMaterials", "Material", "End", "Comment", "Other" };
45  KeyWord GetKeyword(char *line);
46  MeKeyWord GetMeKeyword(char *line);
47 };
48 
49 // face index
50 typedef struct { int iVert, iFace; } iVertFace;
51 bool operator<(const iVertFace& a, const iVertFace& b) {
52  return a.iVert < b.iVert;
53 }
54 
55 // pour la comparaison de deux mat�riaux (indices de mat�riaux + distance)
56 struct MaterialComp { int i, j; float d; };
57 bool operator<(const MaterialComp &m1, const MaterialComp &m2) { return ( m1.d < m2.d ); }
58 
59 
61  nVertex = nFaces = nMaterials = 0;
62  Vertex = NULL;
63  Indice = NULL;
64  Attribute = NULL;
65  Material = NULL;
66 }
67 
68 void Mesh::Object::Clear(void) {
69  SAFE_ARRAY_DELETE(Vertex);
70  SAFE_ARRAY_DELETE(Indice);
71  SAFE_ARRAY_DELETE(Attribute);
73  nVertex = nFaces = nMaterials = 0;
74 }
75 
76 
78  SAFE_ARRAY_DELETE(Vertex);
79  SAFE_ARRAY_DELETE(Indice);
80  SAFE_ARRAY_DELETE(Attribute);
82 }
83 
84 
86  char key[80];
87  sscanf(line,"%s",key);
88  if (key[0]=='#') return Comment;
89  else {
90  int i=0;
91  do {
92  if (strcmp(key,KeyWordStr[i])==0) return KeyWordLst[i];
93  i++;
94  } while (i<= nKeyWord-2); // les deux derniers keywords sont reserves
95  return Error;
96  }
97 }
98 
99 
101  char key[80];
102  sscanf(line,"%s",key);
103  if (key[0]=='#') return MeComment;
104  else {
105  int i=0;
106  do {
107  if (strcmp(key,MeKeyWordStr[i])==0) return MeKeyWordLst[i];
108  i++;
109  } while (i<= nKeyWord-2); // les deux derniers keywords sont reserves
110  return MeOther;
111  }
112 }
113 
114 
115 bool Mesh::Object::LoadMesh(const char *fname, bool invface) {
116  // int &nVertex, VERTEX* &Vertex, int &nIndex, INDICE* &Index, int &nMaterials, int* &Attribute
117  using namespace MeshLoad;
118  // ReadMesh(const char *fname, LPD3DXMESH *ppMSH, UINT *nmat, bool invface) {
119  const int bufsize=1024;
120  char line[bufsize];
121  FILE *ptf;
122  int nread, v;
123 
124  SAFE_ARRAY_DELETE(Vertex);
125  SAFE_ARRAY_DELETE(Indice);
126  SAFE_ARRAY_DELETE(Attribute);
127 
128  // lecture du fichier
129  nMaterials = 0;
130  ptf = fopen(fname,"r");
131  if (ptf == NULL) return false;
132  while( fgets(line,bufsize,ptf) != NULL ) {
133  KeyWord k = GetKeyword(line);
134  // if (k!=kp) WriteConsole("%s\n",KeyWordStr[(UINT)k]);
135  switch(k) {
136  case Dimension: fgets(line,bufsize,ptf); break; // on passe une ligne
137  case Vertices: {
138  fgets(line,bufsize,ptf);
139  sscanf(line,"%d",&nVertex);
140  Vertex = new Mesh::VERTEX[nVertex];
141  for(int i=0;i<nVertex;i++) {
142  fgets(line,bufsize,ptf);
143  nread = sscanf(line,"%f %f %f %d", &(Vertex[i].P.x), &(Vertex[i].P.y), &(Vertex[i].P.z), &v);
144  // if (i<10) WriteConsole("%05d %f %f %f %d\n",i,vert[i].P.x,vert[i].P.y,vert[i].P.z,v);
145  if (nread != 4) { printf("Vertices Read Error: read=%d\n",nread); nVertex = i; break; }
146  }
147  } break;
148  case Triangles: {
149  int j=0;
150  fgets(line,bufsize,ptf);
151  sscanf(line,"%d",&nFaces);
152  Indice = new Mesh::INDICE[3*nFaces];
153  Attribute = new int[nFaces];
154  for(int i=0;i<nFaces;i++, j+=3) {
155  fgets(line,bufsize,ptf);
156  if (invface) nread = sscanf(line,"%d %d %d %d", &(Indice[j]), &(Indice[j+2]), &(Indice[j+1]), &(Attribute[i]) );
157  else nread = sscanf(line,"%d %d %d %d", &(Indice[j]), &(Indice[j+1]), &(Indice[j+2]), &(Attribute[i]) );
158  // if (i<10) WriteConsole("%05d %6d %6d %6d %6d\n",i,face[j],face[j+1],face[j+2],attr[i]);
159  if (Attribute[i] > nMaterials) nMaterials = Attribute[i];
160  if (nread != 4) { printf("Triangle Read Error: read=%d\n",nread); nFaces=i; break; }
161  }
162  } break;
163  case Quadrilaterals: {
164  int j=0, k=0;
165  int v0, v1, v2, v3, m;
166  fgets(line,bufsize,ptf);
167  sscanf(line,"%d",&nFaces);
168  Indice = new Mesh::INDICE[6*nFaces];
169  Attribute = new int[2*nFaces];
170  for(int i=0;i<nFaces;i++, j+=6, k+=2) {
171  fgets(line,bufsize,ptf);
172  nread = sscanf(line,"%d %d %d %d %d", &v0, &v1, &v2, &v3, &m);
173  if (invface) {
174  Indice[j ] = v0; Indice[j+1] = v1; Indice[j+2] = v2;
175  Indice[j+3] = v0; Indice[j+4] = v2; Indice[j+5] = v3;
176  } else {
177  Indice[j ] = v0; Indice[j+1] = v2; Indice[j+2] = v1;
178  Indice[j+3] = v0; Indice[j+4] = v3; Indice[j+5] = v2;
179  }
180  if (m > nMaterials) nMaterials = m;
181  Attribute[k ] = m;
182  Attribute[k+1] = m;
183  // if (i<10) WriteConsole("%05d %6d %6d %6d %6d\n",i,face[j],face[j+1],face[j+2],attr[i]);
184  if (nread != 5) { printf("Quadrilaterals Read Error: read=%d\n",nread); nFaces=i; break; }
185  }
186  nFaces *= 2;
187  } break;
188  default:
189  printf("WARNING: %s are not processed\n",KeyWordStr[(int)k]);
190  }
191  }
192  fclose(ptf);
193  if ((nFaces == 0) || (nVertex == 0)) {
194  SAFE_ARRAY_DELETE(Vertex);
195  SAFE_ARRAY_DELETE(Indice);
196  SAFE_ARRAY_DELETE(Attribute);
197  return false;
198  }
199 
200  // car les indices commencent a 1
201  for(int i=0; i<3*nFaces; i++) Indice[i]--;
202  (nMaterials)++; // nmat contient initialement le numero de plus grand materiau
203 
204  // calcul des normales
205  ComputeNormals();
206  return true;
207 }
208 
209 bool Mesh::Object::LoadMaterial(const char *fname, bool skip0) {
210  using namespace MeshLoad;
211  const int bufsize=1024;
212  FILE *ptf;
213  char line[bufsize],keyw[128],mname[128],mtext[128];
214  int i=0, mid, nmatmesh;
215 
216  // lecture du fichier
217  nmatmesh = nMaterials;
218  nMaterials = 0;
219  Material = NULL;
220  printf("ReadMedit : %s\n",fname);
221  ptf = fopen(fname,"r");
222  if (ptf == NULL) {
223  printf("\tFile not found\n");
224  return false;
225  } else printf("\tFile opened\n");
226  while( fgets(line,bufsize,ptf) != NULL ) {
227  MeKeyWord k = GetMeKeyword(line);
228  // if (k!=kp) WriteConsole("%s\n",MeKeyWordStr[(UINT)k]);
229  switch(k) {
230  case MeEnd:
231  case MeComment:
232  case MeOther:
233  case NbMaterial:
234  case NbMaterials:
235  fgets(line,bufsize,ptf);
236  sscanf(line,"%d",&nMaterials);
237  printf("\tnMat found = %d (read from Mesh = %d)\n",nMaterials,nmatmesh);
238  if (nMaterials > 0) {
239  (nMaterials)++; // car parfois, un materiau a ce numero
240  Material = new MATERIAL[ nMaterials ];
241  memset(Material,0,nMaterials*sizeof(MATERIAL));
242  }
243  break; // on passe une ligne
244  case MeMaterial:
245  MATERIAL m;
246  if (Material == NULL) {
247  printf("ReadError: material found but no nbmaterial.");
248  return false;
249  }
250  int nfield = sscanf(line,"%s %s %s",keyw,mname,mtext);
251  if ((nfield==3) && (isdigit(mtext[0]))) mid = atoi(mtext);
252  else mid=i;
253  if (skip0) mid++;
254  printf("\t%d Read: %s %d\n",i,mname,mid);
255 
256  fgets(line,bufsize,ptf);
257  sscanf(line,"%f %f %f %f",&m.Ambient.r,&m.Ambient.g,&m.Ambient.b,&m.Ambient.a);
258  fgets(line,bufsize,ptf);
259  sscanf(line,"%f %f %f %f",&m.Diffuse.r,&m.Diffuse.g,&m. Diffuse.b,&m. Diffuse.a);
260  fgets(line,bufsize,ptf);
261  sscanf(line,"%f %f %f %f",&m.Specular.r,&m.Specular.g,&m.Specular.b,&m.Specular.a);
262  fgets(line,bufsize,ptf);
263  sscanf(line,"%f %f %f %f",&m.Emissive.r,&m.Emissive.g,&m.Emissive.b,&m.Emissive.a);
264  fgets(line,bufsize,ptf);
265  sscanf(line,"%f",&m.Power);
266  if (i >= nMaterials) {
267  printf("ReadError: more material than nbmaterial.");
268  } else Material[mid] = m;
269  i++;
270  break;
271  }
272  }
273  fclose(ptf);
274  if (i == nMaterials-1) nMaterials--; // pour les materiaux avec un nombre de couleurs incorrect.
275  printf("%d materials found (%d indicated)\n",i,nMaterials);
276  if (i<nMaterials) printf("WARNING: supplementary materials set to 0\n");
277  return true;
278 }
279 
280 // ajout d'une normale
282  VECTOR *FaceNormals = new VECTOR[nFaces];
283  // calcul des normales aux faces
284  for(int i=0;i<nFaces;i++) {
285  VECTOR V12, V13;
286  V12.diff( Vertex[ Indice[3*i+1] ].P, Vertex[ Indice[3*i] ].P );
287  V13.diff( Vertex[ Indice[3*i+2] ].P, Vertex[ Indice[3*i] ].P );
288  FaceNormals[i].vecprod(V12,V13);
289  FaceNormals[i].normalize();
290  }
291  // moyennage des normales
292  iVertFace *iVF = new iVertFace[3*nFaces];
293  for(int i=0,k=0;i<nFaces;i++) {
294  iVF[k].iFace = i;
295  iVF[k].iVert = Indice[k];
296  k++;
297  iVF[k].iFace = i;
298  iVF[k].iVert = Indice[k];
299  k++;
300  iVF[k].iFace = i;
301  iVF[k].iVert = Indice[k];
302  k++;
303  }
304  // tri des indices
305  std::sort(iVF,iVF+3*nFaces);
306  // calcul des normales aux sommets
307  int k=0;
308  for(int i=0;i<nVertex;i++) {
309  Vertex[i].N.zero();
310  while( iVF[k].iVert == i ) {
311  Vertex[i].N.add( FaceNormals[ iVF[k].iFace ] );
312  k++;
313  }
314  Vertex[i].N.normalize();
315  }
316 }
317 
318 #define EUCLIDIANDIST
319 float Mesh::Distance(Mesh::COLOR &col1, Mesh::COLOR &col2) {
320  float dist;
321  float dr = (col1.r - col2.r) * 255.f;
322  float dg = (col1.g - col2.g) * 255.f;
323  float db = (col1.b - col2.b) * 255.f;
324  float da = (col1.a - col2.a) * 255.f;
325 #ifdef EUCLIDIANDIST
326  dist = sqrtf( dr*dr + dg*dg + db*db * da*da );
327 #else
328  float rmean = (col1.r + col2.r) * 255.f / 2.f;
329  dist = sqrtf( (512.f+rmean)*dr*dr/256.f + 4.f*dg*dg + (767.f-rmean)*db*db/256.f + da*da ) / 256.f;
330 #endif
331  return dist;
332 }
333 
334 void Mesh::COLOR::Interpolate(float u1, Mesh::COLOR &col1, float u2, Mesh::COLOR &col2) {
335  r = u1*col1.r + u2*col2.r;
336  g = u1*col1.g + u2*col2.g;
337  b = u1*col1.b + u2*col2.b;
338  a = u1*col1.a + u2*col2.a;
339 }
340 
341 float Mesh::Distance(MATERIAL &mat1, MATERIAL &mat2) {
342  float d = Distance( mat1.Ambient, mat2.Ambient );
343  d += Distance( mat1.Diffuse, mat2.Diffuse );
344  d += Distance( mat1.Emissive, mat2.Emissive );
345  d += Distance( mat1.Specular, mat2.Specular );
346  d += fabs( logf(mat1.Power) - logf(mat2.Power) );
347  return d;
348 }
349 
350 void Mesh::MATERIAL::Interpolate(int n1, Mesh::MATERIAL &mat1, int n2, Mesh::MATERIAL &mat2) {
351  float u = float(n1)/float(n1+n2), v = float(n2)/float(n1+n2);
352  Ambient.Interpolate(u,mat1.Ambient,v,mat2.Ambient);
353  Diffuse.Interpolate(u,mat1.Diffuse,v,mat2.Diffuse);
354  Emissive.Interpolate(u,mat1.Emissive,v,mat2.Emissive);
355  Specular.Interpolate(u,mat1.Specular,v,mat2.Specular);
356  Power = expf( u*(mat1.Power<1.f ? 0.f : logf(mat1.Power)) + v*(mat2.Power<1.f ? 0.f : logf(mat2.Power)) );
357 }
358 
359 void Mesh::Object::CompressAttributeTable(float Similarity) {
360  int *nA, *iA;
361 
362  if (nMaterials == 0) return;
363 
364  // calcul du max des mat�riaux
365  int MatMin, MatMax;
366  MatMin = MatMax = Attribute[0];
367  for(int i=1;i<nFaces;i++) {
368  if (Attribute[i]>MatMax) MatMax = Attribute[i];
369  if (Attribute[i]<MatMin) MatMin = Attribute[i];
370  }
371  printf("Attribute Value Extrema: %d %d\n",MatMin,MatMax);
372  if ((MatMin == 1) && (MatMax == nMaterials)) { // d�calage de 1 dans la table des mat�riaux
373  printf("WARNING: invalid attribute table (numbered from 1 instead of 0) - renumbering\n");
374  for(int i=0;i<nFaces;i++) --(Attribute[i]);
375  MatMin = 0;
376  MatMax--;
377  }
378 
379  // renum�rotation
380  if (MatMax >= nMaterials) {
381  printf("WARNING: invalid attribute table - renumbering by increasing numbers\n");
382  // attributs de chaque mat�riau
383  int *table = new int[MatMax+1];
384  memset(table,0,(MatMax+1)*sizeof(int));
385  for(int i=0;i<nFaces;i++) table[ Attribute[i] ]++;
386  // nombre de mat�riaux r�els
387  int cMat = 0;
388  for(int i=0;i<MatMax+1;i++)
389  if (table[i] > 0) cMat++;
390  if (cMat > nMaterials) printf("WARNING: too much attributes\n");
391  // table de conversion
392  int firstMat = (cMat == nMaterials ? 1 : 0);
393  for(int i=0,k=firstMat;i<MatMax+1;i++) {
394  if (table[i] > 0) {
395  table[i] = std::min(k,nMaterials-1);
396  k++;
397  } else table[i] = -1;
398  }
399  // printf("Conversion table\n"); for(int i=0,k=firstMat;i<MatMax+1;i++) printf("%2d-%d ",i,table[i]); printf("\n");
400  // renumerotation des mat�riaux
401  for(int i=0;i<nFaces;i++) Attribute[i] = table[ Attribute[i] ];
402  // liberation
403  delete [] table;
404  }
405 
406  // compression 1 : retrait des attributs dont le num�ro d'index n'est pas utilis�
407  // pour compter le nombre de faces qui utilisent ce mat�riau
408  printf("Invalid Attribute: ");
409  bool invalid = false;
410  nA = new int[nMaterials];
411  memset(nA,0,nMaterials*sizeof(int));
412  for(int i=0;i<nFaces;i++) {
413  if (Attribute[i] >= nMaterials) {
414  printf("%d ",Attribute[i]);
415  Attribute[i]=0;
416  invalid=true;
417  }
418  nA[ Attribute[i] ]++;
419  }
420  if (invalid == false) printf("none found.");
421  printf("\n");
422 
423  // table de correspondance avant compression (i -> i)
424  iA = new int[nMaterials];
425  for(int i=0;i<nMaterials;i++) iA[i] = i;
426  // affichage des stats
427  int j=0;
428  for(int i=0;i<nMaterials;i++) {
429  if (nA[i]>0) {
430  iA[i] = j;
431  Material[j] = Material[i];
432  nA[j] = nA[i];
433  j++;
434  }
435  }
436  printf("\nOldTable=%d NewTable = %d\n",nMaterials,j);
437  nMaterials = j;
438 
439  printf("Attributes Table:\n\t");
440  for(int i=0;i<nMaterials;i++) {
441  printf("%02d->%02d %05d ",i,iA[i],nA[iA[i]]);
442  if ((i+1)%3 == 0) printf("\n\t");
443  }
444  printf("\n");
445 
446  // remplacement de l'indice du mat�riau avant compression par l'indice apr�s compression
447  for(int i=0;i<nFaces;i++) Attribute[i] = iA[ Attribute[i] ];
448 
449  // compression 2 : construction d'une table de distance entre materiaux
450  printf("Compressing similar colors:\n");
451  int nDist = nMaterials*(nMaterials-1)/2;
452  MaterialComp *MatDist = new MaterialComp[nDist];
453  // r�organisation de la table de conversion
454  for(int i=0;i<nMaterials;i++) iA[i] = i;
455  bool Change;
456  do {
457  // table des distances � trier
458  int nDist = 0;
459  Change = false;
460  for(int i=0; i<nMaterials-1; i++) {
461  for(int j=i+1;j<nMaterials;j++) {
462  if ((iA[i]!=i) || (iA[j]!=j)) continue;
463  MatDist[nDist].i = i;
464  MatDist[nDist].j = j;
465  MatDist[nDist].d = Distance( Material[i], Material[j] );
466  nDist++;
467  }
468  }
469  if (nDist > 0) {
470  std::sort(MatDist,MatDist+nDist);
471  // fusion des premi�res si le crit�re est respect�
472  if (MatDist[0].d < Similarity) {
473  int i0 = MatDist[0].i, i1 = MatDist[0].j;
474  if ( (iA[i0] == i0) && (iA[i1] == i1) ) { // i.e. couleurs non encore �chang�es
475  iA[i1] = i0; // new color indice of i1
476  Material[i0].Interpolate( nA[i0], Material[i0], nA[i1], Material[i1] ); // new material as barycenter
477  nA[i0] += nA[i1]; // updating the current indice mass
478  for(int k=0;k<nMaterials;k++) if (iA[k]==i1) iA[k]=i0; // redirecting all other indices pointing to i1 to i0
479  printf("\t(%2d -> %2d) %f %d\n",i1,i0,MatDist[0].d,nA[i0]);
480  Change = true;
481  }
482  }
483  }
484  } while(Change);
485  // table compression
486  { // here nDist = nb different colors
487  int *iB = new int[nMaterials]; // unique identifier table
488  memset(iB,0,nMaterials*sizeof(int));
489  // final shifting table
490  int Nmat=0;
491  for(int i=0; i<nMaterials; i++) {
492  // WriteConsole("\t%2d -> %2d\n",i,iA[i]);
493  if (iA[i] == i) {
494  Material[Nmat] = Material[ iA[i] ];
495  iB[i] = Nmat;
496  Nmat++;
497  }
498  }
499  // changing attribute
500  for(int i=0;i<nFaces;i++)
501  Attribute[i] = iB[ iA[ Attribute[i] ] ];
502  delete [] iB;
503  nMaterials = Nmat;
504  printf("Final table : %d colors\n",nMaterials);
505  }
506 
507  // applying indice changes
508  delete [] iA;
509  delete [] nA;
510 }
511 
513  memset(Attribute, 0, nFaces*sizeof(int) );
514  nMaterials = 1;
516  Material = new MATERIAL;
517  Material[0].Ambient.set(0.f);
518  Material[0].Diffuse.set(0.8f);
519  Material[0].Specular.set(0.2f);
520  Material[0].Emissive.set(0.f);
521  Material[0].Power = 30.f;
522 }
523 
525  printf("Vertex Info (nVertex=%d)\n",nVertex);
526  n = (n == 0 ? nVertex : std::min(nVertex,10) );
527 
528  for(int i=0;i<n;i++)
529  printf("%3d: P=[%4.2f %4.2f %4.2f] N=[%4.2f %4.2f %4.2f]\n",i,Vertex[i].P.x,Vertex[i].P.y,Vertex[i].P.z,Vertex[i].N.x,Vertex[i].N.y,Vertex[i].N.z);
530 
531  BOUNDINGBOX bb = GetBoundingBox();
532  printf("Bounding box = [%4.2f %4.2f %4.2f] -> [%4.2f %4.2f %4.2f]\n",bb.Min.x, bb.Min.y, bb.Min.z, bb.Max.x, bb.Max.y, bb.Max.z );
533 }
534 
536  printf("Faces Info (nFaces=%d)\n",nFaces);
537  n = (n == 0 ? nFaces : std::min(nFaces,10) );
538  for(int i=0;i<n;i++) {
539  if ((i>0) && (i%4==0)) printf("\n");
540  printf("[%3d %3d %3d - %3d] ",Indice[3*i],Indice[3*i+1],Indice[3*i+2],Attribute[i]);
541  }
542 }
543 
545  printf("Material Info (nMaterials=%d)\n",nMaterials);
546  n = (n == 0 ? nMaterials : std::min(nMaterials,10) );
547  for(int i=0;i<n;i++) {
548  printf("%2d Ambient=[%4.2f %4.2f %4.2f %4.2f], Diffuse=[%4.2f %4.2f %4.2f %4.2f], Specular=[%4.2f %4.2f %4.2f %4.2f], Emissive=[%4.2f %4.2f %4.2f %4.2f] Power=%f\n",
549  i,
550  Material[i].Ambient.r, Material[i].Ambient.g, Material[i].Ambient.b, Material[i].Ambient.a,
551  Material[i].Diffuse.r, Material[i].Diffuse.g, Material[i].Diffuse.b, Material[i].Diffuse.a,
552  Material[i].Specular.r, Material[i].Specular.g, Material[i].Specular.b, Material[i].Specular.a,
553  Material[i].Emissive.r, Material[i].Emissive.g, Material[i].Emissive.b, Material[i].Emissive.a,
554  Material[i].Power);
555  }
556 }
557 
559  VECTOR Pmin, Pmax;
560  Pmin = Vertex[0].P;
561  Pmax = Vertex[0].P;
562  for(int i=1;i<nVertex;i++) {
563  if (Pmin.x > Vertex[i].P.x) Pmin.x = Vertex[i].P.x;
564  if (Pmax.x < Vertex[i].P.x) Pmax.x = Vertex[i].P.x;
565  if (Pmin.y > Vertex[i].P.y) Pmin.y = Vertex[i].P.y;
566  if (Pmax.y < Vertex[i].P.y) Pmax.y = Vertex[i].P.y;
567  if (Pmin.z > Vertex[i].P.z) Pmin.z = Vertex[i].P.z;
568  if (Pmax.z < Vertex[i].P.z) Pmax.z = Vertex[i].P.z;
569  }
570  BOUNDINGBOX bb = { Pmin, Pmax };
571  return bb;
572 }
573 
574 
576  if (nVertex == 0) return;
577  // calcul du min/max
578  BOUNDINGBOX bb = GetBoundingBox();
579  // centre de l'objet
580  VECTOR C = { (bb.Min.x + bb.Max.x)*0.5f, (bb.Min.y + bb.Max.y)*0.5f, (bb.Min.z + bb.Max.z)*0.5f };
581  // facteur d'�chelle
582  float InvS = 2.f / std::max( std::max( bb.Max.x - bb.Min.x, bb.Max.y - bb.Min.y ), bb.Max.z - bb.Min.z );
583  // transformation des sommets
584  for(int i=0; i<nVertex; i++) {
585  Vertex[i].P.x = (Vertex[i].P.x - C.x) * InvS;
586  Vertex[i].P.y = (Vertex[i].P.y - C.y) * InvS;
587  Vertex[i].P.z = (Vertex[i].P.z - C.z) * InvS;
588  }
589 }
COLOR Ambient
Definition: ReadMesh.h:20
MeKeyWord MeKeyWordLst[nMeKeyWord]
Definition: ReadMesh.cpp:44
#define max(a, b)
Definition: defUtil.h:30
BOUNDINGBOX GetBoundingBox(void)
normalisation de l'objet ([-1;+1] x [-1;+1] x [-1;+1])
Definition: ReadMesh.cpp:558
void Interpolate(int n1, MATERIAL &mat1, int n2, MATERIAL &mat2)
exposant sp�culaire
Definition: ReadMesh.cpp:350
void CompressAttributeTable(float)
met la table des mat�riaux � 0 (m�me mat�riau pour toutes les faces)
Definition: ReadMesh.cpp:359
float a
Definition: ReadMesh.h:10
~Object()
constructeur
Definition: ReadMesh.cpp:77
Object()
calcul des normales � partir de la g�om�trie de l'objet
Definition: ReadMesh.cpp:60
int nFaces
Definition: ReadMesh.h:57
int iVert
Definition: ReadMesh.cpp:50
float b
Definition: ReadMesh.h:10
MeKeyWord GetMeKeyword(char *line)
Definition: ReadMesh.cpp:100
boite englobante
Definition: ReadMesh.h:50
#define SAFE_ARRAY_DELETE(x)
Definition: ReadMesh.cpp:11
KeyWord KeyWordLst[nKeyWord]
Definition: ReadMesh.cpp:32
Structure définissant un matériau tel que vu dans le cours (modèle de Phong).
Definition: Material.h:6
const int nMeKeyWord
Definition: ReadMesh.cpp:41
int * Attribute
tableau des indices (3 indices cons�cutifs = 1 face)
Definition: ReadMesh.h:60
void Clear(void)
Definition: ReadMesh.cpp:68
distance entre 2 couleurs
Definition: ReadMesh.h:19
bool LoadMesh(const char *fname, bool invface)
reduit le nombre de mat�riaux dans la table (param�tre=distance entre 2 mat�riaux pour les amalgam...
Definition: ReadMesh.cpp:115
void normalize(void)
norme du vecteur
Definition: ReadMesh.h:34
float y
Definition: ReadMesh.h:29
void Interpolate(float u1, COLOR &col1, float u2, COLOR &col2)
rouge, vert, bleu, alpha
Definition: ReadMesh.cpp:334
float Power
couleurs diffuses, ambiante, sp�culaire et �missive
Definition: ReadMesh.h:21
structure de sommet (position+normale)
Definition: ReadMesh.h:42
float r
Definition: ReadMesh.h:10
const char KeyWordStr[nKeyWord][32]
Definition: ReadMesh.cpp:24
void set(const rgb &_col, float _kd, float _ks, float _ns)
Fixe les propriétés du matériau.
Definition: Material.h:16
VERTEX * Vertex
nombre de sommets, de faces et de mat�riaux
Definition: ReadMesh.h:58
float Distance(COLOR &col1, COLOR &col2)
Definition: ReadMesh.cpp:319
structure pour la gestion des couleurs
Definition: ReadMesh.h:9
KeyWord GetKeyword(char *line)
Definition: ReadMesh.cpp:85
INDICE * Indice
tableau de sommets
Definition: ReadMesh.h:59
COLOR Specular
Definition: ReadMesh.h:20
int nMaterials
Definition: ReadMesh.h:57
const int nKeyWord
Definition: ReadMesh.cpp:15
COLOR Emissive
Definition: ReadMesh.h:20
float g
Definition: ReadMesh.h:10
void Normalize(void)
destructeur
Definition: ReadMesh.cpp:575
float z
Definition: ReadMesh.h:29
void MaterialInfo(int=0)
affiche les 10 premi�res faces
Definition: ReadMesh.cpp:544
void FlattenAttributeTable(void)
calcule et retourne la boite englobante
Definition: ReadMesh.cpp:512
distance entre 2 mat�riaux
Definition: ReadMesh.h:28
bool LoadMaterial(const char *, bool skip0)
charge un objet g�om�trique .mesh dans l'objet (invface = inverser l'ordre des faces (false = ...
Definition: ReadMesh.cpp:209
void vecprod(VECTOR &v1, VECTOR &v2)
ajoute un vecteur au vecteur courant
Definition: ReadMesh.h:37
void FacesInfo(int=0)
affiche les 10 premiers sommets
Definition: ReadMesh.cpp:535
void diff(VECTOR &v1, VECTOR &v2)
normalise le vecteur
Definition: ReadMesh.h:35
void ComputeNormals(void)
tableau des mat�riaux
Definition: ReadMesh.cpp:281
unsigned int INDICE
indice des sommets
Definition: ReadMesh.h:46
int nVertex
Definition: ReadMesh.h:57
bool operator<(const iVertFace &a, const iVertFace &b)
Definition: ReadMesh.cpp:51
const char MeKeyWordStr[nMeKeyWord][12]
Definition: ReadMesh.cpp:43
float x
Definition: ReadMesh.h:29
int iFace
Definition: ReadMesh.cpp:50
void VertexInfo(int=0)
charge un table de mat�riau .medit dans l'objet (skip0 = ne pas utiliser le mat�riau 0 - faux en gï¿...
Definition: ReadMesh.cpp:524
#define min(a, b)
Definition: defUtil.h:29
COLOR Diffuse
Definition: ReadMesh.h:20