00001 #include "mrilib.h"
00002
00003
00004
00005
00006
00007 #define SUMA_EXTEND_NUM 64
00008 #define SUMA_EXTEND_FAC 1.05
00009
00010
00011
00012
00013
00014 SUMA_surface * SUMA_create_empty_surface(void)
00015 {
00016 SUMA_surface *ag ;
00017
00018 ENTRY("SUMA_create_empty_surface") ;
00019
00020 ag = (SUMA_surface *) calloc(1,sizeof(SUMA_surface)) ;
00021 ag->type = SUMA_SURFACE_TYPE ;
00022
00023 ag->num_ixyz = ag->num_ijk = 0 ;
00024 ag->nall_ixyz = ag->nall_ijk = 1 ;
00025 ag->ixyz = (SUMA_ixyz *) malloc(sizeof(SUMA_ixyz)) ;
00026 ag->ijk = (SUMA_ijk *) malloc(sizeof(SUMA_ijk) ) ;
00027 ag->norm = NULL ; ;
00028
00029 if( ag->ixyz == NULL || ag->ijk == NULL ){
00030 fprintf(stderr,"SUMA_create_empty_surface: can't malloc!\n"); EXIT(1);
00031 }
00032
00033 ag->idcode[0] = ag->idcode_dset[0] = ag->idcode_ldp[0] =
00034 ag->label[0] = ag->label_ldp[0] = '\0' ;
00035
00036 ag->xbot = ag->ybot = ag->zbot = WAY_BIG ;
00037 ag->xtop = ag->ytop = ag->ztop = -WAY_BIG ;
00038 ag->xcen = ag->ycen = ag->zcen = 0.0 ;
00039
00040 ag->seq = ag->seqbase = ag->sorted = 0 ;
00041
00042 ag->vv = NULL ;
00043 ag->vn = NULL ;
00044
00045 RETURN( ag ) ;
00046 }
00047
00048
00049
00050
00051
00052 void SUMA_destroy_surface( SUMA_surface *ag )
00053 {
00054 ENTRY("SUMA_destroy_surface") ;
00055
00056 if( ag == NULL ) EXRETURN ;
00057 if( ag->ixyz != NULL ) free((void *)ag->ixyz) ;
00058 if( ag->ijk != NULL ) free((void *)ag->ijk) ;
00059 if( ag->norm != NULL ) free((void *)ag->norm) ;
00060
00061 if( ag->vv != NULL ) DESTROY_VVLIST(ag->vv) ;
00062 if( ag->vn != NULL ) SUMA_destroy_vnlist(ag->vn) ;
00063
00064 free((void *)ag) ; EXRETURN ;
00065 }
00066
00067
00068
00069
00070
00071 void SUMA_add_nodes_ixyz( SUMA_surface *ag, int nadd,
00072 int *iadd, float *xadd, float *yadd, float *zadd )
00073 {
00074 int ii , nup ;
00075
00076 ENTRY("SUMA_add_nodes_ixyz") ;
00077
00078 if( ag == NULL || nadd < 1 ) EXRETURN ;
00079 if( xadd == NULL || yadd == NULL || zadd == NULL || iadd == NULL ) EXRETURN ;
00080
00081 nup = ag->num_ixyz + nadd ;
00082
00083 if( nup >= SUMA_MAX_NODES ){
00084 fprintf(stderr,
00085 "** SUMA surface can't have more than %d nodes!\n",
00086 SUMA_MAX_NODES-1 ) ;
00087 EXRETURN ;
00088 }
00089
00090 if( nup > ag->nall_ixyz ){
00091 ag->nall_ixyz = nup = nup*SUMA_EXTEND_FAC + SUMA_EXTEND_NUM ;
00092 ag->ixyz = (SUMA_ixyz *) realloc( (void *)ag->ixyz, sizeof(SUMA_ixyz)*nup );
00093 if( ag->ixyz == NULL ){
00094 fprintf(stderr,"SUMA_add_nodes_ixyz: can't malloc!\n"); EXIT(1);
00095 }
00096 }
00097
00098 nup = ag->num_ixyz ;
00099
00100 for( ii=0 ; ii < nadd ; ii++ ){
00101 ag->ixyz[ii+nup].x = xadd[ii] ;
00102 ag->ixyz[ii+nup].y = yadd[ii] ;
00103 ag->ixyz[ii+nup].z = zadd[ii] ;
00104 ag->ixyz[ii+nup].id = iadd[ii] ;
00105 }
00106
00107 ag->num_ixyz += nadd ;
00108
00109 ag->seq = ag->sorted = 0 ; EXRETURN ;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119 int SUMA_add_norms_xyz( SUMA_surface *ag, int nadd,
00120 float *xadd, float *yadd, float *zadd )
00121 {
00122 int ii ;
00123
00124 ENTRY("SUMA_add_norms_xyz") ;
00125
00126 if( ag == NULL || nadd < 1 ) RETURN(-1) ;
00127 if( xadd == NULL || yadd == NULL || zadd == NULL ) RETURN(-1) ;
00128
00129 if( nadd != ag->num_ixyz ){
00130 fprintf(stderr, "** SUMA surface has %d nodes but %d normals!\n",
00131 ag->num_ixyz, nadd ) ;
00132 RETURN(-1) ;
00133 }
00134
00135
00136 if( ag->norm == NULL ){
00137 ag->norm = (THD_fvec3 *)calloc(nadd, sizeof(THD_fvec3));
00138 if( ag->norm == NULL ){
00139 fprintf(stderr,"SUMA_add_norms_xyz: can't malloc!\n"); EXIT(1);
00140 }
00141 }
00142
00143 for( ii=0 ; ii < nadd ; ii++ ){
00144 ag->norm[ii].xyz[0] = xadd[ii] ;
00145 ag->norm[ii].xyz[1] = yadd[ii] ;
00146 ag->norm[ii].xyz[2] = zadd[ii] ;
00147 }
00148
00149 RETURN(0) ;
00150 }
00151
00152
00153
00154
00155
00156 void SUMA_add_node_ixyz( SUMA_surface *ag , int i,float x,float y,float z )
00157 {
00158 SUMA_add_nodes_ixyz( ag , 1 , &i,&x,&y,&z ) ;
00159 }
00160
00161
00162
00163
00164
00165 void SUMA_add_triangles( SUMA_surface *ag, int nadd, int *it, int *jt, int *kt )
00166 {
00167 int ii , nup ;
00168
00169 ENTRY("SUMA_add_triangles") ;
00170
00171 if( ag == NULL || nadd < 1 ) EXRETURN ;
00172 if( it == NULL || jt == NULL || kt == NULL ) EXRETURN ;
00173
00174 nup = ag->num_ijk + nadd ;
00175 if( nup > ag->nall_ijk ){
00176 ag->nall_ijk = nup = nup*SUMA_EXTEND_FAC + SUMA_EXTEND_NUM ;
00177 ag->ijk = (SUMA_ijk *) realloc( (void *)ag->ijk , sizeof(SUMA_ijk)*nup ) ;
00178 if( ag->ijk == NULL ){
00179 fprintf(stderr,"SUMA_add_triangles: can't malloc!\n"); EXIT(1);
00180 }
00181 }
00182
00183 nup = ag->num_ijk ;
00184 for( ii=0 ; ii < nadd ; ii++ ){
00185 ag->ijk[ii+nup].id = it[ii] ;
00186 ag->ijk[ii+nup].jd = jt[ii] ;
00187 ag->ijk[ii+nup].kd = kt[ii] ;
00188 }
00189
00190 ag->num_ijk += nadd ; EXRETURN ;
00191 }
00192
00193
00194
00195
00196
00197 void SUMA_add_triangle( SUMA_surface *ag, int it, int jt, int kt )
00198 {
00199 SUMA_add_triangles( ag , 1 , &it,&jt,&kt ) ;
00200 }
00201
00202
00203
00204
00205
00206
00207 void SUMA_truncate_memory( SUMA_surface *ag )
00208 {
00209 int nn ;
00210
00211 ENTRY("SUMA_truncate_memory") ;
00212
00213 if( ag == NULL ) EXRETURN ;
00214
00215 if( ag->num_ixyz < ag->nall_ixyz && ag->num_ixyz > 0 ){
00216 ag->nall_ixyz = nn = ag->num_ixyz ;
00217 ag->ixyz = (SUMA_ixyz *) realloc( (void *)ag->ixyz, sizeof(SUMA_ixyz)*nn );
00218 }
00219
00220 if( ag->num_ijk < ag->nall_ijk && ag->num_ijk > 0 ){
00221 ag->nall_ijk = nn = ag->num_ijk ;
00222 ag->ijk = (SUMA_ijk *) realloc( (void *)ag->ijk , sizeof(SUMA_ijk)*nn ) ;
00223 }
00224
00225 EXRETURN ;
00226 }
00227
00228
00229
00230
00231
00232 #undef STYPE
00233 #define STYPE SUMA_ixyz
00234 #define SLT(a,b) ((a).id < (b).id)
00235 #define SNAME SUMA_ixyz
00236 #include "cs_sort_template.h"
00237 #undef STYPE
00238
00239
00240
00241
00242
00243
00244
00245 void SUMA_ixyzsort_surface( SUMA_surface *ag )
00246 {
00247 int nn , ii , ndup ;
00248 float xb,yb,zb , xt,yt,zt , xc,yc,zc ;
00249
00250 ENTRY("SUMA_ixyzsort_surface") ;
00251
00252 if( ag == NULL || ag->num_ixyz < 1 ) EXRETURN ;
00253
00254 SUMA_truncate_memory( ag ) ;
00255
00256 nn = ag->num_ixyz ;
00257
00258
00259
00260 for( ii=1 ; ii < nn ; ii++ )
00261 if( ag->ixyz[ii].id <= ag->ixyz[ii-1].id ) break ;
00262
00263
00264
00265
00266 if( ii < nn ){
00267 qsort_SUMA_ixyz( nn , ag->ixyz ) ;
00268 }
00269
00270 ag->sorted = 1 ;
00271
00272
00273
00274 for( ii=1 ; ii < nn ; ii++ )
00275 if( ag->ixyz[ii].id != ag->ixyz[ii-1].id+1 ) break ;
00276
00277
00278
00279
00280
00281 if( ii == nn ){
00282 ag->seq = 1 ; ag->seqbase = ag->ixyz[0].id ;
00283 }
00284
00285
00286
00287 for( ndup=0,ii=1 ; ii < nn ; ii++ )
00288 if( ag->ixyz[ii].id == ag->ixyz[ii-1].id ) ndup++ ;
00289
00290 if( ndup > 0 )
00291 fprintf(stderr,"** SUMA WARNING: %d duplicate surface node id's found!\n",ndup);
00292
00293
00294
00295 xb = xt = ag->ixyz[0].x ;
00296 yb = yt = ag->ixyz[0].y ;
00297 zb = zt = ag->ixyz[0].z ;
00298 xc = yc = zc = 0.0 ;
00299 for( ii=1 ; ii < nn ; ii++ ){
00300 xc += ag->ixyz[ii].x ;
00301 yc += ag->ixyz[ii].y ;
00302 zc += ag->ixyz[ii].z ;
00303
00304 if( ag->ixyz[ii].x < xb ) xb = ag->ixyz[ii].x ;
00305 else if( ag->ixyz[ii].x > xt ) xt = ag->ixyz[ii].x ;
00306
00307 if( ag->ixyz[ii].y < yb ) yb = ag->ixyz[ii].y ;
00308 else if( ag->ixyz[ii].y > yt ) yt = ag->ixyz[ii].y ;
00309
00310 if( ag->ixyz[ii].z < zb ) zb = ag->ixyz[ii].z ;
00311 else if( ag->ixyz[ii].z > zt ) zt = ag->ixyz[ii].z ;
00312 }
00313
00314 ag->xbot = xb ; ag->xtop = xt ;
00315 ag->ybot = yb ; ag->ytop = yt ;
00316 ag->zbot = zb ; ag->ztop = zt ;
00317
00318 ag->xcen = xc/nn ; ag->ycen = yc/nn ; ag->zcen = zc/nn ;
00319
00320 EXRETURN ;
00321 }
00322
00323
00324
00325
00326
00327
00328 int SUMA_find_node_id( SUMA_surface *ag , int target )
00329 {
00330 int nn , ii,jj,kk ;
00331
00332 if( ag == NULL || ag->num_ixyz < 1 || target < 0 ) return( -1 );
00333
00334 if( !ag->sorted ) SUMA_ixyzsort_surface( ag ) ;
00335
00336 if( ag->seq ){
00337 kk = target - ag->seqbase ;
00338 if( kk >= 0 && kk < ag->num_ixyz ) return( kk );
00339 return( -1 );
00340 }
00341
00342
00343
00344
00345 ii = 0 ; jj = ag->num_ixyz - 1 ;
00346
00347 if( target < ag->ixyz[0].id ) return( -1 );
00348 else if( target == ag->ixyz[0].id ) return( ii );
00349
00350 if( target > ag->ixyz[jj].id ) return( -1 );
00351 else if( target == ag->ixyz[jj].id ) return( jj );
00352
00353 while( jj - ii > 1 ){
00354
00355 kk = (ii+jj) / 2 ;
00356
00357 nn = ag->ixyz[kk].id - target ;
00358 if( nn == 0 ) return( kk );
00359
00360 if( nn < 0 ) ii = kk ;
00361 else jj = kk ;
00362 }
00363
00364 return( -1 );
00365 }
00366
00367
00368
00369
00370
00371 SUMA_vnlist * SUMA_make_vnlist( SUMA_surface *ag , THD_3dim_dataset *dset )
00372 {
00373 int ii,jj,kk , nx,ny,nz , nxy,nxyz , nnode , pp,qq,nn,nvox ;
00374 THD_fvec3 fv ;
00375 THD_ivec3 iv ;
00376 int *vlist , *nlist , wodsave ;
00377 SUMA_vnlist *vnlist ;
00378 float xbot,xtop , ybot,ytop , zbot,ztop ;
00379
00380 ENTRY("SUMA_make_vnlist") ;
00381
00382 if( ag == NULL || ag->num_ixyz < 1 || !ISVALID_DSET(dset) ) RETURN(NULL) ;
00383
00384 if( !ag->sorted ) SUMA_ixyzsort_surface( ag ) ;
00385
00386
00387
00388 nx = DSET_NX(dset) ; ny = DSET_NY(dset) ; nz = DSET_NZ(dset) ;
00389 nxy = nx*ny ; nxyz = nxy*nz ; nnode = ag->num_ixyz ;
00390 vlist = (int *) malloc(sizeof(int)*nnode) ;
00391 nlist = (int *) malloc(sizeof(int)*nnode) ;
00392 if( vlist == NULL || nlist == NULL ){
00393 fprintf(stderr,"SUMA_make_vnlist: can't malloc!\n"); EXIT(1);
00394 }
00395
00396
00397
00398 wodsave = dset->wod_flag ; dset->wod_flag = 0 ;
00399
00400 xbot = DSET_XXMIN(dset) ; xtop = DSET_XXMAX(dset) ;
00401 ybot = DSET_YYMIN(dset) ; ytop = DSET_YYMAX(dset) ;
00402 zbot = DSET_ZZMIN(dset) ; ztop = DSET_ZZMAX(dset) ;
00403
00404 for( nn=pp=0 ; pp < nnode ; pp++ ){
00405 LOAD_FVEC3( fv , ag->ixyz[pp].x, ag->ixyz[pp].y, ag->ixyz[pp].z ) ;
00406 fv = THD_dicomm_to_3dmm( dset , fv ) ;
00407
00408 if( fv.xyz[0] < xbot || fv.xyz[0] > xtop ) continue ;
00409 if( fv.xyz[1] < ybot || fv.xyz[1] > ytop ) continue ;
00410 if( fv.xyz[2] < zbot || fv.xyz[2] > ztop ) continue ;
00411
00412 iv = THD_3dmm_to_3dind( dset , fv ) ;
00413 UNLOAD_IVEC3( iv , ii,jj,kk ) ;
00414
00415 nlist[nn] = pp ;
00416 vlist[nn] = ii + jj*nx + kk*nxy ;
00417 nn++ ;
00418 }
00419
00420 nnode = nn ;
00421 if( nnode == 0 ){ free(nlist); free(vlist); RETURN(NULL); }
00422
00423 dset->wod_flag = wodsave ;
00424
00425
00426
00427
00428 qsort_intint( nnode , vlist , nlist ) ;
00429
00430
00431
00432 nvox = 1 ; ii = vlist[0] ;
00433 for( pp=1 ; pp < nnode ; pp++ ){
00434 if( vlist[pp] != ii ){ nvox++; ii = vlist[pp]; }
00435 }
00436
00437
00438
00439 vnlist = (SUMA_vnlist *) malloc( sizeof(SUMA_vnlist) ) ;
00440 vnlist->nvox = nvox ;
00441 vnlist->voxijk = (int *) malloc(sizeof(int) *nvox) ;
00442 vnlist->numnod = (int *) calloc(sizeof(int) ,nvox) ;
00443 vnlist->nlist = (int **)malloc(sizeof(int*)*nvox);
00444 vnlist->dset = dset ;
00445
00446 if( vnlist->voxijk==NULL || vnlist->numnod==NULL || vnlist->nlist==NULL ){
00447 fprintf(stderr,"SUMA_make_vnlist: can't malloc!\n"); EXIT(1);
00448 }
00449
00450
00451
00452 ii = vlist[0] ; qq = nn = 0 ;
00453 for( pp=1 ; pp < nnode ; pp++ ){
00454 if( vlist[pp] != ii ){
00455 vnlist->voxijk[nn] = ii ;
00456 vnlist->numnod[nn] = jj = pp-qq ;
00457 vnlist->nlist[nn] = (int *) malloc(sizeof(int)*jj) ;
00458 memcpy( vnlist->nlist[nn] , nlist+qq , sizeof(int)*jj ) ;
00459 ii = vlist[pp] ; nn++ ; qq = pp ;
00460 }
00461 }
00462 vnlist->voxijk[nn] = ii ;
00463 vnlist->numnod[nn] = jj = pp-qq ;
00464 vnlist->nlist[nn] = (int *) malloc(sizeof(int)*jj) ;
00465 memcpy( vnlist->nlist[nn] , nlist+qq , sizeof(int)*jj ) ;
00466
00467
00468
00469 free(nlist) ; free(vlist) ; RETURN( vnlist ) ;
00470 }
00471
00472
00473
00474
00475
00476 void SUMA_destroy_vnlist( SUMA_vnlist *vnlist )
00477 {
00478 int ii ;
00479 if( vnlist == NULL ) return ;
00480 if( vnlist->voxijk != NULL ) free( vnlist->voxijk ) ;
00481 if( vnlist->numnod != NULL ) free( vnlist->numnod ) ;
00482 if( vnlist->nlist != NULL ){
00483 for( ii=0 ; ii < vnlist->nvox ; ii++ )
00484 if( vnlist->nlist[ii] != NULL ) free( vnlist->nlist[ii] ) ;
00485 free( vnlist->nlist ) ;
00486 }
00487 free( vnlist ) ;
00488 }
00489
00490
00491
00492
00493
00494
00495 THD_fvec3 THD_dicomm_to_surefit( THD_3dim_dataset *dset , THD_fvec3 fv )
00496 {
00497 float xx,yy,zz , xbase,ybase,zbase ;
00498 THD_fvec3 vout ;
00499
00500 xx = -fv.xyz[0] ; yy = -fv.xyz[1] ; zz = fv.xyz[2] ;
00501
00502 if( dset != NULL ){
00503 THD_fvec3 v1 , v2 ;
00504 LOAD_FVEC3(v1, DSET_XORG(dset),DSET_YORG(dset),DSET_ZORG(dset)) ;
00505 v1 = THD_3dmm_to_dicomm( dset , v1 ) ;
00506 LOAD_FVEC3(v2, DSET_XORG(dset)+(DSET_NX(dset)-1)*DSET_DX(dset) ,
00507 DSET_YORG(dset)+(DSET_NY(dset)-1)*DSET_DY(dset) ,
00508 DSET_ZORG(dset)+(DSET_NZ(dset)-1)*DSET_DZ(dset) ) ;
00509 v2 = THD_3dmm_to_dicomm( dset , v2 ) ;
00510 xbase = MAX( v1.xyz[0] , v2.xyz[0] ) ; xbase = -xbase ;
00511 ybase = MAX( v1.xyz[1] , v2.xyz[1] ) ; ybase = -ybase ;
00512 zbase = MIN( v1.xyz[2] , v2.xyz[2] ) ;
00513 } else {
00514 xbase = ybase = zbase = 0.0 ;
00515 }
00516
00517 vout.xyz[0] = xx - xbase ;
00518 vout.xyz[1] = yy - ybase ;
00519 vout.xyz[2] = zz - zbase ; return vout ;
00520 }
00521
00522
00523
00524 THD_fvec3 THD_surefit_to_dicomm( THD_3dim_dataset *dset , THD_fvec3 fv )
00525 {
00526 float xx,yy,zz , xbase,ybase,zbase ;
00527 THD_fvec3 vout ;
00528
00529 xx = -fv.xyz[0] ; yy = -fv.xyz[1] ; zz = fv.xyz[2] ;
00530
00531 if( dset != NULL ){
00532 THD_fvec3 v1 , v2 ;
00533 LOAD_FVEC3(v1, DSET_XORG(dset),DSET_YORG(dset),DSET_ZORG(dset)) ;
00534 v1 = THD_3dmm_to_dicomm( dset , v1 ) ;
00535 LOAD_FVEC3(v2, DSET_XORG(dset)+(DSET_NX(dset)-1)*DSET_DX(dset) ,
00536 DSET_YORG(dset)+(DSET_NY(dset)-1)*DSET_DY(dset) ,
00537 DSET_ZORG(dset)+(DSET_NZ(dset)-1)*DSET_DZ(dset) ) ;
00538 v2 = THD_3dmm_to_dicomm( dset , v2 ) ;
00539 xbase = MAX( v1.xyz[0] , v2.xyz[0] ) ; xbase = -xbase ;
00540 ybase = MAX( v1.xyz[1] , v2.xyz[1] ) ; ybase = -ybase ;
00541 zbase = MIN( v1.xyz[2] , v2.xyz[2] ) ;
00542 } else {
00543 xbase = ybase = zbase = 0.0 ;
00544 }
00545
00546 vout.xyz[0] = xx - xbase ;
00547 vout.xyz[1] = yy - ybase ;
00548 vout.xyz[2] = zz + zbase ; return vout ;
00549 }
00550
00551
00552
00553
00554
00555 #undef ALLOW_SURFACE_FILES
00556 #ifdef ALLOW_SURFACE_FILES
00557
00558
00559
00560 #undef NBUF
00561 #define NBUF 64
00562
00563
00564
00565
00566
00567
00568
00569 SUMA_surface * SUMA_read_surface( char *fname , THD_3dim_dataset *dset )
00570 {
00571 SUMA_surface *ag ;
00572 FILE *fp ;
00573 char lbuf[1024] , *cpt ;
00574 int do_nod=1 , ii ;
00575 float xx[NBUF],yy[NBUF],zz[NBUF] ;
00576 int pp[NBUF],qq[NBUF],rr[NBUF] , nn ;
00577
00578 THD_vecmat mv ;
00579 int have_mv=0 ;
00580
00581 ENTRY("SUMA_read_surface") ;
00582
00583 if( fname == NULL || fname[0] == '\0' ) RETURN( NULL );
00584
00585
00586
00587 if( strcmp(fname,"-") == 0 ){
00588 fp = stdin ;
00589 } else {
00590 fp = fopen( fname , "r" ) ;
00591 if( fp == NULL ) RETURN( NULL );
00592 }
00593
00594
00595
00596 ag = SUMA_create_empty_surface() ;
00597
00598
00599
00600 cpt = UNIQ_hashcode(fname); strcpy(ag->idcode,cpt); free(cpt);
00601
00602 strcpy( ag->idcode_dset , dset->idcode.str ) ;
00603
00604 MCW_strncpy( ag->label, THD_trailname(fname,0), 32 ) ;
00605
00606
00607
00608 nn = 0 ;
00609 while(1){
00610 cpt = fgets(lbuf,1024,fp) ;
00611 if( cpt == NULL ) break ;
00612
00613
00614
00615 if( strncmp(lbuf,"<MATVEC>",8) == 0 ){
00616 float a11,a12,a13 , v1 ,
00617 a21,a22,a23 , v2 ,
00618 a31,a32,a33 , v3 ;
00619
00620 ii = sscanf( lbuf+8 , "%f%f%f%f%f%f%f%f%f%f%f%f" ,
00621 &a11,&a12,&a13 , &v1 ,
00622 &a21,&a22,&a23 , &v2 ,
00623 &a31,&a32,&a33 , &v3 ) ;
00624
00625 if( ii < 12 ){
00626 fprintf(stderr,"** SUMA: Illegal MATVEC in %s\n",fname) ;
00627 have_mv = 0 ;
00628 } else {
00629 LOAD_FVEC3(mv.vv , v1,v2,v3 ) ;
00630 LOAD_MAT (mv.mm , a11,a12,a13,a21,a22,a23,a31,a32,a33) ;
00631 have_mv = 1 ;
00632 }
00633 continue ;
00634 }
00635
00636
00637
00638 if( strncmp(lbuf,"<SureFit",8) == 0 ){
00639
00640 if( nn > 0 ){
00641 if( do_nod )
00642 SUMA_add_nodes_ixyz( ag,nn , pp,xx,yy,zz ) ;
00643 else
00644 SUMA_add_triangles( ag,nn , pp,qq,rr ) ;
00645 nn = 0 ;
00646 }
00647
00648 SUMA_import_surefit( ag , lbuf , dset ) ;
00649 continue ;
00650
00651 }
00652
00653
00654
00655 if( strstr(lbuf,"</NODES>") != NULL ){
00656 if( do_nod && nn > 0 ){
00657 SUMA_add_nodes_ixyz( ag,nn , pp,xx,yy,zz ) ;
00658 nn = 0 ;
00659 }
00660 #if 1
00661 do_nod = 0 ;
00662 continue ;
00663 #else
00664 break ;
00665 #endif
00666 }
00667
00668
00669
00670 if( do_nod ){
00671
00672 ii = sscanf(lbuf,"%d%f%f%f",pp+nn,xx+nn,yy+nn,zz+nn) ;
00673 if( ii < 4 ) continue ;
00674 if( have_mv ){
00675 THD_fvec3 fv , qv ;
00676 LOAD_FVEC3(fv , xx[nn],yy[nn],zz[nn] ) ;
00677 qv = VECSUB_MAT( mv.mm , fv , mv.vv ) ;
00678 UNLOAD_FVEC3( qv , xx[nn],yy[nn],zz[nn] ) ;
00679 }
00680 nn++ ;
00681 if( nn == NBUF ){
00682 SUMA_add_nodes_ixyz( ag,nn , pp,xx,yy,zz ) ;
00683 nn = 0 ;
00684 }
00685
00686
00687
00688 } else {
00689
00690 ii = sscanf(lbuf,"%d%d%d",pp+nn,qq+nn,rr+nn) ;
00691 if( ii < 3 ) continue ;
00692 nn++ ;
00693 if( nn == NBUF ){
00694 SUMA_add_triangles( ag,nn , pp,qq,rr ) ;
00695 nn = 0 ;
00696 }
00697 }
00698 }
00699
00700
00701
00702 if( fp != stdin ) fclose(fp) ;
00703 if( nn > 0 ){
00704 if( do_nod )
00705 SUMA_add_nodes_ixyz( ag,nn , pp,xx,yy,zz ) ;
00706 else
00707 SUMA_add_triangles( ag,nn , pp,qq,rr ) ;
00708 }
00709
00710
00711
00712 if( ag->num_ixyz < 1 ){
00713 SUMA_destroy_surface(ag) ; RETURN(NULL) ;
00714 }
00715
00716
00717
00718 SUMA_ixyzsort_surface(ag) ;
00719
00720
00721
00722 RETURN( ag );
00723 }
00724
00725
00726
00727
00728
00729
00730 static int ip[26][3] = { {-1,-1,-1},{-1,-1, 0},{-1,-1, 1},
00731 {-1, 0,-1},{-1, 0, 0},{-1, 0, 1},
00732 {-1, 1,-1},{-1, 1, 0},{-1, 1, 1},
00733 { 0,-1,-1},{ 0,-1, 0},{ 0,-1, 1},
00734 { 0, 0,-1}, { 0, 0, 1},
00735 { 0, 1,-1},{ 0, 1, 0},{ 0, 1, 1},
00736 { 1,-1,-1},{ 1,-1, 0},{ 1,-1, 1},
00737 { 1, 0,-1},{ 1, 0, 0},{ 1, 0, 1},
00738 { 1, 1,-1},{ 1, 1, 0},{ 1, 1, 1} } ;
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 int * SUMA_map_dset_to_surf( SUMA_surface *ag , THD_3dim_dataset *dset )
00766 {
00767 int *vmap , ii,jj,kk , nx,ny,nz , nxy,nxyz , pp,qq,pbest ;
00768 THD_fvec3 fv ;
00769 THD_ivec3 iv ;
00770 int ibot,jbot,kbot , itop,jtop,ktop , lev , ijk ;
00771 float xv,yv,zv , dd,dbest=0 , xp,yp,zp ;
00772 char *elev ; int ltop , ntop , lmask ;
00773
00774 ENTRY("SUMA_map_dset_to_surf") ;
00775
00776 if( ag == NULL || ag->num_ixyz < 1 || !ISVALID_DSET(dset) ) RETURN( NULL );
00777
00778 if( !ag->sorted ) SUMA_ixyzsort_surface( ag ) ;
00779
00780
00781
00782 nx = DSET_NX(dset) ; ny = DSET_NY(dset) ; nz = DSET_NZ(dset) ;
00783 nxy = nx*ny ; nxyz = nxy*nz ;
00784 vmap = (int *) malloc(sizeof(int)*nxyz) ;
00785 if( vmap == NULL ){
00786 fprintf(stderr,"SUMA_map_dset_to_surf: can't malloc!\n"); EXIT(1);
00787 }
00788 for( ii=0 ; ii < nxyz ; ii++ ) vmap[ii] = -1 ;
00789
00790
00791
00792 STATUS("putting nodes into voxels") ;
00793
00794 for( pp=0 ; pp < ag->num_ixyz ; pp++ ){
00795 LOAD_FVEC3( fv , ag->ixyz[pp].x, ag->ixyz[pp].y, ag->ixyz[pp].z ) ;
00796 fv = THD_dicomm_to_3dmm( dset , fv ) ;
00797 iv = THD_3dmm_to_3dind( dset , fv ) ;
00798 UNLOAD_IVEC3( iv , ii,jj,kk ) ;
00799 qq = vmap[ii+jj*nx+kk*nxy] ;
00800 if( qq < 0 ){
00801 vmap[ii+jj*nx+kk*nxy] = pp ;
00802 } else {
00803 LOAD_IVEC3(iv,ii,jj,kk) ;
00804 fv = THD_3dind_to_3dmm( dset , iv ) ;
00805 fv = THD_3dmm_to_dicomm( dset , fv ) ;
00806 UNLOAD_FVEC3(fv,xv,yv,zv) ;
00807
00808
00809
00810
00811 xp=xv-ag->ixyz[qq].x;
00812 yp=yv-ag->ixyz[qq].y;
00813 zp=zv-ag->ixyz[qq].z; dd=xp*xp+yp*yp+zp*zp;
00814
00815 xp=xv-ag->ixyz[pp].x;
00816 yp=yv-ag->ixyz[pp].y;
00817 zp=zv-ag->ixyz[pp].z; dbest=xp*xp+yp*yp+zp*zp;
00818
00819 if( dbest < dd ) vmap[ii+jj*nx+kk*nxy] = pp ;
00820 }
00821 }
00822
00823 LOAD_FVEC3( fv , ag->xbot,ag->ybot,ag->zbot ) ;
00824 fv = THD_dicomm_to_3dmm( dset , fv ) ;
00825 iv = THD_3dmm_to_3dind( dset , fv ) ;
00826 UNLOAD_IVEC3( iv , ibot,jbot,kbot ) ;
00827
00828 LOAD_FVEC3( fv , ag->xtop,ag->ytop,ag->ztop ) ;
00829 fv = THD_dicomm_to_3dmm( dset , fv ) ;
00830 iv = THD_3dmm_to_3dind( dset , fv ) ;
00831 UNLOAD_IVEC3( iv , itop,jtop,ktop ) ;
00832
00833
00834
00835
00836 if( ibot > itop ){ ii=ibot ; ibot=itop; itop=ii; }
00837 if( jbot > jtop ){ jj=jbot ; jbot=jtop; jtop=jj; }
00838 if( kbot > ktop ){ kk=kbot ; kbot=ktop; ktop=kk; }
00839 if( ibot < 1 ) ibot = 1 ; if( itop >= nx ) itop = nx-1 ;
00840 if( jbot < 1 ) jbot = 1 ; if( jtop >= ny ) jtop = ny-1 ;
00841 if( kbot < 1 ) kbot = 1 ; if( ktop >= nz ) ktop = nz-1 ;
00842
00843
00844
00845 ntop = ag->ixyz[ag->num_ixyz-1].id + 100 ;
00846
00847
00848
00849
00850 elev = getenv("SUMA_NBHD_LEVEL") ;
00851 if( elev != NULL ){
00852 char *cpt ;
00853 ltop = strtol( elev , &cpt , 10 ) ;
00854 if( ltop < 0 || ltop > 7 || (ltop == 0 && *cpt != '\0') ) ltop = 4 ;
00855 } else {
00856 ltop = 4 ;
00857 }
00858
00859
00860
00861 for( lev=1 ; lev <= ltop ; lev++ ){
00862
00863 if(PRINT_TRACING){
00864 char str[256]; sprintf(str,"expansion level %d",lev); STATUS(str);
00865 }
00866
00867
00868
00869 for( kk=kbot ; kk < ktop ; kk++ ){
00870 for( jj=jbot ; jj < jtop ; jj++ ){
00871 for( ii=ibot ; ii < itop ; ii++ ){
00872
00873 ijk = ii+jj*nx+kk*nxy ;
00874 if( vmap[ijk] >= 0 ) continue ;
00875
00876 LOAD_IVEC3(iv,ii,jj,kk) ;
00877 fv = THD_3dind_to_3dmm( dset , iv ) ;
00878 fv = THD_3dmm_to_dicomm( dset , fv ) ;
00879 UNLOAD_FVEC3(fv,xv,yv,zv) ;
00880
00881 for( pbest=-1,qq=0 ; qq < 26 ; qq++ ){
00882
00883
00884
00885
00886
00887 pp = vmap[(ii+ip[qq][0]) + (jj+ip[qq][1])*nx + (kk+ip[qq][2])*nxy];
00888
00889 if( pp >= 0 ){
00890 pp = SUMA_VMAP_UNMASK(pp) ;
00891 xp=xv-ag->ixyz[pp].x ;
00892 yp=yv-ag->ixyz[pp].y ;
00893 zp=zv-ag->ixyz[pp].z ;
00894 dd=xp*xp+yp*yp+zp*zp ;
00895
00896
00897
00898
00899 if( pbest >= 0 ){
00900 if( dd < dbest ){ pbest = pp ; dbest = dd ; }
00901 } else {
00902 pbest = pp ; dbest = dd ;
00903 }
00904 }
00905 }
00906
00907
00908
00909
00910
00911 if( pbest >= 0 ) vmap[ijk] = -(pbest+ntop) ;
00912
00913 }}}
00914
00915 STATUS(".. masking") ;
00916
00917
00918
00919 lmask = SUMA_VMAP_LEVMASK(lev) ;
00920
00921
00922
00923 for( kk=kbot ; kk < ktop ; kk++ ){
00924 for( jj=jbot ; jj < jtop ; jj++ ){
00925 for( ii=ibot ; ii < itop ; ii++ ){
00926 ijk = ii+jj*nx+kk*nxy ;
00927 if( vmap[ijk] < -1 ) vmap[ijk] = (-vmap[ijk] - ntop) | lmask ;
00928 }}}
00929
00930 }
00931
00932 RETURN( vmap );
00933 }
00934
00935
00936
00937
00938
00939 void SUMA_load( THD_3dim_dataset *dset )
00940 {
00941 int ks ;
00942
00943 ENTRY("SUMA_load") ;
00944
00945 if( !ISVALID_DSET(dset) ||
00946 dset->su_num == 0 ||
00947 dset->su_sname == NULL ) EXRETURN ;
00948
00949
00950
00951 if( dset->su_surf == NULL ){
00952 dset->su_surf = (SUMA_surface **) calloc(dset->su_num,sizeof(SUMA_surface *));
00953 dset->su_vmap = (int **) calloc(dset->su_num,sizeof(int *) );
00954 dset->su_vnlist = (SUMA_vnlist **) calloc(dset->su_num,sizeof(SUMA_vnlist *) );
00955 }
00956
00957 for( ks=0 ; ks < dset->su_num ; ks++ ){
00958
00959 if( dset->su_surf[ks] != NULL ) continue ;
00960
00961 dset->su_surf[ks] = SUMA_read_surface( dset->su_sname[ks] , dset ) ;
00962
00963 if( dset->su_surf[ks] == NULL ) continue ;
00964
00965 if( dset->su_vmap[ks] != NULL ) free(dset->su_vmap[ks]) ;
00966 #if 0
00967 dset->su_vmap[ks] = SUMA_map_dset_to_surf( dset->su_surf , dset ) ;
00968 #else
00969 dset->su_vmap[ks] = NULL ;
00970 #endif
00971
00972 if( dset->su_vnlist[ks] != NULL ){
00973 SUMA_destroy_vnlist( dset->su_vnlist[ks] ) ;
00974 dset->su_vnlist[ks] = NULL ;
00975 }
00976 #if 0
00977 dset->su_vnlist[ks] = SUMA_make_vnlist( dset->su_surf[ks] , dset ) ;
00978 #endif
00979
00980 }
00981
00982 EXRETURN ;
00983 }
00984
00985
00986
00987
00988
00989 void SUMA_unload( THD_3dim_dataset *dset )
00990 {
00991 int ks ;
00992
00993 ENTRY("SUMA_unload") ;
00994
00995 if( !ISVALID_DSET(dset) ||
00996 dset->su_num == 0 ||
00997 dset->su_sname == NULL ||
00998 dset->su_surf == NULL ) EXRETURN ;
00999
01000 for( ks=0 ; ks < dset->su_num ; ks++ ){
01001
01002 if( dset->su_sname[ks] == NULL ||
01003 strstr(dset->su_sname[ks],"++LOCK++") != NULL ) continue ;
01004
01005 if( dset->su_surf[ks] != NULL ){
01006 SUMA_destroy_surface( dset->su_surf[ks] ) ; dset->su_surf[ks] = NULL ;
01007 }
01008
01009 if( dset->su_vmap[ks] != NULL ){
01010 free( dset->su_vmap[ks] ) ; dset->su_vmap[ks] = NULL ;
01011 }
01012
01013 if( dset->su_vnlist[ks] != NULL ){
01014 SUMA_destroy_vnlist( dset->su_vnlist[ks] ) ; dset->su_vnlist[ks] = NULL ;
01015 }
01016
01017 }
01018
01019 EXRETURN ;
01020 }
01021
01022
01023
01024
01025
01026
01027
01028
01029 void SUMA_import_surefit( SUMA_surface *ag, char *lbuf, THD_3dim_dataset *dset )
01030 {
01031 float xx[NBUF],yy[NBUF],zz[NBUF] ;
01032 int pp[NBUF] ;
01033 int nn , ii , idadd=0 ;
01034 FILE *sfp ;
01035 char sname[1024] , *cpt ;
01036 THD_fvec3 fv ;
01037
01038 ENTRY("SUMA_import_surefit") ;
01039
01040
01041
01042 cpt = strstr(lbuf,"coord=") ;
01043 if( cpt == NULL ){
01044 fprintf(stderr,"** SUMA: Illegal SureFit: no coord=\n** %s\n",lbuf) ;
01045 EXRETURN ;
01046 }
01047 cpt += 6 ;
01048 if( *cpt == '\"' || *cpt == '\'' ) cpt++ ;
01049 ii = sscanf(cpt,"%s",sname) ;
01050 if( ii == 0 ){
01051 fprintf(stderr,"** SUMA: Illegal SureFit: bad coord=\n** %s\n",lbuf) ;
01052 EXRETURN ;
01053 }
01054 ii = strlen(sname) ;
01055 if( ii == 0 ){
01056 fprintf(stderr,"** SUMA: Illegal SureFit: bad coord=\n** %s\n",lbuf) ;
01057 EXRETURN ;
01058 }
01059 if( sname[ii-1] == '\'' || sname[ii-1] == '\"' ) sname[ii-1] = '\0' ;
01060 if( strlen(sname) == 0 ){
01061 fprintf(stderr,"** SUMA: Illegal SureFit: bad coord=\n** %s\n",lbuf) ;
01062 EXRETURN ;
01063 }
01064
01065
01066
01067 if( sname[0] != '/' ){
01068 char buf[1024] ;
01069 sprintf(buf,"%s%s",DSET_DIRNAME(dset),sname) ;
01070 strcpy(sname,buf) ;
01071 }
01072
01073
01074
01075 cpt = strstr(lbuf,"IDadd=") ;
01076 if( cpt != NULL ){
01077 cpt += 6 ;
01078 if( *cpt == '\"' || *cpt == '\'' ) cpt++ ;
01079 ii = sscanf(cpt,"%d",&idadd) ;
01080 if( ii == 0 || idadd < 0 ){
01081 fprintf(stderr,"** SUMA: Illegal SureFit: bad IDadd=\n** %s\n",lbuf) ;
01082 EXRETURN ;
01083 }
01084 }
01085
01086
01087
01088 sfp = fopen( sname , "r" ) ;
01089 if( sfp == NULL ){
01090 fprintf(stderr,"** SUMA: Illegal SureFit: can't open file %s\n** %s\n",sname,lbuf) ;
01091 EXRETURN ;
01092 }
01093
01094 nn = 0 ;
01095
01096 while(1){
01097 cpt = fgets(sname,1024,sfp) ;
01098 if( cpt == NULL ) break ;
01099
01100 if( strstr(sname,"BeginHeader") != NULL ){
01101 do{
01102 cpt = fgets(sname,1024,sfp) ;
01103 if( cpt == NULL ){ fclose(sfp); EXRETURN; }
01104 } while( strstr(sname,"EndHeader") == NULL ) ;
01105 cpt = fgets(sname,1024,sfp) ;
01106 if( cpt == NULL ){ fclose(sfp); EXRETURN; }
01107 continue ;
01108 }
01109
01110 ii = sscanf(sname,"%d%f%f%f",pp+nn,xx+nn,yy+nn,zz+nn) ;
01111 if( ii < 4 ) continue ;
01112
01113
01114
01115 pp[nn] += idadd ;
01116 LOAD_FVEC3(fv,xx[nn],yy[nn],zz[nn]) ;
01117 fv = THD_surefit_to_dicomm( dset , fv ) ;
01118 UNLOAD_FVEC3(fv,xx[nn],yy[nn],zz[nn]) ;
01119
01120 nn++ ;
01121 if( nn == NBUF ){
01122 SUMA_add_nodes_ixyz( ag,nn , pp,xx,yy,zz ) ;
01123 nn = 0 ;
01124 }
01125 }
01126
01127 fclose(sfp) ;
01128
01129 if( nn > 0 ){
01130 SUMA_add_nodes_ixyz( ag,nn , pp,xx,yy,zz ) ;
01131 }
01132
01133 EXRETURN ;
01134 }
01135
01136
01137
01138
01139
01140
01141 void SUMA_get_surfname( THD_3dim_dataset *dset )
01142 {
01143 char *snam ;
01144 int ii , ks ;
01145
01146 ENTRY("THD_get_surfname") ;
01147
01148 if( !ISVALID_DSET(dset) || dset->su_num > 0 ) EXRETURN ;
01149
01150 snam = strdup( DSET_HEADNAME(dset) ) ;
01151 ii = strlen(snam) ;
01152 if( ii > 5 ){
01153 strcpy(snam+ii-4,"SURF") ;
01154 if( THD_is_file(snam) ){
01155 dset->su_num = 1 ;
01156 dset->su_sname = (char **) malloc(sizeof(char *)) ;
01157 dset->su_sname[0] = snam;
01158 EXRETURN;
01159 }
01160 }
01161 free(snam) ; EXRETURN ;
01162 }
01163 #endif