1 #define _CRT_SECURE_NO_WARNINGS
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; } }
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"
73 nVertex = nFaces = nMaterials = 0;
87 sscanf(line,
"%s",key);
88 if (key[0]==
'#')
return Comment;
102 sscanf(line,
"%s",key);
119 const int bufsize=1024;
130 ptf = fopen(fname,
"r");
131 if (ptf == NULL)
return false;
132 while( fgets(line,bufsize,ptf) != NULL ) {
136 case Dimension: fgets(line,bufsize,ptf);
break;
138 fgets(line,bufsize,ptf);
139 sscanf(line,
"%d",&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);
145 if (nread != 4) { printf(
"Vertices Read Error: read=%d\n",nread); nVertex = i;
break; }
150 fgets(line,bufsize,ptf);
151 sscanf(line,
"%d",&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]) );
159 if (Attribute[i] > nMaterials) nMaterials = Attribute[i];
160 if (nread != 4) { printf(
"Triangle Read Error: read=%d\n",nread); nFaces=i;
break; }
165 int v0, v1, v2, v3, m;
166 fgets(line,bufsize,ptf);
167 sscanf(line,
"%d",&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);
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;
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;
180 if (m > nMaterials) nMaterials = m;
184 if (nread != 5) { printf(
"Quadrilaterals Read Error: read=%d\n",nread); nFaces=i;
break; }
189 printf(
"WARNING: %s are not processed\n",
KeyWordStr[(
int)k]);
193 if ((nFaces == 0) || (nVertex == 0)) {
201 for(
int i=0; i<3*nFaces; i++) Indice[i]--;
211 const int bufsize=1024;
213 char line[bufsize],keyw[128],mname[128],mtext[128];
214 int i=0, mid, nmatmesh;
217 nmatmesh = nMaterials;
220 printf(
"ReadMedit : %s\n",fname);
221 ptf = fopen(fname,
"r");
223 printf(
"\tFile not found\n");
225 }
else printf(
"\tFile opened\n");
226 while( fgets(line,bufsize,ptf) != NULL ) {
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) {
247 printf(
"ReadError: material found but no nbmaterial.");
250 int nfield = sscanf(line,
"%s %s %s",keyw,mname,mtext);
251 if ((nfield==3) && (isdigit(mtext[0]))) mid = atoi(mtext);
254 printf(
"\t%d Read: %s %d\n",i,mname,mid);
256 fgets(line,bufsize,ptf);
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);
262 fgets(line,bufsize,ptf);
264 fgets(line,bufsize,ptf);
265 sscanf(line,
"%f",&m.
Power);
266 if (i >= nMaterials) {
267 printf(
"ReadError: more material than nbmaterial.");
274 if (i == nMaterials-1) nMaterials--;
275 printf(
"%d materials found (%d indicated)\n",i,nMaterials);
276 if (i<nMaterials) printf(
"WARNING: supplementary materials set to 0\n");
284 for(
int i=0;i<nFaces;i++) {
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);
293 for(
int i=0,k=0;i<nFaces;i++) {
295 iVF[k].
iVert = Indice[k];
298 iVF[k].
iVert = Indice[k];
301 iVF[k].
iVert = Indice[k];
305 std::sort(iVF,iVF+3*nFaces);
308 for(
int i=0;i<nVertex;i++) {
310 while( iVF[k].iVert == i ) {
311 Vertex[i].N.add( FaceNormals[ iVF[k].iFace ] );
314 Vertex[i].N.normalize();
318 #define EUCLIDIANDIST
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;
326 dist = sqrtf( dr*dr + dg*dg + db*db * da*da );
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;
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;
346 d += fabs( logf(mat1.
Power) - logf(mat2.
Power) );
351 float u = float(n1)/float(n1+n2), v = float(n2)/float(n1+n2);
356 Power = expf( u*(mat1.
Power<1.f ? 0.f : logf(mat1.
Power)) + v*(mat2.
Power<1.f ? 0.f : logf(mat2.
Power)) );
362 if (nMaterials == 0)
return;
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];
371 printf(
"Attribute Value Extrema: %d %d\n",MatMin,MatMax);
372 if ((MatMin == 1) && (MatMax == nMaterials)) {
373 printf(
"WARNING: invalid attribute table (numbered from 1 instead of 0) - renumbering\n");
374 for(
int i=0;i<nFaces;i++) --(Attribute[i]);
380 if (MatMax >= nMaterials) {
381 printf(
"WARNING: invalid attribute table - renumbering by increasing numbers\n");
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] ]++;
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");
392 int firstMat = (cMat == nMaterials ? 1 : 0);
393 for(
int i=0,k=firstMat;i<MatMax+1;i++) {
395 table[i] =
std::min(k,nMaterials-1);
397 }
else table[i] = -1;
401 for(
int i=0;i<nFaces;i++) Attribute[i] = table[ Attribute[i] ];
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]);
418 nA[ Attribute[i] ]++;
420 if (invalid ==
false) printf(
"none found.");
424 iA =
new int[nMaterials];
425 for(
int i=0;i<nMaterials;i++) iA[i] = i;
428 for(
int i=0;i<nMaterials;i++) {
436 printf(
"\nOldTable=%d NewTable = %d\n",nMaterials,j);
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");
447 for(
int i=0;i<nFaces;i++) Attribute[i] = iA[ Attribute[i] ];
450 printf(
"Compressing similar colors:\n");
451 int nDist = nMaterials*(nMaterials-1)/2;
454 for(
int i=0;i<nMaterials;i++) iA[i] = i;
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;
470 std::sort(MatDist,MatDist+nDist);
472 if (MatDist[0].d < Similarity) {
473 int i0 = MatDist[0].i, i1 = MatDist[0].j;
474 if ( (iA[i0] == i0) && (iA[i1] == i1) ) {
478 for(
int k=0;k<nMaterials;k++)
if (iA[k]==i1) iA[k]=i0;
479 printf(
"\t(%2d -> %2d) %f %d\n",i1,i0,MatDist[0].d,nA[i0]);
487 int *iB =
new int[nMaterials];
488 memset(iB,0,nMaterials*
sizeof(
int));
491 for(
int i=0; i<nMaterials; i++) {
500 for(
int i=0;i<nFaces;i++)
501 Attribute[i] = iB[ iA[ Attribute[i] ] ];
504 printf(
"Final table : %d colors\n",nMaterials);
513 memset(Attribute, 0, nFaces*
sizeof(
int) );
525 printf(
"Vertex Info (nVertex=%d)\n",nVertex);
526 n = (n == 0 ? nVertex :
std::min(nVertex,10) );
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);
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 );
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]);
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",
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;
576 if (nVertex == 0)
return;
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;
MeKeyWord MeKeyWordLst[nMeKeyWord]
BOUNDINGBOX GetBoundingBox(void)
normalisation de l'objet ([-1;+1] x [-1;+1] x [-1;+1])
void Interpolate(int n1, MATERIAL &mat1, int n2, MATERIAL &mat2)
exposant sp�culaire
void CompressAttributeTable(float)
met la table des mat�riaux � 0 (m�me mat�riau pour toutes les faces)
Object()
calcul des normales � partir de la g�om�trie de l'objet
MeKeyWord GetMeKeyword(char *line)
#define SAFE_ARRAY_DELETE(x)
KeyWord KeyWordLst[nKeyWord]
Structure définissant un matériau tel que vu dans le cours (modèle de Phong).
int * Attribute
tableau des indices (3 indices cons�cutifs = 1 face)
distance entre 2 couleurs
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...
void normalize(void)
norme du vecteur
void Interpolate(float u1, COLOR &col1, float u2, COLOR &col2)
rouge, vert, bleu, alpha
float Power
couleurs diffuses, ambiante, sp�culaire et �missive
structure de sommet (position+normale)
const char KeyWordStr[nKeyWord][32]
void set(const rgb &_col, float _kd, float _ks, float _ns)
Fixe les propriétés du matériau.
VERTEX * Vertex
nombre de sommets, de faces et de mat�riaux
float Distance(COLOR &col1, COLOR &col2)
structure pour la gestion des couleurs
KeyWord GetKeyword(char *line)
INDICE * Indice
tableau de sommets
void Normalize(void)
destructeur
void MaterialInfo(int=0)
affiche les 10 premi�res faces
void FlattenAttributeTable(void)
calcule et retourne la boite englobante
distance entre 2 mat�riaux
bool LoadMaterial(const char *, bool skip0)
charge un objet g�om�trique .mesh dans l'objet (invface = inverser l'ordre des faces (false = ...
void vecprod(VECTOR &v1, VECTOR &v2)
ajoute un vecteur au vecteur courant
void FacesInfo(int=0)
affiche les 10 premiers sommets
void diff(VECTOR &v1, VECTOR &v2)
normalise le vecteur
void ComputeNormals(void)
tableau des mat�riaux
unsigned int INDICE
indice des sommets
bool operator<(const iVertFace &a, const iVertFace &b)
const char MeKeyWordStr[nMeKeyWord][12]
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ï¿...