1#include <stdio.h> 2#include <stdlib.h> 3#include <assert.h> 4#include <string.h> 5 6#include "libmesh3.h" 7#include "medit.h" 8#include "extern.h" 9#include "sproto.h" 10 11 12/* save mesh to disk */ 13int outmsh(pScene sc,pMesh mesh,char *fileout,ubyte clipon) { 14 LM_mesh_struct ms; 15 pPoint ppt,p1,p2,p3,p4; 16 pTetra ptt; 17 pTriangle pt1; 18 pQuad pq1; 19 pEdge pr; 20 pMaterial pm; 21 float *tv; 22 int *te,*tmp,i,k,l,bin,np,ne,nn,nt,nq,nav,ver; 23 int m,nridge,nrequis; 24 int ncorner,prequis,nbpos,nbneg,nbnul,nedge; 25 char vers[128]; 26 27 if ( !LM_open_mesh(fileout, LM_WRITE, &ms, sm->dim) ) { 28 fprintf(stderr," ** UNABLE TO OPEN %s.\n",data); 29 return(0); 30 } 31 fprintf(stdout," %%%% %s OPENED\n",fileout); 32 33 /* compact vertices */ 34 tabi = (int*)malloc(NPMAX * 4 * sizeof(int)); 35 assert(tabi); 36 tabf = (float*)tabi; 37 38 if ( clipon ) markPt(mesh); 39 40 nbl = 0; 41 for(k=1; k<=mesh->np; k++) { 42 ppt = &mesh->point[k]; 43 if ( ppt->tag & M_UNUSED ) continue; 44 iadr = nbl * 4; 45 tabf[ iadr + 0 ] = ppt->c[0]; 46 tabf[ iadr + 1 ] = ppt->c[1]; 47 tabf[ iadr + 2 ] = ppt->c[2]; 48 tabi[ iadr + 3 ] = ppt->ref; 49 ++nbl; 50 if ( nbl == NPMAX ) { 51 LM_write_field(&ms, LM_Vertices, nbl, tabf); 52 nbl = 0; 53 } 54 } 55 LM_write_field(&ms, LM_Vertices, nbl, tabf); 56 57 58 59 for (k=1; k<=mesh->np; k++) { 60 ppt = &mesh->point[k]; 61 if ( ppt->ttmp ) 62 ppt->tmp = ++np; 63 } 64 65 66 /* mark used faces */ 67 if ( clipon ) { 68 for (k=1; k<=sm->nt; k++) { 69 pt1 = & sm->tria[k]; 70 if ( !pt1->v[0] ) continue; 71 nbpos = nbneg = nbnul = 0; 72 for (l=0; l<3; l++) { 73 ppt = &sm->point[pt1->v[l]]; 74 if ( ppt->clip == 2 ) nbpos++; 75 else if ( ppt->clip == 1 ) nbneg++; 76 else nbnul++; 77 } 78 if ( nbpos && nbpos+nbnul < 4 ) { 79 ++ne; 80 ++nt; 81 for (l=0; l<3; l++) { 82 ppt = &sm->point[pt1->v[l]]; 83 tmp[pt1->v[l]] = 1; 84 } 85 } 86 else 87 pt1->v[0] = 0; 88 } 89 for (k=1; k<=sm->nq; k++) { 90 pq1 = & sm->quad[k]; 91 if ( !pq1->v[0] ) continue; 92 nbpos = nbneg = nbnul = 0; 93 for (l=0; l<4; l++) { 94 ppt = &sm->point[pq1->v[l]]; 95 if ( ppt->clip == 2 ) nbpos++; 96 else if ( ppt->clip == 1 ) nbneg++; 97 else nbnul++; 98 } 99 if ( nbpos && nbpos+nbnul < 5 ) { 100 ++ne; 101 ++nq; 102 for (l=0; l<4; l++) { 103 ppt = &sm->point[pq1->v[l]]; 104 tmp[pq1->v[l]] = 1; 105 } 106 } 107 else 108 pq1->v[0] = 0; 109 } 110 } 111 112 else { 113 for (k=1; k<=sm->nt; k++) { 114 pt1 = &sm->tria[k]; 115 if ( !pt1->v[0] ) continue; 116 m = matRef(sc,pt1->ref); 117 pm = &sc->material[m]; 118 if ( pm->flag ) continue; 119 ++ne; 120 ++nt; 121 for (i=0; i<3; i++) tmp[pt1->v[i]] = 1; 122 } 123 for (k=1; k<=sm->nq; k++) { 124 pq1 = &sm->quad[k]; 125 if ( !pq1->v[0] ) continue; 126 m = matRef(sc,pq1->ref); 127 pm = &sc->material[m]; 128 if ( pm->flag ) continue; 129 ++ne; 130 ++nq; 131 for (i=0; i<4; i++) tmp[pq1->v[i]] = 1; 132 } 133 for (k=1; k<=sm->ntet; k++) { 134 ptt = &sm->tetra[k]; 135 if ( !ptt->v[0] ) continue; 136 m = matRef(sc,ptt->ref); 137 pm = &sc->material[m]; 138 if ( pm->flag ) continue; 139 ++ne; 140 for (i=0; i<4; i++) tmp[ptt->v[i]] = 1; 141 } 142 } 143 if ( !ne ) { 144 fclose(out); 145 free(tmp); 146 return(1); 147 } 148 149 /* mark used vertices */ 150 np = nav = 0; 151 ncorner = prequis = 0; 152 for (k=1; k<=sm->np; k++) { 153 ppt = &sm->point[k]; 154 if ( !tmp[k] ) continue; 155 tmp[k] = ++np; 156 if ( ppt->tag == M_NOTAG ) nav++; 157 } 158 159 /* mesh vertices */ 160 np = 0; 161 if ( sm->dim == 3 ) { 162 te = (int*)malloc(4*(sm->np+1)*sizeof(int)); 163 tv = (float*)te; 164 if ( te ) { 165 for (k=1; k<=sm->np; k++) { 166 if ( !tmp[k] ) continue; 167 ppt = & sm->point[k]; 168 tv[np*4+0] = ppt->x + sm->xtra; 169 tv[np*4+1] = ppt->y + sm->ytra; 170 tv[np*4+2] = ppt->z + sm->ztra; 171 te[np*4+3] = (int)ppt->ref; 172 np++; 173 if ( ppt->tag & M_CORNER ) ncorner++; 174 if ( ppt->tag & M_REQUIRED ) prequis++; 175 } 176 ecrire_bloc(out,te,np,Vertices,4,"%g %g %g %d\n"); 177 free(te); 178 } 179 else { 180 if ( !bin ) formater(out); 181 ecrire_commentaire(out,"Set of mesh vertices"); 182 ecrire_mot_clef(out,Vertices); 183 ecrire_int(out,np); 184 if ( !bin ) formater(out); 185 for (k=1; k<=sm->np; k++) { 186 if ( !tmp[k] ) continue; 187 ppt = & sm->point[k]; 188 np++; 189 ecrire_reel(out,ppt->x); 190 ecrire_reel(out,ppt->y); 191 ecrire_reel(out,ppt->z); 192 ecrire_int(out,(int)ppt->ref); 193 if ( !bin ) formater(out); 194 if ( ppt->tag & M_CORNER ) ncorner++; 195 if ( ppt->tag & M_REQUIRED ) prequis++; 196 } 197 } 198 } 199 else { 200 te = (int*)malloc(3*sm->np*sizeof(int)); 201 tv = (float*)te; 202 if ( tv ) { 203 for (k=1; k<=sm->np; k++) { 204 if ( !tmp[k] ) continue; 205 ppt = & sm->point[k]; 206 tv[np*3+0] = ppt->x; 207 tv[np*3+1] = ppt->y; 208 te[np*3+2] = (int)ppt->ref; 209 if ( ppt->tag & M_CORNER ) ncorner++; 210 if ( ppt->tag & M_REQUIRED ) prequis++; 211 np++; 212 } 213 ecrire_bloc(out,te,np,Vertices,3,"%g %g %d\n"); 214 free(te); 215 } 216 else { 217 if ( !bin ) formater(out); 218 ecrire_commentaire(out,"Set of mesh vertices"); 219 ecrire_mot_clef(out,Vertices); 220 ecrire_int(out,np); 221 if ( !bin ) formater(out); 222 for (k=1; k<=sm->np; k++) { 223 if ( !tmp[k] ) continue; 224 ppt = & sm->point[k]; 225 ecrire_reel(out,ppt->x); 226 ecrire_reel(out,ppt->y); 227 ecrire_int(out,(int)ppt->ref); 228 if ( !bin ) formater(out); 229 if ( ppt->tag & M_CORNER ) ncorner++; 230 if ( ppt->tag & M_REQUIRED ) prequis++; 231 } 232 } 233 } 234 235 /* mesh triangles */ 236 if ( !bin ) formater(out); 237 nridge = nrequis = nn = 0; 238 te = (int*)malloc((4*sm->nt+1)*sizeof(int)); 239 if ( te ) { 240 ne = 0; 241 for (k=1; k<=sm->nt; k++) { 242 pt1 = &sm->tria[k]; 243 if ( !pt1->v[0] ) continue; 244 m = matRef(sc,pt1->ref); 245 /*m = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/ 246 pm = &sc->material[m]; 247 if ( pm->flag ) continue; 248 te[ne++] = tmp[pt1->v[0]]; 249 te[ne++] = tmp[pt1->v[1]]; 250 te[ne++] = tmp[pt1->v[2]]; 251 te[ne++] = (int)pt1->ref; 252 } 253 ne /= 4; 254 ecrire_bloc(out,te,ne,Triangles,4,"%d %d %d %d\n"); 255 free(te); 256 } 257 else { 258 if ( !bin ) formater(out); 259 ecrire_commentaire(out,"Set of mesh triangles (v1,v2,v3,tag)"); 260 ecrire_mot_clef(out,Triangles); 261 ecrire_int(out,nt); 262 if ( !bin ) formater(out); 263 for (k=1; k<=sm->nt; k++) { 264 pt1 = &sm->tria[k]; 265 if ( !pt1->v[0] ) continue; 266 m = matRef(sc,pt1->ref); 267 /*m = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/ 268 pm = &sc->material[m]; 269 if ( pm->flag ) continue; 270 if ( !tmp[pt1->v[0]] || !tmp[pt1->v[1]] || !tmp[pt1->v[2]] ) 271 continue; 272 ecrire_int(out,tmp[pt1->v[0]]); 273 ecrire_int(out,tmp[pt1->v[1]]); 274 ecrire_int(out,tmp[pt1->v[2]]); 275 ecrire_int(out,(int)pt1->ref); 276 if ( !bin ) formater(out); 277 } 278 } 279 280 /* mesh quads */ 281 if ( !bin ) formater(out); 282 te = (int*)malloc((5*sm->nq+1)*sizeof(int)); 283 if ( te ) { 284 ne = 0; 285 for (k=1; k<=sm->nq; k++) { 286 pq1 = &sm->quad[k]; 287 if ( !pq1->v[0] ) continue; 288 m = matRef(sc,pq1->ref); 289 /*m = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/ 290 pm = &sc->material[m]; 291 if ( pm->flag ) continue; 292 p1 = &sm->point[pq1->v[0]]; 293 p2 = &sm->point[pq1->v[1]]; 294 p3 = &sm->point[pq1->v[2]]; 295 p4 = &sm->point[pq1->v[3]]; 296 if ( !tmp[pq1->v[0]] || !tmp[pq1->v[1]] || !tmp[pq1->v[2]] || !tmp[pq1->v[3]] ) 297 continue; 298 299 te[ne++] = tmp[pq1->v[0]]; 300 te[ne++] = tmp[pq1->v[1]]; 301 te[ne++] = tmp[pq1->v[2]]; 302 te[ne++] = tmp[pq1->v[3]]; 303 te[ne++] = (int)pq1->ref; 304 } 305 ne /= 5; 306 ecrire_bloc(out,te,ne,Quadrilaterals,5,"%d %d %d %d %d\n"); 307 free(te); 308 } 309 else { 310 if ( !bin ) formater(out); 311 ecrire_commentaire(out,"Set of mesh quads (v1,v2,v3,v4,tag)"); 312 ecrire_mot_clef(out,Quadrilaterals); 313 ecrire_int(out,nq); 314 if ( !bin ) formater(out); 315 for (k=1; k<=sm->nq; k++) { 316 pq1 = &sm->quad[k]; 317 if ( !pq1->v[0] ) continue; 318 m = matRef(sc,pq1->ref); 319 /*m = !pt1->ref ? DEFAULT_MAT : 1+(pt1->ref-1)%(sc->par.nbmat-1);*/ 320 pm = &sc->material[m]; 321 if ( pm->flag ) continue; 322 p1 = &sm->point[pq1->v[0]]; 323 p2 = &sm->point[pq1->v[1]]; 324 p3 = &sm->point[pq1->v[2]]; 325 p4 = &sm->point[pq1->v[3]]; 326 if ( !tmp[pq1->v[0]] || !tmp[pq1->v[1]] || !tmp[pq1->v[2]] || !tmp[pq1->v[3]] ) 327 continue; 328 ecrire_int(out,tmp[pq1->v[0]]); 329 ecrire_int(out,tmp[pq1->v[1]]); 330 ecrire_int(out,tmp[pq1->v[2]]); 331 ecrire_int(out,tmp[pq1->v[3]]); 332 ecrire_int(out,(int)pq1->ref); 333 if ( !bin ) formater(out); 334 } 335 } 336 337 /* corners */ 338 te = (int*)malloc(3*(sm->np+1)*sizeof(int)); 339 if ( ncorner ) { 340 if ( te ) { 341 ncorner = 0; 342 for (k=1; k<=sm->np; k++) { 343 ppt = &sm->point[k]; 344 if ( !tmp[k] ) continue; 345 else if ( ppt->tag & M_CORNER ) 346 te[ncorner++] = tmp[k]; 347 } 348 ecrire_bloc(out,te,ncorner,Corners,1,"%d\n"); 349 } 350 else { 351 if ( !bin ) formater(out); 352 ecrire_commentaire(out,"Set of corners"); 353 ecrire_mot_clef(out,Corners); 354 ecrire_int(out,ncorner); 355 if ( !bin ) formater(out); 356 for (k=1; k<=sm->np; k++) { 357 ppt = &sm->point[k]; 358 if ( !tmp[k] ) continue; 359 else if ( ppt->tag & M_CORNER ) { 360 ecrire_int(out,tmp[k]); 361 if ( !bin ) formater(out); 362 } 363 } 364 } 365 } 366 367 /* required vertices */ 368 if ( prequis ) { 369 if ( te ) { 370 prequis = 0; 371 for (k=1; k<=sm->np; k++) { 372 ppt = &sm->point[k]; 373 if ( !tmp[k] ) continue; 374 else if ( ppt->tag & M_REQUIRED ) 375 te[prequis++] = tmp[k]; 376 } 377 ecrire_bloc(out,te,prequis,RequiredVertices,1,"%d\n"); 378 } 379 else { 380 if ( !bin ) formater(out); 381 ecrire_commentaire(out,"Set of required vertices"); 382 ecrire_mot_clef(out,RequiredVertices); 383 ecrire_int(out,prequis); 384 if ( !bin ) formater(out); 385 for (k=1; k<=sm->np; k++) { 386 ppt = &sm->point[k]; 387 if ( !tmp[k] ) continue; 388 else if ( ppt->tag & M_REQUIRED ) { 389 ecrire_int(out,tmp[k]); 390 if ( !bin ) formater(out); 391 } 392 } 393 } 394 } 395 if ( te ) free(te); 396 397 /* edges */ 398 nedge = 0; 399 for (k=1; k<=sm->na; k++) { 400 pr = &sm->edge[k]; 401 p1 = &sm->point[pr->v[0]]; 402 p2 = &sm->point[pr->v[1]]; 403 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 404 ++nedge; 405 } 406 if ( nedge ) { 407 te = (int*)malloc(3*(sm->na+1)*sizeof(int)); 408 nridge = nrequis = 0; 409 if ( te ) { 410 nedge = 0; 411 for (k=1; k<=sm->na; k++) { 412 pr = &sm->edge[k]; 413 p1 = &sm->point[pr->v[0]]; 414 p2 = &sm->point[pr->v[1]]; 415 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 416 417 te[nedge++] = tmp[pr->v[0]]; 418 te[nedge++] = tmp[pr->v[1]]; 419 te[nedge++] = pr->tag; 420 if ( pr->tag & M_RIDGE ) nridge++; 421 if ( pr->tag & M_REQUIRED) nrequis++; 422 } 423 nedge /= 3; 424 ecrire_bloc(out,te,nedge,Edges,3,"%d %d %d\n"); 425 } 426 else { 427 if ( !bin ) formater(out); 428 ecrire_commentaire(out,"Set of mesh edges (v1,v2,tag)"); 429 ecrire_mot_clef(out,Edges); 430 ecrire_int(out,nedge); 431 if ( !bin ) formater(out); 432 for (k=1; k<=sm->na; k++) { 433 pr = &sm->edge[k]; 434 p1 = &sm->point[pr->v[0]]; 435 p2 = &sm->point[pr->v[1]]; 436 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 437 ecrire_int(out,tmp[pr->v[0]]); 438 ecrire_int(out,tmp[pr->v[1]]); 439 ecrire_int(out,pr->tag); 440 if ( !bin ) formater(out); 441 } 442 } 443 444 /* ridges */ 445 if ( nridge ) { 446 if ( te ) { 447 nridge = nedge = 0; 448 for (k=1; k<=sm->na; k++) { 449 pr = &sm->edge[k]; 450 p1 = &sm->point[pr->v[0]]; 451 p2 = &sm->point[pr->v[1]]; 452 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 453 ++nedge; 454 if ( pr->tag & M_RIDGE ) 455 te[nridge++] = nedge; 456 } 457 ecrire_bloc(out,te,nridge,Ridges,1,"%d\n"); 458 } 459 else { 460 if ( !bin ) formater(out); 461 ecrire_commentaire(out,"Set of ridges (iv,tag)"); 462 ecrire_mot_clef(out,Ridges); 463 ecrire_int(out,nridge); 464 if ( !bin ) formater(out); 465 nridge = nedge = 0; 466 for (k=1; k<=sm->na; k++) { 467 pr = &sm->edge[k]; 468 p1 = &sm->point[pr->v[0]]; 469 p2 = &sm->point[pr->v[1]]; 470 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 471 ++nedge; 472 if ( pr->tag & M_RIDGE ) { 473 ecrire_int(out,nedge); 474 if ( !bin ) formater(out); 475 } 476 } 477 } 478 } 479 480 /* required edges */ 481 if ( nrequis ) { 482 if ( te ) { 483 nrequis = nedge = 0; 484 for (k=1; k<=sm->na; k++) { 485 pr = &sm->edge[k]; 486 p1 = &sm->point[pr->v[0]]; 487 p2 = &sm->point[pr->v[1]]; 488 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 489 ++nedge; 490 if ( pr->tag & M_REQUIRED ) 491 te[nrequis++] = nedge; 492 } 493 ecrire_bloc(out,te,nrequis,RequiredEdges,1,"%d\n"); 494 } 495 else { 496 if ( !bin ) formater(out); 497 ecrire_commentaire(out,"Set of required edges (iv,tag)"); 498 ecrire_mot_clef(out,RequiredEdges); 499 ecrire_int(out,nrequis); 500 if ( !bin ) formater(out); 501 nridge = nedge = 0; 502 for (k=1; k<=sm->na; k++) { 503 pr = &sm->edge[k]; 504 p1 = &sm->point[pr->v[0]]; 505 p2 = &sm->point[pr->v[1]]; 506 if ( !tmp[pr->v[0]] || !tmp[pr->v[1]] ) continue; 507 ++nedge; 508 if ( pr->tag & M_REQUIRED ) { 509 ecrire_int(out,nedge); 510 if ( !bin ) formater(out); 511 } 512 } 513 } 514 } 515 if ( te ) free(te); 516 } 517 ecrire_mot_clef(out,End); 518 fclose(out); 519 free(tmp); 520 521 if ( !quiet ) { 522 fprintf(stdout," Vertices %8d",sm->np); 523 fprintf(stdout," Corners %d",ncorner); 524 fprintf(stdout," Required %d\n",prequis); 525 fprintf(stdout," Edges %8d",nedge); 526 fprintf(stdout," Ridges %d",nridge); 527 fprintf(stdout," Required %d\n",nrequis); 528 if ( sm->ne ) fprintf(stdout," Triangles %8d Quads %8d\n",nt,nq); 529 } 530 531 return(1); 532} 533